@cognipeer/agent-sdk 0.8.6 → 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;
@@ -798,28 +802,6 @@ function normalizeUsage(raw) {
798
802
  };
799
803
  return normalized;
800
804
  }
801
- function recordUsage(state, modelName, normalized) {
802
- const usageState = state.usage || { perRequest: [], totals: {} };
803
- const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
804
- const cachedInput = normalized.prompt_tokens_details?.cached_tokens;
805
- usageState.perRequest.push({
806
- id,
807
- modelName,
808
- usage: normalized,
809
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
810
- turn: usageState.perRequest.length + 1,
811
- cachedInput
812
- });
813
- const previous = usageState.totals[modelName] || { input: 0, output: 0, total: 0, cachedInput: 0 };
814
- usageState.totals[modelName] = {
815
- input: previous.input + (Number(normalized.prompt_tokens) || 0),
816
- output: previous.output + (Number(normalized.completion_tokens) || 0),
817
- total: previous.total + (Number(normalized.total_tokens) || 0),
818
- cachedInput: previous.cachedInput + (Number(cachedInput) || 0)
819
- };
820
- state.usage = usageState;
821
- return id;
822
- }
823
805
  function num(...vals) {
824
806
  for (const v of vals) {
825
807
  if (v === 0) return 0;
@@ -1962,6 +1944,270 @@ function estimatePayloadBytes(value) {
1962
1944
  }
1963
1945
  }
1964
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
+
1965
2211
  // src/smart/runtimeConfig.ts
1966
2212
  var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
1967
2213
  var BASE_DEFAULTS = {
@@ -2012,6 +2258,11 @@ var BASE_DEFAULTS = {
2012
2258
  maxToolResponseTokens: 8e3,
2013
2259
  defaultPolicy: "summarize_archive",
2014
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,
2015
2266
  criticalTools: [...DEFAULT_CRITICAL_TOOLS],
2016
2267
  schemaValidation: "strict"
2017
2268
  },
@@ -2066,7 +2317,8 @@ function buildProfile(overrides) {
2066
2317
  ...BASE_DEFAULTS.toolResponses,
2067
2318
  ...overrides.toolResponses,
2068
2319
  criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2069
- toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2320
+ toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {},
2321
+ retentionByTool: overrides.toolResponses?.retentionByTool ?? {}
2070
2322
  },
2071
2323
  contextPilot: mergeContextPilot(BASE_DEFAULTS.contextPilot, overrides.contextPilot)
2072
2324
  };
@@ -2220,6 +2472,14 @@ function normalizeSmartAgentOptions(opts) {
2220
2472
  ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2221
2473
  ...opts.toolResponses?.toolResponseRetentionByTool || {}
2222
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,
2223
2483
  criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2224
2484
  },
2225
2485
  contextPilot: mergeContextPilot(mergeContextPilot(preset.contextPilot, customProfile.contextPilot), opts.contextPilot)
@@ -2404,53 +2664,6 @@ function detectVolatileContent(text, limit = 20) {
2404
2664
 
2405
2665
  // src/smart/contextPilot/jsonCrusher.ts
2406
2666
  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
2667
  var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
2455
2668
  function findCompressibleArray(output, minItems) {
2456
2669
  if (Array.isArray(output)) {
@@ -2958,7 +3171,24 @@ function createAgentCoreNode(opts) {
2958
3171
  messageList: messagesWithResponse
2959
3172
  });
2960
3173
  if (normalized) {
2961
- recordUsage(state, modelName, normalized);
3174
+ const usageState = state.usage || { perRequest: [], totals: {} };
3175
+ const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
3176
+ const turn = usageState.perRequest.length + 1;
3177
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3178
+ const cachedInputTok = normalized.prompt_tokens_details?.cached_tokens;
3179
+ usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
3180
+ const inputTok = normalized.prompt_tokens;
3181
+ const outputTok = normalized.completion_tokens;
3182
+ const totalTok = normalized.total_tokens;
3183
+ const key = modelName;
3184
+ const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
3185
+ usageState.totals[key] = {
3186
+ input: agg.input + (Number(inputTok) || 0),
3187
+ output: agg.output + (Number(outputTok) || 0),
3188
+ total: agg.total + (Number(totalTok) || 0),
3189
+ cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
3190
+ };
3191
+ state.usage = usageState;
2962
3192
  }
2963
3193
  return { messages: messagesWithResponse, usage: state.usage };
2964
3194
  };
@@ -3002,100 +3232,6 @@ function extractToolItems(output) {
3002
3232
  });
3003
3233
  }
