opencode-anthropic-fix 0.1.8 → 0.1.9
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 +222 -27
- package/lib/config.mjs +2 -9
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -666,6 +666,7 @@ export async function AnthropicAuthPlugin({ client, project, directory, worktree
|
|
|
666
666
|
const secondary = (args[1] || "").toLowerCase();
|
|
667
667
|
if (secondary === "reset") {
|
|
668
668
|
sessionMetrics.turns = 0;
|
|
669
|
+
sessionMetrics.usedTools.clear();
|
|
669
670
|
sessionMetrics.totalInput = 0;
|
|
670
671
|
sessionMetrics.totalOutput = 0;
|
|
671
672
|
sessionMetrics.totalCacheRead = 0;
|
|
@@ -1081,8 +1082,6 @@ export async function AnthropicAuthPlugin({ client, project, directory, worktree
|
|
|
1081
1082
|
const enabled = value === "on" || value === "true" || value === "1";
|
|
1082
1083
|
const te = config.token_economy || {
|
|
1083
1084
|
token_efficient_tools: true,
|
|
1084
|
-
redact_thinking: false,
|
|
1085
|
-
connector_text_summarization: true,
|
|
1086
1085
|
};
|
|
1087
1086
|
te.token_efficient_tools = enabled;
|
|
1088
1087
|
saveConfig({ token_economy: te });
|
|
@@ -1094,25 +1093,35 @@ export async function AnthropicAuthPlugin({ client, project, directory, worktree
|
|
|
1094
1093
|
const enabled = value === "on" || value === "true" || value === "1";
|
|
1095
1094
|
const te = config.token_economy || {
|
|
1096
1095
|
token_efficient_tools: true,
|
|
1097
|
-
redact_thinking: false,
|
|
1098
|
-
connector_text_summarization: true,
|
|
1099
1096
|
};
|
|
1100
1097
|
te.redact_thinking = enabled;
|
|
1101
1098
|
saveConfig({ token_economy: te });
|
|
1102
1099
|
config.token_economy = te;
|
|
1103
1100
|
betaLatchState.dirty = true;
|
|
1104
1101
|
},
|
|
1105
|
-
"
|
|
1102
|
+
"tool-deferral": () => {
|
|
1106
1103
|
const enabled = value === "on" || value === "true" || value === "1";
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
saveConfig({
|
|
1114
|
-
config.
|
|
1115
|
-
|
|
1104
|
+
saveConfig({ token_economy_strategies: { tool_deferral: enabled } });
|
|
1105
|
+
if (!config.token_economy_strategies) config.token_economy_strategies = {};
|
|
1106
|
+
config.token_economy_strategies.tool_deferral = enabled;
|
|
1107
|
+
},
|
|
1108
|
+
"tool-compaction": () => {
|
|
1109
|
+
const enabled = value === "on" || value === "true" || value === "1";
|
|
1110
|
+
saveConfig({ token_economy_strategies: { tool_description_compaction: enabled } });
|
|
1111
|
+
if (!config.token_economy_strategies) config.token_economy_strategies = {};
|
|
1112
|
+
config.token_economy_strategies.tool_description_compaction = enabled;
|
|
1113
|
+
},
|
|
1114
|
+
"adaptive-tools": () => {
|
|
1115
|
+
const enabled = value === "on" || value === "true" || value === "1";
|
|
1116
|
+
saveConfig({ token_economy_strategies: { adaptive_tool_set: enabled } });
|
|
1117
|
+
if (!config.token_economy_strategies) config.token_economy_strategies = {};
|
|
1118
|
+
config.token_economy_strategies.adaptive_tool_set = enabled;
|
|
1119
|
+
},
|
|
1120
|
+
"prompt-tailing": () => {
|
|
1121
|
+
const enabled = value === "on" || value === "true" || value === "1";
|
|
1122
|
+
saveConfig({ token_economy_strategies: { system_prompt_tailing: enabled } });
|
|
1123
|
+
if (!config.token_economy_strategies) config.token_economy_strategies = {};
|
|
1124
|
+
config.token_economy_strategies.system_prompt_tailing = enabled;
|
|
1116
1125
|
},
|
|
1117
1126
|
};
|
|
1118
1127
|
|
|
@@ -2785,11 +2794,19 @@ export async function AnthropicAuthPlugin({ client, project, directory, worktree
|
|
|
2785
2794
|
cachePolicy: effectiveCachePolicy,
|
|
2786
2795
|
fastMode: config.fast_mode || false,
|
|
2787
2796
|
strategy: getEffectiveStrategy(),
|
|
2797
|
+
toolDeferral: config.token_economy_strategies?.tool_deferral,
|
|
2798
|
+
toolDescriptionCompaction: config.token_economy_strategies?.tool_description_compaction,
|
|
2799
|
+
adaptiveToolSet: config.token_economy_strategies?.adaptive_tool_set,
|
|
2800
|
+
systemPromptTailing: config.token_economy_strategies?.system_prompt_tailing,
|
|
2801
|
+
systemPromptTailTurns: config.token_economy_strategies?.system_prompt_tail_turns,
|
|
2802
|
+
systemPromptTailMaxChars: config.token_economy_strategies?.system_prompt_tail_max_chars,
|
|
2788
2803
|
},
|
|
2789
2804
|
{
|
|
2790
2805
|
persistentUserId: signatureUserId,
|
|
2791
2806
|
sessionId: signatureSessionId,
|
|
2792
2807
|
accountId: getAccountIdentifier(account),
|
|
2808
|
+
turns: sessionMetrics.turns,
|
|
2809
|
+
usedTools: sessionMetrics.usedTools,
|
|
2793
2810
|
},
|
|
2794
2811
|
computedBetaHeader,
|
|
2795
2812
|
config,
|
|
@@ -3908,6 +3925,8 @@ const sessionMetrics = {
|
|
|
3908
3925
|
continuations: 0,
|
|
3909
3926
|
outputHistory: [], // last 5 output token deltas
|
|
3910
3927
|
},
|
|
3928
|
+
/** Tools used in this session (populated from assistant tool_use blocks in messages) */
|
|
3929
|
+
usedTools: new Set(),
|
|
3911
3930
|
};
|
|
3912
3931
|
|
|
3913
3932
|
// ---------------------------------------------------------------------------
|
|
@@ -5357,6 +5376,23 @@ const BEDROCK_UNSUPPORTED_BETAS = new Set([
|
|
|
5357
5376
|
"context-1m-2025-08-07",
|
|
5358
5377
|
"tool-search-tool-2025-10-19",
|
|
5359
5378
|
]);
|
|
5379
|
+
// OpenCode SDK betas that leak through the host's Anthropic SDK but are NOT
|
|
5380
|
+
// part of CC's beta vocabulary. Filtered out when signature emulation is on.
|
|
5381
|
+
// Core tool names (CC PascalCase) that are always eager-loaded.
|
|
5382
|
+
const CORE_TOOL_NAMES = new Set([
|
|
5383
|
+
"Bash",
|
|
5384
|
+
"Read",
|
|
5385
|
+
"Glob",
|
|
5386
|
+
"Grep",
|
|
5387
|
+
"Edit",
|
|
5388
|
+
"Write",
|
|
5389
|
+
"WebFetch",
|
|
5390
|
+
"TodoWrite",
|
|
5391
|
+
"Skill",
|
|
5392
|
+
"Task",
|
|
5393
|
+
"Compress",
|
|
5394
|
+
]);
|
|
5395
|
+
const HOST_SDK_BETAS_BLOCKLIST = new Set(["fine-grained-tool-streaming-2025-05-14", "structured-outputs-2025-11-13"]);
|
|
5360
5396
|
const EXPERIMENTAL_BETA_FLAGS = new Set([
|
|
5361
5397
|
"adaptive-thinking-2026-01-28",
|
|
5362
5398
|
"advanced-tool-use-2025-11-20",
|
|
@@ -5883,6 +5919,55 @@ function sanitizeSystemText(text) {
|
|
|
5883
5919
|
* @param {'minimal' | 'off'} mode
|
|
5884
5920
|
* @returns {string}
|
|
5885
5921
|
*/
|
|
5922
|
+
function tailSystemBlock(text, maxChars, turnThreshold) {
|
|
5923
|
+
const lines = text.split("\n");
|
|
5924
|
+
const kept = [];
|
|
5925
|
+
let charCount = 0;
|
|
5926
|
+
const importantRe = /\b(MUST|NEVER|CRITICAL|IMPORTANT|REQUIRED|DO NOT|ALWAYS|FORBIDDEN)\b/i;
|
|
5927
|
+
const headerRe = /^#{1,4}\s/;
|
|
5928
|
+
const listItemRe = /^\s*[-*]\s/;
|
|
5929
|
+
// Always keep the first paragraph (identity/role definition)
|
|
5930
|
+
let firstParaEnd = 0;
|
|
5931
|
+
for (let j = 0; j < lines.length; j++) {
|
|
5932
|
+
if (lines[j].trim() === "" && j > 0) {
|
|
5933
|
+
firstParaEnd = j;
|
|
5934
|
+
break;
|
|
5935
|
+
}
|
|
5936
|
+
}
|
|
5937
|
+
if (firstParaEnd === 0) firstParaEnd = Math.min(5, lines.length);
|
|
5938
|
+
for (let j = 0; j <= firstParaEnd; j++) {
|
|
5939
|
+
kept.push(lines[j]);
|
|
5940
|
+
charCount += (lines[j]?.length || 0) + 1;
|
|
5941
|
+
}
|
|
5942
|
+
// Scan remaining lines: keep headers, important constraints, short list items
|
|
5943
|
+
for (let j = firstParaEnd + 1; j < lines.length; j++) {
|
|
5944
|
+
const line = lines[j];
|
|
5945
|
+
const isHeader = headerRe.test(line);
|
|
5946
|
+
const isImportant = importantRe.test(line);
|
|
5947
|
+
const isShortListItem = listItemRe.test(line) && line.length < 120;
|
|
5948
|
+
if (isHeader || isImportant || isShortListItem) {
|
|
5949
|
+
if (charCount + line.length + 1 > maxChars) break;
|
|
5950
|
+
kept.push(line);
|
|
5951
|
+
charCount += line.length + 1;
|
|
5952
|
+
}
|
|
5953
|
+
}
|
|
5954
|
+
kept.push("", "[Verbose instructions trimmed after turn " + turnThreshold + ". Key constraints preserved above.]");
|
|
5955
|
+
return kept.join("\n");
|
|
5956
|
+
}
|
|
5957
|
+
|
|
5958
|
+
function compactToolDescription(text) {
|
|
5959
|
+
return text
|
|
5960
|
+
.replace(/<example[\s\S]*?<\/example>/gi, "")
|
|
5961
|
+
.replace(/\|[\s|:-]+\|/g, "")
|
|
5962
|
+
.replace(/^\|.*\|$/gm, "")
|
|
5963
|
+
.replace(/^(?:\s*[-*]\s+.{200,})$/gm, (m) => m.slice(0, 200) + "...")
|
|
5964
|
+
.replace(/^(#{1,3}\s+)/gm, "")
|
|
5965
|
+
.replace(/\*\*([^*]+)\*\*/g, "$1")
|
|
5966
|
+
.replace(/`([^`]+)`/g, "$1")
|
|
5967
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
5968
|
+
.trim();
|
|
5969
|
+
}
|
|
5970
|
+
|
|
5886
5971
|
function compactSystemText(text, mode) {
|
|
5887
5972
|
const withoutDuplicateIdentityPrefix = text.startsWith(`${CLAUDE_CODE_IDENTITY_STRING}\n`)
|
|
5888
5973
|
? text.slice(CLAUDE_CODE_IDENTITY_STRING.length).trimStart()
|
|
@@ -6386,6 +6471,14 @@ function buildAnthropicBetaHeader(
|
|
|
6386
6471
|
betas.push("web-search-2025-03-05");
|
|
6387
6472
|
}
|
|
6388
6473
|
|
|
6474
|
+
// Advisor tool — in CC this is gated by server-side feature flag
|
|
6475
|
+
// (tengu_sage_compass2) and firstParty+isLoggedIn. Since we can't check
|
|
6476
|
+
// CC's feature flags, include it unconditionally for Claude 4+ models.
|
|
6477
|
+
// CC v108 sends it in MITM captures for Max/Pro users.
|
|
6478
|
+
if (!/claude-3-/i.test(model)) {
|
|
6479
|
+
betas.push("advisor-tool-2026-03-01");
|
|
6480
|
+
}
|
|
6481
|
+
|
|
6389
6482
|
// Files API — scoped to file endpoints/references
|
|
6390
6483
|
if (isFilesEndpoint || hasFileReferences) {
|
|
6391
6484
|
betas.push("files-api-2025-04-14");
|
|
@@ -6396,16 +6489,15 @@ function buildAnthropicBetaHeader(
|
|
|
6396
6489
|
betas.push(TOKEN_COUNTING_BETA_FLAG);
|
|
6397
6490
|
}
|
|
6398
6491
|
|
|
6399
|
-
// === TOKEN ECONOMY BETAS (
|
|
6492
|
+
// === TOKEN ECONOMY BETAS (on by default for token savings) ===
|
|
6400
6493
|
|
|
6401
6494
|
// redact-thinking: suppresses thinking summaries server-side.
|
|
6402
|
-
//
|
|
6403
|
-
//
|
|
6495
|
+
// CC v108 enables this by default but we keep it off so thinking is visible.
|
|
6496
|
+
// Users can opt in via `/anthropic set redact-thinking on`.
|
|
6404
6497
|
if (te.redact_thinking && !disableExperimentalBetas) {
|
|
6405
6498
|
betas.push("redact-thinking-2026-02-12");
|
|
6406
6499
|
}
|
|
6407
6500
|
|
|
6408
|
-
// summarize-connector-text-2026-03-13 was removed in v2.1.90 (dead slot njq="").
|
|
6409
6501
|
// compact-2026-01-12 and mcp-client-2025-11-20 exist only in docs, not runtime.
|
|
6410
6502
|
|
|
6411
6503
|
// afk-mode — NOT auto-included (requires user opt-in)
|
|
@@ -6418,8 +6510,11 @@ function buildAnthropicBetaHeader(
|
|
|
6418
6510
|
}
|
|
6419
6511
|
}
|
|
6420
6512
|
|
|
6421
|
-
// Merge incoming betas from the original request
|
|
6422
|
-
|
|
6513
|
+
// Merge incoming betas from the original request, filtering out host-injected
|
|
6514
|
+
// betas (e.g. fine-grained-tool-streaming-2025-05-14, structured-outputs-2025-11-13)
|
|
6515
|
+
// that OpenCode's Anthropic SDK adds but real Claude Code never sends.
|
|
6516
|
+
const filteredIncoming = incomingBetasList.filter((b) => !HOST_SDK_BETAS_BLOCKLIST.has(b));
|
|
6517
|
+
let mergedBetas = [...new Set([...betas, ...filteredIncoming])];
|
|
6423
6518
|
|
|
6424
6519
|
// Add custom betas from config
|
|
6425
6520
|
if (customBetas?.length) {
|
|
@@ -6713,7 +6808,7 @@ function resolveMaxTokens(body, config) {
|
|
|
6713
6808
|
*
|
|
6714
6809
|
* @param {string | undefined} body
|
|
6715
6810
|
* @param {{enabled: boolean, claudeCliVersion: string, promptCompactionMode: 'minimal' | 'off', provider?: string}} signature
|
|
6716
|
-
* @param {{persistentUserId: string, sessionId: string, accountId: string}} runtime
|
|
6811
|
+
* @param {{persistentUserId: string, sessionId: string, accountId: string, turns?: number, usedTools?: Set<string>}} runtime
|
|
6717
6812
|
* @param {string} [betaHeader] - Pre-computed anthropic-beta header value to inject into the body.
|
|
6718
6813
|
* @param {import('./lib/config.mjs').AnthropicAuthConfig} [config] - Plugin configuration for output cap
|
|
6719
6814
|
* @returns {string | undefined}
|
|
@@ -6813,6 +6908,22 @@ function transformRequestBody(body, signature, runtime, betaHeader, config) {
|
|
|
6813
6908
|
// Sanitize system prompt and optionally inject Claude Code identity/billing blocks.
|
|
6814
6909
|
parsed.system = buildSystemPromptBlocks(normalizeSystemTextBlocks(parsed.system), signatureWithModel);
|
|
6815
6910
|
|
|
6911
|
+
// Strategy 5 — System prompt tailing: after N turns, trim large system blocks
|
|
6912
|
+
// to essential sections only. The model has internalized verbose instructions
|
|
6913
|
+
// (shell strategy, package manager tables, delegation protocols) by this point.
|
|
6914
|
+
// Preserves: first paragraph (identity/role), lines containing MUST/NEVER/CRITICAL/
|
|
6915
|
+
// IMPORTANT, section headers, and short blocks. Drops verbose body paragraphs.
|
|
6916
|
+
const tailThreshold = signature.systemPromptTailTurns ?? 6;
|
|
6917
|
+
if (signature.systemPromptTailing !== false && runtime.turns >= tailThreshold && Array.isArray(parsed.system)) {
|
|
6918
|
+
const maxChars = signature.systemPromptTailMaxChars ?? 2000;
|
|
6919
|
+
for (let i = 0; i < parsed.system.length; i++) {
|
|
6920
|
+
const block = parsed.system[i];
|
|
6921
|
+
if (block.type === "text" && block.text && block.text.length > maxChars * 2) {
|
|
6922
|
+
block.text = tailSystemBlock(block.text, maxChars, tailThreshold);
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6925
|
+
}
|
|
6926
|
+
|
|
6816
6927
|
// Token budget (A9): parse NL budget from last user message, inject status block
|
|
6817
6928
|
if (config?.token_budget?.enabled && Array.isArray(parsed.messages)) {
|
|
6818
6929
|
const budgetExpr = parseNaturalLanguageBudget(parsed.messages);
|
|
@@ -6864,10 +6975,12 @@ function transformRequestBody(body, signature, runtime, betaHeader, config) {
|
|
|
6864
6975
|
// our system prompt ttl=1h). Then add our own 1h to the last user message
|
|
6865
6976
|
// (matching real CC behavior seen in proxy capture).
|
|
6866
6977
|
const ccTtl = signature.cachePolicy?.ttl || "1h";
|
|
6867
|
-
if (Array.isArray(parsed.tools)) {
|
|
6978
|
+
if (Array.isArray(parsed.tools) && parsed.tools.length > 0) {
|
|
6868
6979
|
for (const tool of parsed.tools) {
|
|
6869
6980
|
if (tool.cache_control) delete tool.cache_control;
|
|
6870
6981
|
}
|
|
6982
|
+
// Add cache_control to last tool as prompt-cache breakpoint (CC does this)
|
|
6983
|
+
parsed.tools[parsed.tools.length - 1].cache_control = { type: "ephemeral", ttl: ccTtl };
|
|
6871
6984
|
}
|
|
6872
6985
|
if (Array.isArray(parsed.messages)) {
|
|
6873
6986
|
for (const msg of parsed.messages) {
|
|
@@ -6925,6 +7038,69 @@ function transformRequestBody(body, signature, runtime, betaHeader, config) {
|
|
|
6925
7038
|
}
|
|
6926
7039
|
}
|
|
6927
7040
|
}
|
|
7041
|
+
// Track which tools the model has used (from assistant tool_use blocks).
|
|
7042
|
+
// Names are already CC PascalCase after renaming above.
|
|
7043
|
+
if (Array.isArray(parsed.messages)) {
|
|
7044
|
+
for (const msg of parsed.messages) {
|
|
7045
|
+
if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
7046
|
+
for (const block of msg.content) {
|
|
7047
|
+
if (block.type === "tool_use" && block.name) {
|
|
7048
|
+
runtime.usedTools.add(block.name);
|
|
7049
|
+
}
|
|
7050
|
+
}
|
|
7051
|
+
}
|
|
7052
|
+
}
|
|
7053
|
+
}
|
|
7054
|
+
|
|
7055
|
+
// Strategy 4 — Adaptive tool set: after turn 3, defer non-core tools that
|
|
7056
|
+
// the model hasn't used yet. This saves schema bytes on turns where tools
|
|
7057
|
+
// are unlikely to be needed. Core tools stay eager. Resets on /clear.
|
|
7058
|
+
if (
|
|
7059
|
+
Array.isArray(parsed.tools) &&
|
|
7060
|
+
signature.adaptiveToolSet !== false &&
|
|
7061
|
+
runtime.turns >= 3 &&
|
|
7062
|
+
parsed.model &&
|
|
7063
|
+
!/claude-3-|haiku/i.test(parsed.model)
|
|
7064
|
+
) {
|
|
7065
|
+
const used = runtime.usedTools;
|
|
7066
|
+
for (const tool of parsed.tools) {
|
|
7067
|
+
if (tool.name && !used.has(tool.name) && !CORE_TOOL_NAMES.has(tool.name)) {
|
|
7068
|
+
tool.defer_loading = true;
|
|
7069
|
+
}
|
|
7070
|
+
}
|
|
7071
|
+
}
|
|
7072
|
+
|
|
7073
|
+
// Tool description compaction: apply the same compaction logic used for
|
|
7074
|
+
// system prompts (strip examples, collapse whitespace, dedup lines) to tool
|
|
7075
|
+
// descriptions. The top 4 tools (Bash 10.6K, TodoWrite 9.7K, Task 5.5K,
|
|
7076
|
+
// Compress 4.5K) account for 30KB. Compaction typically saves 30-50%.
|
|
7077
|
+
if (Array.isArray(parsed.tools) && signature.toolDescriptionCompaction !== false) {
|
|
7078
|
+
for (const tool of parsed.tools) {
|
|
7079
|
+
if (tool.description && tool.description.length > 500) {
|
|
7080
|
+
tool.description = compactToolDescription(tool.description);
|
|
7081
|
+
}
|
|
7082
|
+
}
|
|
7083
|
+
}
|
|
7084
|
+
|
|
7085
|
+
// MCP tool deferral: mark non-core tools with defer_loading: true.
|
|
7086
|
+
// CC defers all MCP tools by default — the API omits their full schemas from token
|
|
7087
|
+
// counting, only sending the tool name. When the model needs a deferred tool, it uses
|
|
7088
|
+
// tool_reference to load the schema on demand. This saves ~20KB per turn.
|
|
7089
|
+
// Core tools (OC_TO_CC_TOOL_NAMES) are always eager-loaded.
|
|
7090
|
+
if (
|
|
7091
|
+
Array.isArray(parsed.tools) &&
|
|
7092
|
+
signature.toolDeferral !== false &&
|
|
7093
|
+
parsed.model &&
|
|
7094
|
+
!/claude-3-|haiku/i.test(parsed.model)
|
|
7095
|
+
) {
|
|
7096
|
+
const coreToolNames = new Set(Object.values(OC_TO_CC_TOOL_NAMES));
|
|
7097
|
+
for (const tool of parsed.tools) {
|
|
7098
|
+
if (tool.name && !coreToolNames.has(tool.name)) {
|
|
7099
|
+
tool.defer_loading = true;
|
|
7100
|
+
}
|
|
7101
|
+
}
|
|
7102
|
+
}
|
|
7103
|
+
|
|
6928
7104
|
// Task budgets: when the task-budgets beta is active, preserve or inject output_config.
|
|
6929
7105
|
// The beta unlocks output_config.max_output_tokens for per-task budget control.
|
|
6930
7106
|
// Model-router compatibility: the beta header + output_config body are forwarded as-is.
|
|
@@ -7019,6 +7195,22 @@ function transformRequestUrl(input) {
|
|
|
7019
7195
|
}
|
|
7020
7196
|
}
|
|
7021
7197
|
|
|
7198
|
+
// MITM proxy redirect: rewrite host/port/protocol when OPENCODE_MITM_BASE_URL is set.
|
|
7199
|
+
// This allows capturing the exact over-the-wire request for conformance testing.
|
|
7200
|
+
// Example: OPENCODE_MITM_BASE_URL=http://localhost:9999
|
|
7201
|
+
const mitmBase = process.env.OPENCODE_MITM_BASE_URL;
|
|
7202
|
+
if (mitmBase && requestUrl) {
|
|
7203
|
+
try {
|
|
7204
|
+
const mitmUrl = new URL(mitmBase);
|
|
7205
|
+
requestUrl.protocol = mitmUrl.protocol;
|
|
7206
|
+
requestUrl.hostname = mitmUrl.hostname;
|
|
7207
|
+
requestUrl.port = mitmUrl.port;
|
|
7208
|
+
requestInput = input instanceof Request ? new Request(requestUrl.toString(), input) : requestUrl;
|
|
7209
|
+
} catch {
|
|
7210
|
+
// Invalid MITM URL — ignore silently
|
|
7211
|
+
}
|
|
7212
|
+
}
|
|
7213
|
+
|
|
7022
7214
|
return { requestInput, requestUrl };
|
|
7023
7215
|
}
|
|
7024
7216
|
|
|
@@ -7189,10 +7381,10 @@ function stripMcpPrefixFromParsedEvent(parsed) {
|
|
|
7189
7381
|
|
|
7190
7382
|
let modified = false;
|
|
7191
7383
|
|
|
7192
|
-
// content_block_start: { content_block: { type: "tool_use", name: "..." } }
|
|
7384
|
+
// content_block_start: { content_block: { type: "tool_use"|"tool_reference", name: "..." } }
|
|
7193
7385
|
if (
|
|
7194
7386
|
parsed.content_block &&
|
|
7195
|
-
parsed.content_block.type === "tool_use" &&
|
|
7387
|
+
(parsed.content_block.type === "tool_use" || parsed.content_block.type === "tool_reference") &&
|
|
7196
7388
|
typeof parsed.content_block.name === "string"
|
|
7197
7389
|
) {
|
|
7198
7390
|
const mapped = reverseMapToolName(parsed.content_block.name);
|
|
@@ -7202,10 +7394,10 @@ function stripMcpPrefixFromParsedEvent(parsed) {
|
|
|
7202
7394
|
}
|
|
7203
7395
|
}
|
|
7204
7396
|
|
|
7205
|
-
// message_start: { message: { content: [{ type: "tool_use", name: "..." }] } }
|
|
7397
|
+
// message_start: { message: { content: [{ type: "tool_use"|"tool_reference", name: "..." }] } }
|
|
7206
7398
|
if (parsed.message && Array.isArray(parsed.message.content)) {
|
|
7207
7399
|
for (const block of parsed.message.content) {
|
|
7208
|
-
if (block.type === "tool_use" && typeof block.name === "string") {
|
|
7400
|
+
if ((block.type === "tool_use" || block.type === "tool_reference") && typeof block.name === "string") {
|
|
7209
7401
|
const mapped = reverseMapToolName(block.name);
|
|
7210
7402
|
if (mapped !== block.name) {
|
|
7211
7403
|
block.name = mapped;
|
|
@@ -7218,7 +7410,7 @@ function stripMcpPrefixFromParsedEvent(parsed) {
|
|
|
7218
7410
|
// Top-level content array (non-streaming responses forwarded through SSE)
|
|
7219
7411
|
if (Array.isArray(parsed.content)) {
|
|
7220
7412
|
for (const block of parsed.content) {
|
|
7221
|
-
if (block.type === "tool_use" && typeof block.name === "string") {
|
|
7413
|
+
if ((block.type === "tool_use" || block.type === "tool_reference") && typeof block.name === "string") {
|
|
7222
7414
|
const mapped = reverseMapToolName(block.name);
|
|
7223
7415
|
if (mapped !== block.name) {
|
|
7224
7416
|
block.name = mapped;
|
|
@@ -7674,9 +7866,12 @@ function extractFileIds(body) {
|
|
|
7674
7866
|
AnthropicAuthPlugin.__testing__ = {
|
|
7675
7867
|
sanitizeSystemText,
|
|
7676
7868
|
compactSystemText,
|
|
7869
|
+
compactToolDescription,
|
|
7677
7870
|
dedupeSystemBlocks,
|
|
7678
7871
|
normalizeSystemTextBlocks,
|
|
7679
7872
|
buildSystemPromptBlocks,
|
|
7873
|
+
stripMcpPrefixFromParsedEvent,
|
|
7874
|
+
CORE_TOOL_NAMES,
|
|
7680
7875
|
get cachedCCPrompt() {
|
|
7681
7876
|
return cachedCCPrompt;
|
|
7682
7877
|
},
|
package/lib/config.mjs
CHANGED
|
@@ -190,12 +190,9 @@ export const DEFAULT_CONFIG = {
|
|
|
190
190
|
* This flag is retained for config backward compatibility but has no effect. */
|
|
191
191
|
token_efficient_tools: false,
|
|
192
192
|
/** Enable redact-thinking-2026-02-12 beta (suppresses thinking summaries
|
|
193
|
-
* server-side for lower bandwidth). Off by default
|
|
194
|
-
*
|
|
193
|
+
* server-side for lower bandwidth). Off by default so thinking stays
|
|
194
|
+
* visible. Opt in via `/anthropic set redact-thinking on`. */
|
|
195
195
|
redact_thinking: false,
|
|
196
|
-
/** [DEPRECATED] summarize-connector-text-2026-03-13 was removed in CC v2.1.90.
|
|
197
|
-
* This flag is retained for config backward compatibility but has no effect. */
|
|
198
|
-
connector_text_summarization: false,
|
|
199
196
|
},
|
|
200
197
|
/** Output cap: default max_tokens to save context window. */
|
|
201
198
|
output_cap: {
|
|
@@ -577,10 +574,6 @@ function validateConfig(raw) {
|
|
|
577
574
|
: DEFAULT_CONFIG.token_economy.token_efficient_tools,
|
|
578
575
|
redact_thinking:
|
|
579
576
|
typeof te.redact_thinking === "boolean" ? te.redact_thinking : DEFAULT_CONFIG.token_economy.redact_thinking,
|
|
580
|
-
connector_text_summarization:
|
|
581
|
-
typeof te.connector_text_summarization === "boolean"
|
|
582
|
-
? te.connector_text_summarization
|
|
583
|
-
: DEFAULT_CONFIG.token_economy.connector_text_summarization,
|
|
584
577
|
};
|
|
585
578
|
}
|
|
586
579
|
|