@cognipeer/agent-sdk 0.8.5 → 0.8.7

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;
@@ -1940,6 +1944,270 @@ function estimatePayloadBytes(value) {
1940
1944
  }
1941
1945
  }
1942
1946
 
1947
+ // src/smart/toolResponses.ts
1948
+ init_utilTokens();
1949
+
1950
+ // src/utils/content.ts
1951
+ function contentToString(content) {
1952
+ try {
1953
+ if (content == null) return "";
1954
+ if (typeof content === "string") return content;
1955
+ if (Array.isArray(content)) {
1956
+ return content.map((p) => {
1957
+ if (!p || typeof p !== "object") return String(p);
1958
+ if (p.type === "text") return String(p.text ?? "");
1959
+ if (p.type === "image_url") {
1960
+ const img = p.image_url;
1961
+ const url = typeof img === "string" ? img : img?.url;
1962
+ const detail = typeof img === "string" ? void 0 : img?.detail;
1963
+ return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
1964
+ }
1965
+ return JSON.stringify(p);
1966
+ }).join("\n");
1967
+ }
1968
+ return JSON.stringify(content);
1969
+ } catch {
1970
+ return String(content);
1971
+ }
1972
+ }
1973
+ function mergeContentsToString(contents) {
1974
+ return contents.map((c) => contentToString(c)).join("\n");
1975
+ }
1976
+ function safeStringify(value, pretty = false) {
1977
+ if (value == null) return "";
1978
+ if (typeof value === "string") return value;
1979
+ try {
1980
+ return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
1981
+ } catch {
1982
+ return String(value);
1983
+ }
1984
+ }
1985
+ function extractMessageText2(message) {
1986
+ if (!message) return "";
1987
+ const content = message.content;
1988
+ if (typeof content === "string") return content;
1989
+ if (Array.isArray(content)) {
1990
+ return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
1991
+ }
1992
+ return "";
1993
+ }
1994
+
1995
+ // src/smart/toolResponses.ts
1996
+ var CONTROL_PLANE_TOOL_NAMES = [
1997
+ "response",
1998
+ "manage_todo_list",
1999
+ "get_tool_response",
2000
+ "ask_user_question",
2001
+ "open_skill",
2002
+ "bind_skill_tools",
2003
+ "search_skills"
2004
+ ];
2005
+ var DELEGATION_TOOL_NAMES = [
2006
+ "delegate_to",
2007
+ "spawn_subagent",
2008
+ "spawn_subagents_parallel"
2009
+ ];
2010
+ var INPUT_PROTECTED_TOOL_NAMES = /* @__PURE__ */ new Set([
2011
+ ...CONTROL_PLANE_TOOL_NAMES,
2012
+ ...DELEGATION_TOOL_NAMES
2013
+ ]);
2014
+ var CONTROL_PLANE_OUTPUT_DEFAULTS = new Set(CONTROL_PLANE_TOOL_NAMES);
2015
+ var DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS = 2e3;
2016
+ var DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS = 200;
2017
+ var TOOL_INPUT_DIGEST_KEY = "__digest";
2018
+ function summarizeObject(value) {
2019
+ if (value == null) return "null";
2020
+ if (typeof value === "string") {
2021
+ return value.length > 240 ? `${value.slice(0, 240)}...` : value;
2022
+ }
2023
+ if (Array.isArray(value)) {
2024
+ const preview = value.slice(0, 3).map((entry) => safeStringify(entry).slice(0, 120)).join(" | ");
2025
+ return `array(length=${value.length}) ${preview}`.trim();
2026
+ }
2027
+ if (typeof value === "object") {
2028
+ const keys = Object.keys(value);
2029
+ const preview = keys.slice(0, 6).map((key) => `${key}=${safeStringify(value[key]).slice(0, 80)}`).join("; ");
2030
+ return `object(keys=${keys.length}) ${preview}`.trim();
2031
+ }
2032
+ return safeStringify(value);
2033
+ }
2034
+ function classifyToolResponse(toolName, output, config) {
2035
+ const criticalTools = new Set(config.toolResponses.criticalTools);
2036
+ if (criticalTools.has(toolName)) return "critical";
2037
+ const serialized = safeStringify(output);
2038
+ const tokenCount = countApproxTokens(serialized);
2039
+ if (tokenCount >= config.toolResponses.maxToolResponseTokens || serialized.length >= config.toolResponses.maxToolResponseChars) {
2040
+ return "verbose";
2041
+ }
2042
+ return "informative";
2043
+ }
2044
+ function applyToolResponseHardCap(toolName, output, executionId, config) {
2045
+ const serialized = safeStringify(output);
2046
+ const tokenCount = countApproxTokens(serialized);
2047
+ const classification = classifyToolResponse(toolName, output, config);
2048
+ if (classification !== "verbose") {
2049
+ return { classification, content: serialized, rawOutput: output, tokenCount, truncated: false };
2050
+ }
2051
+ const cap = config.toolResponses.maxToolResponseChars;
2052
+ const head = serialized.slice(0, cap);
2053
+ const note = `
2054
+ ... [TRUNCATED ${serialized.length - cap} chars by hard cap. Use get_tool_response with executionId="${executionId}" to fetch the full payload.]`;
2055
+ return {
2056
+ classification,
2057
+ content: head + note,
2058
+ rawOutput: output,
2059
+ tokenCount,
2060
+ truncated: true
2061
+ };
2062
+ }
2063
+ function collectToolRetentionDeclarations(tools) {
2064
+ const declarations = /* @__PURE__ */ new Map();
2065
+ if (!Array.isArray(tools)) return declarations;
2066
+ for (const tool of tools) {
2067
+ const spec = tool?.retention;
2068
+ const name = typeof tool?.name === "string" ? tool.name : "";
2069
+ if (!name || !spec || typeof spec !== "object") continue;
2070
+ declarations.set(name, spec);
2071
+ }
2072
+ return declarations;
2073
+ }
2074
+ function resolveSummarizationRetention(toolName, config, declarations) {
2075
+ const criticalTools = new Set(config.toolResponses.criticalTools);
2076
+ if (criticalTools.has(toolName)) return "keep_full";
2077
+ const twoAxis = config.toolResponses.retentionByTool?.[toolName]?.output;
2078
+ if (twoAxis) return twoAxis;
2079
+ const legacy = config.toolResponses.toolResponseRetentionByTool[toolName];
2080
+ if (legacy) return legacy;
2081
+ const declared = declarations?.get(toolName)?.output;
2082
+ if (declared) return declared;
2083
+ if (CONTROL_PLANE_OUTPUT_DEFAULTS.has(toolName)) return "keep_full";
2084
+ return config.toolResponses.defaultPolicy;
2085
+ }
2086
+ function resolveInputRetention(toolName, config, declarations) {
2087
+ if (INPUT_PROTECTED_TOOL_NAMES.has(toolName)) return "keep";
2088
+ const criticalTools = new Set(config.toolResponses.criticalTools);
2089
+ if (criticalTools.has(toolName)) return "keep";
2090
+ const twoAxis = config.toolResponses.retentionByTool?.[toolName]?.input;
2091
+ if (twoAxis) return twoAxis;
2092
+ const declared = declarations?.get(toolName)?.input;
2093
+ if (declared) return declared;
2094
+ return config.toolResponses.defaultInputPolicy;
2095
+ }
2096
+ function shortSha256(value) {
2097
+ return createHash("sha256").update(value, "utf8").digest("hex").slice(0, 16);
2098
+ }
2099
+ function isDigestMarker(value) {
2100
+ return Boolean(
2101
+ value && typeof value === "object" && !Array.isArray(value) && TOOL_INPUT_DIGEST_KEY in value
2102
+ );
2103
+ }
2104
+ function digestToolInputValue(value, options) {
2105
+ const maxFieldChars = options?.maxFieldChars ?? DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS;
2106
+ const headChars = options?.headChars ?? DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS;
2107
+ const executionId = options?.executionId;
2108
+ const digestedPaths = [];
2109
+ let reclaimedChars = 0;
2110
+ const walk = (node, path2) => {
2111
+ if (typeof node === "string") {
2112
+ if (node.length <= maxFieldChars) return node;
2113
+ digestedPaths.push(path2 || "(root)");
2114
+ const marker = {
2115
+ chars: node.length,
2116
+ sha256: shortSha256(node),
2117
+ head: node.slice(0, headChars)
2118
+ };
2119
+ if (executionId) {
2120
+ marker.recover = `get_tool_response executionId="${executionId}" part="input"`;
2121
+ }
2122
+ const replacement = { [TOOL_INPUT_DIGEST_KEY]: marker };
2123
+ reclaimedChars += node.length - safeStringify(replacement).length;
2124
+ return replacement;
2125
+ }
2126
+ if (Array.isArray(node)) {
2127
+ let changed = false;
2128
+ const next = node.map((entry, index) => {
2129
+ const walked = walk(entry, path2 ? `${path2}[${index}]` : `[${index}]`);
2130
+ if (walked !== entry) changed = true;
2131
+ return walked;
2132
+ });
2133
+ return changed ? next : node;
2134
+ }
2135
+ if (node && typeof node === "object") {
2136
+ if (isDigestMarker(node)) return node;
2137
+ let changed = false;
2138
+ const next = {};
2139
+ for (const [key, entry] of Object.entries(node)) {
2140
+ const walked = walk(entry, path2 ? `${path2}.${key}` : key);
2141
+ if (walked !== entry) changed = true;
2142
+ next[key] = walked;
2143
+ }
2144
+ return changed ? next : node;
2145
+ }
2146
+ return node;
2147
+ };
2148
+ const nextValue = walk(value, "");
2149
+ return { value: nextValue, digestedPaths, reclaimedChars: Math.max(0, reclaimedChars) };
2150
+ }
2151
+ function digestToolInputArguments(argumentsJson, options) {
2152
+ const unchanged = { arguments: argumentsJson, digestedPaths: [], reclaimedChars: 0 };
2153
+ if (typeof argumentsJson !== "string" || argumentsJson.length === 0) return unchanged;
2154
+ let parsed;
2155
+ try {
2156
+ parsed = JSON.parse(argumentsJson);
2157
+ } catch {
2158
+ return unchanged;
2159
+ }
2160
+ const digested = digestToolInputValue(parsed, options);
2161
+ if (digested.digestedPaths.length === 0) return unchanged;
2162
+ const serialized = safeStringify(digested.value);
2163
+ if (serialized.length >= argumentsJson.length) return unchanged;
2164
+ return {
2165
+ arguments: serialized,
2166
+ digestedPaths: digested.digestedPaths,
2167
+ reclaimedChars: argumentsJson.length - serialized.length
2168
+ };
2169
+ }
2170
+ function renderRetainedToolMessage(args) {
2171
+ const { policy, rawOutput, toolName, toolCallId, executionId, prebuiltSummary } = args;
2172
+ if (policy === "keep_full") {
2173
+ return typeof rawOutput === "string" ? rawOutput : safeStringify(rawOutput);
2174
+ }
2175
+ const summary = prebuiltSummary || summarizeObject(rawOutput);
2176
+ const refs = [
2177
+ `toolName=${toolName}`,
2178
+ toolCallId ? `toolCallId=${toolCallId}` : null,
2179
+ executionId ? `executionId=${executionId}` : null
2180
+ ].filter(Boolean).join("; ");
2181
+ const refId = executionId || toolCallId || "";
2182
+ if (policy === "keep_structured") {
2183
+ return `STRUCTURED_TOOL_RESPONSE [${refs}]
2184
+ Preview: ${summary}
2185
+ Use get_tool_response with executionId "${refId}" to fetch the full payload when a specific field is needed.`;
2186
+ }
2187
+ if (policy === "summarize_archive") {
2188
+ return `ARCHIVED_TOOL_RESPONSE [${refs}]
2189
+ Summary: ${summary}
2190
+ Use get_tool_response with executionId "${refId}" to fetch the full payload.`;
2191
+ }
2192
+ return `DROPPED_TOOL_RESPONSE [${refs}]
2193
+ Use get_tool_response with executionId "${refId}" only if you must recover the original payload.`;
2194
+ }
2195
+ function validateToolArgs(tool, args) {
2196
+ const schema = tool.schema;
2197
+ if (!schema || typeof schema.parse !== "function") {
2198
+ return { ok: true, value: args };
2199
+ }
2200
+ try {
2201
+ return { ok: true, value: schema.parse(args) };
2202
+ } catch (error) {
2203
+ if (error instanceof ZodError) {
2204
+ const message = error.issues.map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
2205
+ return { ok: false, message };
2206
+ }
2207
+ return { ok: false, message: error instanceof Error ? error.message : String(error) };
2208
+ }
2209
+ }
2210
+
1943
2211
  // src/smart/runtimeConfig.ts
