Skip to content

Commit 3edb134

Browse files
claude-code-bestdeepseek-v4-pro
andcommitted
refactor: 移除 attribution header 中的 per-message fingerprint 以提升缓存稳定性
getAttributionHeader() 不再接收 fingerprint 参数,cc_version 仅用 MACRO.VERSION。原来 cc_version=2.1.888.abc 中 abc 是 per-message 的 fingerprint,每次请求都变,即使 header 标记为 cacheScope:null 也不利于 未来的缓存优化。 - system.ts: 移除 fingerprint 参数,cc_version 仅用 MACRO.VERSION - claude.ts: 移除 computeFingerprintFromMessages import 及调用 - sideQuery.ts: 移除 fingerprint 计算、extractFirstUserMessageText 及 computeFingerprint import Co-Authored-By: deepseek-v4-pro <deepseek-ai@claude-code-best.win>
1 parent 7af6dda commit 3edb134

3 files changed

Lines changed: 6 additions & 37 deletions

File tree

src/constants/system.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function isAttributionHeaderEnabled(): boolean {
5858

5959
/**
6060
* Get attribution header for API requests.
61-
* Returns a header string with cc_version (including fingerprint) and cc_entrypoint.
61+
* Returns a header string with cc_version and cc_entrypoint.
6262
* Enabled by default, can be disabled via env var or GrowthBook killswitch.
6363
*
6464
* When NATIVE_CLIENT_ATTESTATION is enabled, includes a `cch=00000` placeholder.
@@ -70,22 +70,18 @@ function isAttributionHeaderEnabled(): boolean {
7070
* We use a placeholder (instead of injecting from Zig) because same-length
7171
* replacement avoids Content-Length changes and buffer reallocation.
7272
*/
73-
export function getAttributionHeader(fingerprint: string): string {
73+
export function getAttributionHeader(): string {
7474
if (!isAttributionHeaderEnabled()) {
7575
return ''
7676
}
7777

78-
const version = `${MACRO.VERSION}.${fingerprint}`
78+
const version = MACRO.VERSION
7979
const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? 'unknown'
8080

8181
// cch=00000 placeholder is overwritten by Bun's HTTP stack with attestation token
8282
const cch = feature('NATIVE_CLIENT_ATTESTATION') ? ' cch=00000;' : ''
8383
// cc_workload: turn-scoped hint so the API can route e.g. cron-initiated
84-
// requests to a lower QoS pool. Absent = interactive default. Safe re:
85-
// fingerprint (computed from msg chars + version only, line 78 above) and
86-
// cch attestation (placeholder overwritten in serialized body bytes after
87-
// this string is built). Server _parse_cc_header tolerates unknown extra
88-
// fields so old API deploys silently ignore this.
84+
// requests to a lower QoS pool. Absent = interactive default.
8985
const workload = getWorkload()
9086
const workloadPair = workload ? ` cc_workload=${workload};` : ''
9187
const header = `x-anthropic-billing-header: cc_version=${version}; cc_entrypoint=${entrypoint};${cch}${workloadPair}`

src/services/api/claude.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ import {
7272
import { resolveAppliedEffort } from '../../utils/effort.js'
7373
import { isEnvTruthy } from '../../utils/envUtils.js'
7474
import { errorMessage } from '../../utils/errors.js'
75-
import { computeFingerprintFromMessages } from '../../utils/fingerprint.js'
7675
import { captureAPIRequest, logError } from '../../utils/log.js'
7776
import {
7877
createAssistantAPIErrorMessage,
@@ -1386,11 +1385,6 @@ async function* queryModel(
13861385
postNormalizedMessageCount: messagesForAPI.length,
13871386
})
13881387

1389-
// Compute fingerprint from first user message for attribution.
1390-
// Must run BEFORE injecting synthetic messages (e.g. deferred tool names)
1391-
// so the fingerprint reflects the actual user input.
1392-
const fingerprint = computeFingerprintFromMessages(messagesForAPI)
1393-
13941388
// When the delta attachment is enabled, deferred tools are announced
13951389
// via persisted deferred_tools_delta attachments instead of this
13961390
// ephemeral prepend (which busts cache whenever the pool changes).
@@ -1438,7 +1432,7 @@ async function* queryModel(
14381432
// filter(Boolean) works by converting each element to a boolean - empty strings become false and are filtered out.
14391433
systemPrompt = asSystemPrompt(
14401434
[
1441-
getAttributionHeader(fingerprint),
1435+
getAttributionHeader(),
14421436
getCLISyspromptPrefix({
14431437
isNonInteractive: options.isNonInteractiveSession,
14441438
hasAppendSystemPrompt: options.hasAppendSystemPrompt,

src/utils/sideQuery.ts

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
import { getModelBetas, modelSupportsStructuredOutputs } from './betas.js'
3131
import { logForDebugging } from './debug.js'
3232
import { errorMessage } from './errors.js'
33-
import { computeFingerprint } from './fingerprint.js'
3433
import { getAPIProvider } from './model/providers.js'
3534
import { normalizeModelStringForAPI } from './model/model.js'
3635
import { getOpenAIClient } from '../services/api/openai/client.js'
@@ -97,21 +96,6 @@ export type SideQueryOptions = {
9796
optional?: boolean
9897
}
9998

100-
/**
101-
* Extract text from first user message for fingerprint computation.
102-
*/
103-
function extractFirstUserMessageText(messages: MessageParam[]): string {
104-
const firstUserMessage = messages.find(m => m.role === 'user')
105-
if (!firstUserMessage) return ''
106-
107-
const content = firstUserMessage.content
108-
if (typeof content === 'string') return content
109-
110-
// Array of content blocks - find first text block
111-
const textBlock = content.find(block => block.type === 'text')
112-
return textBlock?.type === 'text' ? textBlock.text : ''
113-
}
114-
11599
/**
116100
* Extract system prompt text from the `system` option.
117101
*/
@@ -219,12 +203,7 @@ export async function sideQuery(opts: SideQueryOptions): Promise<BetaMessage> {
219203
betas.push(STRUCTURED_OUTPUTS_BETA_HEADER)
220204
}
221205

222-
// Extract first user message text for fingerprint
223-
const messageText = extractFirstUserMessageText(messages)
224-
225-
// Compute fingerprint for OAuth attribution
226-
const fingerprint = computeFingerprint(messageText, MACRO.VERSION)
227-
const attributionHeader = getAttributionHeader(fingerprint)
206+
const attributionHeader = getAttributionHeader()
228207

229208
// Build system as array to keep attribution header in its own block
230209
// (prevents server-side parsing from including system content in cc_entrypoint)

0 commit comments

Comments
 (0)