# AI Agent Guidelines for aibridge > For local overrides, create `AGENTS.local.md` (gitignored). You are an experienced, pragmatic software engineer. Simple solutions over clever ones. Readability is a primary concern. ## Tone & Relationship We're colleagues. Push back on bad ideas and speak up when something doesn't make sense. Honesty over agreeableness. - Disagree when I'm wrong. Act as a critical peer reviewer. - Call out bad ideas, unreasonable expectations, and mistakes. - **Ask for clarification** instead of assuming. Say when you don't know something. - Architectural decisions require discussion; routine fixes do not. ## Foundational Rules - Doing it right is better than doing it fast. - YAGNI. Don't add features we don't need right now. - Make the smallest reasonable changes to achieve the goal. - Reduce code duplication, even if it takes extra effort. - Match the style of surrounding code. Consistency within a file matters. - Fix bugs immediately when you find them. ## Essential Commands | Task | Command | Notes | |-------------|------------------|--------------------------------------------| | Test | `make test` | All tests, no race detector | | Test (race) | `make test-race` | CGO_ENABLED=1, use for CI | | Coverage | `make coverage` | Prints summary to stdout | | Format | `make fmt` | gofumpt; single file: `make fmt FILE=path` | | Mocks | `make mocks` | Regenerate from `mcp/api.go` | **Always use these commands** instead of running `go test` or `gofumpt` directly. ## Code Navigation Use LSP tools (go to definition, find references, hover) **before** resorting to grep. This codebase has 90+ Go files across multiple packages, so LSP is faster and more accurate. ## Architecture Overview AI Bridge is a smart gateway that sits between AI clients (Claude Code, Cursor, etc.) and upstream providers (Anthropic, OpenAI). It intercepts all AI traffic to provide centralized authn/z, auditing, token attribution, and MCP tool administration. It runs as part of `coderd` (the Coder control plane). Users authenticate with their Coder session tokens. ``` ┌─────────────┐ ┌──────────────────────────────────────────┐ │ AI Client │ │ aibridge │ │ (Claude Code,│────▶│ RequestBridge (http.Handler) │ │ Cursor) │ │ ├── Provider (Anthropic/OpenAI) │ └─────────────┘ │ ├── Interceptor (streaming/blocking) │ │ ├── Recorder (tokens, prompts, tools) │ │ └── MCP Proxy (tool injection) │ └──────────────┬───────────────────────────┘ │ ▼ ┌──────────────┐ │ Upstream API │ │ (Anthropic, │ │ OpenAI) │ └──────────────┘ ``` Key packages: - `intercept/`: request/response interception, per-provider subdirs (`messages/`, `responses/`, `chatcompletions/`) - `provider/`: upstream provider definitions (Anthropic, OpenAI, Copilot) - `mcp/`: MCP protocol integration - `circuitbreaker/`: circuit breaker for upstream calls - `context/`: request-scoped context helpers - `internal/integrationtest/`: integration tests with mock upstreams ## Go Patterns - Follow the [Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md). - Use `gofumpt` for formatting (enforced by `make fmt`). - Prefer table-driven tests. - **Never use `time.Sleep` in tests**. Use `github.com/coder/quartz` or channels/contexts for synchronization. - Use unique identifiers in tests: `fmt.Sprintf("test-%s-%d", t.Name(), time.Now().UnixNano())`. - Test observable behavior, not implementation details. ## Streaming Code This codebase heavily uses SSE streaming. When modifying interceptors: - Always handle both blocking and streaming paths. - Test with `*_test.go` files in the same package. They cover edge cases for chunked responses. - Be careful with goroutine lifecycle. Ensure proper cleanup on context cancellation. ## Commit Style ``` type(scope): message ``` - `scope` = real package path (e.g., `intercept/messages`, `provider`, `circuitbreaker`) - Comments: full sentences, max 80 chars, explain **why** not what. ## Do NOT - Rewrite comments or refactor code that isn't related to your task. - Remove context from error messages. - Use `--no-verify` on git operations. - Add `//nolint` without a justification comment. - Introduce new dependencies without discussion. ## Common Pitfalls | Problem | Fix | |-------------------------------|------------------------------------------------------------------| | Race in streaming tests | Use `t.Cleanup()` and proper synchronization, never `time.Sleep` | | Mock not updated | Run `make mocks` after changing `mcp/api.go` | | Formatting failures | Run `make fmt` before committing | | `retract` directive in go.mod | Don't remove. It's intentional (v1.0.8 conflict marker) |