1944
2212
  var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
1945
2213
  var BASE_DEFAULTS = {
@@ -1990,6 +2258,11 @@ var BASE_DEFAULTS = {
1990
2258
  maxToolResponseTokens: 8e3,
1991
2259
  defaultPolicy: "summarize_archive",
1992
2260
  toolResponseRetentionByTool: {},
2261
+ // Argument digesting is opt-in: the default never touches a tool's request.
2262
+ defaultInputPolicy: "keep",
2263
+ retentionByTool: {},
2264
+ maxToolInputFieldChars: DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS,
2265
+ maxToolInputDigestHeadChars: DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS,
1993
2266
  criticalTools: [...DEFAULT_CRITICAL_TOOLS],
1994
2267
  schemaValidation: "strict"
1995
2268
  },
@@ -2044,7 +2317,8 @@ function buildProfile(overrides) {
2044
2317
  ...BASE_DEFAULTS.toolResponses,
2045
2318
  ...overrides.toolResponses,
2046
2319
  criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2047
- toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2320
+ toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {},
2321
+ retentionByTool: overrides.toolResponses?.retentionByTool ?? {}
2048
2322
  },
2049
2323
  contextPilot: mergeContextPilot(BASE_DEFAULTS.contextPilot, overrides.contextPilot)
2050
2324
  };
