From 94ebaf5bf4e2772d083b1091b23e917a13d3f597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Mon, 3 Aug 2026 04:44:33 +0800 Subject: [PATCH] fix(cli): default missing user type in user agent --- src/utils/http.test.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ src/utils/http.ts | 3 ++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/utils/http.test.ts diff --git a/src/utils/http.test.ts b/src/utils/http.test.ts new file mode 100644 index 00000000..a98d69bb --- /dev/null +++ b/src/utils/http.test.ts @@ -0,0 +1,42 @@ +import { afterEach, describe, expect, test } from 'bun:test' +import { CLAUDE_CODE_COMPAT_VERSION } from '../constants/claudeCodeCompatibility.js' +import { getUserAgent } from './http.js' + +const USER_AGENT_ENV_KEYS = [ + 'USER_TYPE', + 'CLAUDE_CODE_ENTRYPOINT', + 'CLAUDE_AGENT_SDK_VERSION', + 'CLAUDE_AGENT_SDK_CLIENT_APP', +] as const + +const originalEnv = Object.fromEntries( + USER_AGENT_ENV_KEYS.map(key => [key, process.env[key]]), +) as Record<(typeof USER_AGENT_ENV_KEYS)[number], string | undefined> + +afterEach(() => { + for (const key of USER_AGENT_ENV_KEYS) { + const value = originalEnv[key] + if (value === undefined) delete process.env[key] + else process.env[key] = value + } +}) + +describe('getUserAgent', () => { + test('uses the external runtime label when USER_TYPE is absent', () => { + delete process.env.USER_TYPE + process.env.CLAUDE_CODE_ENTRYPOINT = 'sdk-cli' + delete process.env.CLAUDE_AGENT_SDK_VERSION + delete process.env.CLAUDE_AGENT_SDK_CLIENT_APP + + expect(getUserAgent()).toBe( + `claude-cli/${CLAUDE_CODE_COMPAT_VERSION} (external, sdk-cli)`, + ) + }) + + test('preserves an explicit runtime label', () => { + process.env.USER_TYPE = 'ant' + process.env.CLAUDE_CODE_ENTRYPOINT = 'cli' + + expect(getUserAgent()).toContain('(ant, cli') + }) +}) diff --git a/src/utils/http.ts b/src/utils/http.ts index a4d6052f..09b00690 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -17,6 +17,7 @@ import { getWorkload } from './workloadContext.js' // WARNING: We rely on `claude-cli` in the user agent for log filtering. // Please do NOT change this without making sure that logging also gets updated! export function getUserAgent(): string { + const userType = process.env.USER_TYPE || 'external' const agentSdkVersion = process.env.CLAUDE_AGENT_SDK_VERSION ? `, agent-sdk/${process.env.CLAUDE_AGENT_SDK_VERSION}` : '' @@ -32,7 +33,7 @@ export function getUserAgent(): string { // so the read picks up the same setWorkload() value as getAttributionHeader. const workload = getWorkload() const workloadSuffix = workload ? `, workload/${workload}` : '' - return `claude-cli/${CLAUDE_CODE_COMPAT_VERSION} (${process.env.USER_TYPE}, ${process.env.CLAUDE_CODE_ENTRYPOINT ?? 'cli'}${agentSdkVersion}${clientApp}${workloadSuffix})` + return `claude-cli/${CLAUDE_CODE_COMPAT_VERSION} (${userType}, ${process.env.CLAUDE_CODE_ENTRYPOINT ?? 'cli'}${agentSdkVersion}${clientApp}${workloadSuffix})` } export function getMCPUserAgent(): string {