@cognipeer/agent-sdk 0.10.2 → 0.10.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/index.mjs CHANGED
@@ -503,7 +503,7 @@ function getModelCapabilities(model) {
503
503
  return {
504
504
  provider,
505
505
  structuredOutput: supportsNativeStructuredOutput(provider) ? "native" : "tool_based",
506
- strictToolCalling: requiresStrictToolCalling(provider),
506
+ strictToolCalling: requiresStrictToolCalling(provider) && isOpenAIHostedEndpoint(model._lc),
507
507
  streaming: true
508
508
  };
509
509
  }
@@ -546,6 +546,17 @@ function supportsNativeStructuredOutput(provider) {
546
546
  function requiresStrictToolCalling(provider) {
547
547
  return ["openai"].includes(provider);
548
548
  }
549
+ function isOpenAIHostedEndpoint(lcModel) {
550
+ if (!lcModel) return true;
551
+ const baseURL = lcModel.clientConfig?.baseURL ?? lcModel.configuration?.baseURL ?? lcModel.baseURL;
552
+ if (typeof baseURL !== "string" || baseURL.trim() === "") return true;
553
+ try {
554
+ const host = new URL(baseURL).hostname.toLowerCase();
555
+ return host === "api.openai.com" || host.endsWith(".openai.azure.com") || host.endsWith(".cognitiveservices.azure.com");
556
+ } catch {
557
+ return false;
558
+ }
559
+ }
549
560
 
550
561
  // src/model.ts
551
562
  function isSmartModel(m) {
@@ -2510,13 +2521,19 @@ function resolveCapabilities(provider) {
2510
2521
  switch (provider) {
2511
2522
  case "openai":
2512
2523
  case "azure":
2513
- case "openai-compatible":
2514
2524
  return {
2515
2525
  structuredOutput: "native",
2516
2526
  strictToolCalling: true,
2517
2527
  streaming: true,
2518
2528
  provider
2519
2529
  };
2530
+ case "openai-compatible":
2531
+ return {
2532
+ structuredOutput: "native",
2533
+ strictToolCalling: false,
2534
+ streaming: true,
2535
+ provider
2536
+ };
2520
2537
  case "anthropic":
2521
2538
  return {
2522
2539
  structuredOutput: "tool_based",
@@ -3845,6 +3862,187 @@ Identical to an earlier ${duplicate.toolName} result. Use get_tool_response with
3845
3862
  }
3846
3863
  return notApplied4(output);
3847
3864
  }
3865
+ var identity = (value) => value;
3866
+ function describeLike(schema, source, suffix) {
3867
+ const description = [source.description, suffix].filter(Boolean).join(" ");
3868
+ return description ? schema.describe(description) : schema;
3869
+ }
3870
+ function jsonString(source) {
3871
+ return {
3872
+ schema: describeLike(z.string(), source, "(a JSON value, encoded as a string)"),
3873
+ restore: (value) => {
3874
+ if (typeof value !== "string") return value;
3875
+ try {
3876
+ return JSON.parse(value);
3877
+ } catch {
3878
+ return value;
3879
+ }
3880
+ }
3881
+ };
3882
+ }
3883
+ function unwrapOptional(schema) {
3884
+ const def = schema._def;
3885
+ if (def?.typeName === "ZodOptional") return { inner: def.innerType, optional: true };
3886
+ if (def?.typeName === "ZodDefault") return { inner: def.innerType, optional: true };
3887
+ return { inner: schema, optional: false };
3888
+ }
3889
+ function isZodSchema2(schema) {
3890
+ return Boolean(schema) && typeof schema.safeParse === "function" && Boolean(schema._def);
3891
+ }
3892
+ function toStrictCompatible(schema) {
3893
+ const def = schema?._def;
3894
+ switch (def?.typeName) {
3895
+ case "ZodObject": {
3896
+ const shape = typeof def.shape === "function" ? def.shape() : def.shape;
3897
+ const keys = Object.keys(shape ?? {});
3898
+ const open = def.unknownKeys === "passthrough" || def.catchall && def.catchall._def?.typeName !== "ZodNever";
3899
+ if (keys.length === 0 && open) return jsonString(schema);
3900
+ const nextShape = {};
3901
+ const restores = {};
3902
+ for (const key of keys) {
3903
+ const field = shape[key];
3904
+ const { inner, optional } = unwrapOptional(field);
3905
+ const child = toStrictCompatible(inner);
3906
+ const childSchema = describeLike(child.schema, field.description ? field : inner);
3907
+ nextShape[key] = optional ? childSchema.nullable() : childSchema;
3908
+ restores[key] = { restore: child.restore, optional };
3909
+ }
3910
+ return {
3911
+ schema: describeLike(z.object(nextShape), schema),
3912
+ restore: (value) => {
3913
+ if (!value || typeof value !== "object" || Array.isArray(value)) return value;
3914
+ const out = {};
3915
+ for (const [key, raw] of Object.entries(value)) {
3916
+ const entry = restores[key];
3917
+ if (raw === null && entry?.optional) continue;
3918
+ out[key] = entry ? entry.restore(raw) : raw;
3919
+ }
3920
+ return out;
3921
+ }
3922
+ };
3923
+ }
3924
+ case "ZodOptional":
3925
+ case "ZodDefault": {
3926
+ const child = toStrictCompatible(def.innerType);
3927
+ return {
3928
+ schema: describeLike(child.schema.nullable(), schema),
3929
+ restore: (value) => value === null ? void 0 : child.restore(value)
3930
+ };
3931
+ }
3932
+ case "ZodNullable": {
3933
+ const child = toStrictCompatible(def.innerType);
3934
+ return {
3935
+ schema: describeLike(child.schema.nullable(), schema),
3936
+ restore: (value) => value === null ? null : child.restore(value)
3937
+ };
3938
+ }
3939
+ case "ZodArray": {
3940
+ const child = toStrictCompatible(def.type);
3941
+ return {
3942
+ schema: describeLike(z.array(child.schema), schema),
3943
+ restore: (value) => Array.isArray(value) ? value.map(child.restore) : value
3944
+ };
3945
+ }
3946
+ case "ZodUnion":
3947
+ case "ZodDiscriminatedUnion": {
3948
+ const rawOptions = def.options instanceof Map ? [...def.options.values()] : def.options;
3949
+ const options = rawOptions.map(toStrictCompatible);
3950
+ if (options.length === 1) return options[0];
3951
+ if (options.every((option, index) => option.schema === rawOptions[index])) {
3952
+ return { schema, restore: identity };
3953
+ }
3954
+ return {
3955
+ schema: describeLike(z.union(options.map((option) => option.schema)), schema),
3956
+ restore: (value) => {
3957
+ const candidates = options.map((option) => option.restore(value));
3958
+ const index = candidates.findIndex((candidate, i) => rawOptions[i].safeParse(candidate).success);
3959
+ return candidates[index >= 0 ? index : 0];
3960
+ }
3961
+ };
3962
+ }
3963
+ case "ZodEffects":
3964
+ return toStrictCompatible(def.schema);
3965
+ case "ZodRecord":
3966
+ case "ZodAny":
3967
+ case "ZodUnknown":
3968
+ return jsonString(schema);
3969
+ default:
3970
+ return { schema, restore: identity };
3971
+ }
3972
+ }
3973
+ function topLevelObject(transform) {
3974
+ if (transform.schema._def?.typeName === "ZodObject") return transform;
3975
+ return {
3976
+ schema: z.object({
3977
+ input: transform.schema.describe(
3978
+ transform.schema.description ?? "The tool arguments as a JSON object, encoded as a string"
3979
+ )
3980
+ }),
3981
+ restore: (value) => {
3982
+ const input = value && typeof value === "object" ? value.input : void 0;
3983
+ const restored = transform.restore(input);
3984
+ return restored && typeof restored === "object" ? restored : {};
3985
+ }
3986
+ };
3987
+ }
3988
+ function toStrictToolSchema(schema) {
3989
+ return topLevelObject(toStrictCompatible(schema));
3990
+ }
3991
+ function restoreToolCalls(message, restorers) {
3992
+ if (!message || typeof message !== "object" || restorers.size === 0) return message;
3993
+ const restoreList = (calls) => {
3994
+ if (!Array.isArray(calls) || calls.length === 0) return calls;
3995
+ return calls.map((call) => {
3996
+ const fn = call?.function;
3997
+ const name = call?.name ?? fn?.name;
3998
+ const restore = name ? restorers.get(name) : void 0;
3999
+ if (!restore) return call;
4000
+ let next = call;
4001
+ if (call.args && typeof call.args === "object") next = { ...next, args: restore(call.args) };
4002
+ if (fn && typeof fn.arguments === "string") {
4003
+ try {
4004
+ next = { ...next, function: { ...fn, arguments: JSON.stringify(restore(JSON.parse(fn.arguments))) } };
4005
+ } catch {
4006
+ }
4007
+ }
4008
+ return next;
4009
+ });
4010
+ };
4011
+ const m = message;
4012
+ const hasDirect = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
4013
+ const hasKwargs = Array.isArray(m.additional_kwargs?.tool_calls) && m.additional_kwargs.tool_calls.length > 0;
4014
+ if (!hasDirect && !hasKwargs) return message;
4015
+ return {
4016
+ ...message,
4017
+ ...hasDirect ? { tool_calls: restoreList(m.tool_calls) } : {},
4018
+ ...hasKwargs ? { additional_kwargs: { ...m.additional_kwargs, tool_calls: restoreList(m.additional_kwargs.tool_calls) } } : {}
4019
+ };
4020
+ }
4021
+ var strictViews = /* @__PURE__ */ new WeakMap();
4022
+ function prepareStrictToolMenu(tools) {
4023
+ const restorers = /* @__PURE__ */ new Map();
4024
+ const menu = tools.map((tool) => {
4025
+ const t = tool;
4026
+ if (!t || typeof t.name !== "string" || !isZodSchema2(t.schema)) return tool;
4027
+ const cached = strictViews.get(tool);
4028
+ if (cached && cached.schema === t.schema) {
4029
+ restorers.set(t.name, cached.restore);
4030
+ return cached.view;
4031
+ }
4032
+ try {
4033
+ const transform = toStrictToolSchema(t.schema);
4034
+ const view = Object.create(tool);
4035
+ view.schema = transform.schema;
4036
+ view.__lcTool = void 0;
4037
+ strictViews.set(tool, { schema: t.schema, view, restore: transform.restore });
4038
+ restorers.set(t.name, transform.restore);
4039
+ return view;
4040
+ } catch {
4041
+ return tool;
4042
+ }
4043
+ });
4044
+ return { menu, restorers };
4045
+ }
3848
4046
 
3849
4047
  // src/nodes/agentCore.ts
3850
4048
  function createAgentCoreNode(opts) {
@@ -3865,10 +4063,17 @@ function createAgentCoreNode(opts) {
3865
4063
  };
3866
4064
  let tools = runtime.tools ?? [];
3867
4065
  const shouldUseStrictToolCalling = Boolean(
3868
- runtime.responseFormat && runtime.model?.capabilities?.strictToolCalling
4066
+ runtime.model?.capabilities?.strictToolCalling
3869
4067
  );
4068
+ let strictRestorers = /* @__PURE__ */ new Map();
4069
+ const wireMenu = (menu) => {
4070
+ if (!shouldUseStrictToolCalling) return menu;
4071
+ const prepared = prepareStrictToolMenu(menu);
4072
+ strictRestorers = prepared.restorers;
4073
+ return prepared.menu;
4074
+ };
3870
4075
  const bindToolMenu = (menu) => runtime.model?.bindTools ? runtime.model.bindTools(
3871
- menu,
4076
+ wireMenu(menu),
3872
4077
  shouldUseStrictToolCalling ? { strict: true } : void 0
3873
4078
  ) : runtime.model;
3874
4079
  const menuMutationReachesProvider = typeof runtime.model?.bindTools === "function";
@@ -3879,7 +4084,8 @@ function createAgentCoreNode(opts) {
3879
4084
  const computeTraceToolDefinitions = (menu) => {
3880
4085
  if (!traceSession || !traceSession.resolvedConfig.logData || menu.length === 0) return void 0;
3881
4086
  try {
3882
- return menu.map((tool) => {
4087
+ const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
4088
+ return wire.map((tool) => {
3883
4089
  const def = toToolDefinition(tool, shouldUseStrictToolCalling ? true : void 0);
3884
4090
  return { name: def.name, description: def.description || void 0, parameters: def.parameters };
3885
4091
  });
@@ -4185,6 +4391,9 @@ ${append}`;
4185
4391
  throw err;
4186
4392
  }
4187
4393
  }
4394
+ if (shortCircuited === void 0 && strictRestorers.size > 0) {
4395
+ response = restoreToolCalls(response, strictRestorers);
4396
+ }
4188
4397
  if (!host?.has("postModelCall")) break;
4189
4398
  const postGate = await host.runGate("postModelCall", {
4190
4399
  message: response,
@@ -6146,6 +6355,9 @@ function isSyntheticSummaryMessage(message) {
6146
6355
  }
6147
6356
  return false;
6148
6357
  }
6358
+ function isCompactedToolContent(content) {
6359
+ return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE") || content.startsWith("ARCHIVED_TOOL_RESPONSE") || content.startsWith("STRUCTURED_TOOL_RESPONSE") || content.startsWith("DROPPED_TOOL_RESPONSE"));
6360
+ }
6149
6361
 
6150
6362
  // src/structuredOutput/manager.ts
6151
6363
  var StructuredOutputManager = class {
@@ -8062,6 +8274,10 @@ function collectRecentTurns(messages, lastTurnsToKeep) {
8062
8274
  function renderStructuredSummary(summary) {
8063
8275
  if (!summary) return "";
8064
8276
  const lines = ["Context summary:"];
8277
+ if (summary.user_directives && summary.user_directives.length > 0) {
8278
+ lines.push("User directives (still in force \u2014 follow them):");
8279
+ lines.push(...summary.user_directives.map((directive) => `- ${directive}`));
8280
+ }
8065
8281
  if (summary.stable_facts.length > 0) {
8066
8282
  lines.push("Stable facts:");
8067
8283
  lines.push(...summary.stable_facts.map((fact) => `- ${fact.key}: ${fact.value}`));
@@ -8137,17 +8353,46 @@ function clampToBudget(messages, maxContextTokens) {
8137
8353
  }
8138
8354
  return working;
8139
8355
  }
8356
+ function collectSummaryOnlyBody(body, hasSummary, lastTurnsToKeep) {
8357
+ if (!hasSummary) {
8358
+ return collectRecentTurns(body, Math.max(1, lastTurnsToKeep));
8359
+ }
8360
+ let boundary = -1;
8361
+ for (let index = body.length - 1; index >= 0; index -= 1) {
8362
+ if (isSyntheticSummaryMessage(body[index])) {
8363
+ boundary = index;
8364
+ break;
8365
+ }
8366
+ }
8367
+ let lastUserIndex = -1;
8368
+ for (let index = body.length - 1; index >= 0; index -= 1) {
8369
+ if (body[index].role === "user") {
8370
+ lastUserIndex = index;
8371
+ break;
8372
+ }
8373
+ }
8374
+ const keep = /* @__PURE__ */ new Set();
8375
+ const firstUserIndex = body.findIndex((message) => message.role === "user");
8376
+ if (firstUserIndex >= 0) keep.add(firstUserIndex);
8377
+ const verbatimFrom = Math.min(lastUserIndex >= 0 ? lastUserIndex : body.length, boundary + 1);
8378
+ for (let index = Math.max(0, verbatimFrom); index < body.length; index += 1) {
8379
+ if (!isSyntheticSummaryMessage(body[index])) keep.add(index);
8380
+ }
8381
+ return body.filter((_, index) => keep.has(index));
8382
+ }
8140
8383
  function buildModelMessages(state, config) {
8141
8384
  const rawMessages = state.messages || [];
8142
8385
  if (config.context.policy === "raw") {
8143
8386
  return clampToBudget(rawMessages, config.limits.maxContextTokens);
8144
8387
  }
8145
- const recentMessages = collectRecentTurns(rawMessages, config.context.lastTurnsToKeep);
8146
8388
  const latestSummary = state.summaryRecords?.[state.summaryRecords.length - 1];
8147
8389
  const summaryText = renderStructuredSummary(latestSummary);
8148
8390
  const memoryText = renderMemoryBlock(state.memoryFacts);
8149
- const systemMessage2 = recentMessages[0]?.role === "system" ? recentMessages[0] : void 0;
8150
- const body = systemMessage2 ? recentMessages.slice(1) : recentMessages;
8391
+ const systemMessage2 = rawMessages[0]?.role === "system" ? rawMessages[0] : void 0;
8392
+ const body = config.context.policy === "summary_only" ? collectSummaryOnlyBody(systemMessage2 ? rawMessages.slice(1) : rawMessages, Boolean(summaryText), config.context.lastTurnsToKeep) : (() => {
8393
+ const recentMessages = collectRecentTurns(rawMessages, config.context.lastTurnsToKeep);
8394
+ return recentMessages[0]?.role === "system" ? recentMessages.slice(1) : recentMessages;
8395
+ })();
8151
8396
  const syntheticContextMessages = [];
8152
8397
  if (summaryText) {
8153
8398
  syntheticContextMessages.push({ role: "system", name: "context_summary", content: summaryText });
@@ -8158,7 +8403,7 @@ function buildModelMessages(state, config) {
8158
8403
  const assembled = [
8159
8404
  ...systemMessage2 ? [systemMessage2] : [],
8160
8405
  ...syntheticContextMessages,
8161
- ...config.context.policy === "summary_only" ? body.filter((message) => message.role === "user" || message.role === "assistant").slice(-2) : body
8406
+ ...body
8162
8407
  ];
8163
8408
  return clampToBudget(assembled, config.limits.maxContextTokens);
8164
8409
  }
@@ -8203,6 +8448,7 @@ function extractJsonObject(text) {
8203
8448
  }
8204
8449
  function normalizeStructuredSummary(input, fallbackText) {
8205
8450
  const summary = {
8451
+ user_directives: Array.isArray(input?.user_directives) ? input.user_directives.map((directive) => String(directive ?? "").trim()).filter(Boolean) : [],
8206
8452
  stable_facts: Array.isArray(input?.stable_facts) ? input.stable_facts.filter((fact) => fact && typeof fact === "object").map((fact) => ({
8207
8453
  key: String(fact.key || "unknown"),
8208
8454
  value: String(fact.value || ""),
@@ -8263,7 +8509,7 @@ function extractCanonicalFacts(messages) {
8263
8509
  return [...facts.values()];
8264
8510
  }
8265
8511
  function isSummarizedToolPlaceholder(content) {
8266
- return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE") || content.startsWith("ARCHIVED_TOOL_RESPONSE") || content.startsWith("STRUCTURED_TOOL_RESPONSE") || content.startsWith("DROPPED_TOOL_RESPONSE"));
8512
+ return isCompactedToolContent(content);
8267
8513
  }
8268
8514
  function collectLatestTurnToolCallIds(messages) {
8269
8515
  const ids = /* @__PURE__ */ new Set();
@@ -8322,11 +8568,16 @@ function runIntegrityCheck(previous, current) {
8322
8568
  const previousKeys = new Set((previous?.stable_facts || []).map((fact) => fact.key));
8323
8569
  const currentKeys = new Set(current.stable_facts.map((fact) => fact.key));
8324
8570
  const obsoleteKeys = new Set(current.discarded_obsolete);
8325
- const criticalFactLoss = [...previousKeys].some((key) => !obsoleteKeys.has(key) && !currentKeys.has(key));
8571
+ const currentDirectives = new Set(current.user_directives || []);
8572
+ const lostDirectives = (previous?.user_directives || []).filter((directive) => !currentDirectives.has(directive) && !obsoleteKeys.has(directive));
8573
+ const criticalFactLoss = [...previousKeys].some((key) => !obsoleteKeys.has(key) && !currentKeys.has(key)) || lostDirectives.length > 0;
8326
8574
  const obsoleteFactRevived = current.stable_facts.some((fact) => obsoleteKeys.has(fact.key));
8327
8575
  if (criticalFactLoss) {
8328
8576
  notes.push("Missing previously retained facts; merged forward during integrity repair.");
8329
8577
  }
8578
+ if (lostDirectives.length > 0) {
8579
+ notes.push(`Dropped ${lostDirectives.length} user directive(s); merged forward during integrity repair.`);
8580
+ }
8330
8581
  if (obsoleteFactRevived) {
8331
8582
  notes.push("Obsolete facts reappeared; removed during integrity repair.");
8332
8583
  }
@@ -8349,7 +8600,13 @@ function repairStructuredSummary(previous, current, integrity) {
8349
8600
  }
8350
8601
  }
8351
8602
  const filteredFacts = integrity.obsoleteFactRevived ? nextFacts.filter((fact) => !current.discarded_obsolete.includes(fact.key)) : nextFacts;
8352
- return { ...current, stable_facts: filteredFacts };
8603
+ const directives = [...current.user_directives || []];
8604
+ for (const directive of previous.user_directives || []) {
8605
+ if (!directives.includes(directive) && !current.discarded_obsolete.includes(directive)) {
8606
+ directives.push(directive);
8607
+ }
8608
+ }
8609
+ return { ...current, user_directives: directives, stable_facts: filteredFacts };
8353
8610
  }
8354
8611
  function createContextSummarizeNode(opts) {
8355
8612
  return async (state) => {
@@ -8423,6 +8680,7 @@ function createContextSummarizeNode(opts) {
8423
8680
 
8424
8681
  Return exactly one JSON object with this schema:
8425
8682
  {
8683
+ "user_directives": [string],
8426
8684
  "stable_facts": [{ "key": string, "value": string, "confidence": number }],
8427
8685
  "active_goals": [string],
8428
8686
  "open_questions": [string],
@@ -8431,6 +8689,7 @@ Return exactly one JSON object with this schema:
8431
8689
  }
8432
8690
 
8433
8691
  Rules:
8692
+ - user_directives: standing instructions the user gave about HOW to work or answer for the rest of the conversation (language, format, tone, scope, things to always or never do) that still apply. NOT the tasks or questions themselves \u2014 "read the logs" is a task (an active goal), "always answer in Turkish" is a directive. Copy each directive close to verbatim; never merge, soften or drop one. Carry forward every directive from the previous structured summary unless the user explicitly revoked it \u2014 then put its exact text in discarded_obsolete.
8434
8693
  - Keep stable_facts only for facts that future turns must remember.
8435
8694
  - Put invalidated or superseded fact keys in discarded_obsolete.
8436
8695
  - Preserve active_goals still relevant to the user.
@@ -8498,6 +8757,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
8498
8757
  durationMs = Date.now() - startTime;
8499
8758
  structuredSummary = normalizeStructuredSummary(void 0, previousSummary || conversationText.slice(0, 800));
8500
8759
  structuredSummary = mergeStableFacts(structuredSummary, canonicalFacts);
8760
+ structuredSummary.user_directives = [...previousStructuredSummary?.user_directives || []];
8501
8761
  integrity = { passed: true, criticalFactLoss: false, obsoleteFactRevived: false, notes: ["Fallback summary generated locally."] };
8502
8762
  summaryText = renderStructuredSummary(structuredSummary);
8503
8763
  const errorEvent = {
@@ -8732,6 +8992,21 @@ var todoUpdateItemSchema = z.object({
8732
8992
  status: todoStatusSchema.optional(),
8733
8993
  evidence: z.string().max(300).optional()
8734
8994
  });
8995
+ var todoItemWireSchema = z.object({
8996
+ id: z.number().int().min(1).describe("Sequential id starting from 1 (write) or an existing id (update)"),
8997
+ step: z.string().min(1).optional(),
8998
+ title: z.string().min(1).optional(),
8999
+ description: z.string().min(1).optional(),
9000
+ owner: z.string().min(1).optional(),
9001
+ exitCriteria: z.string().min(1).optional(),
9002
+ status: todoStatusSchema.optional().describe("Required for every item on write"),
9003
+ evidence: z.string().max(300).optional()
9004
+ });
9005
+ function describeTodoIssue(issue) {
9006
+ if (!issue) return void 0;
9007
+ const path2 = issue.path.length > 0 ? `todoList[${issue.path[0]}]${issue.path.slice(1).map((p) => `.${String(p)}`).join("")}` : "todoList";
9008
+ return `${path2}: ${issue.message}`;
9009
+ }
8735
9010
  function normalizeTodoItem(item, existing) {
8736
9011
  const id = item.id ?? existing?.id;
8737
9012
  const step = item.step || item.title || item.description || existing?.step || existing?.title || existing?.description || `Step ${id}`;
@@ -8848,7 +9123,7 @@ function createPlanTool(stateRef, toolName, description) {
8848
9123
  schema: z.object({
8849
9124
  operation: z.enum(["write", "read", "update"]),
8850
9125
  expectedVersion: z.number().int().min(0).optional(),
8851
- todoList: z.array(z.union([todoWriteItemSchema, todoUpdateItemSchema])).optional()
9126
+ todoList: z.array(todoItemWireSchema).optional()
8852
9127
  }),
8853
9128
  func: async ({ operation, expectedVersion, todoList }) => {
8854
9129
  const toolStateRef = manageTodo._stateRef;
@@ -8914,7 +9189,10 @@ function createPlanTool(stateRef, toolName, description) {
8914
9189
  return {
8915
9190
  status: "error",
8916
9191
  operation,
8917
- error: parsed.error.issues[0]?.message || "Invalid todoList for write.",
9192
+ // The wire schema has `status` optional (one shape for write and
9193
+ // update), so a missing one is caught here — named, so the model
9194
+ // can fix the call.
9195
+ error: describeTodoIssue(parsed.error.issues[0]) || "Invalid todoList for write.",
8918
9196
  version: currentVersion,
8919
9197
  adherenceScore: stateRef.adherenceScore || 0
8920
9198
  };
@@ -8937,7 +9215,7 @@ function createPlanTool(stateRef, toolName, description) {
8937
9215
  return {
8938
9216
  status: "error",
8939
9217
  operation,
8940
- error: parsed.error.issues[0]?.message || "Invalid todoList for update.",
9218
+ error: describeTodoIssue(parsed.error.issues[0]) || "Invalid todoList for update.",
8941
9219
  version: currentVersion,
8942
9220
  adherenceScore: stateRef.adherenceScore || 0
8943
9221
  };
@@ -16466,6 +16744,6 @@ function createProvider(config) {
16466
16744
  }
16467
16745
  }
16468
16746
 
16469
- export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText2 as extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isSmartModel, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, loadSkillsFromDisk, mapConsoleHookVerdict, mapTextParts, mcp, mediaPolicy, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, promptInjectionGuard, rateLimit, readMemoryFacts, redactText, regexGuardrail, regexRule, replaceTextContent, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, textFromContent, tokenize, toolPolicy, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
16747
+ export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText2 as extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, loadSkillsFromDisk, mapConsoleHookVerdict, mapTextParts, mcp, mediaPolicy, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, redactText, regexGuardrail, regexRule, replaceTextContent, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, textFromContent, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
16470
16748
  //# sourceMappingURL=index.mjs.map
16471
16749
  //# sourceMappingURL=index.mjs.map