@@ -2198,6 +2472,14 @@ function normalizeSmartAgentOptions(opts) {
2198
2472
  ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2199
2473
  ...opts.toolResponses?.toolResponseRetentionByTool || {}
2200
2474
  },
2475
+ // Two-axis map merges the same way, so a caller can layer a small override
2476
+ // on top of a profile's table instead of restating it.
2477
+ retentionByTool: {
2478
+ ...preset.toolResponses.retentionByTool,
2479
+ ...customProfile.toolResponses?.retentionByTool || {},
2480
+ ...opts.toolResponses?.retentionByTool || {}
2481
+ },
2482
+ defaultInputPolicy: opts.toolResponses?.defaultInputPolicy ?? customProfile.toolResponses?.defaultInputPolicy ?? preset.toolResponses.defaultInputPolicy,
2201
2483
  criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2202
2484
  },
2203
2485
  contextPilot: mergeContextPilot(mergeContextPilot(preset.contextPilot, customProfile.contextPilot), opts.contextPilot)
@@ -2382,53 +2664,6 @@ function detectVolatileContent(text, limit = 20) {
2382
2664
 
2383
2665
  // src/smart/contextPilot/jsonCrusher.ts
2384
2666
  init_utilTokens();
2385
-
2386
- // src/utils/content.ts
2387
- function contentToString(content) {
2388
- try {
2389
- if (content == null) return "";
2390
- if (typeof content === "string") return content;
2391
- if (Array.isArray(content)) {
2392
- return content.map((p) => {
2393
- if (!p || typeof p !== "object") return String(p);
2394
- if (p.type === "text") return String(p.text ?? "");
2395
- if (p.type === "image_url") {
2396
- const img = p.image_url;
2397
- const url = typeof img === "string" ? img : img?.url;
2398
- const detail = typeof img === "string" ? void 0 : img?.detail;
2399
- return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2400
- }
2401
- return JSON.stringify(p);
2402
- }).join("\n");
2403
- }
2404
- return JSON.stringify(content);
2405
- } catch {
2406
- return String(content);
2407
- }
2408
- }
2409
- function mergeContentsToString(contents) {
2410
- return contents.map((c) => contentToString(c)).join("\n");
2411
- }
2412
- function safeStringify(value, pretty = false) {
2413
- if (value == null) return "";
2414
- if (typeof value === "string") return value;
2415
- try {
2416
- return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2417
- } catch {
2418
- return String(value);
2419
- }
2420
- }
2421
- function extractMessageText2(message) {
2422
- if (!message) return "";
2423
- const content = message.content;
2424
- if (typeof content === "string") return content;
2425
- if (Array.isArray(content)) {
2426
- return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2427
- }
2428
- return "";
2429
- }
2430
-
2431
- // src/smart/contextPilot/jsonCrusher.ts
2432
2667
  var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
2433
2668
  function findCompressibleArray(output, minItems) {
2434
2669
  if (Array.isArray(output)) {
@@ -2997,100 +3232,6 @@ function extractToolItems(output) {
2997
3232
  });
2998
3233
  }
2999
3234
 
3000
- // src/smart/toolResponses.ts
3001
- init_utilTokens();
3002
- function summarizeObject(value) {
3003
- if (value == null) return "null";
3004
- if (typeof value === "string") {
3005
- return value.length > 240 ? `${value.slice(0, 240)}...` : value;
3006
- }
3007
- if (Array.isArray(value)) {
3008
- const preview = value.slice(0, 3).map((entry) => safeStringify(entry).slice(0, 120)).join(" | ");
3009
- return `array(length=${value.length}) ${preview}`.trim();
3010
- }
3011
- if (typeof value === "object") {
3012
- const keys = Object.keys(value);
3013
- const preview = keys.slice(0, 6).map((key) => `${key}=${safeStringify(value[key]).slice(0, 80)}`).join("; ");
3014
- return `object(keys=${keys.length}) ${preview}`.trim();
3015
- }
3016
- return safeStringify(value);
3017
- }
3018
- function classifyToolResponse(toolName, output, config) {
3019
- const criticalTools = new Set(config.toolResponses.criticalTools);
3020
- if (criticalTools.has(toolName)) return "critical";
3021
- const serialized = safeStringify(output);
3022
- const tokenCount = countApproxTokens(serialized);
3023
- if (tokenCount >= config.toolResponses.maxToolResponseTokens || serialized.length >= config.toolResponses.maxToolResponseChars) {
3024
- return "verbose";
3025
- }
3026
- return "informative";
3027
- }
3028
- function applyToolResponseHardCap(toolName, output, executionId, config) {
3029
- const serialized = safeStringify(output);
3030
- const tokenCount = countApproxTokens(serialized);
3031
- const classification = classifyToolResponse(toolName, output, config);
3032
- if (classification !== "verbose") {
3033
- return { classification, content: serialized, rawOutput: output, tokenCount, truncated: false };
3034
- }
3035
- const cap = config.toolResponses.maxToolResponseChars;
3036
- const head = serialized.slice(0, cap);
3037
- const note = `
3038
- ... [TRUNCATED ${serialized.length - cap} chars by hard cap. Use get_tool_response with executionId="${executionId}" to fetch the full payload.]`;
3039
- return {
3040
- classification,
3041
- content: head + note,
3042
- rawOutput: output,
3043
- tokenCount,
3044
- truncated: true
3045
- };
3046
- }
3047
- function resolveSummarizationRetention(toolName, config) {
3048
- const criticalTools = new Set(config.toolResponses.criticalTools);
3049
- if (criticalTools.has(toolName)) return "keep_full";
3050
- const byTool = config.toolResponses.toolResponseRetentionByTool[toolName];
3051
- return byTool || config.toolResponses.defaultPolicy;
3052
- }
3053
- function renderRetainedToolMessage(args) {
3054
- const { policy, rawOutput, toolName, toolCallId, executionId, prebuiltSummary } = args;
3055
- if (policy === "keep_full") {
3056
- return typeof rawOutput === "string" ? rawOutput : safeStringify(rawOutput);
3057
- }
3058
- const summary = prebuiltSummary || summarizeObject(rawOutput);
3059
- const refs = [
3060
- `toolName=${toolName}`,
3061
- toolCallId ? `toolCallId=${toolCallId}` : null,
3062
- executionId ? `executionId=${executionId}` : null
3063
- ].filter(Boolean).join("; ");
3064
- const refId = executionId || toolCallId || "";
3065
- if (policy === "keep_structured") {
3066
- return `STRUCTURED_TOOL_RESPONSE [${refs}]
3067
- Preview: ${summary}
3068
- Use get_tool_response with executionId "${refId}" to fetch the full payload when a specific field is needed.`;
3069
- }
3070
- if (policy === "summarize_archive") {
3071
- return `ARCHIVED_TOOL_RESPONSE [${refs}]
3072
- Summary: ${summary}
3073
- Use get_tool_response with executionId "${refId}" to fetch the full payload.`;
3074
- }
3075
- return `DROPPED_TOOL_RESPONSE [${refs}]
3076
- Use get_tool_response with executionId "${refId}" only if you must recover the original payload.`;
3077
- }
3078
- function validateToolArgs(tool, args) {
3079
- const schema = tool.schema;
3080
- if (!schema || typeof schema.parse !== "function") {
3081
- return { ok: true, value: args };
3082
- }
3083
- try {
3084
- return { ok: true, value: schema.parse(args) };
3085
- } catch (error) {
3086
- if (error instanceof ZodError) {
3087
- const message = error.issues.map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
3088
- return { ok: false, message };
3089
- }
3090
- return { ok: false, message: error instanceof Error ? error.message : String(error) };
3091
- }
3092
- }
3093
-
3094
3235
  // src/utils/pendingToolCalls.ts
3095
3236
  function selectPendingToolCalls(messages) {
3096
3237
  if (!Array.isArray(messages) || messages.length === 0) return [];
@@ -5347,7 +5488,10 @@ function createAgent(opts) {
5347
5488
  }
5348
5489
  }
5349
5490
  }
