@opencow-ai/opencow-agent-sdk 0.4.23 → 0.4.24

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/sdk.js CHANGED
@@ -224458,10 +224458,23 @@ function deepOmitNullProps(value) {
224458
224458
  }
224459
224459
  return value;
224460
224460
  }
224461
- function safeParseToolInputWithNullCoercion(schema, input) {
224461
+ function containsUnrecognizedKeysIssue(value) {
224462
+ if (Array.isArray(value))
224463
+ return value.some(containsUnrecognizedKeysIssue);
224464
+ if (value === null || typeof value !== "object")
224465
+ return false;
224466
+ const issue2 = value;
224467
+ if (issue2.code === "unrecognized_keys")
224468
+ return true;
224469
+ return containsUnrecognizedKeysIssue(issue2.errors);
224470
+ }
224471
+ function safeParseToolInputWithNullCoercion(schema, input, unknownKeys = "strip") {
224462
224472
  const first = schema.safeParse(input);
224463
224473
  if (first.success)
224464
224474
  return first;
224475
+ if (unknownKeys === "reject" && containsUnrecognizedKeysIssue(first.error.issues)) {
224476
+ return first;
224477
+ }
224465
224478
  if (input === null || typeof input !== "object") {
224466
224479
  return first;
224467
224480
  }
@@ -233047,6 +233060,12 @@ function mergeAgentsByType(base2, override) {
233047
233060
  byType.set(agent.agentType, agent);
233048
233061
  return [...byType.values()];
233049
233062
  }
233063
+ function withDefaultAgentForInvocation(activeAgents, requestedType, defaultAgent) {
233064
+ if (requestedType !== undefined || activeAgents.some((agent) => agent.agentType === defaultAgent.agentType)) {
233065
+ return activeAgents;
233066
+ }
233067
+ return [...activeAgents, defaultAgent];
233068
+ }
233050
233069
 
233051
233070
  // src/capabilities/tools/AgentTool/builtInAgents.ts
233052
233071
  var exports_builtInAgents = {};
@@ -233985,11 +234004,62 @@ var init_generators = __esm(() => {
233985
234004
  NO_VALUE = Symbol("NO_VALUE");
233986
234005
  });
233987
234006
 
234007
+ // src/controller/dispatch/permissionPreDecision.ts
234008
+ function startPermissionPreDecisions(blocks, assistantMessages, canUseTool, toolUseContext) {
234009
+ const existing = toolUseContext.permissionPreDecisions;
234010
+ if (existing && existing.size > 0) {
234011
+ return;
234012
+ }
234013
+ const preDecisions = new Map;
234014
+ toolUseContext.permissionPreDecisions = preDecisions;
234015
+ for (const block2 of blocks) {
234016
+ const tool = findToolRuntimeByName(toolUseContext.options.tools, block2.name);
234017
+ if (!tool) {
234018
+ continue;
234019
+ }
234020
+ const parsedInput = safeParseToolInputWithNullCoercion(tool.inputSchema, block2.input, tool.unknownKeys);
234021
+ if (!parsedInput.success) {
234022
+ continue;
234023
+ }
234024
+ const assistantMessage = assistantMessages.find((message) => message.message.content.some((content) => content.type === "tool_use" && content.id === block2.id));
234025
+ if (!assistantMessage) {
234026
+ continue;
234027
+ }
234028
+ let input = parsedInput.data;
234029
+ if (tool.backfillObservableInput && typeof input === "object" && input !== null) {
234030
+ input = { ...input };
234031
+ tool.backfillObservableInput(input);
234032
+ }
234033
+ const promise3 = canUseTool(tool, input, toolUseContext, assistantMessage, block2.id);
234034
+ promise3.catch(() => {});
234035
+ preDecisions.set(block2.id, { input, promise: promise3 });
234036
+ }
234037
+ }
234038
+ function consumePermissionPreDecision(toolUseContext, toolUseID, input, fallback) {
234039
+ const cache2 = toolUseContext.permissionPreDecisions;
234040
+ const entry = cache2?.get(toolUseID);
234041
+ if (!cache2 || !entry) {
234042
+ return fallback();
234043
+ }
234044
+ cache2.delete(toolUseID);
234045
+ if (jsonStringify(entry.input) !== jsonStringify(input)) {
234046
+ return fallback();
234047
+ }
234048
+ return entry.promise;
234049
+ }
234050
+ var init_permissionPreDecision = __esm(() => {
234051
+ init_toolRuntime();
234052
+ init_slowOperations();
234053
+ });
234054
+
233988
234055
  // src/controller/dispatch/toolOrchestration.ts
233989
234056
  function getMaxToolUseConcurrency() {
233990
234057
  return parseInt(resolveEnvVar("MAX_TOOL_USE_CONCURRENCY") || "", 10) || 10;
233991
234058
  }
233992
234059
  async function* runTools(toolUseMessages, assistantMessages, canUseTool, toolUseContext) {
234060
+ if (toolUseContext.options.preDecidePermissions) {
234061
+ startPermissionPreDecisions(toolUseMessages, assistantMessages, canUseTool, toolUseContext);
234062
+ }
233993
234063
  let currentContext = toolUseContext;
233994
234064
  for (const { isConcurrencySafe, blocks } of partitionToolCalls(toolUseMessages, currentContext)) {
233995
234065
  if (isConcurrencySafe) {
@@ -234083,6 +234153,7 @@ var init_toolOrchestration = __esm(() => {
234083
234153
  init_toolRuntime();
234084
234154
  init_generators();
234085
234155
  init_toolExecution();
234156
+ init_permissionPreDecision();
234086
234157
  init_state2();
234087
234158
  });
234088
234159
 
@@ -236316,6 +236387,31 @@ async function* runAgent({
236316
236387
  level: "warn"
236317
236388
  });
236318
236389
  });
236390
+ let partialBaseMessage = null;
236391
+ const partialTextByIndex = new Map;
236392
+ const PARTIAL_PROGRESS_INTERVAL_MS = 50;
236393
+ let lastPartialAssistantAt = 0;
236394
+ let lastPartialProgressHookAt = 0;
236395
+ let foregroundSkipped = 0;
236396
+ let backgroundSkipped = 0;
236397
+ const logPartialProgress = (reason, chars, foregroundEmitted, backgroundEmitted) => {
236398
+ logForDebugging(`[StreamThrottle:SubAgent] ${JSON.stringify({
236399
+ reason,
236400
+ agentId,
236401
+ agentType: agentDefinition.agentType,
236402
+ messageId: partialBaseMessage?.id ?? null,
236403
+ intervalMs: PARTIAL_PROGRESS_INTERVAL_MS,
236404
+ chars,
236405
+ foregroundEmitted,
236406
+ foregroundSkipped,
236407
+ backgroundEmitted,
236408
+ backgroundSkipped
236409
+ })}`);
236410
+ if (foregroundEmitted)
236411
+ foregroundSkipped = 0;
236412
+ if (backgroundEmitted)
236413
+ backgroundSkipped = 0;
236414
+ };
236319
236415
  try {
236320
236416
  const additionalContexts = [];
236321
236417
  for await (const hookResult of executeSubagentStartHooks(agentId, agentDefinition.agentType, agentAbortController.signal, undefined, toolUseContext.toolUseId, isAsync2)) {
@@ -236423,10 +236519,6 @@ async function* runAgent({
236423
236519
  ...description && { description }
236424
236520
  }).catch((_err) => logForDebugging(`Failed to write agent metadata: ${_err}`));
236425
236521
  let lastRecordedUuid = initialMessages.at(-1)?.uuid ?? null;
236426
- let partialBaseMessage = null;
236427
- const partialTextByIndex = new Map;
236428
- const PARTIAL_PROGRESS_HOOK_INTERVAL_MS = 100;
236429
- let lastPartialProgressHookAt = 0;
236430
236522
  const agentExtraBody = agentDefinition.extraBody;
236431
236523
  const agentQuery = query({
236432
236524
  messages: initialMessages,
@@ -236451,6 +236543,11 @@ async function* runAgent({
236451
236543
  if (message.type === "stream_event") {
236452
236544
  const ev = message.event;
236453
236545
  if (ev.type === "message_start") {
236546
+ if (foregroundSkipped > 0 || backgroundSkipped > 0) {
236547
+ logPartialProgress("message-start", 0, false, false);
236548
+ foregroundSkipped = 0;
236549
+ backgroundSkipped = 0;
236550
+ }
236454
236551
  if (message.ttftMs != null) {
236455
236552
  toolUseContext.pushApiMetricsEntry?.(message.ttftMs);
236456
236553
  }
@@ -236462,22 +236559,36 @@ async function* runAgent({
236462
236559
  const idx = ev.index ?? 0;
236463
236560
  const acc = (partialTextByIndex.get(idx) ?? "") + ev.delta.text;
236464
236561
  partialTextByIndex.set(idx, acc);
236465
- onPartialAssistant?.({
236466
- type: "assistant",
236467
- message: {
236468
- ...partialBaseMessage,
236469
- content: [{ type: "text", text: acc, citations: null }]
236470
- },
236471
- uuid: randomUUID6(),
236472
- timestamp: new Date().toISOString()
236473
- });
236562
+ const now = Date.now();
236563
+ let foregroundEmitted = false;
236564
+ let backgroundEmitted = false;
236565
+ if (onPartialAssistant && now - lastPartialAssistantAt >= PARTIAL_PROGRESS_INTERVAL_MS) {
236566
+ lastPartialAssistantAt = now;
236567
+ foregroundEmitted = true;
236568
+ onPartialAssistant({
236569
+ type: "assistant",
236570
+ message: {
236571
+ ...partialBaseMessage,
236572
+ content: [{ type: "text", text: acc, citations: null }]
236573
+ },
236574
+ uuid: randomUUID6(),
236575
+ timestamp: new Date().toISOString()
236576
+ });
236577
+ } else if (onPartialAssistant) {
236578
+ foregroundSkipped += 1;
236579
+ }
236474
236580
  if (isAsync2) {
236475
- const now = Date.now();
236476
- if (now - lastPartialProgressHookAt >= PARTIAL_PROGRESS_HOOK_INTERVAL_MS) {
236581
+ if (now - lastPartialProgressHookAt >= PARTIAL_PROGRESS_INTERVAL_MS) {
236477
236582
  lastPartialProgressHookAt = now;
236583
+ backgroundEmitted = true;
236478
236584
  executeSubagentProgressHooks(agentId, agentDefinition.agentType, partialBaseMessage.id, toolUseContext.toolUseId, [{ type: "text", text: acc }]).catch(() => {});
236585
+ } else {
236586
+ backgroundSkipped += 1;
236479
236587
  }
236480
236588
  }
236589
+ if (foregroundEmitted || backgroundEmitted) {
236590
+ logPartialProgress("emit", acc.length, foregroundEmitted, backgroundEmitted);
236591
+ }
236481
236592
  }
236482
236593
  continue;
236483
236594
  }
@@ -236526,6 +236637,9 @@ async function* runAgent({
236526
236637
  agentRunError = err2;
236527
236638
  throw err2;
236528
236639
  } finally {
236640
+ if (foregroundSkipped > 0 || backgroundSkipped > 0) {
236641
+ logPartialProgress("finalize", 0, false, false);
236642
+ }
236529
236643
  await finalizeLifecycle([
236530
236644
  async () => {
236531
236645
  const naturalStopAlreadyFired = isAsync2 && hasSubagentStopFired(agentId);
@@ -251625,7 +251739,7 @@ var init_AgentTool = __esm(() => {
251625
251739
  }
251626
251740
  selectedAgent = FORK_AGENT;
251627
251741
  } else {
251628
- const allAgents = toolUseContext.options.agentDefinitions.activeAgents;
251742
+ const allAgents = withDefaultAgentForInvocation(toolUseContext.options.agentDefinitions.activeAgents, subagent_type, GENERAL_PURPOSE_AGENT);
251629
251743
  const {
251630
251744
  allowedAgentTypes
251631
251745
  } = toolUseContext.options.agentDefinitions;
@@ -284597,7 +284711,7 @@ async function resolveHookPermissionDecision(hookPermissionResult, tool, input,
284597
284711
  if (requiresInteraction && !interactionSatisfied || requireCanUseTool) {
284598
284712
  logForDebugging(`Hook approved tool use for ${tool.name}, but canUseTool is required`);
284599
284713
  return {
284600
- decision: await canUseTool(tool, hookInput, toolUseContext, assistantMessage, toolUseID),
284714
+ decision: await consumePermissionPreDecision(toolUseContext, toolUseID, hookInput, () => canUseTool(tool, hookInput, toolUseContext, assistantMessage, toolUseID)),
284601
284715
  input: hookInput
284602
284716
  };
284603
284717
  }
@@ -284612,7 +284726,7 @@ async function resolveHookPermissionDecision(hookPermissionResult, tool, input,
284612
284726
  }
284613
284727
  logForDebugging(`Hook approved tool use for ${tool.name}, but ask rule requires prompt`);
284614
284728
  return {
284615
- decision: await canUseTool(tool, hookInput, toolUseContext, assistantMessage, toolUseID),
284729
+ decision: await consumePermissionPreDecision(toolUseContext, toolUseID, hookInput, () => canUseTool(tool, hookInput, toolUseContext, assistantMessage, toolUseID)),
284616
284730
  input: hookInput
284617
284731
  };
284618
284732
  }
@@ -284622,8 +284736,9 @@ async function resolveHookPermissionDecision(hookPermissionResult, tool, input,
284622
284736
  }
284623
284737
  const forceDecision = hookPermissionResult?.behavior === "ask" ? hookPermissionResult : undefined;
284624
284738
  const askInput = hookPermissionResult?.behavior === "ask" && hookPermissionResult.updatedInput ? hookPermissionResult.updatedInput : input;
284739
+ const decision = forceDecision ? await canUseTool(tool, askInput, toolUseContext, assistantMessage, toolUseID, forceDecision) : await consumePermissionPreDecision(toolUseContext, toolUseID, askInput, () => canUseTool(tool, askInput, toolUseContext, assistantMessage, toolUseID));
284625
284740
  return {
284626
- decision: await canUseTool(tool, askInput, toolUseContext, assistantMessage, toolUseID, forceDecision),
284741
+ decision,
284627
284742
  input: askInput
284628
284743
  };
284629
284744
  }
@@ -284784,6 +284899,7 @@ var init_toolHooks = __esm(() => {
284784
284899
  init_permissions2();
284785
284900
  init_toolErrors();
284786
284901
  init_utils5();
284902
+ init_permissionPreDecision();
284787
284903
  });
284788
284904
 
284789
284905
  // src/controller/dispatch/toolExecution.ts
@@ -285026,9 +285142,8 @@ function streamedCheckPermissionsAndCallTool(tool, toolUseID, input, toolUseCont
285026
285142
  return stream4;
285027
285143
  }
285028
285144
  async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContext, canUseTool, assistantMessage, messageId, requestId, mcpServerType, mcpServerBaseUrl, onToolProgress) {
285029
- const parsedInput = safeParseToolInputWithNullCoercion(tool.inputSchema, input);
285030
- if (!parsedInput.success) {
285031
- let errorContent = formatZodValidationError(tool.name, parsedInput.error);
285145
+ const inputValidationFailure = (error41) => {
285146
+ let errorContent = formatZodValidationError(tool.name, error41);
285032
285147
  const schemaHint = buildSchemaNotSentHint(tool, toolUseContext.messages, toolUseContext.options.tools);
285033
285148
  if (schemaHint) {
285034
285149
  logEvent("tengu_deferred_tool_schema_not_sent", {
@@ -285068,11 +285183,15 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
285068
285183
  tool_use_id: toolUseID
285069
285184
  }
285070
285185
  ],
285071
- toolUseResult: `InputValidationError: ${parsedInput.error.message}`,
285186
+ toolUseResult: `InputValidationError: ${error41.message}`,
285072
285187
  sourceToolAssistantUUID: assistantMessage.uuid
285073
285188
  })
285074
285189
  }
285075
285190
  ];
285191
+ };
285192
+ const parsedInput = safeParseToolInputWithNullCoercion(tool.inputSchema, input, tool.unknownKeys);
285193
+ if (!parsedInput.success) {
285194
+ return inputValidationFailure(parsedInput.error);
285076
285195
  }
285077
285196
  const isValidCall = await tool.validateInput?.(parsedInput.data, toolUseContext);
285078
285197
  if (isValidCall?.result === false) {
@@ -285308,6 +285427,16 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
285308
285427
  if (permissionDecision.updatedInput !== undefined) {
285309
285428
  processedInput = permissionDecision.updatedInput;
285310
285429
  }
285430
+ if (tool.unknownKeys === "reject") {
285431
+ const finalInput = safeParseToolInputWithNullCoercion(tool.inputSchema, processedInput, tool.unknownKeys);
285432
+ if (!finalInput.success) {
285433
+ endToolBlockedOnUserSpan("reject", "input-validation");
285434
+ endToolSpan();
285435
+ resultingMessages.push(...inputValidationFailure(finalInput.error));
285436
+ return resultingMessages;
285437
+ }
285438
+ processedInput = finalInput.data;
285439
+ }
285311
285440
  const telemetryToolInput = extractToolInputForTelemetry(processedInput);
285312
285441
  let toolParameters = {};
285313
285442
  if (isToolDetailsLoggingEnabled()) {
@@ -287656,7 +287785,7 @@ function getAnthropicEnvMetadata() {
287656
287785
  function getBuildAgeMinutes() {
287657
287786
  if (false)
287658
287787
  ;
287659
- const buildTime = new Date("2026-08-28T10:03:59.640Z").getTime();
287788
+ const buildTime = new Date("2026-09-03T09:12:13.936Z").getTime();
287660
287789
  if (isNaN(buildTime))
287661
287790
  return;
287662
287791
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -288167,6 +288296,7 @@ function createSubagentContext(parentContext, overrides) {
288167
288296
  dynamicSkillDirTriggers: new Set,
288168
288297
  discoveredSkillNames: new Set,
288169
288298
  toolDecisions: undefined,
288299
+ permissionPreDecisions: undefined,
288170
288300
  contentReplacementState: overrides?.contentReplacementState ?? (parentContext.contentReplacementState ? cloneContentReplacementState(parentContext.contentReplacementState) : undefined),
288171
288301
  abortController,
288172
288302
  getAppState,
@@ -332397,6 +332527,7 @@ class QueryEngine {
332397
332527
  includePartialMessages = false,
332398
332528
  agents = [],
332399
332529
  setSDKStatus,
332530
+ preDecidePermissions,
332400
332531
  onToolInvoke,
332401
332532
  uploadMedia,
332402
332533
  orphanedPermission
@@ -332474,7 +332605,8 @@ class QueryEngine {
332474
332605
  maxOutputTokensLimit,
332475
332606
  contextWindow,
332476
332607
  modelProviders: this.config.modelProviders,
332477
- subagentDisallowedTools: this.config.subagentDisallowedTools
332608
+ subagentDisallowedTools: this.config.subagentDisallowedTools,
332609
+ preDecidePermissions
332478
332610
  },
332479
332611
  getAppState,
332480
332612
  setAppState,
@@ -332572,7 +332704,8 @@ class QueryEngine {
332572
332704
  maxOutputTokensLimit,
332573
332705
  contextWindow,
332574
332706
  modelProviders: this.config.modelProviders,
332575
- subagentDisallowedTools: this.config.subagentDisallowedTools
332707
+ subagentDisallowedTools: this.config.subagentDisallowedTools,
332708
+ preDecidePermissions
332576
332709
  },
332577
332710
  getAppState,
332578
332711
  setAppState,
@@ -333089,6 +333222,7 @@ async function* ask({
333089
333222
  handleElicitation,
333090
333223
  agents = [],
333091
333224
  setSDKStatus,
333225
+ preDecidePermissions,
333092
333226
  onToolInvoke,
333093
333227
  uploadMedia,
333094
333228
  orphanedPermission
@@ -333123,6 +333257,7 @@ async function* ask({
333123
333257
  replayUserMessages,
333124
333258
  includePartialMessages,
333125
333259
  setSDKStatus,
333260
+ preDecidePermissions,
333126
333261
  onToolInvoke,
333127
333262
  uploadMedia,
333128
333263
  abortController,
@@ -334528,11 +334663,12 @@ init_callToolResultAdapter();
334528
334663
  init_toolRuntime();
334529
334664
  import { randomUUID as randomUUID20 } from "node:crypto";
334530
334665
  function toInternalTool(sdkTool) {
334531
- const zodObjectInputSchema = exports_external2.object(sdkTool.inputSchema);
334666
+ const zodObjectInputSchema = sdkTool.unknownKeys === "reject" ? exports_external2.strictObject(sdkTool.inputSchema) : exports_external2.object(sdkTool.inputSchema);
334532
334667
  const internalTool = buildToolRuntime({
334533
334668
  name: sdkTool.name,
334534
334669
  maxResultSizeChars: 1e5,
334535
334670
  inputSchema: zodObjectInputSchema,
334671
+ unknownKeys: sdkTool.unknownKeys,
334536
334672
  isMcp: false,
334537
334673
  shouldDefer: sdkTool.shouldDefer,
334538
334674
  isReadOnly: () => sdkTool.isReadOnly ?? false,
@@ -340705,6 +340841,7 @@ function runSdkQueryRuntime(params) {
340705
340841
  taskBudget: options2.taskBudget,
340706
340842
  subagentDisallowedTools: options2.subagentDisallowedTools,
340707
340843
  canUseTool,
340844
+ preDecidePermissions: options2.preDecidePermissions === true,
340708
340845
  mutableMessages,
340709
340846
  getReadFileCache: () => readFileCache,
340710
340847
  setReadFileCache: (cache3) => {
@@ -342043,4 +342180,4 @@ export {
342043
342180
  watchScheduledTasks
342044
342181
  };
342045
342182
 
342046
- //# debugId=C4D90047AD77BED164756E2164756E21
342183
+ //# debugId=7B58D43EDA533A1B64756E2164756E21
@@ -181,7 +181,8 @@ export type SubagentContextOverrides = {
181
181
  * - abortController: new controller linked to parent (parent abort propagates)
182
182
  * - getAppState: wrapped to set shouldAvoidPermissionPrompts
183
183
  * - All mutation callbacks (setAppState, etc.): no-op
184
- * - Fresh collections: nestedMemoryAttachmentTriggers, toolDecisions
184
+ * - Fresh collections: nestedMemoryAttachmentTriggers, toolDecisions,
185
+ * permissionPreDecisions
185
186
  *
186
187
  * Callers can:
187
188
  * - Override specific fields via the overrides parameter
@@ -130,6 +130,12 @@ export type ToolRuntimeContext = {
130
130
  * nested subagents via agentOptions; the main loop never filters on it.
131
131
  */
132
132
  subagentDisallowedTools?: string[];
133
+ /**
134
+ * 权限决策前置开关(见 Options.preDecidePermissions)。开启后 runTools() 入口
135
+ * 对同批 tool_use 并发预调 canUseTool 并缓存到 permissionPreDecisions;
136
+ * 默认 undefined(关),由 host 显式开启。
137
+ */
138
+ preDecidePermissions?: boolean;
133
139
  };
134
140
  abortController: AbortController;
135
141
  readFileState: FileStateCache;
@@ -184,6 +190,17 @@ export type ToolRuntimeContext = {
184
190
  decision: 'accept' | 'reject';
185
191
  timestamp: number;
186
192
  }>;
193
+ /**
194
+ * 权限预决策缓存(options.preDecidePermissions 开启时由 runTools() 入口填充,
195
+ * 键为 tool_use id)。与 toolDecisions 审计快照不同:本缓存是一次性消费——
196
+ * 执行期 resolveHookPermissionDecision 取出即删,且仅当执行期 input 与缓存
197
+ * input 深比较一致时才采用缓存 promise,否则回退内联询问。预决策拿不到
198
+ * PreToolUse hook 的改写/ask 消息,故 hook 改写 input 后必然 miss 回退。
199
+ */
200
+ permissionPreDecisions?: Map<string, {
201
+ input: Record<string, unknown>;
202
+ promise: Promise<PermissionResult>;
203
+ }>;
187
204
  queryTracking?: QueryChainTracking;
188
205
  requestPrompt?: (sourceName: string, toolInputSummary?: string | null) => (request: PromptRequest) => Promise<PromptResponse>;
189
206
  toolUseId?: string;
@@ -233,6 +250,7 @@ export type ToolRuntime<Input extends AnyObject = AnyObject, Output = unknown, P
233
250
  readonly shouldDefer?: boolean;
234
251
  readonly alwaysLoad?: boolean;
235
252
  readonly strict?: boolean;
253
+ readonly unknownKeys?: 'strip' | 'reject';
236
254
  readonly inputSchema: Input;
237
255
  readonly inputJSONSchema?: ToolInputJSONSchema;
238
256
  outputSchema?: z.ZodType<unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencow-ai/opencow-agent-sdk",
3
- "version": "0.4.23",
3
+ "version": "0.4.24",
4
4
  "description": "Claude Code opened to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",