opencode-anthropic-fix 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +78 -43
- package/lib/config.mjs +27 -4
- package/lib/request-headers.mjs +40 -6
- package/lib/request-headers.test.mjs +12 -12
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -6245,9 +6245,9 @@ function extractFirstUserMessageText(messages) {
|
|
|
6245
6245
|
}
|
|
6246
6246
|
|
|
6247
6247
|
const CLAUDE_CODE_BETA_FLAG = "claude-code-20250219";
|
|
6248
|
-
const
|
|
6249
|
-
const
|
|
6250
|
-
const
|
|
6248
|
+
const _EFFORT_BETA_FLAG = "effort-2025-11-24";
|
|
6249
|
+
const _ADVANCED_TOOL_USE_BETA_FLAG = "advanced-tool-use-2025-11-20";
|
|
6250
|
+
const _FAST_MODE_BETA_FLAG = "fast-mode-2026-02-01";
|
|
6251
6251
|
const TOKEN_COUNTING_BETA_FLAG = "token-counting-2024-11-01";
|
|
6252
6252
|
const CLAUDE_CODE_IDENTITY_STRING = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
6253
6253
|
const KNOWN_IDENTITY_STRINGS = new Set([
|
|
@@ -6481,6 +6481,26 @@ function isOpus47Model(model) {
|
|
|
6481
6481
|
return /claude-opus-4[._-]7|opus[._-]4[._-]7/i.test(model);
|
|
6482
6482
|
}
|
|
6483
6483
|
|
|
6484
|
+
/**
|
|
6485
|
+
* Models eligible for the "simple system prompt" mode that real CC ships in
|
|
6486
|
+
* v2.1.133+ under GrowthBook flag `tengu_vellum_lantern` (or forced via
|
|
6487
|
+
* `CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=1`).
|
|
6488
|
+
*
|
|
6489
|
+
* Real CC's `sR9` matches: `claude-opus-4-7`, any model with `-eap` (early
|
|
6490
|
+
* access) suffix, plus a small GrowthBook-controlled allowlist we can't read.
|
|
6491
|
+
* Plugin mirrors the deterministic subset only.
|
|
6492
|
+
*
|
|
6493
|
+
* @param {string | undefined} model
|
|
6494
|
+
* @returns {boolean}
|
|
6495
|
+
*/
|
|
6496
|
+
function isSimpleSystemPromptEligible(model) {
|
|
6497
|
+
if (!model) return false;
|
|
6498
|
+
if (isOpus47Model(model)) return true;
|
|
6499
|
+
// -eap suffix variant, e.g. "claude-opus-4-7-eap" or "claude-opus-4-7-eap[1m]"
|
|
6500
|
+
if (/-eap(?:\[|$|-)/i.test(model)) return true;
|
|
6501
|
+
return false;
|
|
6502
|
+
}
|
|
6503
|
+
|
|
6484
6504
|
/**
|
|
6485
6505
|
* Detects claude-sonnet-4.6 / claude-sonnet-4-6 model IDs.
|
|
6486
6506
|
* @param {string | undefined} body
|
|
@@ -6724,9 +6744,11 @@ function buildRequestMetadata(input) {
|
|
|
6724
6744
|
* @param {string} version - CLI version (e.g., "2.1.97")
|
|
6725
6745
|
* @param {string} [firstUserMessage] - First user message text for fingerprint computation
|
|
6726
6746
|
* @param {string} [provider] - API provider ("anthropic" | "bedrock" | "vertex" | "foundry" | "anthropicAws" | "mantle")
|
|
6747
|
+
* @param {string} [workloadOverride] - Explicit workload tag from config (`signature_emulation.workload`).
|
|
6748
|
+
* Takes precedence over `CLAUDE_CODE_WORKLOAD` env var. Mirrors real CC's `--workload <tag>` flag.
|
|
6727
6749
|
* @returns {string}
|
|
6728
6750
|
*/
|
|
6729
|
-
function buildAnthropicBillingHeader(version, firstUserMessage, provider) {
|
|
6751
|
+
function buildAnthropicBillingHeader(version, firstUserMessage, provider, workloadOverride) {
|
|
6730
6752
|
if (isFalsyEnv(process.env.CLAUDE_CODE_ATTRIBUTION_HEADER)) return "";
|
|
6731
6753
|
// Real CC sends cc_entrypoint=cli (confirmed via proxy capture).
|
|
6732
6754
|
const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT || "cli";
|
|
@@ -6741,13 +6763,15 @@ function buildAnthropicBillingHeader(version, firstUserMessage, provider) {
|
|
|
6741
6763
|
// The server uses the PRESENCE of cch=00000 as a CC identification signal.
|
|
6742
6764
|
const cchDisabled = provider === "bedrock" || provider === "anthropicAws" || provider === "mantle";
|
|
6743
6765
|
const cchPart = cchDisabled ? "" : " cch=00000;";
|
|
6744
|
-
// Build workload part (upstream concatenates directly, no regex replace)
|
|
6766
|
+
// Build workload part (upstream concatenates directly, no regex replace).
|
|
6767
|
+
// Config wins over env so `signature_emulation.workload` is portable across hosts.
|
|
6745
6768
|
let workloadPart = "";
|
|
6746
|
-
const workload = process.env.CLAUDE_CODE_WORKLOAD;
|
|
6747
|
-
if (workload) {
|
|
6748
|
-
// QA fix M5: sanitize workload value to prevent header injection
|
|
6749
|
-
|
|
6750
|
-
|
|
6769
|
+
const workload = workloadOverride || process.env.CLAUDE_CODE_WORKLOAD;
|
|
6770
|
+
if (workload && !cchDisabled) {
|
|
6771
|
+
// QA fix M5: sanitize workload value to prevent header injection.
|
|
6772
|
+
// Real CC skips cc_workload on bedrock/anthropicAws/mantle (same gate as cch).
|
|
6773
|
+
const safeWorkload = String(workload).replace(/[;\s\r\n]/g, "_");
|
|
6774
|
+
if (safeWorkload) workloadPart = ` cc_workload=${safeWorkload};`;
|
|
6751
6775
|
}
|
|
6752
6776
|
return `x-anthropic-billing-header: cc_version=${ccVersion}; cc_entrypoint=${entrypoint};${cchPart}${workloadPart}`;
|
|
6753
6777
|
}
|
|
@@ -7195,8 +7219,20 @@ function buildSystemPromptBlocks(system, signature) {
|
|
|
7195
7219
|
|
|
7196
7220
|
// Anti-verbosity injection (CC v2.1.100 quiet_salted_ember equivalent).
|
|
7197
7221
|
// Applies to Opus 4.6 / 4.7 for non-title-generator requests.
|
|
7222
|
+
//
|
|
7223
|
+
// Simple-system-prompt gate (CC v2.1.133+ `tengu_vellum_lantern` equivalent):
|
|
7224
|
+
// when `signature.simpleSystemPrompt` is true AND the model is eligible
|
|
7225
|
+
// (Opus 4.7, -eap variants), skip the anti-verbosity boilerplate. Real CC's
|
|
7226
|
+
// simple-prompt mode strips this kind of post-hoc behavioral hand-holding on
|
|
7227
|
+
// models that don't need it. Conservative implementation: gates ONLY the
|
|
7228
|
+
// anti-verbosity push, not the identity / billing / sanitized blocks. Saves
|
|
7229
|
+
// ~600-1500 tokens per request on eligible models without touching the CC
|
|
7230
|
+
// fingerprint markers the server checks.
|
|
7231
|
+
const skipAntiVerbosity = signature.simpleSystemPrompt === true && isSimpleSystemPromptEligible(signature.modelId);
|
|
7232
|
+
|
|
7198
7233
|
if (
|
|
7199
7234
|
!titleGeneratorRequest &&
|
|
7235
|
+
!skipAntiVerbosity &&
|
|
7200
7236
|
signature.modelId &&
|
|
7201
7237
|
(isOpus46Model(signature.modelId) || isOpus47Model(signature.modelId))
|
|
7202
7238
|
) {
|
|
@@ -7233,6 +7269,7 @@ function buildSystemPromptBlocks(system, signature) {
|
|
|
7233
7269
|
signature.claudeCliVersion,
|
|
7234
7270
|
signature.firstUserMessage,
|
|
7235
7271
|
signature.provider,
|
|
7272
|
+
signature.workload,
|
|
7236
7273
|
);
|
|
7237
7274
|
|
|
7238
7275
|
// Select the identity string (matches real CC getCLISyspromptPrefix())
|
|
@@ -7321,24 +7358,12 @@ function buildAnthropicBetaHeader(
|
|
|
7321
7358
|
// behavior from the Anthropic API.
|
|
7322
7359
|
betas.push(CLAUDE_CODE_BETA_FLAG); // "claude-code-20250219"
|
|
7323
7360
|
|
|
7324
|
-
//
|
|
7325
|
-
//
|
|
7326
|
-
// Vertex/Bedrock u2192 tool-search-tool-2025-10-19 (3P-compatible subset)
|
|
7327
|
-
if (provider === "vertex" || provider === "bedrock" || provider === "mantle") {
|
|
7328
|
-
betas.push("tool-search-tool-2025-10-19");
|
|
7329
|
-
} else {
|
|
7330
|
-
betas.push(ADVANCED_TOOL_USE_BETA_FLAG); // "advanced-tool-use-2025-11-20"
|
|
7331
|
-
}
|
|
7361
|
+
// v2.1.150: advanced-tool-use / tool-search-tool removed from always-on.
|
|
7362
|
+
// CC 2.1.150 D5q does not push these per-request. Available via custom betas.
|
|
7332
7363
|
|
|
7333
|
-
|
|
7364
|
+
// v2.1.150: fast-mode-2026-02-01 removed from always-on (CC sends only when speed feature active).
|
|
7334
7365
|
|
|
7335
|
-
// effort-2025-11-24
|
|
7336
|
-
// is true (Opus 4.6 / Sonnet 4.6). Pushing it for non-adaptive models like
|
|
7337
|
-
// Haiku is a fingerprint mismatch vs real CC and can contaminate billing
|
|
7338
|
-
// attribution even when the request body has no effort field.
|
|
7339
|
-
if (isAdaptiveThinkingModel(model)) {
|
|
7340
|
-
betas.push(EFFORT_BETA_FLAG); // "effort-2025-11-24"
|
|
7341
|
-
}
|
|
7366
|
+
// v2.1.150: effort-2025-11-24 removed from always-on (CC sends only when effort is explicitly requested).
|
|
7342
7367
|
|
|
7343
7368
|
// Interleaved thinking — real CC's i01 pushes via hv4(model), which is
|
|
7344
7369
|
// (firstParty && non-Claude-3). Claude 3.x models don't support interleaved
|
|
@@ -7363,18 +7388,20 @@ function buildAnthropicBetaHeader(
|
|
|
7363
7388
|
if (!isRoundRobin) {
|
|
7364
7389
|
betas.push("prompt-caching-scope-2026-01-05");
|
|
7365
7390
|
}
|
|
7391
|
+
// v2.1.150: extended-cache-ttl for better cache hit rates (opt-out via token_economy.extended_cache_ttl = false).
|
|
7392
|
+
if (te.extended_cache_ttl !== false && !isRoundRobin) {
|
|
7393
|
+
betas.push("extended-cache-ttl-2025-04-11");
|
|
7394
|
+
}
|
|
7366
7395
|
|
|
7367
7396
|
// === CONDITIONAL BETAS (model/context-dependent) ===
|
|
7368
7397
|
|
|
7369
|
-
//
|
|
7370
|
-
|
|
7371
|
-
if (!/claude-3-/i.test(model)) {
|
|
7398
|
+
// v2.1.150: context-management gated behind opt-in (CC has hardcoded && false).
|
|
7399
|
+
if (te.context_management && !/claude-3-/i.test(model)) {
|
|
7372
7400
|
betas.push("context-management-2025-06-27");
|
|
7373
7401
|
}
|
|
7374
7402
|
|
|
7375
|
-
//
|
|
7376
|
-
|
|
7377
|
-
if (supportsStructuredOutputs(model)) {
|
|
7403
|
+
// v2.1.150: structured-outputs gated behind opt-in (CC has behind tengu_tool_pear flag).
|
|
7404
|
+
if (te.structured_outputs && supportsStructuredOutputs(model)) {
|
|
7378
7405
|
betas.push("structured-outputs-2025-12-15");
|
|
7379
7406
|
}
|
|
7380
7407
|
|
|
@@ -7408,12 +7435,6 @@ function buildAnthropicBetaHeader(
|
|
|
7408
7435
|
betas.push("context-hint-2026-04-09");
|
|
7409
7436
|
}
|
|
7410
7437
|
|
|
7411
|
-
// extended-cache-ttl-2025-04-11 — found in CC v2.1.133. Extends server-side
|
|
7412
|
-
// prompt cache TTL. Auto-on for 1P + Claude 4+ to improve cache hit rates.
|
|
7413
|
-
if (isFirstPartyProvider && !/claude-3-/i.test(model)) {
|
|
7414
|
-
betas.push("extended-cache-ttl-2025-04-11");
|
|
7415
|
-
}
|
|
7416
|
-
|
|
7417
7438
|
// Files API — scoped to file endpoints/references
|
|
7418
7439
|
if (isFilesEndpoint || hasFileReferences) {
|
|
7419
7440
|
betas.push("files-api-2025-04-14");
|
|
@@ -7426,13 +7447,18 @@ function buildAnthropicBetaHeader(
|
|
|
7426
7447
|
|
|
7427
7448
|
// === TOKEN ECONOMY BETAS (on by default for token savings) ===
|
|
7428
7449
|
|
|
7429
|
-
// redact-thinking
|
|
7430
|
-
//
|
|
7431
|
-
|
|
7432
|
-
if (te.redact_thinking && !disableExperimentalBetas) {
|
|
7450
|
+
// v2.1.150: redact-thinking is default-ON in CC (first-party, non-SDK, thinking models).
|
|
7451
|
+
// Opt out via `/anthropic set redact-thinking off` to see thinking content.
|
|
7452
|
+
if (te.redact_thinking !== false && !disableExperimentalBetas && !/claude-3-/i.test(model)) {
|
|
7433
7453
|
betas.push("redact-thinking-2026-02-12");
|
|
7434
7454
|
}
|
|
7435
7455
|
|
|
7456
|
+
// v2.1.150: thinking-token-count for token budget tracking (behind tengu_chert_bezel in CC).
|
|
7457
|
+
// Default ON for token economy visibility. Opt out via token_economy.thinking_token_count = false.
|
|
7458
|
+
if (te.thinking_token_count !== false && !disableExperimentalBetas && !/claude-3-/i.test(model)) {
|
|
7459
|
+
betas.push("thinking-token-count-2026-05-13");
|
|
7460
|
+
}
|
|
7461
|
+
|
|
7436
7462
|
// compact-2026-01-12 and mcp-client-2025-11-20 exist only in docs, not runtime.
|
|
7437
7463
|
|
|
7438
7464
|
// afk-mode — NOT auto-included (requires user opt-in)
|
|
@@ -7667,7 +7693,7 @@ function buildRequestHeaders(
|
|
|
7667
7693
|
// the minifier identifier renamed, d66 → g86). Re-verify on every upstream bump:
|
|
7668
7694
|
// rg -n '"0\.\d+\.\d+"' _tmp_claude_pkg/<version>/package/cli.js | rg -C2 stainless
|
|
7669
7695
|
// See docs/future-improvements.md §7 and claude-code-reverse-engineering.md §16.
|
|
7670
|
-
requestHeaders.set("x-stainless-package-version", "0.
|
|
7696
|
+
requestHeaders.set("x-stainless-package-version", "0.94.0");
|
|
7671
7697
|
// Real CC on Windows/Node reports "node" — confirmed via proxy capture.
|
|
7672
7698
|
requestHeaders.set("x-stainless-runtime", "node");
|
|
7673
7699
|
requestHeaders.set("x-stainless-runtime-version", process.version);
|
|
@@ -7967,6 +7993,15 @@ function transformRequestBody(body, signature, runtime, betaHeader, config) {
|
|
|
7967
7993
|
// Default off — opt-in via `token_economy.lean_system_non_main: true`.
|
|
7968
7994
|
requestRole: runtime?.requestRole,
|
|
7969
7995
|
leanNonMain: config?.token_economy?.lean_system_non_main === true,
|
|
7996
|
+
// Simple-system-prompt mode for Opus 4.7+ (CC v2.1.133+ parity, gated by
|
|
7997
|
+
// GrowthBook `tengu_vellum_lantern` in real CC). Plugin gate: model
|
|
7998
|
+
// eligibility + opt-in flag. See buildSystemPromptBlocks for what it
|
|
7999
|
+
// strips (anti-verbosity boilerplate only; identity/billing untouched).
|
|
8000
|
+
simpleSystemPrompt: config?.token_economy?.simple_system_prompt === true,
|
|
8001
|
+
// Workload tag for x-anthropic-billing-header `cc_workload=` segment.
|
|
8002
|
+
// Mirrors real CC's `--workload <tag>` CLI flag (process-scoped, used by
|
|
8003
|
+
// SDK daemon callers spawning cron subprocesses). Empty string -> omit.
|
|
8004
|
+
workload: typeof config?.signature_emulation?.workload === "string" ? config.signature_emulation.workload : "",
|
|
7970
8005
|
};
|
|
7971
8006
|
// Sanitize system prompt and optionally inject Claude Code identity/billing blocks.
|
|
7972
8007
|
parsed.system = buildSystemPromptBlocks(normalizeSystemTextBlocks(parsed.system), signatureWithModel);
|
package/lib/config.mjs
CHANGED
|
@@ -80,7 +80,7 @@ import { randomBytes } from "node:crypto";
|
|
|
80
80
|
* @property {AccountSelectionStrategy} account_selection_strategy
|
|
81
81
|
* @property {number} failure_ttl_seconds
|
|
82
82
|
* @property {boolean} debug
|
|
83
|
-
* @property {{ enabled: boolean, fetch_claude_code_version_on_startup: boolean, prompt_compaction: 'minimal' | 'off' }} signature_emulation
|
|
83
|
+
* @property {{ enabled: boolean, fetch_claude_code_version_on_startup: boolean, prompt_compaction: 'minimal' | 'off', workload: string }} signature_emulation
|
|
84
84
|
* @property {OverrideModelLimitsConfig} override_model_limits
|
|
85
85
|
* @property {string[]} custom_betas
|
|
86
86
|
* @property {HealthScoreConfig} health_score
|
|
@@ -115,6 +115,13 @@ export const DEFAULT_CONFIG = {
|
|
|
115
115
|
enabled: true,
|
|
116
116
|
fetch_claude_code_version_on_startup: true,
|
|
117
117
|
prompt_compaction: "minimal",
|
|
118
|
+
/** Workload tag emitted in the `x-anthropic-billing-header` as
|
|
119
|
+
* `cc_workload=<tag>;`. Mirrors real CC's `--workload <tag>` flag — used
|
|
120
|
+
* by SDK daemon callers that spawn subprocesses for cron work, to tag
|
|
121
|
+
* billing attribution. Empty string => omit (default). Provider-gated:
|
|
122
|
+
* bedrock/anthropicAws/mantle skip this segment (same gate as `cch`).
|
|
123
|
+
* Env var `CLAUDE_CODE_WORKLOAD` is a fallback when this is empty. */
|
|
124
|
+
workload: "",
|
|
118
125
|
},
|
|
119
126
|
override_model_limits: {
|
|
120
127
|
enabled: false,
|
|
@@ -190,9 +197,9 @@ export const DEFAULT_CONFIG = {
|
|
|
190
197
|
* This flag is retained for config backward compatibility but has no effect. */
|
|
191
198
|
token_efficient_tools: false,
|
|
192
199
|
/** Enable redact-thinking-2026-02-12 beta (suppresses thinking summaries
|
|
193
|
-
* server-side for lower bandwidth).
|
|
194
|
-
*
|
|
195
|
-
redact_thinking:
|
|
200
|
+
* server-side for lower bandwidth). On by default for non-Claude-3 models
|
|
201
|
+
* (CC v2.1.150+). Opt out via `/anthropic set redact-thinking off`. */
|
|
202
|
+
redact_thinking: true,
|
|
196
203
|
/** Enable context-hint-2026-04-09 beta (CC v2.1.110+). When on, the server
|
|
197
204
|
* MAY reject 422/424 and trigger client-side compaction retries.
|
|
198
205
|
* Default ON (Phase C2). Server-side gating + contextHintState.disabled
|
|
@@ -279,6 +286,17 @@ export const DEFAULT_CONFIG = {
|
|
|
279
286
|
* enable deliberately rather than by default. */
|
|
280
287
|
lean_system_non_main: false,
|
|
281
288
|
|
|
289
|
+
/** Simple system prompt mode (real CC v2.1.133+ `tengu_vellum_lantern`
|
|
290
|
+
* equivalent). When enabled AND the request model is eligible
|
|
291
|
+
* (claude-opus-4-7, -eap variants — see `isSimpleSystemPromptEligible`),
|
|
292
|
+
* skip the anti-verbosity boilerplate (`ANTI_VERBOSITY_SYSTEM_PROMPT` +
|
|
293
|
+
* `NUMERIC_LENGTH_ANCHORS_PROMPT`) that the plugin injects on Opus 4.x.
|
|
294
|
+
* Conservative implementation: gates ONLY anti-verbosity. Identity
|
|
295
|
+
* preamble, billing block, user instructions, and `<system-reminder>`
|
|
296
|
+
* blocks are all preserved so the CC fingerprint match still holds.
|
|
297
|
+
* Saves ~600-1500 tokens per request on eligible models. Opt-in. */
|
|
298
|
+
simple_system_prompt: false,
|
|
299
|
+
|
|
282
300
|
// NOTE: identical-tool-call short-circuit was considered but requires SSE
|
|
283
301
|
// response-stream rewriting that breaks normal tool-execution semantics.
|
|
284
302
|
// Tracked as future work — not exposed as a config flag here.
|
|
@@ -496,6 +514,7 @@ function validateConfig(raw) {
|
|
|
496
514
|
se.prompt_compaction === "off" || se.prompt_compaction === "minimal"
|
|
497
515
|
? se.prompt_compaction
|
|
498
516
|
: DEFAULT_CONFIG.signature_emulation.prompt_compaction,
|
|
517
|
+
workload: typeof se.workload === "string" ? se.workload.trim() : DEFAULT_CONFIG.signature_emulation.workload,
|
|
499
518
|
};
|
|
500
519
|
}
|
|
501
520
|
|
|
@@ -759,6 +778,10 @@ function validateConfig(raw) {
|
|
|
759
778
|
typeof te.lean_system_non_main === "boolean"
|
|
760
779
|
? te.lean_system_non_main
|
|
761
780
|
: DEFAULT_CONFIG.token_economy.lean_system_non_main,
|
|
781
|
+
simple_system_prompt:
|
|
782
|
+
typeof te.simple_system_prompt === "boolean"
|
|
783
|
+
? te.simple_system_prompt
|
|
784
|
+
: DEFAULT_CONFIG.token_economy.simple_system_prompt,
|
|
762
785
|
};
|
|
763
786
|
}
|
|
764
787
|
|
package/lib/request-headers.mjs
CHANGED
|
@@ -16,20 +16,32 @@
|
|
|
16
16
|
// Version / build / SDK constants
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
18
|
|
|
19
|
-
export const FALLBACK_CLAUDE_CLI_VERSION = "2.1.
|
|
19
|
+
export const FALLBACK_CLAUDE_CLI_VERSION = "2.1.150";
|
|
20
20
|
export const CLAUDE_CODE_NPM_LATEST_URL = "https://registry.npmjs.org/@anthropic-ai/claude-code/latest";
|
|
21
|
-
export const CLAUDE_CODE_BUILD_TIME = "2026-05-
|
|
21
|
+
export const CLAUDE_CODE_BUILD_TIME = "2026-05-15T17:39:39Z";
|
|
22
22
|
|
|
23
23
|
// The @anthropic-ai/sdk version bundled with Claude Code.
|
|
24
24
|
// This is distinct from the CLI version and goes in X-Stainless-Package-Version.
|
|
25
25
|
// v2.1.107 switched from @anthropic-ai/sdk v0.208.0 to v0.81.0 (confirmed via bundle var x$H="0.81.0").
|
|
26
|
-
// Still 0.81.0 in v2.1.
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
26
|
+
// Still 0.81.0 in v2.1.143 (verified by binary string extraction of win32-x64 native binary:
|
|
27
|
+
// 2.1.134-2.1.143 are telemetry / subagent-header / mid-conversation-system additions with
|
|
28
|
+
// no SDK version bump; mid-conversation-system-2026-04-07 registered in 2.1.143 but not
|
|
29
|
+
// auto-emitted; two new conditional x- headers x-claude-code-agent-id /
|
|
30
|
+
// x-claude-code-parent-agent-id are only emitted in subagent dispatch contexts).
|
|
31
|
+
export const ANTHROPIC_SDK_VERSION = "0.94.0";
|
|
30
32
|
|
|
31
33
|
// Map of CLI version to bundled SDK version (update when CLI version changes)
|
|
32
34
|
export const CLI_TO_SDK_VERSION = new Map([
|
|
35
|
+
["2.1.150", "0.94.0"],
|
|
36
|
+
["2.1.143", "0.81.0"],
|
|
37
|
+
["2.1.142", "0.81.0"],
|
|
38
|
+
["2.1.141", "0.81.0"],
|
|
39
|
+
["2.1.140", "0.81.0"],
|
|
40
|
+
["2.1.139", "0.81.0"],
|
|
41
|
+
["2.1.138", "0.81.0"],
|
|
42
|
+
["2.1.137", "0.81.0"],
|
|
43
|
+
["2.1.136", "0.81.0"],
|
|
44
|
+
["2.1.134", "0.81.0"],
|
|
33
45
|
["2.1.133", "0.81.0"],
|
|
34
46
|
["2.1.132", "0.81.0"],
|
|
35
47
|
["2.1.131", "0.81.0"],
|
|
@@ -112,11 +124,19 @@ export const EXPERIMENTAL_BETA_FLAGS = new Set([
|
|
|
112
124
|
"fast-mode-2026-02-01",
|
|
113
125
|
"files-api-2025-04-14",
|
|
114
126
|
"interleaved-thinking-2025-05-14",
|
|
127
|
+
// Registered in CC v2.1.143 but NOT in real CC's always-on emission set
|
|
128
|
+
// (master registry only, not in the always-on subset). Likely GrowthBook-gated
|
|
129
|
+
// pending server rollout. Paired telemetry: tengu_mid_conv_system_fallback_retry.
|
|
130
|
+
"mid-conversation-system-2026-04-07",
|
|
115
131
|
"prompt-caching-scope-2026-01-05",
|
|
116
132
|
"redact-thinking-2026-02-12",
|
|
117
133
|
"structured-outputs-2025-12-15",
|
|
118
134
|
"task-budgets-2026-03-13",
|
|
119
135
|
"tool-search-tool-2025-10-19",
|
|
136
|
+
// SDK admin route beta (used for /v1/user_profiles* endpoints). Registered for
|
|
137
|
+
// forward-compat; the plugin proxies /v1/messages only and does NOT emit this
|
|
138
|
+
// on chat completions.
|
|
139
|
+
"user-profiles-2026-03-24",
|
|
120
140
|
"web-search-2025-03-05",
|
|
121
141
|
]);
|
|
122
142
|
|
|
@@ -138,6 +158,20 @@ export const BETA_SHORTCUTS = new Map([
|
|
|
138
158
|
["task-budgets", "task-budgets-2026-03-13"],
|
|
139
159
|
["budgets", "task-budgets-2026-03-13"],
|
|
140
160
|
["redact-thinking", "redact-thinking-2026-02-12"],
|
|
161
|
+
["mid-conv-system", "mid-conversation-system-2026-04-07"],
|
|
162
|
+
["mid-system", "mid-conversation-system-2026-04-07"],
|
|
163
|
+
["context-management", "context-management-2025-06-27"],
|
|
164
|
+
["structured-outputs", "structured-outputs-2025-12-15"],
|
|
165
|
+
["web-search", "web-search-2025-03-05"],
|
|
166
|
+
["advanced-tool-use", "advanced-tool-use-2025-11-20"],
|
|
167
|
+
["tool-search-tool", "tool-search-tool-2025-10-19"],
|
|
168
|
+
["effort", "effort-2025-11-24"],
|
|
169
|
+
["prompt-caching-scope", "prompt-caching-scope-2026-01-05"],
|
|
170
|
+
["thinking-token-count", "thinking-token-count-2026-05-13"],
|
|
171
|
+
["afk-mode", "afk-mode-2026-01-31"],
|
|
172
|
+
["advisor-tool", "advisor-tool-2026-03-01"],
|
|
173
|
+
["mcp-servers", "mcp-servers-2025-12-04"],
|
|
174
|
+
["ccr-byoc", "ccr-byoc-2025-07-29"],
|
|
141
175
|
]);
|
|
142
176
|
|
|
143
177
|
// ---------------------------------------------------------------------------
|
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
} from "./request-headers.mjs";
|
|
14
14
|
|
|
15
15
|
describe("request-headers constants", () => {
|
|
16
|
-
it("FALLBACK_CLAUDE_CLI_VERSION is 2.1.
|
|
17
|
-
expect(FALLBACK_CLAUDE_CLI_VERSION).toBe("2.1.
|
|
16
|
+
it("FALLBACK_CLAUDE_CLI_VERSION is 2.1.150", () => {
|
|
17
|
+
expect(FALLBACK_CLAUDE_CLI_VERSION).toBe("2.1.150");
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it("ANTHROPIC_SDK_VERSION matches expected value", () => {
|
|
@@ -24,9 +24,9 @@ describe("request-headers constants", () => {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
describe("getSdkVersion", () => {
|
|
27
|
-
it("returns known SDK version for CLI version 2.1.
|
|
28
|
-
// 2.1.
|
|
29
|
-
const v = getSdkVersion("2.1.
|
|
27
|
+
it("returns known SDK version for CLI version 2.1.143", () => {
|
|
28
|
+
// 2.1.143 is in the VERSION_TO_SDK_MAP
|
|
29
|
+
const v = getSdkVersion("2.1.143");
|
|
30
30
|
expect(typeof v).toBe("string");
|
|
31
31
|
expect(v).toMatch(/^\d+\.\d+\.\d+$/);
|
|
32
32
|
});
|
|
@@ -95,26 +95,26 @@ describe("buildExtendedUserAgent", () => {
|
|
|
95
95
|
delete process.env.CLAUDE_CODE_ENTRYPOINT;
|
|
96
96
|
delete process.env.CLAUDE_AGENT_SDK_VERSION;
|
|
97
97
|
delete process.env.CLAUDE_AGENT_SDK_CLIENT_APP;
|
|
98
|
-
const ua = buildExtendedUserAgent("2.1.
|
|
99
|
-
expect(ua).toBe("claude-cli/2.1.
|
|
98
|
+
const ua = buildExtendedUserAgent("2.1.143");
|
|
99
|
+
expect(ua).toBe("claude-cli/2.1.143 (external, cli)");
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
it("uses CLAUDE_CODE_ENTRYPOINT when set", () => {
|
|
103
103
|
process.env.CLAUDE_CODE_ENTRYPOINT = "vscode";
|
|
104
|
-
const ua = buildExtendedUserAgent("2.1.
|
|
105
|
-
expect(ua).toBe("claude-cli/2.1.
|
|
104
|
+
const ua = buildExtendedUserAgent("2.1.143");
|
|
105
|
+
expect(ua).toBe("claude-cli/2.1.143 (external, vscode)");
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
it("appends agent-sdk suffix when CLAUDE_AGENT_SDK_VERSION is set", () => {
|
|
109
109
|
process.env.CLAUDE_AGENT_SDK_VERSION = "1.2.3";
|
|
110
|
-
const ua = buildExtendedUserAgent("2.1.
|
|
110
|
+
const ua = buildExtendedUserAgent("2.1.143");
|
|
111
111
|
expect(ua).toContain("agent-sdk/1.2.3");
|
|
112
|
-
expect(ua).toMatch(/^claude-cli\/2\.1\.
|
|
112
|
+
expect(ua).toMatch(/^claude-cli\/2\.1\.143/);
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
it("appends client-app suffix when CLAUDE_AGENT_SDK_CLIENT_APP is set", () => {
|
|
116
116
|
process.env.CLAUDE_AGENT_SDK_CLIENT_APP = "myapp";
|
|
117
|
-
const ua = buildExtendedUserAgent("2.1.
|
|
117
|
+
const ua = buildExtendedUserAgent("2.1.143");
|
|
118
118
|
expect(ua).toContain("client-app/myapp");
|
|
119
119
|
});
|
|
120
120
|
|