mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
e00e85765b
This PR merges code from `coder/aibridge` repository into `coder/coder`. It was split into 4 PRs for easier review but stacked PRs will need to be merged into this PR so all checks pass. * https://github.com/coder/coder/pull/24190 -> raw code copy (this PR, before merging PRs on top of it, it was just 1 commit: https://github.com/coder/coder/commit/70d33f33200c7e77df910957595715f81f9bec24) * https://github.com/coder/coder/pull/24570 -> update imports in `coder/coder` to use copied code * https://github.com/coder/coder/pull/24586 -> linter fixes and CI integration (also added README.md) * https://github.com/coder/coder/pull/24571 -> added exclude to scripts/check_emdash.sh check Original PR message (before PR squash): Moves coder/aibridge code into coder/coder repository. Omitted files: - `go.mod`, `go.sum`, `.gitignore`, `.github/workflows/ci.yml,` `Makefile`, `LICENSE`, `README.md` (modified README.md is added later) - `.github`, `example`, `buildinfo,` `scripts` directories Simple verification script (will list omitted files) ``` tmp=$(mktemp -d) echo "$tmp" git clone --depth=1 https://github.com/coder/aibridge "$tmp/aibridge" git clone --depth=1 --branch pb/aibridge-code-move https://github.com/coder/coder "$tmp/coder" diff -rq --exclude=.git "$tmp/aibridge" "$tmp/coder/aibridge" # rm -rf "$tmp" ```
61 lines
2.2 KiB
Go
61 lines
2.2 KiB
Go
package aibridge
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type Client string
|
|
|
|
const (
|
|
// Possible values for the "client" field in interception records.
|
|
// Must be kept in sync with documentation: https://github.com/coder/coder/blob/90c11f3386578da053ec5cd9f1475835b980e7c7/docs/ai-coder/ai-bridge/monitoring.md?plain=1#L36-L44
|
|
ClientClaudeCode Client = "Claude Code"
|
|
ClientCodex Client = "Codex"
|
|
ClientZed Client = "Zed"
|
|
ClientCopilotVSC Client = "GitHub Copilot (VS Code)"
|
|
ClientCopilotCLI Client = "GitHub Copilot (CLI)"
|
|
ClientKilo Client = "Kilo Code"
|
|
ClientCoderAgents Client = "Coder Agents"
|
|
ClientCrush Client = "Charm Crush"
|
|
ClientMux Client = "Mux"
|
|
ClientRoo Client = "Roo Code"
|
|
ClientCursor Client = "Cursor"
|
|
ClientUnknown Client = "Unknown"
|
|
)
|
|
|
|
// GuessClient attempts to guess the client application from the request headers.
|
|
// Not all clients set proper user agent headers, so this is a best-effort approach.
|
|
// Based on https://github.com/coder/aibridge/issues/20#issuecomment-3769444101.
|
|
func GuessClient(r *http.Request) Client {
|
|
userAgent := strings.ToLower(r.UserAgent())
|
|
originator := r.Header.Get("originator")
|
|
|
|
// Must be kept in sync with documentation: https://github.com/coder/coder/blob/90c11f3386578da053ec5cd9f1475835b980e7c7/docs/ai-coder/ai-bridge/monitoring.md?plain=1#L36-L44
|
|
switch {
|
|
case strings.HasPrefix(userAgent, "mux/"):
|
|
return ClientMux
|
|
case strings.HasPrefix(userAgent, "claude"):
|
|
return ClientClaudeCode
|
|
case strings.HasPrefix(userAgent, "codex"):
|
|
return ClientCodex
|
|
case strings.HasPrefix(userAgent, "zed/"):
|
|
return ClientZed
|
|
case strings.HasPrefix(userAgent, "githubcopilotchat/"):
|
|
return ClientCopilotVSC
|
|
case strings.HasPrefix(userAgent, "copilot/"):
|
|
return ClientCopilotCLI
|
|
case strings.HasPrefix(userAgent, "kilo-code/") || originator == "kilo-code":
|
|
return ClientKilo
|
|
case strings.HasPrefix(userAgent, "roo-code/") || originator == "roo-code":
|
|
return ClientRoo
|
|
case strings.HasPrefix(userAgent, "coder-agents/"):
|
|
return ClientCoderAgents
|
|
case strings.HasPrefix(userAgent, "charm crush/"):
|
|
return ClientCrush
|
|
case r.Header.Get("x-cursor-client-version") != "":
|
|
return ClientCursor
|
|
}
|
|
return ClientUnknown
|
|
}
|