@opencow-ai/opencow-agent-sdk 0.4.3 → 0.4.4
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.mjs +253 -85
- package/dist/client.js +244 -76
- package/dist/lib/schemaSanitizer.d.ts +27 -6
- package/dist/providers/openai/capabilities.d.ts +8 -0
- package/dist/providers/openai/shim.d.ts +9 -2
- package/dist/sdk.js +244 -76
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -68866,12 +68866,12 @@ function getOpus46CostTier(fastMode) {
|
|
|
68866
68866
|
return COST_TIER_5_25;
|
|
68867
68867
|
}
|
|
68868
68868
|
function tokensToUSDCost(modelCosts, usage) {
|
|
68869
|
-
return usage
|
|
68869
|
+
return (usage?.input_tokens ?? 0) / 1e6 * modelCosts.inputTokens + (usage?.output_tokens ?? 0) / 1e6 * modelCosts.outputTokens + (usage?.cache_read_input_tokens ?? 0) / 1e6 * modelCosts.promptCacheReadTokens + (usage?.cache_creation_input_tokens ?? 0) / 1e6 * modelCosts.promptCacheWriteTokens + (usage?.server_tool_use?.web_search_requests ?? 0) * modelCosts.webSearchRequests;
|
|
68870
68870
|
}
|
|
68871
68871
|
function getModelCosts(model, usage) {
|
|
68872
68872
|
const shortName = getCanonicalName(model);
|
|
68873
68873
|
if (shortName === firstPartyNameToCanonical(CLAUDE_OPUS_4_6_CONFIG.firstParty)) {
|
|
68874
|
-
const isFastMode = usage
|
|
68874
|
+
const isFastMode = usage?.speed === "fast";
|
|
68875
68875
|
return getOpus46CostTier(isFastMode);
|
|
68876
68876
|
}
|
|
68877
68877
|
const costs = MODEL_COSTS[shortName];
|
|
@@ -94949,10 +94949,25 @@ function sanitizeTypeField(record3) {
|
|
|
94949
94949
|
record3.type = filtered;
|
|
94950
94950
|
}
|
|
94951
94951
|
}
|
|
94952
|
-
function makeSchemaNullable(schema) {
|
|
94952
|
+
function makeSchemaNullable(schema, style = "union") {
|
|
94953
94953
|
if ("enum" in schema || "const" in schema)
|
|
94954
94954
|
return schema;
|
|
94955
|
+
if (schema.nullable === true)
|
|
94956
|
+
return schema;
|
|
94955
94957
|
const raw = schema.type;
|
|
94958
|
+
if (style === "nullable") {
|
|
94959
|
+
if (typeof raw === "string") {
|
|
94960
|
+
if (raw === "null")
|
|
94961
|
+
return schema;
|
|
94962
|
+
return { ...schema, nullable: true };
|
|
94963
|
+
}
|
|
94964
|
+
if (Array.isArray(raw)) {
|
|
94965
|
+
if (raw.includes("null"))
|
|
94966
|
+
return schema;
|
|
94967
|
+
return { ...schema, nullable: true };
|
|
94968
|
+
}
|
|
94969
|
+
return schema;
|
|
94970
|
+
}
|
|
94956
94971
|
if (typeof raw === "string") {
|
|
94957
94972
|
if (raw === "null")
|
|
94958
94973
|
return schema;
|
|
@@ -94965,6 +94980,52 @@ function makeSchemaNullable(schema) {
|
|
|
94965
94980
|
}
|
|
94966
94981
|
return schema;
|
|
94967
94982
|
}
|
|
94983
|
+
function splitTypeArrayToAnyOf(schema) {
|
|
94984
|
+
if (!Array.isArray(schema.type) || schema.type.length < 2)
|
|
94985
|
+
return schema;
|
|
94986
|
+
const types2 = schema.type;
|
|
94987
|
+
const hasNull = types2.includes("null");
|
|
94988
|
+
const nonNullTypes = types2.filter((t) => t !== "null");
|
|
94989
|
+
if (hasNull && nonNullTypes.length === 1) {
|
|
94990
|
+
const { type: _type, ...rest } = schema;
|
|
94991
|
+
return { ...rest, type: nonNullTypes[0], nullable: true };
|
|
94992
|
+
}
|
|
94993
|
+
const ARRAY_KEYS = new Set(["items"]);
|
|
94994
|
+
const OBJECT_KEYS = new Set(["properties", "required", "additionalProperties"]);
|
|
94995
|
+
const TYPE_SPECIFIC_KEYS = new Set([...ARRAY_KEYS, ...OBJECT_KEYS]);
|
|
94996
|
+
const base2 = {};
|
|
94997
|
+
const structural = {};
|
|
94998
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
94999
|
+
if (key === "type")
|
|
95000
|
+
continue;
|
|
95001
|
+
if (TYPE_SPECIFIC_KEYS.has(key)) {
|
|
95002
|
+
structural[key] = value;
|
|
95003
|
+
} else {
|
|
95004
|
+
base2[key] = value;
|
|
95005
|
+
}
|
|
95006
|
+
}
|
|
95007
|
+
const variants = nonNullTypes.map((t) => {
|
|
95008
|
+
const variant = { type: t };
|
|
95009
|
+
if (t === "array") {
|
|
95010
|
+
for (const k of ARRAY_KEYS) {
|
|
95011
|
+
if (k in structural)
|
|
95012
|
+
variant[k] = structural[k];
|
|
95013
|
+
}
|
|
95014
|
+
} else if (t === "object") {
|
|
95015
|
+
for (const k of OBJECT_KEYS) {
|
|
95016
|
+
if (k in structural)
|
|
95017
|
+
variant[k] = structural[k];
|
|
95018
|
+
}
|
|
95019
|
+
}
|
|
95020
|
+
return variant;
|
|
95021
|
+
});
|
|
95022
|
+
if (hasNull)
|
|
95023
|
+
base2.nullable = true;
|
|
95024
|
+
if (variants.length === 1) {
|
|
95025
|
+
return { ...base2, ...variants[0] };
|
|
95026
|
+
}
|
|
95027
|
+
return { ...base2, anyOf: variants };
|
|
95028
|
+
}
|
|
94968
95029
|
function sanitizeSchemaForOpenAICompat(schema) {
|
|
94969
95030
|
const stripped = stripSchemaKeywords(schema, OPENAI_INCOMPATIBLE_SCHEMA_KEYWORDS);
|
|
94970
95031
|
if (!isSchemaRecord(stripped)) {
|
|
@@ -95864,6 +95925,51 @@ var init_providerProfile = __esm(() => {
|
|
|
95864
95925
|
];
|
|
95865
95926
|
});
|
|
95866
95927
|
|
|
95928
|
+
// src/providers/openai/capabilities.ts
|
|
95929
|
+
function supportsReasoningEffort(model) {
|
|
95930
|
+
return /^(o\d|gpt-5|gpt-4\.5)/i.test(model);
|
|
95931
|
+
}
|
|
95932
|
+
function isGeminiLikeModel(model) {
|
|
95933
|
+
const normalized = (model ?? "").trim().toLowerCase();
|
|
95934
|
+
return normalized.startsWith("gemini-") || normalized.includes("/gemini-");
|
|
95935
|
+
}
|
|
95936
|
+
function isGeminiTarget(model) {
|
|
95937
|
+
if (isEnvTruthy(getQueryEnvVar("CLAUDE_CODE_USE_GEMINI")))
|
|
95938
|
+
return true;
|
|
95939
|
+
return isGeminiLikeModel(model);
|
|
95940
|
+
}
|
|
95941
|
+
function supportsParallelToolCalls(model) {
|
|
95942
|
+
return !isGeminiTarget(model);
|
|
95943
|
+
}
|
|
95944
|
+
function getOpenAICompatMaxOutputTokens(model) {
|
|
95945
|
+
const max = getOpenAIMaxOutputTokens(model);
|
|
95946
|
+
if (max === undefined)
|
|
95947
|
+
return null;
|
|
95948
|
+
return { default: max, upperLimit: max };
|
|
95949
|
+
}
|
|
95950
|
+
function getOpenAICompatContextWindow(model) {
|
|
95951
|
+
return getOpenAIContextWindow(model) ?? null;
|
|
95952
|
+
}
|
|
95953
|
+
function openAICompatSupports(feature, model) {
|
|
95954
|
+
if (feature === "reasoning-effort")
|
|
95955
|
+
return supportsReasoningEffort(model);
|
|
95956
|
+
if (feature === "parallel-tool-calls")
|
|
95957
|
+
return supportsParallelToolCalls(model);
|
|
95958
|
+
return FEATURES_OPENAI_COMPAT.includes(feature);
|
|
95959
|
+
}
|
|
95960
|
+
var FEATURES_OPENAI_COMPAT;
|
|
95961
|
+
var init_capabilities2 = __esm(() => {
|
|
95962
|
+
init_openaiContextWindows();
|
|
95963
|
+
init_envUtils();
|
|
95964
|
+
init_state2();
|
|
95965
|
+
FEATURES_OPENAI_COMPAT = Object.freeze([
|
|
95966
|
+
"streaming",
|
|
95967
|
+
"tool-use",
|
|
95968
|
+
"image-input",
|
|
95969
|
+
"system-message-top-level"
|
|
95970
|
+
]);
|
|
95971
|
+
});
|
|
95972
|
+
|
|
95867
95973
|
// src/providers/openai/shim.ts
|
|
95868
95974
|
var exports_shim = {};
|
|
95869
95975
|
__export(exports_shim, {
|
|
@@ -96033,15 +96139,18 @@ function convertMessages(messages, system) {
|
|
|
96033
96139
|
}
|
|
96034
96140
|
}
|
|
96035
96141
|
if (otherContent.length > 0) {
|
|
96036
|
-
|
|
96037
|
-
|
|
96038
|
-
|
|
96039
|
-
|
|
96142
|
+
const converted = convertContentBlocks(otherContent);
|
|
96143
|
+
if (converted !== "") {
|
|
96144
|
+
result.push({
|
|
96145
|
+
role: "user",
|
|
96146
|
+
content: converted
|
|
96147
|
+
});
|
|
96148
|
+
}
|
|
96040
96149
|
}
|
|
96041
96150
|
} else {
|
|
96042
96151
|
result.push({
|
|
96043
96152
|
role: "user",
|
|
96044
|
-
content: convertContentBlocks(content)
|
|
96153
|
+
content: convertContentBlocks(content) || "."
|
|
96045
96154
|
});
|
|
96046
96155
|
}
|
|
96047
96156
|
} else if (role === "assistant") {
|
|
@@ -96053,7 +96162,8 @@ function convertMessages(messages, system) {
|
|
|
96053
96162
|
role: "assistant",
|
|
96054
96163
|
content: (() => {
|
|
96055
96164
|
const c5 = convertContentBlocks(textContent);
|
|
96056
|
-
|
|
96165
|
+
const text = typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
|
|
96166
|
+
return text || null;
|
|
96057
96167
|
})()
|
|
96058
96168
|
};
|
|
96059
96169
|
if (thinkingBlocks.length > 0) {
|
|
@@ -96076,26 +96186,28 @@ function convertMessages(messages, system) {
|
|
|
96076
96186
|
}
|
|
96077
96187
|
result.push(assistantMsg);
|
|
96078
96188
|
} else {
|
|
96189
|
+
const c5 = convertContentBlocks(content);
|
|
96190
|
+
const text = typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
|
|
96079
96191
|
result.push({
|
|
96080
96192
|
role: "assistant",
|
|
96081
|
-
content:
|
|
96082
|
-
const c5 = convertContentBlocks(content);
|
|
96083
|
-
return typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
|
|
96084
|
-
})()
|
|
96193
|
+
content: text || null
|
|
96085
96194
|
});
|
|
96086
96195
|
}
|
|
96087
96196
|
}
|
|
96088
96197
|
}
|
|
96089
96198
|
return result;
|
|
96090
96199
|
}
|
|
96091
|
-
function normalizeSchemaForOpenAI(schema, strict = true, topLevel = true) {
|
|
96092
|
-
|
|
96200
|
+
function normalizeSchemaForOpenAI(schema, strict = true, topLevel = true, geminiTarget = false) {
|
|
96201
|
+
let record3 = sanitizeSchemaForOpenAICompat(schema);
|
|
96202
|
+
if (geminiTarget) {
|
|
96203
|
+
record3 = splitTypeArrayToAnyOf(record3);
|
|
96204
|
+
}
|
|
96093
96205
|
if (record3.type === "object" && record3.properties) {
|
|
96094
96206
|
const properties = record3.properties;
|
|
96095
96207
|
const existingRequired = Array.isArray(record3.required) ? record3.required : [];
|
|
96096
96208
|
const normalizedProps = {};
|
|
96097
96209
|
for (const [key, value] of Object.entries(properties)) {
|
|
96098
|
-
normalizedProps[key] = normalizeSchemaForOpenAI(value, strict, false);
|
|
96210
|
+
normalizedProps[key] = normalizeSchemaForOpenAI(value, strict, false, geminiTarget);
|
|
96099
96211
|
}
|
|
96100
96212
|
record3.properties = normalizedProps;
|
|
96101
96213
|
if (strict) {
|
|
@@ -96103,9 +96215,10 @@ function normalizeSchemaForOpenAI(schema, strict = true, topLevel = true) {
|
|
|
96103
96215
|
record3.required = Array.from(new Set([...existingRequired, ...allKeys]));
|
|
96104
96216
|
record3.additionalProperties = false;
|
|
96105
96217
|
if (topLevel) {
|
|
96218
|
+
const style = geminiTarget ? "nullable" : "union";
|
|
96106
96219
|
for (const key of allKeys) {
|
|
96107
96220
|
if (!existingRequired.includes(key)) {
|
|
96108
|
-
normalizedProps[key] = makeSchemaNullable(normalizedProps[key]);
|
|
96221
|
+
normalizedProps[key] = makeSchemaNullable(normalizedProps[key], style);
|
|
96109
96222
|
}
|
|
96110
96223
|
}
|
|
96111
96224
|
}
|
|
@@ -96115,20 +96228,21 @@ function normalizeSchemaForOpenAI(schema, strict = true, topLevel = true) {
|
|
|
96115
96228
|
}
|
|
96116
96229
|
if ("items" in record3) {
|
|
96117
96230
|
if (Array.isArray(record3.items)) {
|
|
96118
|
-
record3.items = record3.items.map((item) => normalizeSchemaForOpenAI(item, strict, false));
|
|
96231
|
+
record3.items = record3.items.map((item) => normalizeSchemaForOpenAI(item, strict, false, geminiTarget));
|
|
96119
96232
|
} else {
|
|
96120
|
-
record3.items = normalizeSchemaForOpenAI(record3.items, strict, false);
|
|
96233
|
+
record3.items = normalizeSchemaForOpenAI(record3.items, strict, false, geminiTarget);
|
|
96121
96234
|
}
|
|
96122
96235
|
}
|
|
96123
96236
|
for (const key of ["anyOf", "oneOf", "allOf"]) {
|
|
96124
96237
|
if (key in record3 && Array.isArray(record3[key])) {
|
|
96125
|
-
record3[key] = record3[key].map((item) => normalizeSchemaForOpenAI(item, strict, false));
|
|
96238
|
+
record3[key] = record3[key].map((item) => normalizeSchemaForOpenAI(item, strict, false, geminiTarget));
|
|
96126
96239
|
}
|
|
96127
96240
|
}
|
|
96128
96241
|
return record3;
|
|
96129
96242
|
}
|
|
96130
|
-
function convertTools(tools) {
|
|
96243
|
+
function convertTools(tools, model = "") {
|
|
96131
96244
|
const isGemini = isEnvTruthy(getQueryEnvVar("CLAUDE_CODE_USE_GEMINI"));
|
|
96245
|
+
const geminiTarget = isGeminiTarget(model);
|
|
96132
96246
|
return tools.filter((t) => t.name !== "ToolSearchTool").map((t) => {
|
|
96133
96247
|
const schema = { ...t.input_schema ?? { type: "object", properties: {} } };
|
|
96134
96248
|
if (t.name === "Agent" && schema.properties) {
|
|
@@ -96146,7 +96260,7 @@ function convertTools(tools) {
|
|
|
96146
96260
|
function: {
|
|
96147
96261
|
name: t.name,
|
|
96148
96262
|
description: t.description ?? "",
|
|
96149
|
-
parameters: normalizeSchemaForOpenAI(schema, !isGemini)
|
|
96263
|
+
parameters: normalizeSchemaForOpenAI(schema, !isGemini, true, geminiTarget)
|
|
96150
96264
|
}
|
|
96151
96265
|
};
|
|
96152
96266
|
});
|
|
@@ -96167,8 +96281,63 @@ function convertChunkUsage(usage) {
|
|
|
96167
96281
|
function toOpenAIChatReasoningEffort(effort) {
|
|
96168
96282
|
return effort === "xhigh" ? "high" : effort;
|
|
96169
96283
|
}
|
|
96284
|
+
function getOpenAIChatProviderCapabilities(model) {
|
|
96285
|
+
return {
|
|
96286
|
+
supportsParallelToolCalls: openAICompatSupports("parallel-tool-calls", model)
|
|
96287
|
+
};
|
|
96288
|
+
}
|
|
96289
|
+
function collectAdjacentToolMessages(messages, startIndex) {
|
|
96290
|
+
const toolMessages = [];
|
|
96291
|
+
for (let i2 = startIndex;i2 < messages.length && messages[i2]?.role === "tool"; i2++) {
|
|
96292
|
+
toolMessages.push(messages[i2]);
|
|
96293
|
+
}
|
|
96294
|
+
return toolMessages;
|
|
96295
|
+
}
|
|
96296
|
+
function indexToolMessagesById(toolMessages) {
|
|
96297
|
+
const byId = new Map;
|
|
96298
|
+
for (const toolMessage of toolMessages) {
|
|
96299
|
+
if (typeof toolMessage.tool_call_id === "string") {
|
|
96300
|
+
byId.set(toolMessage.tool_call_id, toolMessage);
|
|
96301
|
+
}
|
|
96302
|
+
}
|
|
96303
|
+
return byId;
|
|
96304
|
+
}
|
|
96305
|
+
function splitParallelToolCallTurn(assistantMessage, toolCalls, toolMessagesById) {
|
|
96306
|
+
const serialized = [];
|
|
96307
|
+
toolCalls.forEach((toolCall, index) => {
|
|
96308
|
+
serialized.push({
|
|
96309
|
+
...assistantMessage,
|
|
96310
|
+
tool_calls: [toolCall],
|
|
96311
|
+
content: index === 0 ? assistantMessage.content : null
|
|
96312
|
+
});
|
|
96313
|
+
const toolResponse = toolMessagesById.get(toolCall.id);
|
|
96314
|
+
if (toolResponse)
|
|
96315
|
+
serialized.push(toolResponse);
|
|
96316
|
+
});
|
|
96317
|
+
return serialized;
|
|
96318
|
+
}
|
|
96319
|
+
function serializeParallelToolCalls(messages, capabilities) {
|
|
96320
|
+
if (capabilities.supportsParallelToolCalls)
|
|
96321
|
+
return messages;
|
|
96322
|
+
const result = [];
|
|
96323
|
+
for (let i2 = 0;i2 < messages.length; i2++) {
|
|
96324
|
+
const message = messages[i2];
|
|
96325
|
+
const toolCalls = message.tool_calls;
|
|
96326
|
+
const isParallelToolTurn = message.role === "assistant" && (toolCalls?.length ?? 0) > 1;
|
|
96327
|
+
if (!isParallelToolTurn || !toolCalls) {
|
|
96328
|
+
result.push(message);
|
|
96329
|
+
continue;
|
|
96330
|
+
}
|
|
96331
|
+
const toolMessages = collectAdjacentToolMessages(messages, i2 + 1);
|
|
96332
|
+
const toolMessagesById = indexToolMessagesById(toolMessages);
|
|
96333
|
+
result.push(...splitParallelToolCallTurn(message, toolCalls, toolMessagesById));
|
|
96334
|
+
i2 += toolMessages.length;
|
|
96335
|
+
}
|
|
96336
|
+
return result;
|
|
96337
|
+
}
|
|
96170
96338
|
function buildOpenAIRequestBody(params, ctx) {
|
|
96171
|
-
const
|
|
96339
|
+
const capabilities = getOpenAIChatProviderCapabilities(ctx.resolvedModel);
|
|
96340
|
+
const openaiMessages = serializeParallelToolCalls(convertMessages(params.messages, params.system), capabilities);
|
|
96172
96341
|
const body = {
|
|
96173
96342
|
model: ctx.resolvedModel,
|
|
96174
96343
|
messages: openaiMessages,
|
|
@@ -96196,9 +96365,12 @@ function buildOpenAIRequestBody(params, ctx) {
|
|
|
96196
96365
|
body.reasoning_effort = toOpenAIChatReasoningEffort(ctx.reasoning.effort);
|
|
96197
96366
|
}
|
|
96198
96367
|
if (params.tools && params.tools.length > 0) {
|
|
96199
|
-
const converted = convertTools(params.tools);
|
|
96368
|
+
const converted = convertTools(params.tools, ctx.resolvedModel);
|
|
96200
96369
|
if (converted.length > 0) {
|
|
96201
96370
|
body.tools = converted;
|
|
96371
|
+
if (!capabilities.supportsParallelToolCalls) {
|
|
96372
|
+
body.parallel_tool_calls = false;
|
|
96373
|
+
}
|
|
96202
96374
|
if (params.tool_choice) {
|
|
96203
96375
|
const tc = params.tool_choice;
|
|
96204
96376
|
if (tc.type === "auto") {
|
|
@@ -96294,7 +96466,13 @@ async function* openaiStreamToAnthropic(response, model) {
|
|
|
96294
96466
|
})}`);
|
|
96295
96467
|
}
|
|
96296
96468
|
}
|
|
96297
|
-
|
|
96469
|
+
let reasoningText = delta.reasoning_content ?? delta.reasoning;
|
|
96470
|
+
if (reasoningText == null && Array.isArray(delta.reasoning_details)) {
|
|
96471
|
+
const parts = delta.reasoning_details.map((d) => d.content ?? d.summary ?? "").filter(Boolean);
|
|
96472
|
+
if (parts.length > 0)
|
|
96473
|
+
reasoningText = parts.join("");
|
|
96474
|
+
}
|
|
96475
|
+
if (reasoningText != null) {
|
|
96298
96476
|
if (reasoningBlockIndex === null) {
|
|
96299
96477
|
reasoningBlockIndex = contentBlockIndex;
|
|
96300
96478
|
contentBlockIndex++;
|
|
@@ -96316,7 +96494,7 @@ async function* openaiStreamToAnthropic(response, model) {
|
|
|
96316
96494
|
index: reasoningBlockIndex,
|
|
96317
96495
|
delta: {
|
|
96318
96496
|
type: "thinking_delta",
|
|
96319
|
-
thinking:
|
|
96497
|
+
thinking: reasoningText
|
|
96320
96498
|
}
|
|
96321
96499
|
};
|
|
96322
96500
|
continue;
|
|
@@ -96679,6 +96857,22 @@ class OpenAIShimMessages {
|
|
|
96679
96857
|
function convertOpenAIResponseToAnthropic(data, model) {
|
|
96680
96858
|
const choice = data.choices?.[0];
|
|
96681
96859
|
const content = [];
|
|
96860
|
+
const msg = choice?.message;
|
|
96861
|
+
let reasoningText = msg?.reasoning_content ?? msg?.reasoning;
|
|
96862
|
+
if (reasoningText == null && Array.isArray(msg?.reasoning_details)) {
|
|
96863
|
+
const parts = msg.reasoning_details.map((d) => d.content ?? d.summary ?? "").filter(Boolean);
|
|
96864
|
+
if (parts.length > 0)
|
|
96865
|
+
reasoningText = parts.join(`
|
|
96866
|
+
`);
|
|
96867
|
+
}
|
|
96868
|
+
if (typeof reasoningText === "string" && reasoningText) {
|
|
96869
|
+
content.push({
|
|
96870
|
+
type: "thinking",
|
|
96871
|
+
thinking: reasoningText,
|
|
96872
|
+
signature: "",
|
|
96873
|
+
extra_content: { provenance: "openai-chat" }
|
|
96874
|
+
});
|
|
96875
|
+
}
|
|
96682
96876
|
const rawContent = choice?.message?.content;
|
|
96683
96877
|
if (typeof rawContent === "string" && rawContent) {
|
|
96684
96878
|
content.push({ type: "text", text: rawContent });
|
|
@@ -96782,6 +96976,7 @@ var init_shim2 = __esm(() => {
|
|
|
96782
96976
|
init_config2();
|
|
96783
96977
|
init_schemaSanitizer();
|
|
96784
96978
|
init_providerProfile();
|
|
96979
|
+
init_capabilities2();
|
|
96785
96980
|
OpenAIShimStream = class OpenAIShimStream {
|
|
96786
96981
|
generator;
|
|
96787
96982
|
controller = new AbortController;
|
|
@@ -97054,36 +97249,6 @@ var init_anthropic = __esm(() => {
|
|
|
97054
97249
|
init_errors6();
|
|
97055
97250
|
});
|
|
97056
97251
|
|
|
97057
|
-
// src/providers/openai/capabilities.ts
|
|
97058
|
-
function supportsReasoningEffort(model) {
|
|
97059
|
-
return /^(o\d|gpt-5|gpt-4\.5)/i.test(model);
|
|
97060
|
-
}
|
|
97061
|
-
function getOpenAICompatMaxOutputTokens(model) {
|
|
97062
|
-
const max = getOpenAIMaxOutputTokens(model);
|
|
97063
|
-
if (max === undefined)
|
|
97064
|
-
return null;
|
|
97065
|
-
return { default: max, upperLimit: max };
|
|
97066
|
-
}
|
|
97067
|
-
function getOpenAICompatContextWindow(model) {
|
|
97068
|
-
return getOpenAIContextWindow(model) ?? null;
|
|
97069
|
-
}
|
|
97070
|
-
function openAICompatSupports(feature, model) {
|
|
97071
|
-
if (feature === "reasoning-effort")
|
|
97072
|
-
return supportsReasoningEffort(model);
|
|
97073
|
-
return FEATURES_OPENAI_COMPAT.includes(feature);
|
|
97074
|
-
}
|
|
97075
|
-
var FEATURES_OPENAI_COMPAT;
|
|
97076
|
-
var init_capabilities2 = __esm(() => {
|
|
97077
|
-
init_openaiContextWindows();
|
|
97078
|
-
FEATURES_OPENAI_COMPAT = Object.freeze([
|
|
97079
|
-
"streaming",
|
|
97080
|
-
"tool-use",
|
|
97081
|
-
"image-input",
|
|
97082
|
-
"parallel-tool-calls",
|
|
97083
|
-
"system-message-top-level"
|
|
97084
|
-
]);
|
|
97085
|
-
});
|
|
97086
|
-
|
|
97087
97252
|
// src/providers/openai/errors.ts
|
|
97088
97253
|
function readErrorMessage(body) {
|
|
97089
97254
|
if (!body || typeof body !== "object")
|
|
@@ -106603,7 +106768,7 @@ function isValidAdvisorModel(model) {
|
|
|
106603
106768
|
return m.includes("opus-4-6") || m.includes("sonnet-4-6") || process.env.USER_TYPE === "ant";
|
|
106604
106769
|
}
|
|
106605
106770
|
function getAdvisorUsage(usage) {
|
|
106606
|
-
const iterations = usage
|
|
106771
|
+
const iterations = usage?.iterations;
|
|
106607
106772
|
if (!iterations) {
|
|
106608
106773
|
return [];
|
|
106609
106774
|
}
|
|
@@ -106644,11 +106809,11 @@ function addToTotalModelUsage(cost, usage, model) {
|
|
|
106644
106809
|
contextWindow: 0,
|
|
106645
106810
|
maxOutputTokens: 0
|
|
106646
106811
|
};
|
|
106647
|
-
modelUsage.inputTokens += usage
|
|
106648
|
-
modelUsage.outputTokens += usage
|
|
106649
|
-
modelUsage.cacheReadInputTokens += usage
|
|
106650
|
-
modelUsage.cacheCreationInputTokens += usage
|
|
106651
|
-
modelUsage.webSearchRequests += usage
|
|
106812
|
+
modelUsage.inputTokens += usage?.input_tokens ?? 0;
|
|
106813
|
+
modelUsage.outputTokens += usage?.output_tokens ?? 0;
|
|
106814
|
+
modelUsage.cacheReadInputTokens += usage?.cache_read_input_tokens ?? 0;
|
|
106815
|
+
modelUsage.cacheCreationInputTokens += usage?.cache_creation_input_tokens ?? 0;
|
|
106816
|
+
modelUsage.webSearchRequests += usage?.server_tool_use?.web_search_requests ?? 0;
|
|
106652
106817
|
modelUsage.costUSD += cost;
|
|
106653
106818
|
modelUsage.contextWindow = getContextWindowForModel(model, getSdkBetas());
|
|
106654
106819
|
modelUsage.maxOutputTokens = getModelMaxOutputTokens(model).default;
|
|
@@ -106657,15 +106822,18 @@ function addToTotalModelUsage(cost, usage, model) {
|
|
|
106657
106822
|
function addToTotalSessionCost(cost, usage, model) {
|
|
106658
106823
|
const modelUsage = addToTotalModelUsage(cost, usage, model);
|
|
106659
106824
|
addToTotalCostState(cost, modelUsage, model);
|
|
106660
|
-
const attrs = isFastModeEnabled() && usage
|
|
106825
|
+
const attrs = isFastModeEnabled() && usage?.speed === "fast" ? { model, speed: "fast" } : { model };
|
|
106661
106826
|
getCostCounter()?.add(cost, attrs);
|
|
106662
|
-
getTokenCounter()?.add(usage
|
|
106663
|
-
getTokenCounter()?.add(usage
|
|
106664
|
-
|
|
106827
|
+
getTokenCounter()?.add(usage?.input_tokens ?? 0, { ...attrs, type: "input" });
|
|
106828
|
+
getTokenCounter()?.add(usage?.output_tokens ?? 0, {
|
|
106829
|
+
...attrs,
|
|
106830
|
+
type: "output"
|
|
106831
|
+
});
|
|
106832
|
+
getTokenCounter()?.add(usage?.cache_read_input_tokens ?? 0, {
|
|
106665
106833
|
...attrs,
|
|
106666
106834
|
type: "cacheRead"
|
|
106667
106835
|
});
|
|
106668
|
-
getTokenCounter()?.add(usage
|
|
106836
|
+
getTokenCounter()?.add(usage?.cache_creation_input_tokens ?? 0, {
|
|
106669
106837
|
...attrs,
|
|
106670
106838
|
type: "cacheCreation"
|
|
106671
106839
|
});
|
|
@@ -106944,10 +107112,10 @@ function getCLISyspromptPrefix(options) {
|
|
|
106944
107112
|
return DEFAULT_PREFIX;
|
|
106945
107113
|
}
|
|
106946
107114
|
function isAttributionHeaderEnabled() {
|
|
106947
|
-
if (
|
|
106948
|
-
return
|
|
107115
|
+
if (isEnvTruthy(resolveEnvVar("ATTRIBUTION_HEADER"))) {
|
|
107116
|
+
return true;
|
|
106949
107117
|
}
|
|
106950
|
-
return getFeatureValue_CACHED_MAY_BE_STALE("tengu_attribution_header",
|
|
107118
|
+
return getFeatureValue_CACHED_MAY_BE_STALE("tengu_attribution_header", false);
|
|
106951
107119
|
}
|
|
106952
107120
|
function getAttributionHeader(fingerprint) {
|
|
106953
107121
|
if (!isAttributionHeaderEnabled()) {
|
|
@@ -106958,7 +107126,7 @@ function getAttributionHeader(fingerprint) {
|
|
|
106958
107126
|
const cch = "";
|
|
106959
107127
|
const workload = getWorkload();
|
|
106960
107128
|
const workloadPair = workload ? ` cc_workload=${workload};` : "";
|
|
106961
|
-
const header = `x-
|
|
107129
|
+
const header = `x-opencow-billing-header: cc_version=${version2}; cc_entrypoint=${entrypoint};${cch}${workloadPair}`;
|
|
106962
107130
|
logForDebugging(`attribution header ${header}`);
|
|
106963
107131
|
return header;
|
|
106964
107132
|
}
|
|
@@ -282088,7 +282256,7 @@ function getAnthropicEnvMetadata() {
|
|
|
282088
282256
|
function getBuildAgeMinutes() {
|
|
282089
282257
|
if (false)
|
|
282090
282258
|
;
|
|
282091
|
-
const buildTime = new Date("2026-
|
|
282259
|
+
const buildTime = new Date("2026-06-03T08:42:39.310Z").getTime();
|
|
282092
282260
|
if (isNaN(buildTime))
|
|
282093
282261
|
return;
|
|
282094
282262
|
return Math.floor((Date.now() - buildTime) / 60000);
|
|
@@ -292368,7 +292536,7 @@ function splitSysPromptPrefix(systemPrompt, options2) {
|
|
|
292368
292536
|
continue;
|
|
292369
292537
|
if (prompt === SYSTEM_PROMPT_DYNAMIC_BOUNDARY)
|
|
292370
292538
|
continue;
|
|
292371
|
-
if (prompt.startsWith("x-
|
|
292539
|
+
if (prompt.startsWith("x-opencow-billing-header")) {
|
|
292372
292540
|
attributionHeader2 = prompt;
|
|
292373
292541
|
} else if (CLI_SYSPROMPT_PREFIXES.has(prompt)) {
|
|
292374
292542
|
systemPromptPrefix2 = prompt;
|
|
@@ -292402,7 +292570,7 @@ function splitSysPromptPrefix(systemPrompt, options2) {
|
|
|
292402
292570
|
const block2 = systemPrompt[i3];
|
|
292403
292571
|
if (!block2 || block2 === SYSTEM_PROMPT_DYNAMIC_BOUNDARY)
|
|
292404
292572
|
continue;
|
|
292405
|
-
if (block2.startsWith("x-
|
|
292573
|
+
if (block2.startsWith("x-opencow-billing-header")) {
|
|
292406
292574
|
attributionHeader2 = block2;
|
|
292407
292575
|
} else if (CLI_SYSPROMPT_PREFIXES.has(block2)) {
|
|
292408
292576
|
systemPromptPrefix2 = block2;
|
|
@@ -292445,7 +292613,7 @@ function splitSysPromptPrefix(systemPrompt, options2) {
|
|
|
292445
292613
|
for (const block2 of systemPrompt) {
|
|
292446
292614
|
if (!block2)
|
|
292447
292615
|
continue;
|
|
292448
|
-
if (block2.startsWith("x-
|
|
292616
|
+
if (block2.startsWith("x-opencow-billing-header")) {
|
|
292449
292617
|
attributionHeader = block2;
|
|
292450
292618
|
} else if (CLI_SYSPROMPT_PREFIXES.has(block2)) {
|
|
292451
292619
|
systemPromptPrefix = block2;
|
|
@@ -335268,4 +335436,4 @@ export {
|
|
|
335268
335436
|
AbortError2 as AbortError
|
|
335269
335437
|
};
|
|
335270
335438
|
|
|
335271
|
-
//# debugId=
|
|
335439
|
+
//# debugId=5C1C50C89C84EDAD64756E2164756E21
|
|
@@ -6,13 +6,34 @@
|
|
|
6
6
|
* issue #77:gpt 用 read 工具频繁出错)。让字段可空后,模型可以用 `null` 明确表达
|
|
7
7
|
* 「未提供」,再由入参解析层把 `null` 还原为缺省。
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* 可空的两种写法没有「最大公约数」,必须按目标 provider 选择:
|
|
10
|
+
* - `'union'`(默认):`type: [T, "null"]`。OpenAI / Codex 的 **strict 结构化输出
|
|
11
|
+
* 只接受这种**(`nullable` 是 OpenAPI 扩展,不在其 JSON-Schema 子集里,会被
|
|
12
|
+
* strict 校验拒绝 400);DeepSeek / Kimi / Qwen 同样接受。
|
|
13
|
+
* - `'nullable'`:`nullable: true`。Gemini / Vertex 只接受这种,拒绝 type 数组。
|
|
14
|
+
*
|
|
15
|
+
* 注意 OpenAI chat(非 strict)会忽略 `nullable`,从而丢掉「可传 null」的提示,
|
|
16
|
+
* 退回 issue #77 的形态——所以对 OpenAI 路径必须用 `'union'`。Gemini 路径由调用方
|
|
17
|
+
* (normalizeSchemaForOpenAI)传 `'nullable'`,或经 splitTypeArrayToAnyOf 转换。
|
|
18
|
+
*
|
|
19
|
+
* 带 `enum`/`const` 的字段保持不动(避免自相矛盾);
|
|
20
|
+
* 无明确 `type` 的字段也保持不动(零回归)。
|
|
21
|
+
*/
|
|
22
|
+
export declare function makeSchemaNullable(schema: Record<string, unknown>, style?: 'union' | 'nullable'): Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* 把 type 数组改写为 **Gemini/Vertex** 能接受的形式——仅在目标是 Gemini 时调用
|
|
25
|
+
* (见 normalizeSchemaForOpenAI 的 geminiTarget 门控)。OpenAI/DeepSeek/Kimi 等接受
|
|
26
|
+
* type 数组、且对 OpenAI 而言 `nullable` 会被忽略,故对它们不应调用本函数。
|
|
27
|
+
*
|
|
28
|
+
* Gemini 侧约束:拒绝 type 数组,拒绝 anyOf + null,只接受 nullable: true。
|
|
29
|
+
*
|
|
30
|
+
* 转换策略:
|
|
31
|
+
* - `type: ["T", "null"]` → `{ type: "T", nullable: true, ...结构性关键字 }`
|
|
32
|
+
* - `type: ["T1", "T2", ...]`(>1 种非 null 类型)→ 拆为 anyOf,null 以 nullable 表达
|
|
33
|
+
*
|
|
34
|
+
* 不递归——由调用方(normalizeSchemaForOpenAI)的递归遍历负责嵌套层级。
|
|
14
35
|
*/
|
|
15
|
-
export declare function
|
|
36
|
+
export declare function splitTypeArrayToAnyOf(schema: Record<string, unknown>): Record<string, unknown>;
|
|
16
37
|
/**
|
|
17
38
|
* Sanitize JSON Schema into a shape OpenAI-compatible providers and Codex
|
|
18
39
|
* strict-mode tooling are more likely to accept. This strips provider-rejected
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { ModelOutputTokenCap, ProviderFeature } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 判断最终目标是否为 Gemini/Vertex 系列。
|
|
4
|
+
*
|
|
5
|
+
* 这是 Gemini 专属适配(关闭并行工具调用、schema 用 nullable:true 而非 type 数组)的
|
|
6
|
+
* 统一判定入口。后端纯透传时 SDK 侧 family 恒为 openai,无法据此识别最终 provider,
|
|
7
|
+
* 因此依据 CLAUDE_CODE_USE_GEMINI 环境标志 + model 名两路信号判断。
|
|
8
|
+
*/
|
|
9
|
+
export declare function isGeminiTarget(model: string): boolean;
|
|
2
10
|
export declare function getOpenAICompatMaxOutputTokens(model: string): ModelOutputTokenCap | null;
|
|
3
11
|
export declare function getOpenAICompatContextWindow(model: string): number | null;
|
|
4
12
|
export declare function openAICompatSupports(feature: ProviderFeature, model: string): boolean;
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { type AnthropicStreamEvent, type ShimCreateParams } from '../../providers/codex/shim.js';
|
|
24
24
|
interface OpenAIMessage {
|
|
25
25
|
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
26
|
-
content?: string | Array<{
|
|
26
|
+
content?: string | null | Array<{
|
|
27
27
|
type: string;
|
|
28
28
|
text?: string;
|
|
29
29
|
image_url?: {
|
|
@@ -65,7 +65,7 @@ export declare function convertTools(tools: Array<{
|
|
|
65
65
|
name: string;
|
|
66
66
|
description?: string;
|
|
67
67
|
input_schema?: Record<string, unknown>;
|
|
68
|
-
}
|
|
68
|
+
}>, model?: string): OpenAITool[];
|
|
69
69
|
export declare function makeMessageId(): string;
|
|
70
70
|
/**
|
|
71
71
|
* Async generator that transforms an OpenAI SSE stream into
|
|
@@ -146,6 +146,13 @@ export declare function convertOpenAIResponseToAnthropic(data: {
|
|
|
146
146
|
};
|
|
147
147
|
extra_content?: Record<string, unknown>;
|
|
148
148
|
}>;
|
|
149
|
+
reasoning_content?: string | null;
|
|
150
|
+
reasoning?: string | null;
|
|
151
|
+
reasoning_details?: Array<{
|
|
152
|
+
type?: string;
|
|
153
|
+
content?: string;
|
|
154
|
+
summary?: string;
|
|
155
|
+
}> | null;
|
|
149
156
|
};
|
|
150
157
|
finish_reason?: string;
|
|
151
158
|
}>;
|