opencode-anthropic-fix 0.6.0 → 2.0.0
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/README.md +30 -3
- package/cli.mjs +77 -24
- package/index.mjs +297 -200
- package/lib/account-state.mjs +48 -0
- package/lib/accounts.mjs +211 -12
- package/lib/betas.mjs +131 -0
- package/lib/config.mjs +90 -12
- package/lib/diagnose.mjs +4 -2
- package/lib/mimicry/adapter-input.mjs +137 -33
- package/lib/mimicry/headers.mjs +143 -15
- package/lib/mimicry/request-body.mjs +51 -14
- package/lib/mimicry/system-prompt.mjs +72 -293
- package/lib/mimicry/wire-compat.mjs +133 -11
- package/lib/oauth-constants.mjs +109 -0
- package/lib/oauth-env.mjs +187 -0
- package/lib/oauth-scopes.mjs +119 -0
- package/lib/oauth.mjs +270 -90
- package/lib/passthrough-headers.mjs +152 -0
- package/lib/token-economy/microcompact.mjs +3 -12
- package/package.json +2 -2
- package/lib/mimicry/models.mjs +0 -146
- package/lib/request-headers.mjs +0 -303
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Microcompact decision helpers (token-economy).
|
|
3
3
|
*
|
|
4
|
-
* Pure
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* interceptor shell in index.mjs.
|
|
4
|
+
* Pure helper extracted from index.mjs: whether estimated prompt token usage has
|
|
5
|
+
* crossed the microcompact threshold. The stateful microcompact gating
|
|
6
|
+
* (microcompactState) remains in the interceptor shell in index.mjs.
|
|
8
7
|
*
|
|
9
8
|
* @module token-economy/microcompact
|
|
10
9
|
*/
|
|
@@ -25,11 +24,3 @@ export function shouldMicrocompact(estimatedTokens, config) {
|
|
|
25
24
|
const threshold = contextWindow * (thresholdPct / 100);
|
|
26
25
|
return estimatedTokens >= threshold;
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Build the list of microcompact betas to inject.
|
|
31
|
-
* @returns {string[]} Array of beta flag strings
|
|
32
|
-
*/
|
|
33
|
-
export function buildMicrocompactBetas() {
|
|
34
|
-
return ["clear_tool_uses_20250919", "clear_thinking_20251015"];
|
|
35
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-anthropic-fix",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"license": "GPL-3.0-or-later",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
"vitest": "^4.0.18"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@tormentalabs/claude-code-wire-compat": "
|
|
58
|
+
"@tormentalabs/claude-code-wire-compat": "0.5.0"
|
|
59
59
|
}
|
|
60
60
|
}
|
package/lib/mimicry/models.mjs
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { isTruthyEnv } from "../env.mjs";
|
|
2
|
-
|
|
3
|
-
// Perf: module-scope regex reused across per-request hot paths. It does not use
|
|
4
|
-
// the `/g` flag and is consumed via `.test()`, so the shared instance is
|
|
5
|
-
// stateless and safe (no `lastIndex` to reset between calls).
|
|
6
|
-
export const CLAUDE_3_MODEL_RE = /claude-3-/i;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Detects claude-opus-4.6 / claude-opus-4-6 model IDs.
|
|
10
|
-
* These models use adaptive thinking (effort parameter) instead of
|
|
11
|
-
* manual budgetTokens.
|
|
12
|
-
* @param {string | undefined} model
|
|
13
|
-
* @returns {boolean}
|
|
14
|
-
*/
|
|
15
|
-
export function isOpus46Model(model) {
|
|
16
|
-
if (!model) return false;
|
|
17
|
-
// Match standard IDs (claude-opus-4-6, claude-opus-4.6) and Bedrock ARNs
|
|
18
|
-
// (arn:aws:bedrock:...anthropic.claude-opus-4-6-...).
|
|
19
|
-
// Also match bare "opus-4-6" / "opus-4.6" fragments for non-standard strings.
|
|
20
|
-
return /claude-opus-4[._-]6|opus[._-]4[._-]6/i.test(model);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Detects claude-opus-4.7 / claude-opus-4-7 model IDs.
|
|
25
|
-
* @param {string | undefined} model
|
|
26
|
-
* @returns {boolean}
|
|
27
|
-
*/
|
|
28
|
-
export function isOpus47Model(model) {
|
|
29
|
-
if (!model) return false;
|
|
30
|
-
return /claude-opus-4[._-]7|opus[._-]4[._-]7/i.test(model);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Detects claude-opus-4.8 / claude-opus-4-8 model IDs.
|
|
35
|
-
* Opus 4.8 (launched 2026-05-28) is an adaptive-thinking model: manual
|
|
36
|
-
* `thinking: {type: "enabled", budget_tokens}` returns a 400 — it MUST use
|
|
37
|
-
* `thinking: {type: "adaptive"}` + the effort parameter. It also supports
|
|
38
|
-
* `speed: "fast"` (fast-mode research preview) and 1M context by default.
|
|
39
|
-
* @param {string | undefined} model
|
|
40
|
-
* @returns {boolean}
|
|
41
|
-
*/
|
|
42
|
-
export function isOpus48Model(model) {
|
|
43
|
-
if (!model) return false;
|
|
44
|
-
return /claude-opus-4[._-]8|opus[._-]4[._-]8/i.test(model);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Check if a model is eligible for 1M context (can receive context-1m beta).
|
|
49
|
-
* Real CC v2.1.97 U01(): claude-sonnet-4* || opus-4-6 are eligible.
|
|
50
|
-
* Also matches explicit "1m" in the name (e.g. "claude-opus-4-6[1m]").
|
|
51
|
-
* @param {string} model
|
|
52
|
-
* @returns {boolean}
|
|
53
|
-
*/
|
|
54
|
-
export function isEligibleFor1MContext(model) {
|
|
55
|
-
if (!model) return false;
|
|
56
|
-
if (/(^|[-_ ])1m($|[-_ ])|context[-_]?1m|\[1m\]/i.test(model)) return true;
|
|
57
|
-
return (
|
|
58
|
-
/claude-sonnet-4|sonnet[._-]4/i.test(model) || isOpus46Model(model) || isOpus47Model(model) || isOpus48Model(model)
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Check if a model should ALWAYS use 1M context (static mode, no adaptive gating).
|
|
64
|
-
* Only models with explicit "1m" in the name — NOT bare Opus 4.6.
|
|
65
|
-
* When adaptive_context is enabled, Opus 4.6 uses the adaptive decision instead.
|
|
66
|
-
* @param {string} model
|
|
67
|
-
* @returns {boolean}
|
|
68
|
-
*/
|
|
69
|
-
export function hasOneMillionContext(model) {
|
|
70
|
-
return /(^|[-_ ])1m($|[-_ ])|context[-_]?1m/i.test(model);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Detects claude-sonnet-4.6 / claude-sonnet-4-6 model IDs.
|
|
75
|
-
* @param {string | undefined} model
|
|
76
|
-
* @returns {boolean}
|
|
77
|
-
*/
|
|
78
|
-
export function isSonnet46Model(model) {
|
|
79
|
-
if (!model) return false;
|
|
80
|
-
return /claude-sonnet-4[._-]6|sonnet[._-]4[._-]6/i.test(model);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @param {string | undefined} model
|
|
85
|
-
* @returns {boolean}
|
|
86
|
-
*/
|
|
87
|
-
export function isFable5Model(model) {
|
|
88
|
-
if (!model) return false;
|
|
89
|
-
return /claude-fable-5|fable[._-]5/i.test(model);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @param {string | undefined} model
|
|
94
|
-
* @returns {boolean}
|
|
95
|
-
*/
|
|
96
|
-
export function isMythos5Model(model) {
|
|
97
|
-
if (!model) return false;
|
|
98
|
-
return /claude-mythos-5|mythos[._-]5/i.test(model);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Detects models that support adaptive thinking ({type: "adaptive"}).
|
|
103
|
-
* Currently: Opus 4.6, Opus 4.7, Opus 4.8, Sonnet 4.6, Fable 5, and Mythos 5.
|
|
104
|
-
* @param {string | undefined} model
|
|
105
|
-
* @returns {boolean}
|
|
106
|
-
*/
|
|
107
|
-
export function isAdaptiveThinkingModel(model) {
|
|
108
|
-
return (
|
|
109
|
-
isOpus46Model(model) ||
|
|
110
|
-
isOpus47Model(model) ||
|
|
111
|
-
isOpus48Model(model) ||
|
|
112
|
-
isSonnet46Model(model) ||
|
|
113
|
-
isFable5Model(model) ||
|
|
114
|
-
isMythos5Model(model)
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* @param {any} thinking
|
|
120
|
-
* @param {string} model
|
|
121
|
-
* @returns {any}
|
|
122
|
-
*/
|
|
123
|
-
export function normalizeThinkingBlock(thinking, model) {
|
|
124
|
-
// If thinking is absent or not an object, pass through
|
|
125
|
-
if (!thinking || typeof thinking !== "object") {
|
|
126
|
-
return thinking;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Adaptive thinking models always get { type: "adaptive" }
|
|
130
|
-
// regardless of what format the incoming thinking block has
|
|
131
|
-
if (isAdaptiveThinkingModel(model)) {
|
|
132
|
-
// Check for env-var override to force budget_tokens fallback
|
|
133
|
-
if (isTruthyEnv(process.env.OPENCODE_ANTHROPIC_DISABLE_ADAPTIVE_THINKING)) {
|
|
134
|
-
// Fallback: return as-is if already budget_tokens shape, otherwise default
|
|
135
|
-
if (thinking.type === "enabled" && typeof thinking.budget_tokens === "number") {
|
|
136
|
-
return thinking;
|
|
137
|
-
}
|
|
138
|
-
const parsedBudget = parseInt(process.env.MAX_THINKING_TOKENS, 10);
|
|
139
|
-
return { type: "enabled", budget_tokens: Number.isNaN(parsedBudget) ? 16000 : parsedBudget };
|
|
140
|
-
}
|
|
141
|
-
return { type: "adaptive" };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Non-adaptive models: pass through unchanged
|
|
145
|
-
return thinking;
|
|
146
|
-
}
|
package/lib/request-headers.mjs
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure header/mimicry helpers extracted from index.mjs.
|
|
3
|
-
* No runtime state, no imports needed - all values are self-contained constants
|
|
4
|
-
* or derive from process.env at call time.
|
|
5
|
-
*
|
|
6
|
-
* Exported:
|
|
7
|
-
* - Version/build/SDK constants and CLI_TO_SDK_VERSION map
|
|
8
|
-
* - getSdkVersion(cliVersion)
|
|
9
|
-
* - EXPERIMENTAL_BETA_FLAGS (Set<string>)
|
|
10
|
-
* - BETA_SHORTCUTS (Map<string, string>)
|
|
11
|
-
* - resolveBetaShortcut(value)
|
|
12
|
-
* - buildExtendedUserAgent(version)
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
// Version / build / SDK constants
|
|
17
|
-
// ---------------------------------------------------------------------------
|
|
18
|
-
|
|
19
|
-
// Tracks the CLI version of the wire-compat package's DEFAULT_PROFILE (see
|
|
20
|
-
// lib/mimicry/adapter-input.mjs PROFILE_CLI_VERSION). Bump both together when
|
|
21
|
-
// the package ships a newer default profile.
|
|
22
|
-
export const FALLBACK_CLAUDE_CLI_VERSION = "2.1.233";
|
|
23
|
-
export const CLAUDE_CODE_NPM_LATEST_URL = "https://registry.npmjs.org/@anthropic-ai/claude-code/latest";
|
|
24
|
-
// Real build markers extracted from the 2.1.195 native binary
|
|
25
|
-
// (Bun-embedded JS): `BUILD_TIME:"2026-06-26T01:00:56Z"`,
|
|
26
|
-
// `GIT_SHA:"4603aa3f2ea164bd0974f82eb413ae7acc99a7ee"`.
|
|
27
|
-
// (Prior 2.1.159 linux-x64: BUILD_TIME 2026-05-31T16:22:50Z,
|
|
28
|
-
// GIT_SHA dd8c11fc8d05cea0b2b9fc8f5a99a5c5c5dffc9b.)
|
|
29
|
-
export const CLAUDE_CODE_BUILD_TIME = "2026-06-26T01:00:56Z";
|
|
30
|
-
export const CLAUDE_CODE_GIT_SHA = "4603aa3f2ea164bd0974f82eb413ae7acc99a7ee";
|
|
31
|
-
|
|
32
|
-
// The @anthropic-ai/sdk version bundled with Claude Code.
|
|
33
|
-
// This is distinct from the CLI version and goes in X-Stainless-Package-Version.
|
|
34
|
-
// v2.1.107 switched from @anthropic-ai/sdk v0.208.0 to v0.81.0 (confirmed via bundle var x$H="0.81.0").
|
|
35
|
-
// Still 0.81.0 in v2.1.143 (verified by binary string extraction of win32-x64 native binary:
|
|
36
|
-
// 2.1.134-2.1.143 are telemetry / subagent-header / mid-conversation-system additions with
|
|
37
|
-
// no SDK version bump; mid-conversation-system-2026-04-07 registered in 2.1.143 but not
|
|
38
|
-
// auto-emitted; two new conditional x- headers x-claude-code-agent-id /
|
|
39
|
-
// x-claude-code-parent-agent-id are only emitted in subagent dispatch contexts).
|
|
40
|
-
export const ANTHROPIC_SDK_VERSION = "0.94.0";
|
|
41
|
-
|
|
42
|
-
// Map of CLI version to bundled SDK version (update when CLI version changes)
|
|
43
|
-
export const CLI_TO_SDK_VERSION = new Map([
|
|
44
|
-
// 2.1.233: the wire-compat package's DEFAULT_PROFILE
|
|
45
|
-
// (`claude-code-2.1.233-sdk-0.112.1`) declares sdkVersion 0.112.1, so the
|
|
46
|
-
// legacy header path stays consistent with the adapter path when the tracked
|
|
47
|
-
// CLI version is the profile baseline.
|
|
48
|
-
["2.1.233", "0.112.1"],
|
|
49
|
-
// 2.1.160-2.1.195: refusal-fallback feature (server-side-fallback /
|
|
50
|
-
// fallback-credit betas) is opt-in/GrowthBook-gated and never emitted on a
|
|
51
|
-
// default /v1/messages turn; no wire SDK bump (binary-verified:
|
|
52
|
-
// x-stainless-package-version still "0.94.0" in 2.1.195).
|
|
53
|
-
["2.1.195", "0.94.0"],
|
|
54
|
-
["2.1.194", "0.94.0"],
|
|
55
|
-
["2.1.193", "0.94.0"],
|
|
56
|
-
["2.1.192", "0.94.0"],
|
|
57
|
-
["2.1.191", "0.94.0"],
|
|
58
|
-
["2.1.190", "0.94.0"],
|
|
59
|
-
["2.1.189", "0.94.0"],
|
|
60
|
-
["2.1.188", "0.94.0"],
|
|
61
|
-
["2.1.187", "0.94.0"],
|
|
62
|
-
["2.1.186", "0.94.0"],
|
|
63
|
-
["2.1.185", "0.94.0"],
|
|
64
|
-
["2.1.184", "0.94.0"],
|
|
65
|
-
["2.1.183", "0.94.0"],
|
|
66
|
-
["2.1.182", "0.94.0"],
|
|
67
|
-
["2.1.181", "0.94.0"],
|
|
68
|
-
["2.1.180", "0.94.0"],
|
|
69
|
-
["2.1.179", "0.94.0"],
|
|
70
|
-
["2.1.178", "0.94.0"],
|
|
71
|
-
["2.1.177", "0.94.0"],
|
|
72
|
-
["2.1.176", "0.94.0"],
|
|
73
|
-
["2.1.175", "0.94.0"],
|
|
74
|
-
["2.1.174", "0.94.0"],
|
|
75
|
-
["2.1.173", "0.94.0"],
|
|
76
|
-
["2.1.172", "0.94.0"],
|
|
77
|
-
["2.1.171", "0.94.0"],
|
|
78
|
-
["2.1.170", "0.94.0"],
|
|
79
|
-
["2.1.169", "0.94.0"],
|
|
80
|
-
["2.1.168", "0.94.0"],
|
|
81
|
-
["2.1.167", "0.94.0"],
|
|
82
|
-
["2.1.166", "0.94.0"],
|
|
83
|
-
["2.1.165", "0.94.0"],
|
|
84
|
-
["2.1.164", "0.94.0"],
|
|
85
|
-
["2.1.163", "0.94.0"],
|
|
86
|
-
["2.1.162", "0.94.0"],
|
|
87
|
-
["2.1.161", "0.94.0"],
|
|
88
|
-
["2.1.160", "0.94.0"],
|
|
89
|
-
// 2.1.155-2.1.159: only wire change is the revival of
|
|
90
|
-
// summarize-connector-text-2026-03-13 (label narration_summaries), gated by
|
|
91
|
-
// GrowthBook pewter_owl_header (default-off) — not always-on. SDK still 0.94.0
|
|
92
|
-
// (binary-verified: x-stainless-package-version NQ="0.94.0" in 2.1.159).
|
|
93
|
-
["2.1.159", "0.94.0"],
|
|
94
|
-
["2.1.158", "0.94.0"],
|
|
95
|
-
["2.1.157", "0.94.0"],
|
|
96
|
-
["2.1.156", "0.94.0"],
|
|
97
|
-
["2.1.155", "0.94.0"],
|
|
98
|
-
// 2.1.151-2.1.154: Opus 4.8 launch (2026-05-28). npm now ships a native
|
|
99
|
-
// binary (no JS bundle), so the bundled SDK version can't be string-extracted;
|
|
100
|
-
// no SDK bump was observed across 2.1.150->2.1.154, so we carry 0.94.0 forward.
|
|
101
|
-
["2.1.154", "0.94.0"],
|
|
102
|
-
["2.1.153", "0.94.0"],
|
|
103
|
-
["2.1.152", "0.94.0"],
|
|
104
|
-
["2.1.151", "0.94.0"],
|
|
105
|
-
["2.1.150", "0.94.0"],
|
|
106
|
-
["2.1.143", "0.81.0"],
|
|
107
|
-
["2.1.142", "0.81.0"],
|
|
108
|
-
["2.1.141", "0.81.0"],
|
|
109
|
-
["2.1.140", "0.81.0"],
|
|
110
|
-
["2.1.139", "0.81.0"],
|
|
111
|
-
["2.1.138", "0.81.0"],
|
|
112
|
-
["2.1.137", "0.81.0"],
|
|
113
|
-
["2.1.136", "0.81.0"],
|
|
114
|
-
["2.1.134", "0.81.0"],
|
|
115
|
-
["2.1.133", "0.81.0"],
|
|
116
|
-
["2.1.132", "0.81.0"],
|
|
117
|
-
["2.1.131", "0.81.0"],
|
|
118
|
-
["2.1.130", "0.81.0"],
|
|
119
|
-
["2.1.129", "0.81.0"],
|
|
120
|
-
["2.1.128", "0.81.0"],
|
|
121
|
-
["2.1.127", "0.81.0"],
|
|
122
|
-
["2.1.126", "0.81.0"],
|
|
123
|
-
["2.1.125", "0.81.0"],
|
|
124
|
-
["2.1.124", "0.81.0"],
|
|
125
|
-
["2.1.123", "0.81.0"],
|
|
126
|
-
["2.1.122", "0.81.0"],
|
|
127
|
-
["2.1.121", "0.81.0"],
|
|
128
|
-
["2.1.120", "0.81.0"],
|
|
129
|
-
["2.1.119", "0.81.0"],
|
|
130
|
-
["2.1.117", "0.81.0"],
|
|
131
|
-
["2.1.116", "0.81.0"],
|
|
132
|
-
["2.1.115", "0.81.0"],
|
|
133
|
-
["2.1.114", "0.81.0"],
|
|
134
|
-
["2.1.113", "0.81.0"],
|
|
135
|
-
["2.1.112", "0.81.0"],
|
|
136
|
-
["2.1.111", "0.81.0"],
|
|
137
|
-
["2.1.110", "0.81.0"],
|
|
138
|
-
["2.1.109", "0.81.0"],
|
|
139
|
-
["2.1.108", "0.81.0"],
|
|
140
|
-
["2.1.107", "0.81.0"],
|
|
141
|
-
["2.1.105", "0.81.0"],
|
|
142
|
-
["2.1.97", "0.208.0"],
|
|
143
|
-
["2.1.96", "0.208.0"],
|
|
144
|
-
["2.1.95", "0.208.0"],
|
|
145
|
-
["2.1.94", "0.208.0"],
|
|
146
|
-
["2.1.93", "0.208.0"],
|
|
147
|
-
["2.1.92", "0.208.0"],
|
|
148
|
-
["2.1.91", "0.208.0"],
|
|
149
|
-
["2.1.90", "0.208.0"],
|
|
150
|
-
["2.1.89", "0.208.0"],
|
|
151
|
-
["2.1.88", "0.208.0"],
|
|
152
|
-
["2.1.87", "0.208.0"],
|
|
153
|
-
["2.1.86", "0.208.0"],
|
|
154
|
-
["2.1.85", "0.208.0"],
|
|
155
|
-
["2.1.84", "0.208.0"],
|
|
156
|
-
["2.1.83", "0.208.0"],
|
|
157
|
-
["2.1.81", "0.208.0"],
|
|
158
|
-
["2.1.80", "0.208.0"],
|
|
159
|
-
]);
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Get the SDK version corresponding to a CLI version.
|
|
163
|
-
* Falls back to ANTHROPIC_SDK_VERSION constant.
|
|
164
|
-
* @param {string | null | undefined} cliVersion
|
|
165
|
-
* @returns {string}
|
|
166
|
-
*/
|
|
167
|
-
export function getSdkVersion(cliVersion) {
|
|
168
|
-
return CLI_TO_SDK_VERSION.get(cliVersion) ?? ANTHROPIC_SDK_VERSION;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ---------------------------------------------------------------------------
|
|
172
|
-
// Beta flag registries
|
|
173
|
-
// ---------------------------------------------------------------------------
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Set of all known experimental/optional beta flags.
|
|
177
|
-
* Used to filter betas when CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1.
|
|
178
|
-
* WARNING: this set intentionally overlaps with always-on betas - only use
|
|
179
|
-
* it with the disable-experimental guard, never unconditionally.
|
|
180
|
-
*/
|
|
181
|
-
export const EXPERIMENTAL_BETA_FLAGS = new Set([
|
|
182
|
-
"adaptive-thinking-2026-01-28",
|
|
183
|
-
"advanced-tool-use-2025-11-20",
|
|
184
|
-
"advisor-tool-2026-03-01",
|
|
185
|
-
"afk-mode-2026-01-31",
|
|
186
|
-
"cache-diagnosis-2026-04-07",
|
|
187
|
-
// CCR bring-your-own-cloud beta. Registered in the 2.1.154 binary's _W() table
|
|
188
|
-
// but not emitted on /v1/messages; kept here for the disable-experimental guard.
|
|
189
|
-
"ccr-byoc-2025-07-29",
|
|
190
|
-
"code-execution-2025-08-25",
|
|
191
|
-
"compact-2026-01-12",
|
|
192
|
-
"context-1m-2025-08-07",
|
|
193
|
-
"context-hint-2026-04-09",
|
|
194
|
-
"context-management-2025-06-27",
|
|
195
|
-
"environments-2025-11-01",
|
|
196
|
-
"extended-cache-ttl-2025-04-11",
|
|
197
|
-
// Refusal-fallback credit beta from the upstream Udd registry (CC 2.1.195).
|
|
198
|
-
// Opt-in/GrowthBook-gated; never auto-emitted on a default /v1/messages turn.
|
|
199
|
-
// Listed here for the disable-experimental guard + manual opt-in ONLY.
|
|
200
|
-
"fallback-credit-2026-06-01",
|
|
201
|
-
"fast-mode-2026-02-01",
|
|
202
|
-
"files-api-2025-04-14",
|
|
203
|
-
"interleaved-thinking-2025-05-14",
|
|
204
|
-
// Registered in the 2.1.154 binary's _W() table (mcp_servers label). Plugin
|
|
205
|
-
// proxies MCP tool calls inline and does not emit this on chat completions.
|
|
206
|
-
"mcp-servers-2025-12-04",
|
|
207
|
-
// Registered in CC v2.1.143 but NOT in real CC's always-on emission set
|
|
208
|
-
// (master registry only, not in the always-on subset). Likely GrowthBook-gated
|
|
209
|
-
// pending server rollout. Paired telemetry: tengu_mid_conv_system_fallback_retry.
|
|
210
|
-
"mid-conversation-system-2026-04-07",
|
|
211
|
-
"prompt-caching-scope-2026-01-05",
|
|
212
|
-
"redact-thinking-2026-02-12",
|
|
213
|
-
// Server-side refusal-fallback beta from the upstream Udd registry (CC 2.1.195).
|
|
214
|
-
// Opt-in/GrowthBook-gated; never auto-emitted on a default /v1/messages turn.
|
|
215
|
-
// Listed here for the disable-experimental guard + manual opt-in ONLY.
|
|
216
|
-
"server-side-fallback-2026-06-01",
|
|
217
|
-
"structured-outputs-2025-12-15",
|
|
218
|
-
// Revived in CC 2.1.159 as registry label `narration_summaries` (it was a dead
|
|
219
|
-
// slot from v2.1.90-2.1.154). Real CC emits it only when GrowthBook flag
|
|
220
|
-
// `pewter_owl_header` is on (default-off), first-party, and NOT in fast-mode.
|
|
221
|
-
// Listed here for the disable-guard + manual opt-in ONLY; never emitted always-on.
|
|
222
|
-
"summarize-connector-text-2026-03-13",
|
|
223
|
-
"task-budgets-2026-03-13",
|
|
224
|
-
"tool-search-tool-2025-10-19",
|
|
225
|
-
// SDK admin route beta (used for /v1/user_profiles* endpoints). Registered for
|
|
226
|
-
// forward-compat; the plugin proxies /v1/messages only and does NOT emit this
|
|
227
|
-
// on chat completions.
|
|
228
|
-
"user-profiles-2026-03-24",
|
|
229
|
-
"web-search-2025-03-05",
|
|
230
|
-
]);
|
|
231
|
-
|
|
232
|
-
/** Friendly shortcut aliases for config.custom_betas values. */
|
|
233
|
-
export const BETA_SHORTCUTS = new Map([
|
|
234
|
-
["1m", "context-1m-2025-08-07"],
|
|
235
|
-
["1m-context", "context-1m-2025-08-07"],
|
|
236
|
-
["context-1m", "context-1m-2025-08-07"],
|
|
237
|
-
["cache-diagnosis", "cache-diagnosis-2026-04-07"],
|
|
238
|
-
["cache-diag", "cache-diagnosis-2026-04-07"],
|
|
239
|
-
["cache-ttl", "extended-cache-ttl-2025-04-11"],
|
|
240
|
-
["context-hint", "context-hint-2026-04-09"],
|
|
241
|
-
["environments", "environments-2025-11-01"],
|
|
242
|
-
["extended-cache-ttl", "extended-cache-ttl-2025-04-11"],
|
|
243
|
-
["hint", "context-hint-2026-04-09"],
|
|
244
|
-
["fast", "fast-mode-2026-02-01"],
|
|
245
|
-
["fast-mode", "fast-mode-2026-02-01"],
|
|
246
|
-
["opus-fast", "fast-mode-2026-02-01"],
|
|
247
|
-
["task-budgets", "task-budgets-2026-03-13"],
|
|
248
|
-
["budgets", "task-budgets-2026-03-13"],
|
|
249
|
-
["redact-thinking", "redact-thinking-2026-02-12"],
|
|
250
|
-
["mid-conv-system", "mid-conversation-system-2026-04-07"],
|
|
251
|
-
["mid-system", "mid-conversation-system-2026-04-07"],
|
|
252
|
-
["context-management", "context-management-2025-06-27"],
|
|
253
|
-
["structured-outputs", "structured-outputs-2025-12-15"],
|
|
254
|
-
["web-search", "web-search-2025-03-05"],
|
|
255
|
-
["advanced-tool-use", "advanced-tool-use-2025-11-20"],
|
|
256
|
-
["tool-search-tool", "tool-search-tool-2025-10-19"],
|
|
257
|
-
["effort", "effort-2025-11-24"],
|
|
258
|
-
["prompt-caching-scope", "prompt-caching-scope-2026-01-05"],
|
|
259
|
-
["thinking-token-count", "thinking-token-count-2026-05-13"],
|
|
260
|
-
["afk-mode", "afk-mode-2026-01-31"],
|
|
261
|
-
["advisor-tool", "advisor-tool-2026-03-01"],
|
|
262
|
-
["mcp-servers", "mcp-servers-2025-12-04"],
|
|
263
|
-
["ccr-byoc", "ccr-byoc-2025-07-29"],
|
|
264
|
-
["connector-text", "summarize-connector-text-2026-03-13"],
|
|
265
|
-
["narration-summaries", "summarize-connector-text-2026-03-13"],
|
|
266
|
-
["summarize-connector-text", "summarize-connector-text-2026-03-13"],
|
|
267
|
-
["server-side-fallback", "server-side-fallback-2026-06-01"],
|
|
268
|
-
["fallback", "server-side-fallback-2026-06-01"],
|
|
269
|
-
["fallback-credit", "fallback-credit-2026-06-01"],
|
|
270
|
-
]);
|
|
271
|
-
|
|
272
|
-
// ---------------------------------------------------------------------------
|
|
273
|
-
// Helper functions
|
|
274
|
-
// ---------------------------------------------------------------------------
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Resolve a beta shortcut alias to its canonical flag name.
|
|
278
|
-
* Returns the value unchanged if no alias matches.
|
|
279
|
-
* @param {string | null | undefined} value
|
|
280
|
-
* @returns {string}
|
|
281
|
-
*/
|
|
282
|
-
export function resolveBetaShortcut(value) {
|
|
283
|
-
if (!value) return "";
|
|
284
|
-
const trimmed = value.trim();
|
|
285
|
-
const mapped = BETA_SHORTCUTS.get(trimmed.toLowerCase());
|
|
286
|
-
return mapped || trimmed;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Build the extended User-Agent for API calls.
|
|
291
|
-
* Real CC v96 sends "claude-cli/{version} (external, {entrypoint})" - confirmed via
|
|
292
|
-
* proxy capture of real CC on Windows/Node.js.
|
|
293
|
-
* @param {string} version
|
|
294
|
-
* @returns {string}
|
|
295
|
-
*/
|
|
296
|
-
export function buildExtendedUserAgent(version) {
|
|
297
|
-
const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "cli";
|
|
298
|
-
const sdkVersion = process.env.CLAUDE_AGENT_SDK_VERSION ? `, agent-sdk/${process.env.CLAUDE_AGENT_SDK_VERSION}` : "";
|
|
299
|
-
const clientApp = process.env.CLAUDE_AGENT_SDK_CLIENT_APP
|
|
300
|
-
? `, client-app/${process.env.CLAUDE_AGENT_SDK_CLIENT_APP}`
|
|
301
|
-
: "";
|
|
302
|
-
return `claude-cli/${version} (external, ${entrypoint}${sdkVersion}${clientApp})`;
|
|
303
|
-
}
|