@bman654/clodex 2.12.1 → 2.12.2

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/dist/cli.js CHANGED
@@ -382,7 +382,7 @@ import { join } from "path";
382
382
  // package.json
383
383
  var package_default = {
384
384
  name: "@bman654/clodex",
385
- version: "2.12.1",
385
+ version: "2.12.2",
386
386
  publishConfig: {
387
387
  access: "public"
388
388
  },
@@ -4821,16 +4821,19 @@ var pricing_cache_default = {
4821
4821
  ]
4822
4822
  };
4823
4823
 
4824
+ // src/data/opencode-go-models.ts
4825
+ import { randomUUID as randomUUID2 } from "crypto";
4826
+
4824
4827
  // src/data/opencode-go-models.json
4825
4828
  var opencode_go_models_default = [
4826
4829
  {
4827
4830
  id: "deepseek-v4-flash",
4828
- name: "DeepSeek V4 Flash (2x usage)",
4831
+ name: "DeepSeek V4 Flash",
4829
4832
  contextWindow: 1e6,
4830
4833
  cost: {
4831
- input: 0.07,
4832
- output: 0.14,
4833
- cache_read: 14e-4
4834
+ input: 0.15,
4835
+ output: 0.6,
4836
+ cache_read: 3e-3
4834
4837
  },
4835
4838
  modelFormat: "openai",
4836
4839
  npm: "@ai-sdk/openai-compatible",
@@ -4858,12 +4861,12 @@ var opencode_go_models_default = [
4858
4861
  },
4859
4862
  {
4860
4863
  id: "deepseek-v4-pro",
4861
- name: "DeepSeek V4 Pro",
4864
+ name: "DeepSeek V4 Pro (New)",
4862
4865
  contextWindow: 1e6,
4863
4866
  cost: {
4864
- input: 0.435,
4865
- output: 0.87,
4866
- cache_read: 3625e-6
4867
+ input: 0.66,
4868
+ output: 1.98,
4869
+ cache_read: 0.022
4867
4870
  },
4868
4871
  modelFormat: "openai",
4869
4872
  npm: "@ai-sdk/openai-compatible",
@@ -4889,6 +4892,30 @@ var opencode_go_models_default = [
4889
4892
  upstreamModelId: "deepseek-v4-pro",
4890
4893
  family: "deepseek"
4891
4894
  },
4895
+ {
4896
+ id: "deepseek-v4.1-flash",
4897
+ name: "DeepSeek V4.1 Flash",
4898
+ contextWindow: 1e6,
4899
+ cost: {
4900
+ input: 0.15,
4901
+ output: 0.6,
4902
+ cache_read: 3e-3
4903
+ },
4904
+ modelFormat: "anthropic",
4905
+ npm: "@ai-sdk/anthropic",
4906
+ apiUrl: "https://opencode.ai/zen/go",
4907
+ reasoning: true,
4908
+ modalities: [
4909
+ "text",
4910
+ "image"
4911
+ ],
4912
+ compatibility: {
4913
+ supportsCountTokens: false,
4914
+ supportsReasoningEffort: false
4915
+ },
4916
+ upstreamModelId: "deepseek-v4.1-flash",
4917
+ family: "deepseek"
4918
+ },
4892
4919
  {
4893
4920
  id: "glm-5.1",
4894
4921
  name: "GLM-5.1",
@@ -4906,10 +4933,10 @@ var opencode_go_models_default = [
4906
4933
  "text"
4907
4934
  ],
4908
4935
  compatibility: {
4936
+ supportsReasoningEffort: false,
4909
4937
  supportsStore: false,
4910
4938
  supportsDeveloperRole: false,
4911
- maxTokensField: "max_tokens",
4912
- supportsReasoningEffort: false
4939
+ maxTokensField: "max_tokens"
4913
4940
  },
4914
4941
  upstreamModelId: "glm-5.1",
4915
4942
  family: "glm"
@@ -4949,13 +4976,13 @@ var opencode_go_models_default = [
4949
4976
  },
4950
4977
  {
4951
4978
  id: "gpt-5.6-luna",
4952
- name: "GPT-5.6 Luna (2x usage)",
4979
+ name: "GPT-5.6 Luna",
4953
4980
  contextWindow: 105e4,
4954
4981
  cost: {
4955
- input: 0.1,
4956
- output: 0.6,
4957
- cache_read: 0.01,
4958
- cache_write: 0.125
4982
+ input: 0.2,
4983
+ output: 1.2,
4984
+ cache_read: 0.02,
4985
+ cache_write: 0.25
4959
4986
  },
4960
4987
  modelFormat: "openai",
4961
4988
  npm: "@ai-sdk/openai-compatible",
@@ -4965,8 +4992,6 @@ var opencode_go_models_default = [
4965
4992
  "text",
4966
4993
  "image"
4967
4994
  ],
4968
- upstreamModelId: "gpt-5.6-luna",
4969
- family: "gpt",
4970
4995
  compatibility: {
4971
4996
  reasoningEffortMap: {
4972
4997
  off: "none",
@@ -4980,7 +5005,9 @@ var opencode_go_models_default = [
4980
5005
  supportsStore: false,
4981
5006
  supportsDeveloperRole: false,
4982
5007
  maxTokensField: "max_tokens"
4983
- }
5008
+ },
5009
+ upstreamModelId: "gpt-5.6-luna",
5010
+ family: "gpt"
4984
5011
  },
4985
5012
  {
4986
5013
  id: "hy3",
@@ -5066,10 +5093,10 @@ var opencode_go_models_default = [
5066
5093
  "image"
5067
5094
  ],
5068
5095
  compatibility: {
5096
+ supportsReasoningEffort: false,
5069
5097
  supportsStore: false,
5070
5098
  supportsDeveloperRole: false,
5071
- maxTokensField: "max_tokens",
5072
- supportsReasoningEffort: false
5099
+ maxTokensField: "max_tokens"
5073
5100
  },
5074
5101
  upstreamModelId: "kimi-k2.7-code",
5075
5102
  family: "kimi"
@@ -5126,10 +5153,10 @@ var opencode_go_models_default = [
5126
5153
  "image"
5127
5154
  ],
5128
5155
  compatibility: {
5156
+ supportsReasoningEffort: false,
5129
5157
  supportsStore: false,
5130
5158
  supportsDeveloperRole: false,
5131
- maxTokensField: "max_tokens",
5132
- supportsReasoningEffort: false
5159
+ maxTokensField: "max_tokens"
5133
5160
  },
5134
5161
  upstreamModelId: "mimo-v2.5",
5135
5162
  family: "mimo"
@@ -5151,10 +5178,10 @@ var opencode_go_models_default = [
5151
5178
  "text"
5152
5179
  ],
5153
5180
  compatibility: {
5181
+ supportsReasoningEffort: false,
5154
5182
  supportsStore: false,
5155
5183
  supportsDeveloperRole: false,
5156
- maxTokensField: "max_tokens",
5157
- supportsReasoningEffort: false
5184
+ maxTokensField: "max_tokens"
5158
5185
  },
5159
5186
  upstreamModelId: "mimo-v2.5-pro",
5160
5187
  family: "mimo"
@@ -5176,10 +5203,10 @@ var opencode_go_models_default = [
5176
5203
  "text"
5177
5204
  ],
5178
5205
  compatibility: {
5206
+ supportsReasoningEffort: false,
5179
5207
  supportsStore: false,
5180
5208
  supportsDeveloperRole: false,
5181
- maxTokensField: "max_tokens",
5182
- supportsReasoningEffort: false
5209
+ maxTokensField: "max_tokens"
5183
5210
  },
5184
5211
  upstreamModelId: "minimax-m2.7",
5185
5212
  family: "minimax"
@@ -5201,12 +5228,12 @@ var opencode_go_models_default = [
5201
5228
  "text",
5202
5229
  "image"
5203
5230
  ],
5204
- upstreamModelId: "minimax-m3",
5205
- family: "minimax",
5206
5231
  compatibility: {
5207
5232
  supportsCountTokens: false,
5208
5233
  supportsReasoningEffort: false
5209
- }
5234
+ },
5235
+ upstreamModelId: "minimax-m3",
5236
+ family: "minimax"
5210
5237
  },
5211
5238
  {
5212
5239
  id: "qwen3.6-plus",
@@ -5227,10 +5254,6 @@ var opencode_go_models_default = [
5227
5254
  "image"
5228
5255
  ],
5229
5256
  compatibility: {
5230
- supportsStore: false,
5231
- supportsDeveloperRole: false,
5232
- thinkingFormat: "qwen",
5233
- maxTokensField: "max_tokens",
5234
5257
  reasoningEffortMap: {
5235
5258
  low: "low",
5236
5259
  medium: "medium",
@@ -5239,7 +5262,11 @@ var opencode_go_models_default = [
5239
5262
  max: "max",
5240
5263
  minimal: null,
5241
5264
  off: null
5242
- }
5265
+ },
5266
+ supportsStore: false,
5267
+ supportsDeveloperRole: false,
5268
+ thinkingFormat: "qwen",
5269
+ maxTokensField: "max_tokens"
5243
5270
  },
5244
5271
  upstreamModelId: "qwen3.6-plus",
5245
5272
  family: "qwen3.6"
@@ -5261,12 +5288,12 @@ var opencode_go_models_default = [
5261
5288
  modalities: [
5262
5289
  "text"
5263
5290
  ],
5264
- upstreamModelId: "qwen3.7-max",
5265
- family: "qwen3.7",
5266
5291
  compatibility: {
5267
5292
  supportsCountTokens: false,
5268
5293
  supportsReasoningEffort: false
5269
- }
5294
+ },
5295
+ upstreamModelId: "qwen3.7-max",
5296
+ family: "qwen3.7"
5270
5297
  },
5271
5298
  {
5272
5299
  id: "qwen3.7-plus",
@@ -5286,12 +5313,12 @@ var opencode_go_models_default = [
5286
5313
  "text",
5287
5314
  "image"
5288
5315
  ],
5289
- upstreamModelId: "qwen3.7-plus",
5290
- family: "qwen3.7",
5291
5316
  compatibility: {
5292
5317
  supportsCountTokens: false,
5293
5318
  supportsReasoningEffort: false
5294
- }
5319
+ },
5320
+ upstreamModelId: "qwen3.7-plus",
5321
+ family: "qwen3.7"
5295
5322
  },
5296
5323
  {
5297
5324
  id: "qwen3.8-max",
@@ -5311,12 +5338,12 @@ var opencode_go_models_default = [
5311
5338
  "text",
5312
5339
  "image"
5313
5340
  ],
5314
- upstreamModelId: "qwen3.8-max",
5315
- family: "qwen3.8",
5316
5341
  compatibility: {
5317
5342
  supportsCountTokens: false,
5318
5343
  supportsReasoningEffort: false
5319
- }
5344
+ },
5345
+ upstreamModelId: "qwen3.8-max",
5346
+ family: "qwen3.8"
5320
5347
  }
5321
5348
  ];
5322
5349
 
@@ -5328,6 +5355,13 @@ var OPENCODE_GO_ANTHROPIC_BASE_URL = "https://opencode.ai/zen/go";
5328
5355
  function buildOpenCodeGoModels() {
5329
5356
  return structuredClone(opencode_go_models_default);
5330
5357
  }
5358
+ var OPENCODE_GO_FALLBACK_SESSION_ID = randomUUID2();
5359
+ function openCodeGoSessionHeaders(model, claudeSessionId) {
5360
+ const url = String(model.apiBaseUrl ?? model.baseUrl ?? model.apiUrl ?? "");
5361
+ const isGo = model.providerId === OPENCODE_GO_PROVIDER_ID || /^https:\/\/opencode\.ai\/zen\/go(\/|$)/.test(url);
5362
+ if (!isGo) return void 0;
5363
+ return { "x-opencode-session": claudeSessionId ?? OPENCODE_GO_FALLBACK_SESSION_ID };
5364
+ }
5331
5365
 
5332
5366
  // src/provider-templates.ts
5333
5367
  async function verifyOpenCodeGoCredential(apiKey) {
@@ -5338,7 +5372,12 @@ async function verifyOpenCodeGoCredential(apiKey) {
5338
5372
  method: "POST",
5339
5373
  headers: {
5340
5374
  "Content-Type": "application/json",
5341
- Authorization: `Bearer ${apiKey}`
5375
+ Authorization: `Bearer ${apiKey}`,
5376
+ // Go answers `MissingSessionID` to any request without a session header,
5377
+ // and whether it validates the key BEFORE that check is not something we
5378
+ // have observed. Sending the header removes the question: the probe then
5379
+ // cannot mistake a missing-session rejection for a verdict on the key.
5380
+ ...openCodeGoSessionHeaders({ providerId: OPENCODE_GO_PROVIDER_ID }, void 0)
5342
5381
  },
5343
5382
  body: JSON.stringify({ model: model.upstreamModelId ?? model.id }),
5344
5383
  // This is the FIRST thing a user hits after pasting a key, and it runs
@@ -8998,16 +9037,64 @@ function responsesWebSocketPartitionKey(wsUrl, payload, options = {}, authorizat
8998
9037
  function inputArray(payload) {
8999
9038
  return Array.isArray(payload.input) ? payload.input : [];
9000
9039
  }
9001
- function normalizeToolCallJson(value) {
9002
- if (Array.isArray(value)) return value.map(normalizeToolCallJson);
9040
+ function toolSchemaDefaults(payload) {
9041
+ const defaults = /* @__PURE__ */ new Map();
9042
+ const add = (tool3) => {
9043
+ if (!tool3 || typeof tool3 !== "object") return;
9044
+ const record = tool3;
9045
+ if (record.type === "namespace" && Array.isArray(record.tools)) {
9046
+ for (const nested of record.tools) add(nested);
9047
+ return;
9048
+ }
9049
+ if (record.type !== "function" || typeof record.name !== "string") return;
9050
+ const parameters = record.parameters;
9051
+ const properties = parameters && typeof parameters === "object" ? parameters.properties : void 0;
9052
+ if (!properties || typeof properties !== "object") return;
9053
+ const perTool = /* @__PURE__ */ new Map();
9054
+ for (const [prop, schema] of Object.entries(properties)) {
9055
+ if (schema && typeof schema === "object" && "default" in schema) {
9056
+ perTool.set(prop, canonicalJson(schema.default));
9057
+ }
9058
+ }
9059
+ if (perTool.size) defaults.set(record.name, perTool);
9060
+ };
9061
+ if (Array.isArray(payload.tools)) for (const tool3 of payload.tools) add(tool3);
9062
+ return defaults;
9063
+ }
9064
+ function toolSchemaDefaultsFingerprint(defaults) {
9065
+ if (!defaults.size) return "none";
9066
+ const tuples = [...defaults.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([name, perTool]) => [
9067
+ name,
9068
+ [...perTool.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)
9069
+ ]);
9070
+ return createHash6("sha256").update(JSON.stringify(tuples)).digest("hex").slice(0, 16);
9071
+ }
9072
+ function stripSchemaDefaults(name, args, defaults) {
9073
+ if (!defaults) return args;
9074
+ if (typeof name !== "string" || !args || typeof args !== "object" || Array.isArray(args)) return args;
9075
+ const perTool = defaults.get(name);
9076
+ if (!perTool) return args;
9077
+ const out = {};
9078
+ for (const [key, value] of Object.entries(args)) {
9079
+ const expected = perTool.get(key);
9080
+ if (expected !== void 0 && canonicalJson(value) === expected) continue;
9081
+ out[key] = value;
9082
+ }
9083
+ return out;
9084
+ }
9085
+ function normalizeToolCallJson(value, defaults) {
9086
+ if (Array.isArray(value)) return value.map((item) => normalizeToolCallJson(item, defaults));
9003
9087
  if (!value || typeof value !== "object") return value;
9004
9088
  const record = value;
9005
9089
  const out = {};
9006
- for (const [key, child] of Object.entries(record)) out[key] = normalizeToolCallJson(child);
9090
+ for (const [key, child] of Object.entries(record)) out[key] = normalizeToolCallJson(child, defaults);
9007
9091
  const jsonField = record.type === "function_call" ? "arguments" : record.type === "custom_tool_call" ? "input" : void 0;
9008
9092
  if (jsonField && typeof record[jsonField] === "string") {
9009
9093
  try {
9010
- out[jsonField] = canonicalJson(JSON.parse(record[jsonField]));
9094
+ const parsed = JSON.parse(record[jsonField]);
9095
+ out[jsonField] = canonicalJson(
9096
+ jsonField === "arguments" ? stripSchemaDefaults(record.name, parsed, defaults) : parsed
9097
+ );
9011
9098
  } catch {
9012
9099
  }
9013
9100
  }
@@ -9018,8 +9105,8 @@ function normalizeToolCallJson(value) {
9018
9105
  }
9019
9106
  return out;
9020
9107
  }
9021
- function arraysEqual(left, right) {
9022
- return canonicalJson(normalizeToolCallJson(left)) === canonicalJson(normalizeToolCallJson(right));
9108
+ function arraysEqual(left, right, defaults) {
9109
+ return canonicalJson(normalizeToolCallJson(left, defaults)) === canonicalJson(normalizeToolCallJson(right, defaults));
9023
9110
  }
9024
9111
  function conversationItemKind(value) {
9025
9112
  if (!value || typeof value !== "object") return typeof value;
@@ -9028,17 +9115,17 @@ function conversationItemKind(value) {
9028
9115
  if (typeof record.role === "string") return record.role;
9029
9116
  return "object";
9030
9117
  }
9031
- function conversationItemHash(value) {
9032
- return createHash6("sha256").update(canonicalJson(normalizeToolCallJson(value))).digest("hex").slice(0, 16);
9118
+ function conversationItemHash(value, defaults) {
9119
+ return createHash6("sha256").update(canonicalJson(normalizeToolCallJson(value, defaults))).digest("hex").slice(0, 16);
9033
9120
  }
9034
- function reasoningNormalizationGap(expected, actual) {
9121
+ function reasoningNormalizationGap(expected, actual, defaults) {
9035
9122
  if (conversationItemKind(expected) !== "reasoning" || conversationItemKind(actual) !== "reasoning") return void 0;
9036
9123
  const left = expected;
9037
9124
  const right = actual;
9038
9125
  const blob = left.encrypted_content;
9039
9126
  if (typeof blob !== "string" || !blob || blob !== right.encrypted_content) return void 0;
9040
- const normalizedLeft = normalizeToolCallJson(left);
9041
- const normalizedRight = normalizeToolCallJson(right);
9127
+ const normalizedLeft = normalizeToolCallJson(left, defaults);
9128
+ const normalizedRight = normalizeToolCallJson(right, defaults);
9042
9129
  const fields = [.../* @__PURE__ */ new Set([...Object.keys(normalizedLeft), ...Object.keys(normalizedRight)])].sort().filter((key) => canonicalJson(normalizedLeft[key]) !== canonicalJson(normalizedRight[key]));
9043
9130
  return fields.length ? fields : void 0;
9044
9131
  }
@@ -9086,7 +9173,7 @@ function warnReasoningNormalizationGap(fields, log12) {
9086
9173
  emitParentNotice("clodex: warning: further reasoning-normalization warnings suppressed.");
9087
9174
  }
9088
9175
  }
9089
- function toolArgumentNormalizationGap(expected, actual, requiredProps) {
9176
+ function toolArgumentNormalizationGap(expected, actual, defaults, requiredProps) {
9090
9177
  if (conversationItemKind(expected) !== "function_call") return void 0;
9091
9178
  if (conversationItemKind(actual) !== "function_call") return void 0;
9092
9179
  const left = expected;
@@ -9094,7 +9181,7 @@ function toolArgumentNormalizationGap(expected, actual, requiredProps) {
9094
9181
  const callId = left.call_id;
9095
9182
  if (typeof callId !== "string" || !callId || callId !== right.call_id) return void 0;
9096
9183
  if (typeof left.name !== "string" || left.name !== right.name) return void 0;
9097
- if (canonicalJson(normalizeToolCallJson(left)) === canonicalJson(normalizeToolCallJson(right))) {
9184
+ if (canonicalJson(normalizeToolCallJson(left, defaults)) === canonicalJson(normalizeToolCallJson(right, defaults))) {
9098
9185
  return void 0;
9099
9186
  }
9100
9187
  const required = requiredProps().get(left.name);
@@ -9105,8 +9192,8 @@ function toolArgumentNormalizationGap(expected, actual, requiredProps) {
9105
9192
  const parsed = raw === "" ? {} : JSON.parse(raw);
9106
9193
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
9107
9194
  return canonicalJson({
9108
- ...normalizeToolCallJson(item),
9109
- arguments: canonicalJson(sanitizeToolInput(parsed, required))
9195
+ ...normalizeToolCallJson(item, defaults),
9196
+ arguments: canonicalJson(stripSchemaDefaults(item.name, sanitizeToolInput(parsed, required), defaults))
9110
9197
  });
9111
9198
  } catch {
9112
9199
  return void 0;
@@ -9137,7 +9224,7 @@ function warnToolArgumentNormalizationGap(gap, log12) {
9137
9224
  emitParentNotice("clodex: warning: further tool-argument normalization warnings suppressed.");
9138
9225
  }
9139
9226
  }
9140
- function continuationMismatchDetails(entry, payload, log12, warnOnGap = false, deferWarnings) {
9227
+ function continuationMismatchDetails(entry, payload, defaults, log12, warnOnGap = false, deferWarnings) {
9141
9228
  const raise = (warn) => {
9142
9229
  if (deferWarnings) deferWarnings.push(warn);
9143
9230
  else warn();
@@ -9147,14 +9234,14 @@ function continuationMismatchDetails(entry, payload, log12, warnOnGap = false, d
9147
9234
  const comparable = Math.min(full.length, prefix.length);
9148
9235
  let mismatch = comparable;
9149
9236
  for (let index = 0; index < comparable; index += 1) {
9150
- if (!arraysEqual([full[index]], [prefix[index]])) {
9237
+ if (!arraysEqual([full[index]], [prefix[index]], defaults)) {
9151
9238
  mismatch = index;
9152
9239
  break;
9153
9240
  }
9154
9241
  }
9155
9242
  const expected = mismatch < prefix.length ? prefix[mismatch] : void 0;
9156
9243
  const actual = mismatch < full.length ? full[mismatch] : void 0;
9157
- const reasoningGap = reasoningNormalizationGap(expected, actual);
9244
+ const reasoningGap = reasoningNormalizationGap(expected, actual, defaults);
9158
9245
  if (reasoningGap && warnOnGap) raise(() => warnReasoningNormalizationGap(reasoningGap, log12));
9159
9246
  let gapExpected = expected;
9160
9247
  if (conversationItemKind(expected) === "reasoning" && conversationItemKind(actual) === "function_call") {
@@ -9170,6 +9257,7 @@ function continuationMismatchDetails(entry, payload, log12, warnOnGap = false, d
9170
9257
  toolArgumentGap = toolArgumentNormalizationGap(
9171
9258
  gapExpected,
9172
9259
  actual,
9260
+ defaults,
9173
9261
  // The head's own schema when it has one; the current turn's tools are only a
9174
9262
  // fallback for a head that predates the snapshot (see headRequiredToolProps).
9175
9263
  () => entry.headRequiredToolProps ?? requiredToolProps(payload)
@@ -9191,8 +9279,8 @@ function continuationMismatchDetails(entry, payload, log12, warnOnGap = false, d
9191
9279
  firstMismatch: mismatch,
9192
9280
  expectedKind: expected === void 0 ? "none" : conversationItemKind(expected),
9193
9281
  actualKind: actual === void 0 ? "none" : conversationItemKind(actual),
9194
- ...expected !== void 0 ? { expectedHash: conversationItemHash(expected) } : {},
9195
- ...actual !== void 0 ? { actualHash: conversationItemHash(actual) } : {},
9282
+ ...expected !== void 0 ? { expectedHash: conversationItemHash(expected, defaults) } : {},
9283
+ ...actual !== void 0 ? { actualHash: conversationItemHash(actual, defaults) } : {},
9196
9284
  ...reasoningGap ? {
9197
9285
  reasoningNormalizationGap: reasoningGap,
9198
9286
  reasoningGapShape: reasoningGapShape(
@@ -9206,8 +9294,8 @@ function continuationMismatchDetails(entry, payload, log12, warnOnGap = false, d
9206
9294
  ...toolArgumentGap ? { toolArgumentNormalizationGap: toolArgumentGap } : {}
9207
9295
  };
9208
9296
  }
9209
- function continuationMismatchSummary(entry, payload, log12, mismatchDump = false, precomputedDetails) {
9210
- const details = precomputedDetails ?? continuationMismatchDetails(entry, payload, log12, true);
9297
+ function continuationMismatchSummary(entry, payload, defaults, log12, mismatchDump = false, precomputedDetails) {
9298
+ const details = precomputedDetails ?? continuationMismatchDetails(entry, payload, defaults, log12, true);
9211
9299
  let summary = `full_items=${details.fullItems} expected_prefix_items=${details.expectedPrefixItems} first_mismatch=${details.firstMismatch} expected=${details.expectedKind} actual=${details.actualKind}`;
9212
9300
  if (details.expectedHash || details.actualHash) {
9213
9301
  summary += ` expected_hash=${details.expectedHash ?? "none"} actual_hash=${details.actualHash ?? "none"}`;
@@ -9215,21 +9303,21 @@ function continuationMismatchSummary(entry, payload, log12, mismatchDump = false
9215
9303
  const full = inputArray(payload);
9216
9304
  const prefix = [...entry.requestInput ?? [], ...entry.expectedAssistant ?? []];
9217
9305
  const index = details.firstMismatch;
9218
- log12(`mismatch dump expected[${index}]: ${mismatchDumpLine(prefix, index)}`);
9219
- log12(`mismatch dump actual[${index}]: ${mismatchDumpLine(full, index)}`);
9306
+ log12(`mismatch dump expected[${index}]: ${mismatchDumpLine(prefix, index, defaults)}`);
9307
+ log12(`mismatch dump actual[${index}]: ${mismatchDumpLine(full, index, defaults)}`);
9220
9308
  }
9221
9309
  }
9222
9310
  return summary;
9223
9311
  }
9224
- function mismatchDumpLine(items, index) {
9312
+ function mismatchDumpLine(items, index, defaults) {
9225
9313
  if (index >= items.length) return "(absent)";
9226
- const line = canonicalJson(normalizeToolCallJson(items[index]));
9314
+ const line = canonicalJson(normalizeToolCallJson(items[index], defaults));
9227
9315
  const max = 2e3;
9228
9316
  const marker = " [truncated]";
9229
9317
  return line.length <= max ? line : line.slice(0, max - marker.length) + marker;
9230
9318
  }
9231
- function canonicalItemStrings(items) {
9232
- return items.map((item) => canonicalJson(normalizeToolCallJson([item])));
9319
+ function canonicalItemStrings(items, defaults) {
9320
+ return items.map((item) => canonicalJson(normalizeToolCallJson([item], defaults)));
9233
9321
  }
9234
9322
  function isPrefixOrEqual(head, client) {
9235
9323
  if (client.length < head.length) return false;
@@ -9241,16 +9329,24 @@ function isPrefixOrEqual(head, client) {
9241
9329
  function isStrictPrefix(head, client) {
9242
9330
  return client.length > head.length && isPrefixOrEqual(head, client);
9243
9331
  }
9244
- function continuationMatch(entry, payload, clientItems) {
9332
+ function continuationMatch(entry, payload, clientItems, defaults, defaultsId) {
9245
9333
  if (!entry.responseId || !entry.requestInput || !entry.expectedAssistant) return void 0;
9246
9334
  const full = inputArray(payload);
9247
- entry.canonicalPrefix ??= canonicalItemStrings([...entry.requestInput, ...entry.expectedAssistant]);
9335
+ if (entry.canonicalToolDefaultsId !== defaultsId) {
9336
+ entry.canonicalPrefix = void 0;
9337
+ entry.canonicalEchoablePrefix = void 0;
9338
+ entry.canonicalToolDefaultsId = defaultsId;
9339
+ }
9340
+ entry.canonicalPrefix ??= canonicalItemStrings(
9341
+ [...entry.requestInput, ...entry.expectedAssistant],
9342
+ defaults
9343
+ );
9248
9344
  if (isStrictPrefix(entry.canonicalPrefix, clientItems)) {
9249
9345
  return { delta: full.slice(entry.canonicalPrefix.length), mode: "exact" };
9250
9346
  }
9251
9347
  const echoedAssistant = entry.expectedAssistant.filter((item) => conversationItemKind(item) !== "reasoning");
9252
9348
  if (echoedAssistant.length === entry.expectedAssistant.length) return void 0;
9253
- entry.canonicalEchoablePrefix ??= canonicalItemStrings([...entry.requestInput, ...echoedAssistant]);
9349
+ entry.canonicalEchoablePrefix ??= canonicalItemStrings([...entry.requestInput, ...echoedAssistant], defaults);
9254
9350
  if (!isStrictPrefix(entry.canonicalEchoablePrefix, clientItems)) return void 0;
9255
9351
  return { delta: full.slice(entry.canonicalEchoablePrefix.length), mode: "omitted_reasoning" };
9256
9352
  }
@@ -10159,13 +10255,15 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10159
10255
  authorizationFingerprint,
10160
10256
  claudeAgentId
10161
10257
  );
10258
+ const requestToolDefaults = toolSchemaDefaults(payload);
10259
+ const requestToolDefaultsId = toolSchemaDefaultsFingerprint(requestToolDefaults);
10162
10260
  const promptFingerprint = responsesWebSocketPromptFingerprint(payload);
10163
10261
  const promptFieldHashes = responsesWebSocketPromptFieldHashes(payload);
10164
10262
  const instructionsSnapshot = instructionsFromPayload(payload);
10165
10263
  let now = resolvedOptions.now();
10166
10264
  const evictions = cleanupExpiredConnections(now);
10167
10265
  let canonicalClientItems;
10168
- const clientItems = () => canonicalClientItems ??= canonicalItemStrings(inputArray(payload));
10266
+ const clientItems = () => canonicalClientItems ??= canonicalItemStrings(inputArray(payload), requestToolDefaults);
10169
10267
  const scanForHeads = () => {
10170
10268
  const scanned = partitionKey ? connectionEntries(partitionKey) : [];
10171
10269
  const idle = scanned.filter((entry) => !entry.inFlight);
@@ -10173,16 +10271,32 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10173
10271
  return {
10174
10272
  candidates: scanned,
10175
10273
  idleCandidates: idle,
10176
- matches: idle.map((entry) => ({ entry, match: continuationMatch(entry, payload, canonical) })).filter((candidate) => candidate.match !== void 0).sort((left, right) => left.match.delta.length - right.match.delta.length || (left.match.mode === right.match.mode ? 0 : left.match.mode === "exact" ? -1 : 1))
10274
+ matches: idle.map((entry) => ({
10275
+ entry,
10276
+ match: continuationMatch(entry, payload, canonical, requestToolDefaults, requestToolDefaultsId)
10277
+ })).filter((candidate) => candidate.match !== void 0).sort((left, right) => left.match.delta.length - right.match.delta.length || (left.match.mode === right.match.mode ? 0 : left.match.mode === "exact" ? -1 : 1))
10177
10278
  };
10178
10279
  };
10179
10280
  const couldPrecedeThisRequest = (entry) => {
10180
10281
  if (entry.responseId && entry.requestInput && entry.expectedAssistant) {
10181
- return continuationMatch(entry, payload, clientItems()) !== void 0;
10282
+ return continuationMatch(
10283
+ entry,
10284
+ payload,
10285
+ clientItems(),
10286
+ requestToolDefaults,
10287
+ requestToolDefaultsId
10288
+ ) !== void 0;
10182
10289
  }
10183
10290
  const streaming = entry.current;
10184
10291
  if (!streaming) return true;
10185
- streaming.canonicalInput ??= canonicalItemStrings(inputArray(streaming.originalPayload));
10292
+ if (streaming.canonicalInputToolDefaultsId !== requestToolDefaultsId) {
10293
+ streaming.canonicalInput = void 0;
10294
+ streaming.canonicalInputToolDefaultsId = requestToolDefaultsId;
10295
+ }
10296
+ streaming.canonicalInput ??= canonicalItemStrings(
10297
+ inputArray(streaming.originalPayload),
10298
+ requestToolDefaults
10299
+ );
10186
10300
  return isPrefixOrEqual(streaming.canonicalInput, clientItems());
10187
10301
  };
10188
10302
  const blockingHead = (entries) => entries.find((entry) => entry.inFlight && couldPrecedeThisRequest(entry));
@@ -10240,6 +10354,7 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10240
10354
  const diagnosticMismatch = continuationMismatchDetails(
10241
10355
  diagnosticEntry,
10242
10356
  payload,
10357
+ requestToolDefaults,
10243
10358
  debug,
10244
10359
  true,
10245
10360
  deferredMismatchWarnings
@@ -10249,13 +10364,21 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10249
10364
  if (candidate === diagnosticEntry) continue;
10250
10365
  candidateMismatchDetails.set(
10251
10366
  candidate,
10252
- continuationMismatchDetails(candidate, payload, debug, true, deferredMismatchWarnings)
10367
+ continuationMismatchDetails(
10368
+ candidate,
10369
+ payload,
10370
+ requestToolDefaults,
10371
+ debug,
10372
+ true,
10373
+ deferredMismatchWarnings
10374
+ )
10253
10375
  );
10254
10376
  }
10255
10377
  debug(
10256
10378
  `history mismatch starting an additional chain; retained ${candidates.length} existing head(s) (${continuationMismatchSummary(
10257
10379
  diagnosticEntry,
10258
10380
  payload,
10381
+ requestToolDefaults,
10259
10382
  debug,
10260
10383
  mismatchDump,
10261
10384
  diagnosticMismatch
@@ -10379,7 +10502,7 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10379
10502
  input: {
10380
10503
  count: requestInput.length,
10381
10504
  kinds: requestInput.map(conversationItemKind),
10382
- hashes: requestInput.map(conversationItemHash)
10505
+ hashes: requestInput.map((item) => conversationItemHash(item, requestToolDefaults))
10383
10506
  },
10384
10507
  candidateCount: candidates.length,
10385
10508
  idleCandidateCount: idleCandidates.length,
@@ -10412,7 +10535,7 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10412
10535
  ttlPausedMs: entry.ttlPausedMs,
10413
10536
  idleMs: Math.max(0, now - entry.lastUsedAt),
10414
10537
  promptChanges: changedPromptFields(entry.promptFieldHashes, promptFieldHashes),
10415
- mismatch: candidateMismatchDetails?.get(entry) ?? continuationMismatchDetails(entry, payload, debug)
10538
+ mismatch: candidateMismatchDetails?.get(entry) ?? continuationMismatchDetails(entry, payload, requestToolDefaults, debug)
10416
10539
  })),
10417
10540
  evictions
10418
10541
  }, diagnosticCorrelation);
@@ -10492,7 +10615,7 @@ function createResponsesWebSocketFetch(wsUrl, log12, options = {}) {
10492
10615
  }
10493
10616
 
10494
10617
  // src/oauth/claude-identity.ts
10495
- import { createHash as createHash7, randomUUID as randomUUID2 } from "crypto";
10618
+ import { createHash as createHash7, randomUUID as randomUUID3 } from "crypto";
10496
10619
  var CLAUDE_CODE_CLI_VERSION = "2.1.195";
10497
10620
  var CLAUDE_CODE_USER_AGENT = `claude-cli/${CLAUDE_CODE_CLI_VERSION} (external, cli)`;
10498
10621
  var CLAUDE_CODE_ENTRYPOINT = process.env.CLAUDE_CODE_ENTRYPOINT ?? "cli";
@@ -10501,7 +10624,7 @@ var sessionCache = /* @__PURE__ */ new Map();
10501
10624
  function getOrCreateSessionId(seed) {
10502
10625
  let id = sessionCache.get(seed);
10503
10626
  if (!id) {
10504
- id = randomUUID2();
10627
+ id = randomUUID3();
10505
10628
  sessionCache.set(seed, id);
10506
10629
  }
10507
10630
  return id;
@@ -11849,7 +11972,7 @@ async function relayAnthropicMessages(res, messagesUrl, body, apiKey, clientWant
11849
11972
  }
11850
11973
 
11851
11974
  // src/proxy.ts
11852
- import { randomUUID as randomUUID3 } from "crypto";
11975
+ import { randomUUID as randomUUID4 } from "crypto";
11853
11976
 
11854
11977
  // src/sdk-adapter.ts
11855
11978
  import { createHash as createHash8 } from "crypto";
@@ -13275,7 +13398,7 @@ function configuredAliasLookupNames(alias) {
13275
13398
  }))].map(normalizeRouteLookupId);
13276
13399
  }
13277
13400
  async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenceLogPath, debugLogPath, webSocketDiagnosticsLogPath, modelAliases) {
13278
- const proxyToken = randomUUID3();
13401
+ const proxyToken = randomUUID4();
13279
13402
  silenceSdkWarnings();
13280
13403
  if (routes.length === 0) {
13281
13404
  throw new Error("Proxy catalog requires at least one route");
@@ -13439,6 +13562,14 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
13439
13562
  const isOAuth = routeAuthType === "oauth";
13440
13563
  let effectiveBeta = inboundBeta;
13441
13564
  let claudeCodeSessionId;
13565
+ const inboundSessionRaw = req.headers["x-claude-code-session-id"];
13566
+ const goSessionHeaders = openCodeGoSessionHeaders(
13567
+ { providerId: route.providerId, baseUrl: upstreamUrl },
13568
+ extractClaudeSessionId(
13569
+ anthropicBody,
13570
+ Array.isArray(inboundSessionRaw) ? inboundSessionRaw[0] : inboundSessionRaw
13571
+ )
13572
+ );
13442
13573
  if (isOAuth) {
13443
13574
  const seed = route.providerId ?? route.realModelId;
13444
13575
  const identity = injectClaudeIdentity(forwardBody, route.providerData, seed);
@@ -13456,7 +13587,7 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
13456
13587
  authType: routeAuthType,
13457
13588
  log: (message) => plog(message),
13458
13589
  claudeCodeSessionId,
13459
- extraHeaders: route.headers,
13590
+ extraHeaders: { ...route.headers, ...goSessionHeaders },
13460
13591
  refreshToken: route.refreshToken,
13461
13592
  onTokenRefreshed: (refreshed) => {
13462
13593
  route.apiKey = refreshed;
@@ -13516,6 +13647,11 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
13516
13647
  upstreamModelId: route.realModelId
13517
13648
  }
13518
13649
  });
13650
+ const goSdkSessionHeaders = openCodeGoSessionHeaders(
13651
+ { providerId: route.providerId, baseUrl: route.baseURL },
13652
+ claudeSessionId
13653
+ );
13654
+ if (goSdkSessionHeaders) params.headers = { ...params.headers, ...goSdkSessionHeaders };
13519
13655
  plog(
13520
13656
  () => `sdk: npm=${route.npm} model=${route.realModelId}, stream=${clientWantsStream}, tools=${anthropicBody.tools?.length ?? 0}, msgs=${params.messages.length}`
13521
13657
  );
@@ -13675,7 +13811,7 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
13675
13811
  res,
13676
13812
  upstreamStatus === 500 ? 502 : upstreamStatus,
13677
13813
  clientMessage,
13678
- contextLengthExceeded ? relayRequestId ?? randomUUID3() : void 0
13814
+ contextLengthExceeded ? relayRequestId ?? randomUUID4() : void 0
13679
13815
  );
13680
13816
  } else {
13681
13817
  const errorType = anthropicErrorType(upstreamStatus, details?.transportCode);
@@ -13683,7 +13819,7 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
13683
13819
  data: ${JSON.stringify({
13684
13820
  type: "error",
13685
13821
  error: { type: errorType, message: clientMessage },
13686
- ...contextLengthExceeded ? { request_id: relayRequestId ?? randomUUID3() } : {}
13822
+ ...contextLengthExceeded ? { request_id: relayRequestId ?? randomUUID4() } : {}
13687
13823
  })}
13688
13824
 
13689
13825
  `);
@@ -15019,7 +15155,7 @@ function localProvidersToServerModels(localProviders) {
15019
15155
  }
15020
15156
 
15021
15157
  // src/registry/credential-cleanup-journal.ts
15022
- import { randomUUID as randomUUID4 } from "crypto";
15158
+ import { randomUUID as randomUUID5 } from "crypto";
15023
15159
  import {
15024
15160
  closeSync as closeSync8,
15025
15161
  existsSync as existsSync6,
@@ -15159,7 +15295,7 @@ function writeJournalUnlocked(journal, path) {
15159
15295
  assertRegistryWriteOwnership(path);
15160
15296
  ensureSecureAppHome();
15161
15297
  mkdirSync6(dirname6(path), { recursive: true, mode: DIR_MODE2 });
15162
- const tmp = `${path}.${process.pid}.${randomUUID4()}.tmp`;
15298
+ const tmp = `${path}.${process.pid}.${randomUUID5()}.tmp`;
15163
15299
  let fd;
15164
15300
  try {
15165
15301
  fd = openSync8(tmp, "wx", FILE_MODE4);
@@ -18052,7 +18188,7 @@ async function askSaveServerPassword() {
18052
18188
 
18053
18189
  // src/server/router.ts
18054
18190
  import { createServer as createServer2 } from "http";
18055
- import { randomUUID as randomUUID5 } from "crypto";
18191
+ import { randomUUID as randomUUID6 } from "crypto";
18056
18192
 
18057
18193
  // src/openai-adapter.ts
18058
18194
  import { tool as tool2, jsonSchema as jsonSchema2, streamText as streamText2, generateText as generateText2 } from "ai";
@@ -18468,7 +18604,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
18468
18604
  plog(`model not found: ${body.model}`);
18469
18605
  return;
18470
18606
  }
18471
- const requestId = randomUUID5();
18607
+ const requestId = randomUUID6();
18472
18608
  const claudeSessionIdHeader = Array.isArray(req.headers["x-claude-code-session-id"]) ? req.headers["x-claude-code-session-id"][0] : req.headers["x-claude-code-session-id"];
18473
18609
  const claudeSessionId = extractClaudeSessionId(body, claudeSessionIdHeader);
18474
18610
  const claudeAgentIds = extractClaudeAgentIds(req.headers);
@@ -18508,6 +18644,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
18508
18644
  const forwardBody = { ...body, model: upstreamModelId(model) };
18509
18645
  const authType = model.authType ?? "api";
18510
18646
  const isOAuth = authType === "oauth";
18647
+ const goSessionHeaders = openCodeGoSessionHeaders(model, claudeSessionId);
18511
18648
  auditInference(options, {
18512
18649
  requestId,
18513
18650
  modelId: body.model,
@@ -18538,7 +18675,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
18538
18675
  authType,
18539
18676
  log: (message) => plog(message),
18540
18677
  claudeCodeSessionId,
18541
- extraHeaders: model.headers,
18678
+ extraHeaders: { ...model.headers, ...goSessionHeaders },
18542
18679
  refreshToken,
18543
18680
  onTokenRefreshed: (refreshed) => {
18544
18681
  model.apiKey = refreshed;
@@ -18610,6 +18747,8 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog) {
18610
18747
  maxTools: npmMaxTools,
18611
18748
  log: plog
18612
18749
  });
18750
+ const goSdkSessionHeaders = openCodeGoSessionHeaders(model, claudeSessionId);
18751
+ if (goSdkSessionHeaders) params.headers = { ...params.headers, ...goSdkSessionHeaders };
18613
18752
  const clientWantsStream = Boolean(body.stream);
18614
18753
  const responseModelId = getResponseModelId(body.model, model, options);
18615
18754
  plog(() => `sdk npm=${model.npm} upstream=${upstreamModelId(model)} responseModel=${responseModelId} stream=${clientWantsStream}`);
@@ -18801,6 +18940,8 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
18801
18940
  }
18802
18941
  const model = lookupModel(res, options.catalog, body.model);
18803
18942
  if (!model) return;
18943
+ const openAiSessionIdHeader = Array.isArray(req.headers["x-claude-code-session-id"]) ? req.headers["x-claude-code-session-id"][0] : req.headers["x-claude-code-session-id"];
18944
+ const goSessionHeaders = openCodeGoSessionHeaders(model, openAiSessionIdHeader);
18804
18945
  if (supportsDirectOpenAIChatCompletions(model)) {
18805
18946
  if (model.completionsUrl && !/^https?:\/\//i.test(model.completionsUrl)) {
18806
18947
  sendJson(res, 400, { error: { message: `Invalid provider completionsUrl: must be http:// or https://` } });
@@ -18837,7 +18978,7 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
18837
18978
  try {
18838
18979
  await relayAnthropicMessages(res, completionsUrl, forwardBody, apiKey2, Boolean(body.stream), {
18839
18980
  authType: model.authType ?? "api",
18840
- extraHeaders: model.headers,
18981
+ extraHeaders: { ...model.headers, ...goSessionHeaders },
18841
18982
  refreshToken,
18842
18983
  onTokenRefreshed: (refreshed) => {
18843
18984
  model.apiKey = refreshed;
@@ -18882,6 +19023,7 @@ async function handleOpenAIChatCompletions(req, res, options, modelCache, plog)
18882
19023
  const baseURL = model.modelFormat === "anthropic" ? model.baseUrl : model.apiBaseUrl;
18883
19024
  const openAiOAuth = isOpenAiOAuthRoute(model);
18884
19025
  const params = translateOpenAiRequest(body, { openAiOAuth });
19026
+ if (goSessionHeaders) params.headers = { ...params.headers, ...goSessionHeaders };
18885
19027
  const clientWantsStream = Boolean(body.stream);
18886
19028
  const responseModelId = getResponseModelId(body.model, model, options);
18887
19029
  plog(() => `sdk-openai npm=${npm} upstream=${upstreamModelId(model)} responseModel=${responseModelId} stream=${clientWantsStream}`);
@@ -19136,7 +19278,7 @@ import * as http2 from "http";
19136
19278
  import * as https from "https";
19137
19279
  import * as net from "net";
19138
19280
  import { PassThrough } from "stream";
19139
- import { randomUUID as randomUUID6 } from "crypto";
19281
+ import { randomUUID as randomUUID7 } from "crypto";
19140
19282
  import { URL as URL2 } from "url";
19141
19283
  import { createBrotliDecompress, createGunzip, createInflate } from "zlib";
19142
19284
 
@@ -19994,7 +20136,7 @@ async function startHttpProxy(options) {
19994
20136
  }
19995
20137
  const messagesEndpoint = anthropicMessagesEndpoint(req.url);
19996
20138
  if (req.method === "POST" && messagesEndpoint) {
19997
- const requestId = randomUUID6();
20139
+ const requestId = randomUUID7();
19998
20140
  let parsed = null;
19999
20141
  let route;
20000
20142
  let adapterBody = rawBody;