@cognipeer/agent-sdk 0.8.6 → 0.8.8

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
@@ -410,7 +410,8 @@ function createTool({
410
410
  approvalDefaults,
411
411
  maxExecutionsPerRun,
412
412
  cache,
413
- retry
413
+ retry,
414
+ retention
414
415
  }) {
415
416
  const execute = async (input) => func(input);
416
417
  const toolRecord = {
@@ -441,6 +442,9 @@ function createTool({
441
442
  if (retry !== void 0) {
442
443
  toolRecord.retry = retry;
443
444
  }
445
+ if (retention !== void 0) {
446
+ toolRecord.retention = retention;
447
+ }
444
448
  toolRecord.__source = toolRecord.__source || "smart";
445
449
  toolRecord.__impl = func;
446
450
  return toolRecord;
@@ -1962,6 +1966,270 @@ function estimatePayloadBytes(value) {
1962
1966
  }
1963
1967
  }
1964
1968
 
1969
+ // src/smart/toolResponses.ts
1970
+ init_utilTokens();
1971
+
1972
+ // src/utils/content.ts
1973
+ function contentToString(content) {
1974
+ try {
1975
+ if (content == null) return "";
1976
+ if (typeof content === "string") return content;
1977
+ if (Array.isArray(content)) {
1978
+ return content.map((p) => {
1979
+ if (!p || typeof p !== "object") return String(p);
1980
+ if (p.type === "text") return String(p.text ?? "");
1981
+ if (p.type === "image_url") {
1982
+ const img = p.image_url;
1983
+ const url = typeof img === "string" ? img : img?.url;
1984
+ const detail = typeof img === "string" ? void 0 : img?.detail;
1985
+ return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
1986
+ }
1987
+ return JSON.stringify(p);
1988
+ }).join("\n");
1989
+ }
1990
+ return JSON.stringify(content);
1991
+ } catch {
1992
+ return String(content);
1993
+ }
1994
+ }
1995
+ function mergeContentsToString(contents) {
1996
+ return contents.map((c) => contentToString(c)).join("\n");
1997
+ }
1998
+ function safeStringify(value, pretty = false) {
1999
+ if (value == null) return "";
2000
+ if (typeof value === "string") return value;
2001
+ try {
2002
+ return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2003
+ } catch {
2004
+ return String(value);
2005
+ }
2006
+ }
2007
+ function extractMessageText2(message) {
2008
+ if (!message) return "";
2009
+ const content = message.content;
2010
+ if (typeof content === "string") return content;
2011
+ if (Array.isArray(content)) {
2012
+ return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2013
+ }
2014
+ return "";
2015
+ }
2016
+
2017
+ // src/smart/toolResponses.ts
2018
+ var CONTROL_PLANE_TOOL_NAMES = [
2019
+ "response",
2020
+ "manage_todo_list",
2021
+ "get_tool_response",
2022
+ "ask_user_question",
2023
+ "open_skill",
2024
+ "bind_skill_tools",
2025
+ "search_skills"
2026
+ ];
2027
+ var DELEGATION_TOOL_NAMES = [
2028
+ "delegate_to",
2029
+ "spawn_subagent",
2030
+ "spawn_subagents_parallel"
2031
+ ];
2032
+ var INPUT_PROTECTED_TOOL_NAMES = /* @__PURE__ */ new Set([
2033
+ ...CONTROL_PLANE_TOOL_NAMES,
2034
+ ...DELEGATION_TOOL_NAMES
2035
+ ]);
2036
+ var CONTROL_PLANE_OUTPUT_DEFAULTS = new Set(CONTROL_PLANE_TOOL_NAMES);
2037
+ var DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS = 2e3;
2038
+ var DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS = 200;
2039
+ var TOOL_INPUT_DIGEST_KEY = "__digest";
2040
+ function summarizeObject(value) {
2041
+ if (value == null) return "null";
2042
+ if (typeof value === "string") {
2043
+ return value.length > 240 ? `${value.slice(0, 240)}...` : value;
2044
+ }
2045
+ if (Array.isArray(value)) {
2046
+ const preview = value.slice(0, 3).map((entry) => safeStringify(entry).slice(0, 120)).join(" | ");
2047
+ return `array(length=${value.length}) ${preview}`.trim();
2048
+ }
2049
+ if (typeof value === "object") {
2050
+ const keys = Object.keys(value);
2051
+ const preview = keys.slice(0, 6).map((key) => `${key}=${safeStringify(value[key]).slice(0, 80)}`).join("; ");
2052
+ return `object(keys=${keys.length}) ${preview}`.trim();
2053
+ }
2054
+ return safeStringify(value);
2055
+ }
2056
+ function classifyToolResponse(toolName, output, config) {
2057
+ const criticalTools = new Set(config.toolResponses.criticalTools);
2058
+ if (criticalTools.has(toolName)) return "critical";
2059
+ const serialized = safeStringify(output);
2060
+ const tokenCount = countApproxTokens(serialized);
2061
+ if (tokenCount >= config.toolResponses.maxToolResponseTokens || serialized.length >= config.toolResponses.maxToolResponseChars) {
2062
+ return "verbose";
2063
+ }
2064
+ return "informative";
2065
+ }
2066
+ function applyToolResponseHardCap(toolName, output, executionId, config) {
2067
+ const serialized = safeStringify(output);
2068
+ const tokenCount = countApproxTokens(serialized);
2069
+ const classification = classifyToolResponse(toolName, output, config);
2070
+ if (classification !== "verbose") {
2071
+ return { classification, content: serialized, rawOutput: output, tokenCount, truncated: false };
2072
+ }
2073
+ const cap = config.toolResponses.maxToolResponseChars;
2074
+ const head = serialized.slice(0, cap);
2075
+ const note = `
2076
+ ... [TRUNCATED ${serialized.length - cap} chars by hard cap. Use get_tool_response with executionId="${executionId}" to fetch the full payload.]`;
2077
+ return {
2078
+ classification,
2079
+ content: head + note,
2080
+ rawOutput: output,
2081
+ tokenCount,
2082
+ truncated: true
2083
+ };
2084
+ }
2085
+ function collectToolRetentionDeclarations(tools) {
2086
+ const declarations = /* @__PURE__ */ new Map();
2087
+ if (!Array.isArray(tools)) return declarations;
2088
+ for (const tool of tools) {
2089
+ const spec = tool?.retention;
2090
+ const name = typeof tool?.name === "string" ? tool.name : "";
2091
+ if (!name || !spec || typeof spec !== "object") continue;
2092
+ declarations.set(name, spec);
2093
+ }
2094
+ return declarations;
2095
+ }
2096
+ function resolveSummarizationRetention(toolName, config, declarations) {
2097
+ const criticalTools = new Set(config.toolResponses.criticalTools);
2098
+ if (criticalTools.has(toolName)) return "keep_full";
2099
+ const twoAxis = config.toolResponses.retentionByTool?.[toolName]?.output;
2100
+ if (twoAxis) return twoAxis;
2101
+ const legacy = config.toolResponses.toolResponseRetentionByTool[toolName];
2102
+ if (legacy) return legacy;
2103
+ const declared = declarations?.get(toolName)?.output;
2104
+ if (declared) return declared;
2105
+ if (CONTROL_PLANE_OUTPUT_DEFAULTS.has(toolName)) return "keep_full";
2106
+ return config.toolResponses.defaultPolicy;
2107
+ }
2108
+ function resolveInputRetention(toolName, config, declarations) {
2109
+ if (INPUT_PROTECTED_TOOL_NAMES.has(toolName)) return "keep";
2110
+ const criticalTools = new Set(config.toolResponses.criticalTools);
2111
+ if (criticalTools.has(toolName)) return "keep";
2112
+ const twoAxis = config.toolResponses.retentionByTool?.[toolName]?.input;
2113
+ if (twoAxis) return twoAxis;
2114
+ const declared = declarations?.get(toolName)?.input;
2115
+ if (declared) return declared;
2116
+ return config.toolResponses.defaultInputPolicy;
2117
+ }
2118
+ function shortSha256(value) {
2119
+ return createHash("sha256").update(value, "utf8").digest("hex").slice(0, 16);
2120
+ }
2121
+ function isDigestMarker(value) {
2122
+ return Boolean(
2123
+ value && typeof value === "object" && !Array.isArray(value) && TOOL_INPUT_DIGEST_KEY in value
2124
+ );
2125
+ }
2126
+ function digestToolInputValue(value, options) {
2127
+ const maxFieldChars = options?.maxFieldChars ?? DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS;
2128
+ const headChars = options?.headChars ?? DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS;
2129
+ const executionId = options?.executionId;
2130
+ const digestedPaths = [];
2131
+ let reclaimedChars = 0;
2132
+ const walk = (node, path2) => {
2133
+ if (typeof node === "string") {
2134
+ if (node.length <= maxFieldChars) return node;
2135
+ digestedPaths.push(path2 || "(root)");
2136
+ const marker = {
2137
+ chars: node.length,
2138
+ sha256: shortSha256(node),
2139
+ head: node.slice(0, headChars)
2140
+ };
2141
+ if (executionId) {
2142
+ marker.recover = `get_tool_response executionId="${executionId}" part="input"`;
2143
+ }
2144
+ const replacement = { [TOOL_INPUT_DIGEST_KEY]: marker };
2145
+ reclaimedChars += node.length - safeStringify(replacement).length;
2146
+ return replacement;
2147
+ }
2148
+ if (Array.isArray(node)) {
2149
+ let changed = false;
2150
+ const next = node.map((entry, index) => {
2151
+ const walked = walk(entry, path2 ? `${path2}[${index}]` : `[${index}]`);
2152
+ if (walked !== entry) changed = true;
2153
+ return walked;
2154
+ });
2155
+ return changed ? next : node;
2156
+ }
2157
+ if (node && typeof node === "object") {
2158
+ if (isDigestMarker(node)) return node;
2159
+ let changed = false;
2160
+ const next = {};
2161
+ for (const [key, entry] of Object.entries(node)) {
2162
+ const walked = walk(entry, path2 ? `${path2}.${key}` : key);
2163
+ if (walked !== entry) changed = true;
2164
+ next[key] = walked;
2165
+ }
2166
+ return changed ? next : node;
2167
+ }
2168
+ return node;
2169
+ };
2170
+ const nextValue = walk(value, "");
2171
+ return { value: nextValue, digestedPaths, reclaimedChars: Math.max(0, reclaimedChars) };
2172
+ }
2173
+ function digestToolInputArguments(argumentsJson, options) {
2174
+ const unchanged = { arguments: argumentsJson, digestedPaths: [], reclaimedChars: 0 };
2175
+ if (typeof argumentsJson !== "string" || argumentsJson.length === 0) return unchanged;
2176
+ let parsed;
2177
+ try {
2178
+ parsed = JSON.parse(argumentsJson);
2179
+ } catch {
2180
+ return unchanged;
2181
+ }
2182
+ const digested = digestToolInputValue(parsed, options);
2183
+ if (digested.digestedPaths.length === 0) return unchanged;
2184
+ const serialized = safeStringify(digested.value);
2185
+ if (serialized.length >= argumentsJson.length) return unchanged;
2186
+ return {
2187
+ arguments: serialized,
2188
+ digestedPaths: digested.digestedPaths,
2189
+ reclaimedChars: argumentsJson.length - serialized.length
2190
+ };
2191
+ }
2192
+ function renderRetainedToolMessage(args) {
2193
+ const { policy, rawOutput, toolName, toolCallId, executionId, prebuiltSummary } = args;
2194
+ if (policy === "keep_full") {
2195
+ return typeof rawOutput === "string" ? rawOutput : safeStringify(rawOutput);
2196
+ }
2197
+ const summary = prebuiltSummary || summarizeObject(rawOutput);
2198
+ const refs = [
2199
+ `toolName=${toolName}`,
2200
+ toolCallId ? `toolCallId=${toolCallId}` : null,
2201
+ executionId ? `executionId=${executionId}` : null
2202
+ ].filter(Boolean).join("; ");
2203
+ const refId = executionId || toolCallId || "";
2204
+ if (policy === "keep_structured") {
2205
+ return `STRUCTURED_TOOL_RESPONSE [${refs}]
2206
+ Preview: ${summary}
2207
+ Use get_tool_response with executionId "${refId}" to fetch the full payload when a specific field is needed.`;
2208
+ }
2209
+ if (policy === "summarize_archive") {
2210
+ return `ARCHIVED_TOOL_RESPONSE [${refs}]
2211
+ Summary: ${summary}
2212
+ Use get_tool_response with executionId "${refId}" to fetch the full payload.`;
2213
+ }
2214
+ return `DROPPED_TOOL_RESPONSE [${refs}]
2215
+ Use get_tool_response with executionId "${refId}" only if you must recover the original payload.`;
2216
+ }
2217
+ function validateToolArgs(tool, args) {
2218
+ const schema = tool.schema;
2219
+ if (!schema || typeof schema.parse !== "function") {
2220
+ return { ok: true, value: args };
2221
+ }
2222
+ try {
2223
+ return { ok: true, value: schema.parse(args) };
2224
+ } catch (error) {
2225
+ if (error instanceof ZodError) {
2226
+ const message = error.issues.map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
2227
+ return { ok: false, message };
2228
+ }
2229
+ return { ok: false, message: error instanceof Error ? error.message : String(error) };
2230
+ }
2231
+ }
2232
+
1965
2233
  // src/smart/runtimeConfig.ts
1966
2234
  var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
1967
2235
  var BASE_DEFAULTS = {
@@ -2012,6 +2280,11 @@ var BASE_DEFAULTS = {
2012
2280
  maxToolResponseTokens: 8e3,
2013
2281
  defaultPolicy: "summarize_archive",
2014
2282
  toolResponseRetentionByTool: {},
2283
+ // Argument digesting is opt-in: the default never touches a tool's request.
2284
+ defaultInputPolicy: "keep",
2285
+ retentionByTool: {},
2286
+ maxToolInputFieldChars: DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS,
2287
+ maxToolInputDigestHeadChars: DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS,
2015
2288
  criticalTools: [...DEFAULT_CRITICAL_TOOLS],
2016
2289
  schemaValidation: "strict"
2017
2290
  },
@@ -2066,7 +2339,8 @@ function buildProfile(overrides) {
2066
2339
  ...BASE_DEFAULTS.toolResponses,
2067
2340
  ...overrides.toolResponses,
2068
2341
  criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2069
- toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2342
+ toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {},
2343
+ retentionByTool: overrides.toolResponses?.retentionByTool ?? {}
2070
2344
  },
2071
2345
  contextPilot: mergeContextPilot(BASE_DEFAULTS.contextPilot, overrides.contextPilot)
2072
2346
  };
@@ -2220,6 +2494,14 @@ function normalizeSmartAgentOptions(opts) {
2220
2494
  ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2221
2495
  ...opts.toolResponses?.toolResponseRetentionByTool || {}
2222
2496
  },
2497
+ // Two-axis map merges the same way, so a caller can layer a small override
2498
+ // on top of a profile's table instead of restating it.
2499
+ retentionByTool: {
2500
+ ...preset.toolResponses.retentionByTool,
2501
+ ...customProfile.toolResponses?.retentionByTool || {},
2502
+ ...opts.toolResponses?.retentionByTool || {}
2503
+ },
2504
+ defaultInputPolicy: opts.toolResponses?.defaultInputPolicy ?? customProfile.toolResponses?.defaultInputPolicy ?? preset.toolResponses.defaultInputPolicy,
2223
2505
  criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2224
2506
  },
2225
2507
  contextPilot: mergeContextPilot(mergeContextPilot(preset.contextPilot, customProfile.contextPilot), opts.contextPilot)
@@ -2404,53 +2686,6 @@ function detectVolatileContent(text, limit = 20) {
2404
2686
 
2405
2687
  // src/smart/contextPilot/jsonCrusher.ts
2406
2688
  init_utilTokens();
2407
-
2408
- // src/utils/content.ts
2409
- function contentToString(content) {
2410
- try {
2411
- if (content == null) return "";
2412
- if (typeof content === "string") return content;
2413
- if (Array.isArray(content)) {
2414
- return content.map((p) => {
2415
- if (!p || typeof p !== "object") return String(p);
2416
- if (p.type === "text") return String(p.text ?? "");
2417
- if (p.type === "image_url") {
2418
- const img = p.image_url;
2419
- const url = typeof img === "string" ? img : img?.url;
2420
- const detail = typeof img === "string" ? void 0 : img?.detail;
2421
- return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2422
- }
2423
- return JSON.stringify(p);
2424
- }).join("\n");
2425
- }
2426
- return JSON.stringify(content);
2427
- } catch {
2428
- return String(content);
2429
- }
2430
- }
2431
- function mergeContentsToString(contents) {
2432
- return contents.map((c) => contentToString(c)).join("\n");
2433
- }
2434
- function safeStringify(value, pretty = false) {
2435
- if (value == null) return "";
2436
- if (typeof value === "string") return value;
2437
- try {
2438
- return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2439
- } catch {
2440
- return String(value);
2441
- }
2442
- }
2443
- function extractMessageText2(message) {
2444
- if (!message) return "";
2445
- const content = message.content;
2446
- if (typeof content === "string") return content;
2447
- if (Array.isArray(content)) {
2448
- return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2449
- }
2450
- return "";
2451
- }
2452
-
2453
- // src/smart/contextPilot/jsonCrusher.ts
2454
2689
  var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
2455
2690
  function findCompressibleArray(output, minItems) {
2456
2691
  if (Array.isArray(output)) {
@@ -3002,100 +3237,6 @@ function extractToolItems(output) {
3002
3237
  });
3003
3238
  }
3004
3239
 
3005
- // src/smart/toolResponses.ts
3006
- init_utilTokens();
3007
- function summarizeObject(value) {
3008
- if (value == null) return "null";
3009
- if (typeof value === "string") {
3010
- return value.length > 240 ? `${value.slice(0, 240)}...` : value;
3011
- }
3012
- if (Array.isArray(value)) {
3013
- const preview = value.slice(0, 3).map((entry) => safeStringify(entry).slice(0, 120)).join(" | ");
3014
- return `array(length=${value.length}) ${preview}`.trim();
3015
- }
3016
- if (typeof value === "object") {
3017
- const keys = Object.keys(value);
3018
- const preview = keys.slice(0, 6).map((key) => `${key}=${safeStringify(value[key]).slice(0, 80)}`).join("; ");
3019
- return `object(keys=${keys.length}) ${preview}`.trim();
3020
- }
3021
- return safeStringify(value);
3022
- }
3023
- function classifyToolResponse(toolName, output, config) {
3024
- const criticalTools = new Set(config.toolResponses.criticalTools);
3025
- if (criticalTools.has(toolName)) return "critical";
3026
- const serialized = safeStringify(output);
3027
- const tokenCount = countApproxTokens(serialized);
3028
- if (tokenCount >= config.toolResponses.maxToolResponseTokens || serialized.length >= config.toolResponses.maxToolResponseChars) {
3029
- return "verbose";
3030
- }
3031
- return "informative";
3032
- }
3033
- function applyToolResponseHardCap(toolName, output, executionId, config) {
3034
- const serialized = safeStringify(output);
3035
- const tokenCount = countApproxTokens(serialized);
3036
- const classification = classifyToolResponse(toolName, output, config);
3037
- if (classification !== "verbose") {
3038
- return { classification, content: serialized, rawOutput: output, tokenCount, truncated: false };
3039
- }
3040
- const cap = config.toolResponses.maxToolResponseChars;
3041
- const head = serialized.slice(0, cap);
3042
- const note = `
3043
- ... [TRUNCATED ${serialized.length - cap} chars by hard cap. Use get_tool_response with executionId="${executionId}" to fetch the full payload.]`;
3044
- return {
3045
- classification,
3046
- content: head + note,
3047
- rawOutput: output,
3048
- tokenCount,
3049
- truncated: true
3050
- };
3051
- }
3052
- function resolveSummarizationRetention(toolName, config) {
3053
- const criticalTools = new Set(config.toolResponses.criticalTools);
3054
- if (criticalTools.has(toolName)) return "keep_full";
3055
- const byTool = config.toolResponses.toolResponseRetentionByTool[toolName];
3056
- return byTool || config.toolResponses.defaultPolicy;
3057
- }
3058
- function renderRetainedToolMessage(args) {
3059
- const { policy, rawOutput, toolName, toolCallId, executionId, prebuiltSummary } = args;
3060
- if (policy === "keep_full") {
3061
- return typeof rawOutput === "string" ? rawOutput : safeStringify(rawOutput);
3062
- }
3063
- const summary = prebuiltSummary || summarizeObject(rawOutput);
3064
- const refs = [
3065
- `toolName=${toolName}`,
3066
- toolCallId ? `toolCallId=${toolCallId}` : null,
3067
- executionId ? `executionId=${executionId}` : null
3068
- ].filter(Boolean).join("; ");
3069
- const refId = executionId || toolCallId || "";
3070
- if (policy === "keep_structured") {
3071
- return `STRUCTURED_TOOL_RESPONSE [${refs}]
3072
- Preview: ${summary}
3073
- Use get_tool_response with executionId "${refId}" to fetch the full payload when a specific field is needed.`;
3074
- }
3075
- if (policy === "summarize_archive") {
3076
- return `ARCHIVED_TOOL_RESPONSE [${refs}]
3077
- Summary: ${summary}
3078
- Use get_tool_response with executionId "${refId}" to fetch the full payload.`;
3079
- }
3080
- return `DROPPED_TOOL_RESPONSE [${refs}]
3081
- Use get_tool_response with executionId "${refId}" only if you must recover the original payload.`;
3082
- }
3083
- function validateToolArgs(tool, args) {
3084
- const schema = tool.schema;
3085
- if (!schema || typeof schema.parse !== "function") {
3086
- return { ok: true, value: args };
3087
- }
3088
- try {
3089
- return { ok: true, value: schema.parse(args) };
3090
- } catch (error) {
3091
- if (error instanceof ZodError) {
3092
- const message = error.issues.map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
3093
- return { ok: false, message };
3094
- }
3095
- return { ok: false, message: error instanceof Error ? error.message : String(error) };
3096
- }
3097
- }
3098
-
3099
3240
  // src/utils/pendingToolCalls.ts
3100
3241
  function selectPendingToolCalls(messages) {
3101
3242
  if (!Array.isArray(messages) || messages.length === 0) return [];
@@ -5352,7 +5493,10 @@ function createAgent(opts) {
5352
5493
  }
5353
5494
  }
5354
5495
  }
5355
- if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
5496
+ const structuredFinalizeBlocked = Boolean(
5497
+ pausedStage || state.ctx?.__awaitingApproval || state.ctx?.__awaitingUserQuestion || state.ctx?.__cancelled || state.ctx?.__needsSummarization || state.ctx?.__limitBreached || state.ctx?.__guardrailBlocked
5498
+ );
5499
+ if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
5356
5500
  const lastForParse = state.messages[state.messages.length - 1];
5357
5501
  if (lastForParse?.role === "assistant") {
5358
5502
  const assistantText = extractMessageText2(lastForParse);
@@ -5369,10 +5513,11 @@ function createAgent(opts) {
5369
5513
  }
5370
5514
  }
5371
5515
  }
5372
- if (soManager && soManager.strategy.kind === "tool_based" && !state.ctx?.__finalizedDueToStructuredOutput) {
5516
+ if (soManager && soManager.strategy.kind === "tool_based" && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
5373
5517
  const maxPostLoopRetries = soManager.maxRetries;
5374
5518
  for (let postRetry = 0; postRetry < maxPostLoopRetries; postRetry++) {
5375
5519
  if (state.ctx?.__finalizedDueToStructuredOutput) break;
5520
+ if (state.ctx?.__awaitingApproval || state.ctx?.__awaitingUserQuestion || state.ctx?.__cancelled || state.ctx?.__limitBreached) break;
5376
5521
  const last = state.messages[state.messages.length - 1];
5377
5522
  const lastHasToolCalls = Array.isArray(last?.tool_calls) && last.tool_calls.length > 0;
5378
5523
  if (!lastHasToolCalls) {
@@ -5769,7 +5914,7 @@ function collectRecentTurns(messages, lastTurnsToKeep) {
5769
5914
  if (turnCount >= lastTurnsToKeep) break;
5770
5915
  }
5771
5916
  }
5772
- if (countAssistantTurns && collected.length > 0 && collected[0].role !== "user") {
5917
+ if (collected.length > 0) {
5773
5918
  const firstUserMsg = body.find((m) => m.role === "user");
5774
5919
  if (firstUserMsg && !collected.includes(firstUserMsg)) {
5775
5920
  collected.unshift(firstUserMsg);
@@ -5801,12 +5946,18 @@ function renderMemoryBlock(facts) {
5801
5946
  ...facts.map((fact) => `- ${fact.key}: ${fact.value}`)
5802
5947
  ].join("\n");
5803
5948
  }
5949
+ function isClampProtected(message, index, firstUserIndex) {
5950
+ if (message.role === "system") return true;
5951
+ if (index === firstUserIndex) return true;
5952
+ return false;
5953
+ }
5804
5954
  function clampToBudget(messages, maxContextTokens) {
5805
5955
  let working = [...messages];
5806
5956
  while (working.length > 2) {
5807
5957
  const tokenCount = countApproxTokens(working.map(extractMessageText2).join("\n"));
5808
5958
  if (tokenCount <= maxContextTokens) return working;
5809
- const firstNonSystem = working.findIndex((message, index) => !(index === 0 && message.role === "system"));
5959
+ const firstUserIndex = working.findIndex((message) => message.role === "user");
5960
+ const firstNonSystem = working.findIndex((message, index) => !isClampProtected(message, index, firstUserIndex));
5810
5961
  if (firstNonSystem < 0) break;
5811
5962
  const target = working[firstNonSystem];
5812
5963
  if (target.role === "assistant" && Array.isArray(target.tool_calls) && target.tool_calls.length > 0) {
@@ -6245,9 +6396,42 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
6245
6396
  break;
6246
6397
  }
6247
6398
  }
6399
+ const retentionDeclarations = collectToolRetentionDeclarations(state.agent?.tools);
6400
+ const digestableToolCallIds = /* @__PURE__ */ new Set();
6401
+ for (const m of messages) {
6402
+ if (m.role !== "tool" || isSyntheticSummaryMessage(m)) continue;
6403
+ const toolCallId = m.tool_call_id;
6404
+ if (!toolCallId || !toolCallIdToAssistantIdx.has(toolCallId)) continue;
6405
+ if (protectedToolCallIds.has(toolCallId)) continue;
6406
+ const toolName = m.name || "";
6407
+ if (resolveInputRetention(toolName, resolved, retentionDeclarations) !== "digest") continue;
6408
+ digestableToolCallIds.add(toolCallId);
6409
+ }
6248
6410
  const archivedExecutions = [...state.toolHistoryArchived || []];
6249
6411
  const archivedIds = new Set(archivedExecutions.map((entry) => entry?.executionId).filter(Boolean));
6250
6412
  const newMessages = messages.map((m) => {
6413
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
6414
+ if (m.reasoning?.blocks?.length) return m;
6415
+ let changed = false;
6416
+ const nextToolCalls = m.tool_calls.map((tc) => {
6417
+ const args = tc?.function?.arguments;
6418
+ if (!tc?.id || !digestableToolCallIds.has(tc.id)) return tc;
6419
+ if (typeof args !== "string") return tc;
6420
+ const historyEntry = findToolHistoryEntry(state, tc.id, tc.function?.name);
6421
+ const digested = digestToolInputArguments(args, {
6422
+ maxFieldChars: resolved.toolResponses.maxToolInputFieldChars,
6423
+ headChars: resolved.toolResponses.maxToolInputDigestHeadChars,
6424
+ executionId: historyEntry?.executionId ?? tc.id
6425
+ });
6426
+ if (digested.digestedPaths.length === 0) return tc;
6427
+ changed = true;
6428
+ return {
6429
+ ...tc,
6430
+ function: { ...tc.function, arguments: digested.arguments }
6431
+ };
6432
+ });
6433
+ return changed ? { ...m, tool_calls: nextToolCalls } : m;
6434
+ }
6251
6435
  if (m.role === "tool") {
6252
6436
  if (isSyntheticSummaryMessage(m)) {
6253
6437
  return m;
@@ -6383,7 +6567,9 @@ var TOOL_RESPONSE_RECOVERY_MARKERS = [
6383
6567
  /STRUCTURED_TOOL_RESPONSE\s*\[/,
6384
6568
  /SUMMARIZED_TOOL_RESPONSE\b/,
6385
6569
  /DROPPED_TOOL_RESPONSE\s*\[/,
6386
- /Use get_tool_response with executionId/i
6570
+ /Use get_tool_response with executionId/i,
6571
+ // Field-level ARGUMENT digest marker (see smart/toolResponses digestToolInputValue).
6572
+ /"__digest"\s*:/
6387
6573
  ];
6388
6574
  var todoStatusSchema = z.enum(["not-started", "in-progress", "completed", "blocked"]);
6389
6575
  var todoWriteItemSchema = z.object({
@@ -6475,6 +6661,24 @@ function flattenRecoveryContent(content) {
6475
6661
  }
6476
6662
  return "";
6477
6663
  }
6664
+ function flattenToolCallArguments(message) {
6665
+ const toolCalls = message?.tool_calls;
6666
+ if (!Array.isArray(toolCalls)) {
6667
+ return "";
6668
+ }
6669
+ return toolCalls.map((call) => {
6670
+ const args = call?.function?.arguments;
6671
+ if (typeof args === "string") return args;
6672
+ if (args && typeof args === "object") {
6673
+ try {
6674
+ return JSON.stringify(args);
6675
+ } catch {
6676
+ return "";
6677
+ }
6678
+ }
6679
+ return "";
6680
+ }).filter(Boolean).join("\n");
6681
+ }
6478
6682
  function hasToolResponseRecoveryReference(messages, executionId) {
6479
6683
  if (!Array.isArray(messages) || messages.length === 0) {
6480
6684
  return false;
@@ -6483,7 +6687,10 @@ function hasToolResponseRecoveryReference(messages, executionId) {
6483
6687
  if (message?.role === "system") {
6484
6688
  return false;
6485
6689
  }
6486
- const content = flattenRecoveryContent(message?.content);
6690
+ const content = [
6691
+ flattenRecoveryContent(message?.content),
6692
+ flattenToolCallArguments(message)
6693
+ ].filter(Boolean).join("\n");
6487
6694
  if (!content) {
6488
6695
  return false;
6489
6696
  }
@@ -6663,12 +6870,15 @@ function createManageTodoTool(stateRef) {
6663
6870
  function createGetToolResponseTool(stateRef) {
6664
6871
  const getTool = createTool({
6665
6872
  name: "get_tool_response",
6666
- description: "RETRIEVE the full output of a tool execution whose response was archived, dropped, truncated, or later compacted in conversation history. This tool is only useful when the visible transcript already shows a reduced tool-response marker for the referenced executionId or tool_call_id. Use it only when a marker such as 'ARCHIVED_TOOL_RESPONSE', 'STRUCTURED_TOOL_RESPONSE', 'SUMMARIZED_TOOL_RESPONSE', 'DROPPED_TOOL_RESPONSE', or an explicit truncation note points you to a missing field you still need. Do not call it to re-fetch a normal tool result that is already present in context.",
6667
- schema: z.object({ executionId: z.string().describe("Tool execution id or original tool_call_id") }),
6873
+ description: `RETRIEVE the full input or output of a tool execution that was reduced in conversation history. This tool is only useful when the visible transcript already shows a reduced marker for the referenced executionId or tool_call_id. Use it when a marker such as 'ARCHIVED_TOOL_RESPONSE', 'STRUCTURED_TOOL_RESPONSE', 'SUMMARIZED_TOOL_RESPONSE', 'DROPPED_TOOL_RESPONSE', an explicit truncation note, or a '__digest' descriptor inside a past tool call's arguments points you to something you still need. Pass part="input" to recover arguments that were digested (their small fields are still visible; only the large payload was replaced), or part="output" (the default) to recover an archived result. Do not call it to re-fetch a normal tool result that is already present in context.`,
6874
+ schema: z.object({
6875
+ executionId: z.string().describe("Tool execution id or original tool_call_id"),
6876
+ part: z.enum(["input", "output"]).optional().describe('Which side of the exchange to recover. Defaults to "output".')
6877
+ }),
6668
6878
  maxExecutionsPerRun: 8,
6669
- func: async ({ executionId }) => {
6879
+ func: async ({ executionId, part }) => {
6670
6880
  if (!hasToolResponseRecoveryReference(stateRef.messages, executionId)) {
6671
- return "Execution not recoverable from the visible transcript. Use this only when the conversation already shows a reduced tool-response marker for that executionId.";
6881
+ return "Execution not recoverable from the visible transcript. Use this only when the conversation already shows a reduced tool-response or __digest marker for that executionId.";
6672
6882
  }
6673
6883
  const matchesExecution = (t) => t?.executionId === executionId || t?.tool_call_id === executionId;
6674
6884
  let execution = stateRef.toolHistory?.find((t) => matchesExecution(t));
@@ -6676,6 +6886,9 @@ function createGetToolResponseTool(stateRef) {
6676
6886
  execution = stateRef.toolHistoryArchived?.find((t) => matchesExecution(t));
6677
6887
  }
6678
6888
  if (execution) {
6889
+ if (part === "input") {
6890
+ return execution.args ?? "Arguments were not recorded for this execution.";
6891
+ }
6679
6892
  return execution.rawOutput || execution.output;
6680
6893
  }
6681
6894
  const ccrStore = stateRef.ctx?.__contextPilot?.ccrStore;
@@ -11008,6 +11221,6 @@ function createProvider(config) {
11008
11221
  }
11009
11222
  }
11010
11223
 
11011
- export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONTEXT_PILOT_JSON_MARKER_KEY, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DedupTracker, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, canOpenSkill, canSpawn, captureSnapshot, codePresenceRule, cognipeerSink, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createOpenSkillTool, createParallelTool, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, dedupeToolsByName, defaultTokenCounter, detectTextFormat, detectVolatileContent, emptyUsage, evaluateGuardrails, extractLatestUserQuery, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, loadSkillsFromDisk, normalizeSmartAgentOptions, otlpSink, parseSkillFrontmatter, readMemoryFacts, regexRule, resolveAvailableSkills, resolveAvailableSubagents, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, setTokenCounter, startStreamingSession, tokenize, traceSessionToOtlp, validateReasoningConfig, withTools, withinDepth, writeSummaryFactsToMemory };
11224
+ export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, 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, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, canOpenSkill, canSpawn, captureSnapshot, codePresenceRule, cognipeerSink, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createOpenSkillTool, createParallelTool, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, dedupeToolsByName, defaultTokenCounter, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, loadSkillsFromDisk, normalizeSmartAgentOptions, otlpSink, parseSkillFrontmatter, readMemoryFacts, regexRule, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, setTokenCounter, startStreamingSession, summarizeObject, tokenize, traceSessionToOtlp, validateReasoningConfig, withTools, withinDepth, writeSummaryFactsToMemory };
11012
11225
  //# sourceMappingURL=index.mjs.map
11013
11226
  //# sourceMappingURL=index.mjs.map