5350
- if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
5491
+ const structuredFinalizeBlocked = Boolean(
5492
+ pausedStage || state.ctx?.__awaitingApproval || state.ctx?.__awaitingUserQuestion || state.ctx?.__cancelled || state.ctx?.__needsSummarization || state.ctx?.__limitBreached || state.ctx?.__guardrailBlocked
5493
+ );
5494
+ if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
5351
5495
  const lastForParse = state.messages[state.messages.length - 1];
5352
5496
  if (lastForParse?.role === "assistant") {
5353
5497
  const assistantText = extractMessageText2(lastForParse);
@@ -5364,10 +5508,11 @@ function createAgent(opts) {
5364
5508
  }
5365
5509
  }
5366
5510
  }
5367
- if (soManager && soManager.strategy.kind === "tool_based" && !state.ctx?.__finalizedDueToStructuredOutput) {
5511
+ if (soManager && soManager.strategy.kind === "tool_based" && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
5368
5512
  const maxPostLoopRetries = soManager.maxRetries;
5369
5513
  for (let postRetry = 0; postRetry < maxPostLoopRetries; postRetry++) {
5370
5514
  if (state.ctx?.__finalizedDueToStructuredOutput) break;
5515
+ if (state.ctx?.__awaitingApproval || state.ctx?.__awaitingUserQuestion || state.ctx?.__cancelled || state.ctx?.__limitBreached) break;
5371
5516
  const last = state.messages[state.messages.length - 1];
5372
5517
  const lastHasToolCalls = Array.isArray(last?.tool_calls) && last.tool_calls.length > 0;
5373
5518
  if (!lastHasToolCalls) {
@@ -5781,7 +5926,7 @@ function collectRecentTurns(messages, lastTurnsToKeep) {
5781
5926
  if (turnCount >= lastTurnsToKeep) break;
5782
5927
  }
5783
5928
  }
5784
- if (countAssistantTurns && collected.length > 0 && collected[0].role !== "user") {
5929
+ if (collected.length > 0) {
5785
5930
  const firstUserMsg = body.find((m) => m.role === "user");
5786
5931
  if (firstUserMsg && !collected.includes(firstUserMsg)) {
5787
5932
  collected.unshift(firstUserMsg);
@@ -5813,12 +5958,18 @@ function renderMemoryBlock(facts) {
5813
5958
  ...facts.map((fact) => `- ${fact.key}: ${fact.value}`)
5814
5959
  ].join("\n");
5815
5960
  }
5961
+ function isClampProtected(message, index, firstUserIndex) {
5962
+ if (message.role === "system") return true;
5963
+ if (index === firstUserIndex) return true;
5964
+ return false;
5965
+ }
5816
5966
  function clampToBudget(messages, maxContextTokens) {
5817
5967
  let working = [...messages];
5818
5968
  while (working.length > 2) {
5819
5969
  const tokenCount = countApproxTokens(working.map(extractMessageText2).join("\n"));
5820
5970
  if (tokenCount <= maxContextTokens) return working;
5821
- const firstNonSystem = working.findIndex((message, index) => !(index === 0 && message.role === "system"));
5971
+ const firstUserIndex = working.findIndex((message) => message.role === "user");
5972
+ const firstNonSystem = working.findIndex((message, index) => !isClampProtected(message, index, firstUserIndex));
5822
5973
  if (firstNonSystem < 0) break;
5823
5974
  const target = working[firstNonSystem];
5824
5975
  if (target.role === "assistant" && Array.isArray(target.tool_calls) && target.tool_calls.length > 0) {
@@ -6256,9 +6407,42 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
6256
6407
  break;
6257
6408
  }
6258
6409
  }
6410
+ const retentionDeclarations = collectToolRetentionDeclarations(state.agent?.tools);
6411
+ const digestableToolCallIds = /* @__PURE__ */ new Set();
6412
+ for (const m of messages) {
6413
+ if (m.role !== "tool" || isSyntheticSummaryMessage(m)) continue;
6414
+ const toolCallId = m.tool_call_id;
6415
+ if (!toolCallId || !toolCallIdToAssistantIdx.has(toolCallId)) continue;
6416
+ if (protectedToolCallIds.has(toolCallId)) continue;
6417
+ const toolName = m.name || "";
6418
+ if (resolveInputRetention(toolName, resolved, retentionDeclarations) !== "digest") continue;
6419
+ digestableToolCallIds.add(toolCallId);
6420
+ }
6259
6421
  const archivedExecutions = [...state.toolHistoryArchived || []];
6260
6422
  const archivedIds = new Set(archivedExecutions.map((entry) => entry?.executionId).filter(Boolean));
6261
6423
  const newMessages = messages.map((m) => {
6424
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
6425
+ if (m.reasoning?.blocks?.length) return m;
6426
+ let changed = false;
6427
+ const nextToolCalls = m.tool_calls.map((tc) => {
6428
+ const args = tc?.function?.arguments;
6429
+ if (!tc?.id || !digestableToolCallIds.has(tc.id)) return tc;
6430
+ if (typeof args !== "string") return tc;
6431
+ const historyEntry = findToolHistoryEntry(state, tc.id, tc.function?.name);
6432
+ const digested = digestToolInputArguments(args, {
6433
+ maxFieldChars: resolved.toolResponses.maxToolInputFieldChars,
6434
+ headChars: resolved.toolResponses.maxToolInputDigestHeadChars,
6435
+ executionId: historyEntry?.executionId ?? tc.id
6436
+ });
6437
+ if (digested.digestedPaths.length === 0) return tc;
6438
+ changed = true;
6439
+ return {
6440
+ ...tc,
6441
+ function: { ...tc.function, arguments: digested.arguments }
6442
+ };
6443
+ });
6444
+ return changed ? { ...m, tool_calls: nextToolCalls } : m;
6445
+ }
6262
6446
  if (m.role === "tool") {
6263
6447
  if (isSyntheticSummaryMessage(m)) {
6264
6448
  return m;
@@ -6394,7 +6578,9 @@ var TOOL_RESPONSE_RECOVERY_MARKERS = [
6394
6578
  /STRUCTURED_TOOL_RESPONSE\s*\[/,
6395
6579
  /SUMMARIZED_TOOL_RESPONSE\b/,
6396
6580
  /DROPPED_TOOL_RESPONSE\s*\[/,
6397
- /Use get_tool_response with executionId/i
6581
+ /Use get_tool_response with executionId/i,
6582
+ // Field-level ARGUMENT digest marker (see smart/toolResponses digestToolInputValue).
6583
+ /"__digest"\s*:/
6398
6584
  ];
6399
6585
  var todoStatusSchema = z.enum(["not-started", "in-progress", "completed", "blocked"]);
6400
6586
  var todoWriteItemSchema = z.object({
@@ -6486,6 +6672,24 @@ function flattenRecoveryContent(content) {
6486
6672
  }
6487
6673
  return "";
6488
6674
  }
6675
+ function flattenToolCallArguments(message) {
6676
+ const toolCalls = message?.tool_calls;
6677
+ if (!Array.isArray(toolCalls)) {
6678
+ return "";
6679
+ }
6680
+ return toolCalls.map((call) => {
6681
+ const args = call?.function?.arguments;
6682
+ if (typeof args === "string") return args;
6683
+ if (args && typeof args === "object") {
6684
+ try {
6685
+ return JSON.stringify(args);
6686
+ } catch {
6687
+ return "";
6688
+ }
6689
+ }
6690
+ return "";
6691
+ }).filter(Boolean).join("\n");
6692
+ }
6489
6693
  function hasToolResponseRecoveryReference(messages, executionId) {
6490
6694
  if (!Array.isArray(messages) || messages.length === 0) {
6491
6695
  return false;
@@ -6494,7 +6698,10 @@ function hasToolResponseRecoveryReference(messages, executionId) {
6494
6698
  if (message?.role === "system") {
6495
6699
  return false;
6496
6700
  }
6497
- const content = flattenRecoveryContent(message?.content);
6701
+ const content = [
6702
+ flattenRecoveryContent(message?.content),
6703
+ flattenToolCallArguments(message)
6704
+ ].filter(Boolean).join("\n");
6498
6705
  if (!content) {
6499
6706
  return false;
6500
6707
  }
@@ -6674,12 +6881,15 @@ function createManageTodoTool(stateRef) {
6674
6881
  function createGetToolResponseTool(stateRef) {
6675
6882
  const getTool = createTool({
6676
6883
  name: "get_tool_response",
6677
- 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.",
6678
- schema: z.object({ executionId: z.string().describe("Tool execution id or original tool_call_id") }),
6884
+ 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.`,
6885
+ schema: z.object({
6886
+ executionId: z.string().describe("Tool execution id or original tool_call_id"),
6887
+ part: z.enum(["input", "output"]).optional().describe('Which side of the exchange to recover. Defaults to "output".')
6888
+ }),
6679
6889
  maxExecutionsPerRun: 8,
6680
- func: async ({ executionId }) => {
6890
+ func: async ({ executionId, part }) => {
6681
6891
  if (!hasToolResponseRecoveryReference(stateRef.messages, executionId)) {
6682
- return "Execution not recoverable from the visible transcript. Use this only when the conversation already shows a reduced tool-response marker for that executionId.";
6892
+ 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.";
6683
6893
  }
6684
6894
  const matchesExecution = (t) => t?.executionId === executionId || t?.tool_call_id === executionId;
6685
6895
  let execution = stateRef.toolHistory?.find((t) => matchesExecution(t));
@@ -6687,6 +6897,9 @@ function createGetToolResponseTool(stateRef) {
6687
6897
  execution = stateRef.toolHistoryArchived?.find((t) => matchesExecution(t));
6688
6898
  }
6689
6899
  if (execution) {
6900
+ if (part === "input") {
6901
+ return execution.args ?? "Arguments were not recorded for this execution.";
6902
+ }
6690
6903
  return execution.rawOutput || execution.output;
6691
6904
  }
6692
6905
  const ccrStore = stateRef.ctx?.__contextPilot?.ccrStore;
@@ -11019,6 +11232,6 @@ function createProvider(config) {
11019
11232
  }
11020
11233
  }
11021
11234
 
11022
- 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 };
11235
+ 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 };
11023
11236
  //# sourceMappingURL=index.mjs.map
11024
11237
  //# sourceMappingURL=index.mjs.map