@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 +240 -98
- package/dist/cli.js.map +1 -1
- package/docs/opencode-go.md +2 -0
- package/package.json +1 -1
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.
|
|
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
|
|
4831
|
+
name: "DeepSeek V4 Flash",
|
|
4829
4832
|
contextWindow: 1e6,
|
|
4830
4833
|
cost: {
|
|
4831
|
-
input: 0.
|
|
4832
|
-
output: 0.
|
|
4833
|
-
cache_read:
|
|
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.
|
|
4865
|
-
output:
|
|
4866
|
-
cache_read:
|
|
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
|
|
4979
|
+
name: "GPT-5.6 Luna",
|
|
4953
4980
|
contextWindow: 105e4,
|
|
4954
4981
|
cost: {
|
|
4955
|
-
input: 0.
|
|
4956
|
-
output:
|
|
4957
|
-
cache_read: 0.
|
|
4958
|
-
cache_write: 0.
|
|
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
|
|
9002
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) => ({
|
|
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(
|
|
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.
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 ??
|
|
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 ??
|
|
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
|
|
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}.${
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
20139
|
+
const requestId = randomUUID7();
|
|
19998
20140
|
let parsed = null;
|
|
19999
20141
|
let route;
|
|
20000
20142
|
let adapterBody = rawBody;
|