@opencow-ai/opencow-agent-sdk 0.4.2 → 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/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.input_tokens / 1e6 * modelCosts.inputTokens + usage.output_tokens / 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;
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.speed === "fast";
68874
+ const isFastMode = usage?.speed === "fast";
68875
68875
  return getOpus46CostTier(isFastMode);
68876
68876
  }
68877
68877
  const costs = MODEL_COSTS[shortName];
@@ -94949,6 +94949,83 @@ function sanitizeTypeField(record3) {
94949
94949
  record3.type = filtered;
94950
94950
  }
94951
94951
  }
94952
+ function makeSchemaNullable(schema, style = "union") {
94953
+ if ("enum" in schema || "const" in schema)
94954
+ return schema;
94955
+ if (schema.nullable === true)
94956
+ return schema;
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
+ }
94971
+ if (typeof raw === "string") {
94972
+ if (raw === "null")
94973
+ return schema;
94974
+ return { ...schema, type: [raw, "null"] };
94975
+ }
94976
+ if (Array.isArray(raw)) {
94977
+ if (raw.includes("null"))
94978
+ return schema;
94979
+ return { ...schema, type: [...raw, "null"] };
94980
+ }
94981
+ return schema;
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
+ }
94952
95029
  function sanitizeSchemaForOpenAICompat(schema) {
94953
95030
  const stripped = stripSchemaKeywords(schema, OPENAI_INCOMPATIBLE_SCHEMA_KEYWORDS);
94954
95031
  if (!isSchemaRecord(stripped)) {
@@ -95265,7 +95342,7 @@ function convertAnthropicMessagesToResponsesInput(messages) {
95265
95342
  }
95266
95343
  return items.filter((item) => item.type !== "message" || item.content.length > 0);
95267
95344
  }
95268
- function enforceStrictSchema(schema) {
95345
+ function enforceStrictSchema(schema, topLevel = true) {
95269
95346
  const record3 = sanitizeSchemaForOpenAICompat(schema);
95270
95347
  if (record3.format === "uri") {
95271
95348
  delete record3.format;
@@ -95274,10 +95351,10 @@ function enforceStrictSchema(schema) {
95274
95351
  record3.additionalProperties = false;
95275
95352
  if (record3.properties && typeof record3.properties === "object" && !Array.isArray(record3.properties)) {
95276
95353
  const props = record3.properties;
95277
- const allKeys = Object.keys(props);
95354
+ const originalRequired = Array.isArray(record3.required) ? record3.required.filter((key) => typeof key === "string") : [];
95278
95355
  const enforcedProps = {};
95279
95356
  for (const [key, value] of Object.entries(props)) {
95280
- const strictValue = enforceStrictSchema(value);
95357
+ const strictValue = enforceStrictSchema(value, false);
95281
95358
  if (strictValue && typeof strictValue === "object" && strictValue.type === "object" && strictValue.additionalProperties === false && (!strictValue.properties || Object.keys(strictValue.properties).length === 0)) {
95282
95359
  continue;
95283
95360
  }
@@ -95285,20 +95362,27 @@ function enforceStrictSchema(schema) {
95285
95362
  }
95286
95363
  record3.properties = enforcedProps;
95287
95364
  record3.required = Object.keys(enforcedProps);
95365
+ if (topLevel) {
95366
+ for (const key of Object.keys(enforcedProps)) {
95367
+ if (!originalRequired.includes(key)) {
95368
+ enforcedProps[key] = makeSchemaNullable(enforcedProps[key]);
95369
+ }
95370
+ }
95371
+ }
95288
95372
  } else {
95289
95373
  record3.required = [];
95290
95374
  }
95291
95375
  }
95292
95376
  if ("items" in record3) {
95293
95377
  if (Array.isArray(record3.items)) {
95294
- record3.items = record3.items.map((item) => enforceStrictSchema(item));
95378
+ record3.items = record3.items.map((item) => enforceStrictSchema(item, false));
95295
95379
  } else {
95296
- record3.items = enforceStrictSchema(record3.items);
95380
+ record3.items = enforceStrictSchema(record3.items, false);
95297
95381
  }
95298
95382
  }
95299
95383
  for (const key of ["anyOf", "oneOf", "allOf"]) {
95300
95384
  if (key in record3 && Array.isArray(record3[key])) {
95301
- record3[key] = record3[key].map((item) => enforceStrictSchema(item));
95385
+ record3[key] = record3[key].map((item) => enforceStrictSchema(item, false));
95302
95386
  }
95303
95387
  }
95304
95388
  return record3;
@@ -95841,6 +95925,51 @@ var init_providerProfile = __esm(() => {
95841
95925
  ];
95842
95926
  });
95843
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
+
95844
95973
  // src/providers/openai/shim.ts
95845
95974
  var exports_shim = {};
95846
95975
  __export(exports_shim, {
@@ -96010,15 +96139,18 @@ function convertMessages(messages, system) {
96010
96139
  }
96011
96140
  }
96012
96141
  if (otherContent.length > 0) {
96013
- result.push({
96014
- role: "user",
96015
- content: convertContentBlocks(otherContent)
96016
- });
96142
+ const converted = convertContentBlocks(otherContent);
96143
+ if (converted !== "") {
96144
+ result.push({
96145
+ role: "user",
96146
+ content: converted
96147
+ });
96148
+ }
96017
96149
  }
96018
96150
  } else {
96019
96151
  result.push({
96020
96152
  role: "user",
96021
- content: convertContentBlocks(content)
96153
+ content: convertContentBlocks(content) || "."
96022
96154
  });
96023
96155
  }
96024
96156
  } else if (role === "assistant") {
@@ -96030,7 +96162,8 @@ function convertMessages(messages, system) {
96030
96162
  role: "assistant",
96031
96163
  content: (() => {
96032
96164
  const c5 = convertContentBlocks(textContent);
96033
- return typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
96165
+ const text = typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
96166
+ return text || null;
96034
96167
  })()
96035
96168
  };
96036
96169
  if (thinkingBlocks.length > 0) {
@@ -96053,52 +96186,63 @@ function convertMessages(messages, system) {
96053
96186
  }
96054
96187
  result.push(assistantMsg);
96055
96188
  } else {
96189
+ const c5 = convertContentBlocks(content);
96190
+ const text = typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
96056
96191
  result.push({
96057
96192
  role: "assistant",
96058
- content: (() => {
96059
- const c5 = convertContentBlocks(content);
96060
- return typeof c5 === "string" ? c5 : Array.isArray(c5) ? c5.map((p) => p.text ?? "").join("") : "";
96061
- })()
96193
+ content: text || null
96062
96194
  });
96063
96195
  }
96064
96196
  }
96065
96197
  }
96066
96198
  return result;
96067
96199
  }
96068
- function normalizeSchemaForOpenAI(schema, strict = true) {
96069
- const record3 = sanitizeSchemaForOpenAICompat(schema);
96200
+ function normalizeSchemaForOpenAI(schema, strict = true, topLevel = true, geminiTarget = false) {
96201
+ let record3 = sanitizeSchemaForOpenAICompat(schema);
96202
+ if (geminiTarget) {
96203
+ record3 = splitTypeArrayToAnyOf(record3);
96204
+ }
96070
96205
  if (record3.type === "object" && record3.properties) {
96071
96206
  const properties = record3.properties;
96072
96207
  const existingRequired = Array.isArray(record3.required) ? record3.required : [];
96073
96208
  const normalizedProps = {};
96074
96209
  for (const [key, value] of Object.entries(properties)) {
96075
- normalizedProps[key] = normalizeSchemaForOpenAI(value, strict);
96210
+ normalizedProps[key] = normalizeSchemaForOpenAI(value, strict, false, geminiTarget);
96076
96211
  }
96077
96212
  record3.properties = normalizedProps;
96078
96213
  if (strict) {
96079
96214
  const allKeys = Object.keys(normalizedProps);
96080
96215
  record3.required = Array.from(new Set([...existingRequired, ...allKeys]));
96081
96216
  record3.additionalProperties = false;
96217
+ if (topLevel) {
96218
+ const style = geminiTarget ? "nullable" : "union";
96219
+ for (const key of allKeys) {
96220
+ if (!existingRequired.includes(key)) {
96221
+ normalizedProps[key] = makeSchemaNullable(normalizedProps[key], style);
96222
+ }
96223
+ }
96224
+ }
96082
96225
  } else {
96083
96226
  record3.required = existingRequired.filter((k) => (k in normalizedProps));
96084
96227
  }
96085
96228
  }
96086
96229
  if ("items" in record3) {
96087
96230
  if (Array.isArray(record3.items)) {
96088
- record3.items = record3.items.map((item) => normalizeSchemaForOpenAI(item, strict));
96231
+ record3.items = record3.items.map((item) => normalizeSchemaForOpenAI(item, strict, false, geminiTarget));
96089
96232
  } else {
96090
- record3.items = normalizeSchemaForOpenAI(record3.items, strict);
96233
+ record3.items = normalizeSchemaForOpenAI(record3.items, strict, false, geminiTarget);
96091
96234
  }
96092
96235
  }
96093
96236
  for (const key of ["anyOf", "oneOf", "allOf"]) {
96094
96237
  if (key in record3 && Array.isArray(record3[key])) {
96095
- record3[key] = record3[key].map((item) => normalizeSchemaForOpenAI(item, strict));
96238
+ record3[key] = record3[key].map((item) => normalizeSchemaForOpenAI(item, strict, false, geminiTarget));
96096
96239
  }
96097
96240
  }
96098
96241
  return record3;
96099
96242
  }
96100
- function convertTools(tools) {
96243
+ function convertTools(tools, model = "") {
96101
96244
  const isGemini = isEnvTruthy(getQueryEnvVar("CLAUDE_CODE_USE_GEMINI"));
96245
+ const geminiTarget = isGeminiTarget(model);
96102
96246
  return tools.filter((t) => t.name !== "ToolSearchTool").map((t) => {
96103
96247
  const schema = { ...t.input_schema ?? { type: "object", properties: {} } };
96104
96248
  if (t.name === "Agent" && schema.properties) {
@@ -96116,7 +96260,7 @@ function convertTools(tools) {
96116
96260
  function: {
96117
96261
  name: t.name,
96118
96262
  description: t.description ?? "",
96119
- parameters: normalizeSchemaForOpenAI(schema, !isGemini)
96263
+ parameters: normalizeSchemaForOpenAI(schema, !isGemini, true, geminiTarget)
96120
96264
  }
96121
96265
  };
96122
96266
  });
@@ -96137,8 +96281,63 @@ function convertChunkUsage(usage) {
96137
96281
  function toOpenAIChatReasoningEffort(effort) {
96138
96282
  return effort === "xhigh" ? "high" : effort;
96139
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
+ }
96140
96338
  function buildOpenAIRequestBody(params, ctx) {
96141
- const openaiMessages = convertMessages(params.messages, params.system);
96339
+ const capabilities = getOpenAIChatProviderCapabilities(ctx.resolvedModel);
96340
+ const openaiMessages = serializeParallelToolCalls(convertMessages(params.messages, params.system), capabilities);
96142
96341
  const body = {
96143
96342
  model: ctx.resolvedModel,
96144
96343
  messages: openaiMessages,
@@ -96166,9 +96365,12 @@ function buildOpenAIRequestBody(params, ctx) {
96166
96365
  body.reasoning_effort = toOpenAIChatReasoningEffort(ctx.reasoning.effort);
96167
96366
  }
96168
96367
  if (params.tools && params.tools.length > 0) {
96169
- const converted = convertTools(params.tools);
96368
+ const converted = convertTools(params.tools, ctx.resolvedModel);
96170
96369
  if (converted.length > 0) {
96171
96370
  body.tools = converted;
96371
+ if (!capabilities.supportsParallelToolCalls) {
96372
+ body.parallel_tool_calls = false;
96373
+ }
96172
96374
  if (params.tool_choice) {
96173
96375
  const tc = params.tool_choice;
96174
96376
  if (tc.type === "auto") {
@@ -96264,7 +96466,13 @@ async function* openaiStreamToAnthropic(response, model) {
96264
96466
  })}`);
96265
96467
  }
96266
96468
  }
96267
- if (delta.reasoning_content != null) {
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) {
96268
96476
  if (reasoningBlockIndex === null) {
96269
96477
  reasoningBlockIndex = contentBlockIndex;
96270
96478
  contentBlockIndex++;
@@ -96286,7 +96494,7 @@ async function* openaiStreamToAnthropic(response, model) {
96286
96494
  index: reasoningBlockIndex,
96287
96495
  delta: {
96288
96496
  type: "thinking_delta",
96289
- thinking: delta.reasoning_content
96497
+ thinking: reasoningText
96290
96498
  }
96291
96499
  };
96292
96500
  continue;
@@ -96649,6 +96857,22 @@ class OpenAIShimMessages {
96649
96857
  function convertOpenAIResponseToAnthropic(data, model) {
96650
96858
  const choice = data.choices?.[0];
96651
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
+ }
96652
96876
  const rawContent = choice?.message?.content;
96653
96877
  if (typeof rawContent === "string" && rawContent) {
96654
96878
  content.push({ type: "text", text: rawContent });
@@ -96752,6 +96976,7 @@ var init_shim2 = __esm(() => {
96752
96976
  init_config2();
96753
96977
  init_schemaSanitizer();
96754
96978
  init_providerProfile();
96979
+ init_capabilities2();
96755
96980
  OpenAIShimStream = class OpenAIShimStream {
96756
96981
  generator;
96757
96982
  controller = new AbortController;
@@ -97024,36 +97249,6 @@ var init_anthropic = __esm(() => {
97024
97249
  init_errors6();
97025
97250
  });
97026
97251
 
97027
- // src/providers/openai/capabilities.ts
97028
- function supportsReasoningEffort(model) {
97029
- return /^(o\d|gpt-5|gpt-4\.5)/i.test(model);
97030
- }
97031
- function getOpenAICompatMaxOutputTokens(model) {
97032
- const max = getOpenAIMaxOutputTokens(model);
97033
- if (max === undefined)
97034
- return null;
97035
- return { default: max, upperLimit: max };
97036
- }
97037
- function getOpenAICompatContextWindow(model) {
97038
- return getOpenAIContextWindow(model) ?? null;
97039
- }
97040
- function openAICompatSupports(feature, model) {
97041
- if (feature === "reasoning-effort")
97042
- return supportsReasoningEffort(model);
97043
- return FEATURES_OPENAI_COMPAT.includes(feature);
97044
- }
97045
- var FEATURES_OPENAI_COMPAT;
97046
- var init_capabilities2 = __esm(() => {
97047
- init_openaiContextWindows();
97048
- FEATURES_OPENAI_COMPAT = Object.freeze([
97049
- "streaming",
97050
- "tool-use",
97051
- "image-input",
97052
- "parallel-tool-calls",
97053
- "system-message-top-level"
97054
- ]);
97055
- });
97056
-
97057
97252
  // src/providers/openai/errors.ts
97058
97253
  function readErrorMessage(body) {
97059
97254
  if (!body || typeof body !== "object")
@@ -106573,7 +106768,7 @@ function isValidAdvisorModel(model) {
106573
106768
  return m.includes("opus-4-6") || m.includes("sonnet-4-6") || process.env.USER_TYPE === "ant";
106574
106769
  }
106575
106770
  function getAdvisorUsage(usage) {
106576
- const iterations = usage.iterations;
106771
+ const iterations = usage?.iterations;
106577
106772
  if (!iterations) {
106578
106773
  return [];
106579
106774
  }
@@ -106614,11 +106809,11 @@ function addToTotalModelUsage(cost, usage, model) {
106614
106809
  contextWindow: 0,
106615
106810
  maxOutputTokens: 0
106616
106811
  };
106617
- modelUsage.inputTokens += usage.input_tokens;
106618
- modelUsage.outputTokens += usage.output_tokens;
106619
- modelUsage.cacheReadInputTokens += usage.cache_read_input_tokens ?? 0;
106620
- modelUsage.cacheCreationInputTokens += usage.cache_creation_input_tokens ?? 0;
106621
- modelUsage.webSearchRequests += usage.server_tool_use?.web_search_requests ?? 0;
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;
106622
106817
  modelUsage.costUSD += cost;
106623
106818
  modelUsage.contextWindow = getContextWindowForModel(model, getSdkBetas());
106624
106819
  modelUsage.maxOutputTokens = getModelMaxOutputTokens(model).default;
@@ -106627,15 +106822,18 @@ function addToTotalModelUsage(cost, usage, model) {
106627
106822
  function addToTotalSessionCost(cost, usage, model) {
106628
106823
  const modelUsage = addToTotalModelUsage(cost, usage, model);
106629
106824
  addToTotalCostState(cost, modelUsage, model);
106630
- const attrs = isFastModeEnabled() && usage.speed === "fast" ? { model, speed: "fast" } : { model };
106825
+ const attrs = isFastModeEnabled() && usage?.speed === "fast" ? { model, speed: "fast" } : { model };
106631
106826
  getCostCounter()?.add(cost, attrs);
106632
- getTokenCounter()?.add(usage.input_tokens, { ...attrs, type: "input" });
106633
- getTokenCounter()?.add(usage.output_tokens, { ...attrs, type: "output" });
106634
- getTokenCounter()?.add(usage.cache_read_input_tokens ?? 0, {
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, {
106635
106833
  ...attrs,
106636
106834
  type: "cacheRead"
106637
106835
  });
106638
- getTokenCounter()?.add(usage.cache_creation_input_tokens ?? 0, {
106836
+ getTokenCounter()?.add(usage?.cache_creation_input_tokens ?? 0, {
106639
106837
  ...attrs,
106640
106838
  type: "cacheCreation"
106641
106839
  });
@@ -106914,10 +107112,10 @@ function getCLISyspromptPrefix(options) {
106914
107112
  return DEFAULT_PREFIX;
106915
107113
  }
106916
107114
  function isAttributionHeaderEnabled() {
106917
- if (isEnvDefinedFalsy(resolveEnvVar("ATTRIBUTION_HEADER"))) {
106918
- return false;
107115
+ if (isEnvTruthy(resolveEnvVar("ATTRIBUTION_HEADER"))) {
107116
+ return true;
106919
107117
  }
106920
- return getFeatureValue_CACHED_MAY_BE_STALE("tengu_attribution_header", true);
107118
+ return getFeatureValue_CACHED_MAY_BE_STALE("tengu_attribution_header", false);
106921
107119
  }
106922
107120
  function getAttributionHeader(fingerprint) {
106923
107121
  if (!isAttributionHeaderEnabled()) {
@@ -106928,7 +107126,7 @@ function getAttributionHeader(fingerprint) {
106928
107126
  const cch = "";
106929
107127
  const workload = getWorkload();
106930
107128
  const workloadPair = workload ? ` cc_workload=${workload};` : "";
106931
- const header = `x-anthropic-billing-header: cc_version=${version2}; cc_entrypoint=${entrypoint};${cch}${workloadPair}`;
107129
+ const header = `x-opencow-billing-header: cc_version=${version2}; cc_entrypoint=${entrypoint};${cch}${workloadPair}`;
106932
107130
  logForDebugging(`attribution header ${header}`);
106933
107131
  return header;
106934
107132
  }
@@ -223607,6 +223805,30 @@ var init_permissionLogging = __esm(() => {
223607
223805
  CODE_EDITING_TOOLS = ["Edit", "Write", "NotebookEdit"];
223608
223806
  });
223609
223807
 
223808
+ // src/lib/toolInputNullCoercion.ts
223809
+ function omitNullProps(input) {
223810
+ const out = {};
223811
+ for (const [key, value] of Object.entries(input)) {
223812
+ if (value !== null)
223813
+ out[key] = value;
223814
+ }
223815
+ return out;
223816
+ }
223817
+ function safeParseToolInputWithNullCoercion(schema, input) {
223818
+ const first = schema.safeParse(input);
223819
+ if (first.success)
223820
+ return first;
223821
+ if (input === null || typeof input !== "object" || Array.isArray(input)) {
223822
+ return first;
223823
+ }
223824
+ const record3 = input;
223825
+ const hasNull = Object.values(record3).some((value) => value === null);
223826
+ if (!hasNull)
223827
+ return first;
223828
+ const retry = schema.safeParse(omitNullProps(record3));
223829
+ return retry.success ? retry : first;
223830
+ }
223831
+
223610
223832
  // src/constants/tools.ts
223611
223833
  var ALL_AGENT_DISALLOWED_TOOLS, CUSTOM_AGENT_DISALLOWED_TOOLS, ASYNC_AGENT_ALLOWED_TOOLS, IN_PROCESS_TEAMMATE_ALLOWED_TOOLS, COORDINATOR_MODE_ALLOWED_TOOLS;
223612
223834
  var init_tools = __esm(() => {
@@ -279452,7 +279674,7 @@ function streamedCheckPermissionsAndCallTool(tool, toolUseID, input, toolUseCont
279452
279674
  return stream4;
279453
279675
  }
279454
279676
  async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContext, canUseTool, assistantMessage, messageId, requestId, mcpServerType, mcpServerBaseUrl, onToolProgress) {
279455
- const parsedInput = tool.inputSchema.safeParse(input);
279677
+ const parsedInput = safeParseToolInputWithNullCoercion(tool.inputSchema, input);
279456
279678
  if (!parsedInput.success) {
279457
279679
  let errorContent = formatZodValidationError(tool.name, parsedInput.error);
279458
279680
  const schemaHint = buildSchemaNotSentHint(tool, toolUseContext.messages, toolUseContext.options.tools);
@@ -282034,7 +282256,7 @@ function getAnthropicEnvMetadata() {
282034
282256
  function getBuildAgeMinutes() {
282035
282257
  if (false)
282036
282258
  ;
282037
- const buildTime = new Date("2026-05-19T14:04:55.374Z").getTime();
282259
+ const buildTime = new Date("2026-06-03T08:42:39.310Z").getTime();
282038
282260
  if (isNaN(buildTime))
282039
282261
  return;
282040
282262
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -285786,7 +286008,7 @@ var init_FileReadTool = __esm(() => {
285786
286008
  },
285787
286009
  renderToolUseErrorMessage: renderToolUseErrorMessage9,
285788
286010
  async validateInput({ file_path, pages }, toolUseContext) {
285789
- if (pages !== undefined) {
286011
+ if (typeof pages === "string" && pages.trim() !== "") {
285790
286012
  const parsed = parsePDFPageRange(pages);
285791
286013
  if (!parsed) {
285792
286014
  return {
@@ -285835,7 +286057,8 @@ var init_FileReadTool = __esm(() => {
285835
286057
  }
285836
286058
  return { result: true };
285837
286059
  },
285838
- async call({ file_path, offset = 1, limit = undefined, pages }, context4, _canUseTool, parentMessage) {
286060
+ async call({ file_path, offset = 1, limit = undefined, pages: rawPages }, context4, _canUseTool, parentMessage) {
286061
+ const pages = typeof rawPages === "string" && rawPages.trim() !== "" ? rawPages : undefined;
285839
286062
  const { readFileState, fileReadingLimits } = context4;
285840
286063
  const defaults2 = getDefaultFileReadingLimits();
285841
286064
  const maxSizeBytes = fileReadingLimits?.maxSizeBytes ?? defaults2.maxSizeBytes;
@@ -292313,7 +292536,7 @@ function splitSysPromptPrefix(systemPrompt, options2) {
292313
292536
  continue;
292314
292537
  if (prompt === SYSTEM_PROMPT_DYNAMIC_BOUNDARY)
292315
292538
  continue;
292316
- if (prompt.startsWith("x-anthropic-billing-header")) {
292539
+ if (prompt.startsWith("x-opencow-billing-header")) {
292317
292540
  attributionHeader2 = prompt;
292318
292541
  } else if (CLI_SYSPROMPT_PREFIXES.has(prompt)) {
292319
292542
  systemPromptPrefix2 = prompt;
@@ -292347,7 +292570,7 @@ function splitSysPromptPrefix(systemPrompt, options2) {
292347
292570
  const block2 = systemPrompt[i3];
292348
292571
  if (!block2 || block2 === SYSTEM_PROMPT_DYNAMIC_BOUNDARY)
292349
292572
  continue;
292350
- if (block2.startsWith("x-anthropic-billing-header")) {
292573
+ if (block2.startsWith("x-opencow-billing-header")) {
292351
292574
  attributionHeader2 = block2;
292352
292575
  } else if (CLI_SYSPROMPT_PREFIXES.has(block2)) {
292353
292576
  systemPromptPrefix2 = block2;
@@ -292390,7 +292613,7 @@ function splitSysPromptPrefix(systemPrompt, options2) {
292390
292613
  for (const block2 of systemPrompt) {
292391
292614
  if (!block2)
292392
292615
  continue;
292393
- if (block2.startsWith("x-anthropic-billing-header")) {
292616
+ if (block2.startsWith("x-opencow-billing-header")) {
292394
292617
  attributionHeader = block2;
292395
292618
  } else if (CLI_SYSPROMPT_PREFIXES.has(block2)) {
292396
292619
  systemPromptPrefix = block2;
@@ -335213,4 +335436,4 @@ export {
335213
335436
  AbortError2 as AbortError
335214
335437
  };
335215
335438
 
335216
- //# debugId=003768B505C730B064756E2164756E21
335439
+ //# debugId=5C1C50C89C84EDAD64756E2164756E21