3004
3234
 
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
3235
  // src/utils/pendingToolCalls.ts
3100
3236
  function selectPendingToolCalls(messages) {
3101
3237
  if (!Array.isArray(messages) || messages.length === 0) return [];
@@ -5352,7 +5488,10 @@ function createAgent(opts) {
5352
5488
  }
5353
5489
  }
5354
5490
  }
5355
- 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) {
5356
5495
  const lastForParse = state.messages[state.messages.length - 1];
5357
5496
  if (lastForParse?.role === "assistant") {
5358
5497
  const assistantText = extractMessageText2(lastForParse);
@@ -5369,10 +5508,11 @@ function createAgent(opts) {
5369
5508
  }
5370
5509
  }
5371
5510
  }
5372
- if (soManager && soManager.strategy.kind === "tool_based" && !state.ctx?.__finalizedDueToStructuredOutput) {
5511
+ if (soManager && soManager.strategy.kind === "tool_based" && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
5373
5512
  const maxPostLoopRetries = soManager.maxRetries;
5374
5513
  for (let postRetry = 0; postRetry < maxPostLoopRetries; postRetry++) {
5375
5514
  if (state.ctx?.__finalizedDueToStructuredOutput) break;
5515
+ if (state.ctx?.__awaitingApproval || state.ctx?.__awaitingUserQuestion || state.ctx?.__cancelled || state.ctx?.__limitBreached) break;
5376
5516
  const last = state.messages[state.messages.length - 1];
5377
5517
  const lastHasToolCalls = Array.isArray(last?.tool_calls) && last.tool_calls.length > 0;
5378
5518
  if (!lastHasToolCalls) {
@@ -5741,7 +5881,24 @@ function createAgentNode(opts) {
5741
5881
  messageList: messagesWithResponse
5742
5882
  });
5743
5883
  if (normalized) {
5744
- recordUsage(state, modelName, normalized);
5884
+ const usageState = state.usage || { perRequest: [], totals: {} };
5885
+ const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
5886
+ const turn = usageState.perRequest.length + 1;
5887
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
5888
+ const cachedInputTok = normalized.prompt_tokens_details.cached_tokens;
5889
+ usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
5890
+ const inputTok = normalized.prompt_tokens;
5891
+ const outputTok = normalized.completion_tokens;
5892
+ const totalTok = normalized.total_tokens;
5893
+ const key = modelName;
5894
+ const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
5895
+ usageState.totals[key] = {
5896
+ input: agg.input + (Number(inputTok) || 0),
5897
+ output: agg.output + (Number(outputTok) || 0),
5898
+ total: agg.total + (Number(totalTok) || 0),
5899
+ cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
5900
+ };
5901
+ state.usage = usageState;
5745
5902
  }
5746
5903
  return { messages: messagesWithResponse, usage: state.usage };
5747
5904
  };
@@ -5769,7 +5926,7 @@ function collectRecentTurns(messages, lastTurnsToKeep) {
5769
5926
  if (turnCount >= lastTurnsToKeep) break;
5770
5927
  }
5771
5928
  }
5772
- if (countAssistantTurns && collected.length > 0 && collected[0].role !== "user") {
5929
+ if (collected.length > 0) {
5773
5930
  const firstUserMsg = body.find((m) => m.role === "user");
5774
5931
  if (firstUserMsg && !collected.includes(firstUserMsg)) {
5775
5932
  collected.unshift(firstUserMsg);
@@ -5801,12 +5958,18 @@ function renderMemoryBlock(facts) {
5801
5958
  ...facts.map((fact) => `- ${fact.key}: ${fact.value}`)
5802
5959
  ].join("\n");
5803
5960
  }
5961
+ function isClampProtected(message, index, firstUserIndex) {
5962
+ if (message.role === "system") return true;
5963
+ if (index === firstUserIndex) return true;
5964
+ return false;
5965
+ }
5804
5966
  function clampToBudget(messages, maxContextTokens) {
5805
5967
  let working = [...messages];
5806
5968
  while (working.length > 2) {
5807
5969
  const tokenCount = countApproxTokens(working.map(extractMessageText2).join("\n"));
5808
5970
  if (tokenCount <= maxContextTokens) return working;
5809
- 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));
5810
5973
  if (firstNonSystem < 0) break;
5811
5974
  const target = working[firstNonSystem];
5812
5975
  if (target.role === "assistant" && Array.isArray(target.tool_calls) && target.tool_calls.length > 0) {
@@ -6185,7 +6348,6 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
6185
6348
  outputTokensActual = normalized.completion_tokens;
6186
6349
  totalTokensActual = normalized.total_tokens;
6187
6350
  cachedInputTokens = normalized.prompt_tokens_details?.cached_tokens;
6188
- recordUsage(state, getModelName(model) || "unknown_model", normalized);
6189
6351
  }
6190
6352
  } catch (err) {
6191
6353
  durationMs = Date.now() - startTime;
@@ -6245,9 +6407,42 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
6245
6407
  break;
6246
6408
  }
6247
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
+ }
6248
6421
  const archivedExecutions = [...state.toolHistoryArchived || []];
6249
6422
  const archivedIds = new Set(archivedExecutions.map((entry) => entry?.executionId).filter(Boolean));
6250
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
+ }
6251
6446
  if (m.role === "tool") {
6252
6447
  if (isSyntheticSummaryMessage(m)) {
6253
6448
  return m;
@@ -6383,7 +6578,9 @@ var TOOL_RESPONSE_RECOVERY_MARKERS = [
6383
6578
  /STRUCTURED_TOOL_RESPONSE\s*\[/,
6384
6579
  /SUMMARIZED_TOOL_RESPONSE\b/,
6385
6580
  /DROPPED_TOOL_RESPONSE\s*\[/,
6386
- /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*:/
6387
6584
  ];
6388
6585
  var todoStatusSchema = z.enum(["not-started", "in-progress", "completed", "blocked"]);
6389
6586
  var todoWriteItemSchema = z.object({
@@ -6475,6 +6672,24 @@ function flattenRecoveryContent(content) {
6475
6672
  }
6476
6673
  return "";
6477
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
+ }
6478
6693
  function hasToolResponseRecoveryReference(messages, executionId) {
6479
6694
  if (!Array.isArray(messages) || messages.length === 0) {
6480
6695
  return false;
@@ -6483,7 +6698,10 @@ function hasToolResponseRecoveryReference(messages, executionId) {
6483
6698
  if (message?.role === "system") {
6484
6699
  return false;
6485
6700
  }
6486
- const content = flattenRecoveryContent(message?.content);
6701
+ const content = [
6702
+ flattenRecoveryContent(message?.content),
6703
+ flattenToolCallArguments(message)
6704
+ ].filter(Boolean).join("\n");
6487
6705
  if (!content) {
6488
6706
  return false;
6489
6707
  }
@@ -6663,12 +6881,15 @@ function createManageTodoTool(stateRef) {
6663
6881
  function createGetToolResponseTool(stateRef) {
6664
6882
  const getTool = createTool({
6665
6883
  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") }),
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
+ }),
6668
6889
  maxExecutionsPerRun: 8,
6669
- func: async ({ executionId }) => {
6890
+ func: async ({ executionId, part }) => {
6670
6891
  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.";
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.";
6672
6893
  }
6673
6894
  const matchesExecution = (t) => t?.executionId === executionId || t?.tool_call_id === executionId;
6674
6895
  let execution = stateRef.toolHistory?.find((t) => matchesExecution(t));
@@ -6676,6 +6897,9 @@ function createGetToolResponseTool(stateRef) {
6676
6897
  execution = stateRef.toolHistoryArchived?.find((t) => matchesExecution(t));
6677
6898
  }
6678
6899
  if (execution) {
6900
+ if (part === "input") {
6901
+ return execution.args ?? "Arguments were not recorded for this execution.";
6902
+ }
6679
6903
  return execution.rawOutput || execution.output;
6680
6904
  }
6681
6905
  const ccrStore = stateRef.ctx?.__contextPilot?.ccrStore;
@@ -11008,6 +11232,6 @@ function createProvider(config) {
11008
11232
  }
11009
11233
  }
11010
11234
 
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 };
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 };
11012
11236
  //# sourceMappingURL=index.mjs.map
11013
11237
  //# sourceMappingURL=index.mjs.map