[PECOBLR-1928] Add AI coding agent detection to User-Agent header#333
[PECOBLR-1928] Add AI coding agent detection to User-Agent header#333vikrantpuppala wants to merge 1 commit intomainfrom
Conversation
Detect when the Node.js SQL driver is invoked by an AI coding agent (e.g. Claude Code, Cursor, Gemini CLI) by checking well-known environment variables, and append `agent/<product>` to the User-Agent string. This enables Databricks to understand how much driver usage originates from AI coding agents. Detection only succeeds when exactly one agent is detected to avoid ambiguous attribution. Mirrors the approach in databricks/cli#4287. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
There was a problem hiding this comment.
Pull request overview
Adds AI coding agent attribution to the connector’s User-Agent header by detecting well-known agent environment variables and appending an agent/<product> suffix when exactly one agent is detected.
Changes:
- Introduce
detectAgent()utility to identify a single active AI agent via environment variables. - Update
buildUserAgentString()to appendagent/<product>to the User-Agent when detection succeeds. - Extend unit tests to cover detection logic and the optional User-Agent suffix.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
lib/utils/agentDetector.ts |
New env-var-based agent detection helper with “exactly one match” behavior. |
lib/utils/buildUserAgentString.ts |
Appends agent/<product> to the generated User-Agent when an agent is detected. |
tests/unit/utils/agentDetector.test.ts |
Adds unit coverage for all known agents and ambiguous/empty cases. |
tests/unit/utils/utils.test.ts |
Updates UA regex to allow optional agent suffix and adds a suffix assertion test. |
Comments suppressed due to low confidence (1)
tests/unit/utils/utils.test.ts:36
- The test’s inline User-Agent format description (immediately above) still describes a UA that ends at the closing ")". With the new optional
agent/<product>suffix, that description is now misleading—RFC 7231 allows additional product tokens after the initial product/comment. Update the comment/docs near this regex to reflect the optionalagent/...suffix so future changes don’t “fix” the regex back to the old format.
function checkUserAgentString(ua: string, userAgentEntry?: string) {
// Prefix: 'NodejsDatabricksSqlConnector/'
// Version: three period-separated digits and optional suffix
const re =
/^(?<productName>NodejsDatabricksSqlConnector)\/(?<productVersion>\d+\.\d+\.\d+(-[^(]+)?)\s*\((?<comment>[^)]+)\)(\s+agent\/[a-z-]+)?$/i;
const match = re.exec(ua);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const agentProduct = detectAgent(); | ||
| if (agentProduct) { | ||
| ua += ` agent/${agentProduct}`; | ||
| } |
There was a problem hiding this comment.
User-agent string should have following format: product name + slash + product version, then followed by extra details separated by semicolon and enclosed in parenthesis. In this function, extra serves that purpose. So AI agent detail should be just added there
Summary
agentDetector.tsmodule that detects 7 AI coding agents (Claude Code, Cursor, Gemini CLI, Cline, Codex, OpenCode, Antigravity) by checking well-known environment variables they set in spawned shell processesbuildUserAgentString()to appendagent/<product>to the User-Agent headerApproach
Mirrors the implementation in databricks/cli#4287 and aligns with the latest agent list in
libs/agent/agent.go.antigravityANTIGRAVITY_AGENTclaude-codeCLAUDECODEclineCLINE_ACTIVEcodexCODEX_CIcursorCURSOR_AGENTgemini-cliGEMINI_CLIopencodeOPENCODEAdding a new agent requires only a new entry in the
knownAgentsarray.Changes
lib/utils/agentDetector.ts— environment-variable-based agent detection with injectable env object for testabilitylib/utils/buildUserAgentString.ts— callsdetectAgent()and appendsagent/<product>to the User-Agent stringtests/unit/utils/utils.test.ts— updated User-Agent regex to allow optionalagent/<product>suffix; added test asserting suffix is appended when agent env var is settests/unit/utils/agentDetector.test.ts— 11 test cases covering all agents, no agent, multiple agents, empty/undefined valuesTest plan
agentDetector.test.ts— 11 tests passutils.test.ts(buildUserAgentString) — all 4 tests pass (including new agent suffix assertion)agent/claude-codewhen run from Claude Code viaNODE_DEBUG=httpSELECT 1successfully against dogfood warehouse:[{"1":1}]🤖 Generated with Claude Code