@cognipeer/agent-sdk 0.5.3 → 0.6.0
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/README.md +15 -1
- package/dist/index.cjs +92 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.mjs +92 -138
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -260,7 +260,7 @@ type RuntimeProfile = BuiltInRuntimeProfile | "custom";
|
|
|
260
260
|
type SummarizationMode = "incremental" | "full_rewrite";
|
|
261
261
|
type ContextPolicy = "raw" | "summary_only" | "hybrid";
|
|
262
262
|
type ToolResponseRetentionPolicy = "keep_full" | "keep_structured" | "summarize_archive" | "drop";
|
|
263
|
-
type ToolResponseClassification = "critical" | "informative" | "verbose"
|
|
263
|
+
type ToolResponseClassification = "critical" | "informative" | "verbose";
|
|
264
264
|
type PlanningMode = "off" | "todo" | "planner_executor" | "reasoning_then_tools";
|
|
265
265
|
type ReplanPolicy = "never" | "on_failure" | "on_conflict" | "every_n_steps";
|
|
266
266
|
type DelegationMode = "off" | "role_based" | "automatic";
|
|
@@ -366,15 +366,30 @@ type SmartAgentMemoryConfig = {
|
|
|
366
366
|
readPolicy?: MemoryReadPolicy;
|
|
367
367
|
};
|
|
368
368
|
type SmartAgentToolResponseConfig = {
|
|
369
|
+
/**
|
|
370
|
+
* Hard cap (in characters) applied at tool execution time to a single response.
|
|
371
|
+
* Anything larger is truncated immediately with a get_tool_response retrieval hint
|
|
372
|
+
* so a single oversized payload cannot blow up the next model call. Critical
|
|
373
|
+
* tools are exempt from this cap.
|
|
374
|
+
*/
|
|
369
375
|
maxToolResponseChars?: number;
|
|
376
|
+
/** Hard cap (approx. tokens) for the same eager truncation rule. */
|
|
370
377
|
maxToolResponseTokens?: number;
|
|
378
|
+
/**
|
|
379
|
+
* Retention policy applied to all non-critical tool responses by the summarizer
|
|
380
|
+
* when it fires (context limit reached). Has no effect at execution time.
|
|
381
|
+
* Defaults to "summarize_archive".
|
|
382
|
+
*/
|
|
371
383
|
defaultPolicy?: ToolResponseRetentionPolicy;
|
|
372
|
-
|
|
384
|
+
/**
|
|
385
|
+
* Per-tool override of the summarizer retention policy. Wins over `defaultPolicy`.
|
|
386
|
+
* Critical tools cannot be reduced regardless of override.
|
|
387
|
+
*/
|
|
373
388
|
toolResponseRetentionByTool?: Record<string, ToolResponseRetentionPolicy>;
|
|
389
|
+
/** Tool names whose responses are never reduced by the summarizer or hard cap. */
|
|
374
390
|
criticalTools?: string[];
|
|
375
391
|
schemaValidation?: "strict" | "warn";
|
|
376
392
|
retryOnSchemaError?: boolean;
|
|
377
|
-
fallbackPolicy?: ToolResponseRetentionPolicy;
|
|
378
393
|
};
|
|
379
394
|
type SmartAgentCustomProfileConfig = {
|
|
380
395
|
extends?: BuiltInRuntimeProfile;
|
package/dist/index.d.ts
CHANGED
|
@@ -260,7 +260,7 @@ type RuntimeProfile = BuiltInRuntimeProfile | "custom";
|
|
|
260
260
|
type SummarizationMode = "incremental" | "full_rewrite";
|
|
261
261
|
type ContextPolicy = "raw" | "summary_only" | "hybrid";
|
|
262
262
|
type ToolResponseRetentionPolicy = "keep_full" | "keep_structured" | "summarize_archive" | "drop";
|
|
263
|
-
type ToolResponseClassification = "critical" | "informative" | "verbose"
|
|
263
|
+
type ToolResponseClassification = "critical" | "informative" | "verbose";
|
|
264
264
|
type PlanningMode = "off" | "todo" | "planner_executor" | "reasoning_then_tools";
|
|
265
265
|
type ReplanPolicy = "never" | "on_failure" | "on_conflict" | "every_n_steps";
|
|
266
266
|
type DelegationMode = "off" | "role_based" | "automatic";
|
|
@@ -366,15 +366,30 @@ type SmartAgentMemoryConfig = {
|
|
|
366
366
|
readPolicy?: MemoryReadPolicy;
|
|
367
367
|
};
|
|
368
368
|
type SmartAgentToolResponseConfig = {
|
|
369
|
+
/**
|
|
370
|
+
* Hard cap (in characters) applied at tool execution time to a single response.
|
|
371
|
+
* Anything larger is truncated immediately with a get_tool_response retrieval hint
|
|
372
|
+
* so a single oversized payload cannot blow up the next model call. Critical
|
|
373
|
+
* tools are exempt from this cap.
|
|
374
|
+
*/
|
|
369
375
|
maxToolResponseChars?: number;
|
|
376
|
+
/** Hard cap (approx. tokens) for the same eager truncation rule. */
|
|
370
377
|
maxToolResponseTokens?: number;
|
|
378
|
+
/**
|
|
379
|
+
* Retention policy applied to all non-critical tool responses by the summarizer
|
|
380
|
+
* when it fires (context limit reached). Has no effect at execution time.
|
|
381
|
+
* Defaults to "summarize_archive".
|
|
382
|
+
*/
|
|
371
383
|
defaultPolicy?: ToolResponseRetentionPolicy;
|
|
372
|
-
|
|
384
|
+
/**
|
|
385
|
+
* Per-tool override of the summarizer retention policy. Wins over `defaultPolicy`.
|
|
386
|
+
* Critical tools cannot be reduced regardless of override.
|
|
387
|
+
*/
|
|
373
388
|
toolResponseRetentionByTool?: Record<string, ToolResponseRetentionPolicy>;
|
|
389
|
+
/** Tool names whose responses are never reduced by the summarizer or hard cap. */
|
|
374
390
|
criticalTools?: string[];
|
|
375
391
|
schemaValidation?: "strict" | "warn";
|
|
376
392
|
retryOnSchemaError?: boolean;
|
|
377
|
-
fallbackPolicy?: ToolResponseRetentionPolicy;
|
|
378
393
|
};
|
|
379
394
|
type SmartAgentCustomProfileConfig = {
|
|
380
395
|
extends?: BuiltInRuntimeProfile;
|
package/dist/index.mjs
CHANGED
|
@@ -2126,15 +2126,13 @@ var BASE_DEFAULTS = {
|
|
|
2126
2126
|
requireJsonOutputContract: true
|
|
2127
2127
|
},
|
|
2128
2128
|
toolResponses: {
|
|
2129
|
-
maxToolResponseChars:
|
|
2130
|
-
maxToolResponseTokens:
|
|
2131
|
-
defaultPolicy: "
|
|
2132
|
-
largeResponsePolicy: "summarize_archive",
|
|
2129
|
+
maxToolResponseChars: 12e3,
|
|
2130
|
+
maxToolResponseTokens: 3e3,
|
|
2131
|
+
defaultPolicy: "summarize_archive",
|
|
2133
2132
|
toolResponseRetentionByTool: {},
|
|
2134
2133
|
criticalTools: [...DEFAULT_CRITICAL_TOOLS],
|
|
2135
2134
|
schemaValidation: "strict",
|
|
2136
|
-
retryOnSchemaError: true
|
|
2137
|
-
fallbackPolicy: "keep_structured"
|
|
2135
|
+
retryOnSchemaError: true
|
|
2138
2136
|
}
|
|
2139
2137
|
};
|
|
2140
2138
|
function buildProfile(overrides) {
|
|
@@ -2173,7 +2171,7 @@ var DEFAULT_PROFILE_CONFIGS = {
|
|
|
2173
2171
|
},
|
|
2174
2172
|
memory: { readPolicy: "recent_only" },
|
|
2175
2173
|
delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
|
|
2176
|
-
toolResponses: { maxToolResponseChars:
|
|
2174
|
+
toolResponses: { maxToolResponseChars: 8e3, maxToolResponseTokens: 2e3 }
|
|
2177
2175
|
}),
|
|
2178
2176
|
balanced: buildProfile({}),
|
|
2179
2177
|
deep: buildProfile({
|
|
@@ -2190,7 +2188,7 @@ var DEFAULT_PROFILE_CONFIGS = {
|
|
|
2190
2188
|
},
|
|
2191
2189
|
memory: { scope: "workspace" },
|
|
2192
2190
|
delegation: { maxDelegationDepth: 3, maxChildCalls: 6 },
|
|
2193
|
-
toolResponses: { maxToolResponseChars:
|
|
2191
|
+
toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 }
|
|
2194
2192
|
}),
|
|
2195
2193
|
research: buildProfile({
|
|
2196
2194
|
limits: { maxToolCalls: 20, maxParallelTools: 4, maxContextTokens: 56e3 },
|
|
@@ -2206,7 +2204,7 @@ var DEFAULT_PROFILE_CONFIGS = {
|
|
|
2206
2204
|
},
|
|
2207
2205
|
memory: { scope: "workspace" },
|
|
2208
2206
|
delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 8, maxParallelChild: 3, childContextPolicy: "full" },
|
|
2209
|
-
toolResponses: { maxToolResponseChars:
|
|
2207
|
+
toolResponses: { maxToolResponseChars: 24e3, maxToolResponseTokens: 6e3 }
|
|
2210
2208
|
})
|
|
2211
2209
|
};
|
|
2212
2210
|
function mergeLimits(base, override) {
|
|
@@ -2413,57 +2411,65 @@ function summarizeObject(value) {
|
|
|
2413
2411
|
return safeStringify(value);
|
|
2414
2412
|
}
|
|
2415
2413
|
function classifyToolResponse(toolName, output, config) {
|
|
2416
|
-
const serialized = safeStringify(output);
|
|
2417
|
-
const tokenCount = countApproxTokens(serialized);
|
|
2418
2414
|
const criticalTools = new Set(config.toolResponses.criticalTools);
|
|
2419
2415
|
if (criticalTools.has(toolName)) return "critical";
|
|
2416
|
+
const serialized = safeStringify(output);
|
|
2417
|
+
const tokenCount = countApproxTokens(serialized);
|
|
2420
2418
|
if (tokenCount >= config.toolResponses.maxToolResponseTokens || serialized.length >= config.toolResponses.maxToolResponseChars) {
|
|
2421
2419
|
return "verbose";
|
|
2422
2420
|
}
|
|
2423
|
-
if (serialized === "ok" || serialized === "true" || serialized === "null") {
|
|
2424
|
-
return "redundant";
|
|
2425
|
-
}
|
|
2426
2421
|
return "informative";
|
|
2427
2422
|
}
|
|
2428
|
-
function
|
|
2423
|
+
function applyToolResponseHardCap(toolName, output, executionId, config) {
|
|
2429
2424
|
const serialized = safeStringify(output);
|
|
2430
2425
|
const tokenCount = countApproxTokens(serialized);
|
|
2431
2426
|
const classification = classifyToolResponse(toolName, output, config);
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
if (classification === "critical") {
|
|
2435
|
-
retentionPolicy = byTool || config.toolResponses.fallbackPolicy;
|
|
2436
|
-
} else if (classification === "verbose") {
|
|
2437
|
-
retentionPolicy = byTool || config.toolResponses.largeResponsePolicy;
|
|
2438
|
-
} else if (classification === "redundant") {
|
|
2439
|
-
retentionPolicy = byTool || "drop";
|
|
2440
|
-
}
|
|
2441
|
-
const summary = summarizeObject(output);
|
|
2442
|
-
if (retentionPolicy === "keep_full") {
|
|
2443
|
-
return { classification, retentionPolicy, content: serialized, rawOutput: output, summary, tokenCount };
|
|
2444
|
-
}
|
|
2445
|
-
if (retentionPolicy === "keep_structured") {
|
|
2446
|
-
return { classification, retentionPolicy, content: summary, rawOutput: output, summary, tokenCount };
|
|
2447
|
-
}
|
|
2448
|
-
if (retentionPolicy === "summarize_archive") {
|
|
2449
|
-
return {
|
|
2450
|
-
classification,
|
|
2451
|
-
retentionPolicy,
|
|
2452
|
-
content: `ARCHIVED_TOOL_RESPONSE: ${summary}`,
|
|
2453
|
-
rawOutput: output,
|
|
2454
|
-
summary,
|
|
2455
|
-
tokenCount
|
|
2456
|
-
};
|
|
2427
|
+
if (classification !== "verbose") {
|
|
2428
|
+
return { classification, content: serialized, rawOutput: output, tokenCount, truncated: false };
|
|
2457
2429
|
}
|
|
2430
|
+
const cap = config.toolResponses.maxToolResponseChars;
|
|
2431
|
+
const head = serialized.slice(0, cap);
|
|
2432
|
+
const note = `
|
|
2433
|
+
... [TRUNCATED ${serialized.length - cap} chars by hard cap. Use get_tool_response with executionId="${executionId}" to fetch the full payload.]`;
|
|
2458
2434
|
return {
|
|
2459
2435
|
classification,
|
|
2460
|
-
|
|
2461
|
-
content: `DROPPED_TOOL_RESPONSE: ${summary}`,
|
|
2436
|
+
content: head + note,
|
|
2462
2437
|
rawOutput: output,
|
|
2463
|
-
|
|
2464
|
-
|
|
2438
|
+
tokenCount,
|
|
2439
|
+
truncated: true
|
|
2465
2440
|
};
|
|
2466
2441
|
}
|
|
2442
|
+
function resolveSummarizationRetention(toolName, config) {
|
|
2443
|
+
const criticalTools = new Set(config.toolResponses.criticalTools);
|
|
2444
|
+
if (criticalTools.has(toolName)) return "keep_full";
|
|
2445
|
+
const byTool = config.toolResponses.toolResponseRetentionByTool[toolName];
|
|
2446
|
+
return byTool || config.toolResponses.defaultPolicy;
|
|
2447
|
+
}
|
|
2448
|
+
function renderRetainedToolMessage(args) {
|
|
2449
|
+
const { policy, rawOutput, toolName, toolCallId, executionId, prebuiltSummary } = args;
|
|
2450
|
+
if (policy === "keep_full") {
|
|
2451
|
+
return typeof rawOutput === "string" ? rawOutput : safeStringify(rawOutput);
|
|
2452
|
+
}
|
|
2453
|
+
const summary = prebuiltSummary || summarizeObject(rawOutput);
|
|
2454
|
+
const refs = [
|
|
2455
|
+
`toolName=${toolName}`,
|
|
2456
|
+
toolCallId ? `toolCallId=${toolCallId}` : null,
|
|
2457
|
+
executionId ? `executionId=${executionId}` : null
|
|
2458
|
+
].filter(Boolean).join("; ");
|
|
2459
|
+
const refId = executionId || toolCallId || "";
|
|
2460
|
+
if (policy === "keep_structured") {
|
|
2461
|
+
return `STRUCTURED_TOOL_RESPONSE [${refs}]
|
|
2462
|
+
Preview: ${summary}
|
|
2463
|
+
Use get_tool_response with executionId "${refId}" to fetch the full payload when a specific field is needed.`;
|
|
2464
|
+
}
|
|
2465
|
+
if (policy === "summarize_archive") {
|
|
2466
|
+
return `ARCHIVED_TOOL_RESPONSE [${refs}]
|
|
2467
|
+
Summary: ${summary}
|
|
2468
|
+
Use get_tool_response with executionId "${refId}" to fetch the full payload.`;
|
|
2469
|
+
}
|
|
2470
|
+
return `DROPPED_TOOL_RESPONSE [${refs}]
|
|
2471
|
+
Use get_tool_response with executionId "${refId}" only if you must recover the original payload.`;
|
|
2472
|
+
}
|
|
2467
2473
|
function validateToolArgs(tool, args) {
|
|
2468
2474
|
const schema = tool.schema;
|
|
2469
2475
|
if (!schema || typeof schema.parse !== "function") {
|
|
@@ -2742,52 +2748,25 @@ function createToolsNode(initialTools, opts) {
|
|
|
2742
2748
|
state.ctx.__structuredOutputParsed = output.data;
|
|
2743
2749
|
state.ctx.__finalizedDueToStructuredOutput = true;
|
|
2744
2750
|
}
|
|
2745
|
-
const responsePolicy =
|
|
2751
|
+
const responsePolicy = applyToolResponseHardCap(toolName, output, executionId, resolved);
|
|
2746
2752
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2747
|
-
const storedOutput = responsePolicy.retentionPolicy === "keep_full" ? output : responsePolicy.summary;
|
|
2748
2753
|
toolHistory.push({
|
|
2749
2754
|
executionId,
|
|
2750
2755
|
toolName,
|
|
2751
2756
|
args,
|
|
2752
|
-
output
|
|
2757
|
+
output,
|
|
2753
2758
|
rawOutput: output,
|
|
2754
2759
|
timestamp,
|
|
2755
2760
|
tool_call_id: tc.id,
|
|
2756
|
-
summarized:
|
|
2761
|
+
summarized: false,
|
|
2757
2762
|
originalTokenCount: responsePolicy.tokenCount,
|
|
2758
2763
|
classification: responsePolicy.classification,
|
|
2759
|
-
retentionPolicy:
|
|
2760
|
-
summary:
|
|
2761
|
-
archiveId:
|
|
2764
|
+
retentionPolicy: "keep_full",
|
|
2765
|
+
summary: void 0,
|
|
2766
|
+
archiveId: void 0,
|
|
2762
2767
|
status: "success"
|
|
2763
2768
|
});
|
|
2764
|
-
|
|
2765
|
-
toolHistoryArchived.push({
|
|
2766
|
-
executionId,
|
|
2767
|
-
toolName,
|
|
2768
|
-
args,
|
|
2769
|
-
output,
|
|
2770
|
-
rawOutput: output,
|
|
2771
|
-
timestamp,
|
|
2772
|
-
tool_call_id: tc.id,
|
|
2773
|
-
summarized: true,
|
|
2774
|
-
originalTokenCount: responsePolicy.tokenCount,
|
|
2775
|
-
classification: responsePolicy.classification,
|
|
2776
|
-
retentionPolicy: responsePolicy.retentionPolicy,
|
|
2777
|
-
summary: responsePolicy.summary,
|
|
2778
|
-
archiveId: executionId,
|
|
2779
|
-
status: "success"
|
|
2780
|
-
});
|
|
2781
|
-
}
|
|
2782
|
-
let toolMessageContent = responsePolicy.content;
|
|
2783
|
-
if (responsePolicy.retentionPolicy === "summarize_archive") {
|
|
2784
|
-
toolMessageContent = `ARCHIVED_TOOL_RESPONSE [executionId=${executionId}]: ${responsePolicy.summary}
|
|
2785
|
-
Use get_tool_response with executionId "${executionId}" to retrieve the full output.`;
|
|
2786
|
-
} else if (responsePolicy.retentionPolicy === "drop") {
|
|
2787
|
-
toolMessageContent = `DROPPED_TOOL_RESPONSE [executionId=${executionId}]: ${responsePolicy.summary}
|
|
2788
|
-
Use get_tool_response with executionId "${executionId}" to retrieve the full output.`;
|
|
2789
|
-
}
|
|
2790
|
-
appended.push({ role: "tool", content: toolMessageContent, tool_call_id: tc.id || `${tc.name}_${appended.length}`, name: tc.name });
|
|
2769
|
+
appended.push({ role: "tool", content: responsePolicy.content, tool_call_id: tc.id || `${tc.name}_${appended.length}`, name: tc.name });
|
|
2791
2770
|
onEvent?.({ type: "tool_call", phase: "success", name: toolName, id: tc.id, args, result: output, durationMs });
|
|
2792
2771
|
onProgress?.({ stage: "tools", message: `Tool ${tc.name} completed`, detail: { durationMs } });
|
|
2793
2772
|
if (needsApproval && approvalEntry) {
|
|
@@ -2831,8 +2810,9 @@ Use get_tool_response with executionId "${executionId}" to retrieve the full out
|
|
|
2831
2810
|
messageList,
|
|
2832
2811
|
debug: {
|
|
2833
2812
|
classification: responsePolicy.classification,
|
|
2834
|
-
retentionPolicy:
|
|
2835
|
-
originalTokenCount: responsePolicy.tokenCount
|
|
2813
|
+
retentionPolicy: "keep_full",
|
|
2814
|
+
originalTokenCount: responsePolicy.tokenCount,
|
|
2815
|
+
truncated: responsePolicy.truncated
|
|
2836
2816
|
}
|
|
2837
2817
|
});
|
|
2838
2818
|
toolCount += 1;
|
|
@@ -4193,24 +4173,8 @@ function extractCanonicalFacts(messages) {
|
|
|
4193
4173
|
}
|
|
4194
4174
|
return [...facts.values()];
|
|
4195
4175
|
}
|
|
4196
|
-
function flattenToolMessageContent(message) {
|
|
4197
|
-
if (typeof message.content === "string") {
|
|
4198
|
-
return message.content;
|
|
4199
|
-
}
|
|
4200
|
-
if (Array.isArray(message.content)) {
|
|
4201
|
-
return message.content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? String(part ?? "")).join(" ");
|
|
4202
|
-
}
|
|
4203
|
-
return "";
|
|
4204
|
-
}
|
|
4205
4176
|
function isSummarizedToolPlaceholder(content) {
|
|
4206
|
-
return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE"));
|
|
4207
|
-
}
|
|
4208
|
-
function summarizeToolMessagePreview(message) {
|
|
4209
|
-
const preview = flattenToolMessageContent(message).trim();
|
|
4210
|
-
if (!preview) {
|
|
4211
|
-
return "No summary available.";
|
|
4212
|
-
}
|
|
4213
|
-
return preview.length > 240 ? `${preview.slice(0, 240)}...` : preview;
|
|
4177
|
+
return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE") || content.startsWith("ARCHIVED_TOOL_RESPONSE") || content.startsWith("STRUCTURED_TOOL_RESPONSE") || content.startsWith("DROPPED_TOOL_RESPONSE"));
|
|
4214
4178
|
}
|
|
4215
4179
|
function findToolHistoryEntry(state, toolCallId, toolName) {
|
|
4216
4180
|
const entries = [
|
|
@@ -4236,29 +4200,6 @@ function findToolHistoryEntry(state, toolCallId, toolName) {
|
|
|
4236
4200
|
}
|
|
4237
4201
|
return void 0;
|
|
4238
4202
|
}
|
|
4239
|
-
function buildSummarizedToolMessage(message, state) {
|
|
4240
|
-
const toolName = message.name || "unknown_tool";
|
|
4241
|
-
const toolCallId = message.tool_call_id;
|
|
4242
|
-
const historyEntry = findToolHistoryEntry(state, toolCallId, toolName);
|
|
4243
|
-
const executionId = historyEntry?.executionId;
|
|
4244
|
-
const summary = historyEntry?.summary || summarizeToolMessagePreview(message);
|
|
4245
|
-
const references = [
|
|
4246
|
-
`toolName=${toolName}`,
|
|
4247
|
-
toolCallId ? `toolCallId=${toolCallId}` : null,
|
|
4248
|
-
executionId ? `executionId=${executionId}` : null
|
|
4249
|
-
].filter(Boolean).join("; ");
|
|
4250
|
-
let retrievalHint = "Use get_tool_response if exact details are still needed.";
|
|
4251
|
-
if (executionId && toolCallId) {
|
|
4252
|
-
retrievalHint = `Use get_tool_response with executionId "${executionId}" or tool call id "${toolCallId}" if exact details are still needed.`;
|
|
4253
|
-
} else if (executionId || toolCallId) {
|
|
4254
|
-
retrievalHint = `Use get_tool_response with executionId "${executionId || toolCallId}" if exact details are still needed.`;
|
|
4255
|
-
}
|
|
4256
|
-
return [
|
|
4257
|
-
`SUMMARIZED_TOOL_RESPONSE [${references}]`,
|
|
4258
|
-
`Summary: ${summary}`,
|
|
4259
|
-
retrievalHint
|
|
4260
|
-
].join("\n");
|
|
4261
|
-
}
|
|
4262
4203
|
function mergeStableFacts(summary, additionalFacts) {
|
|
4263
4204
|
if (additionalFacts.length === 0) return summary;
|
|
4264
4205
|
const merged = new Map(summary.stable_facts.map((fact) => [fact.key, fact]));
|
|
@@ -4316,18 +4257,13 @@ function createContextSummarizeNode(opts) {
|
|
|
4316
4257
|
const messages = state.messages || [];
|
|
4317
4258
|
const onEvent = state.ctx?.__onEvent;
|
|
4318
4259
|
const traceSession = state.ctx?.__traceSession;
|
|
4319
|
-
const toolResponsesConfigEarly = resolved.toolResponses;
|
|
4320
4260
|
const compressableMessages = messages.filter(
|
|
4321
4261
|
(m) => {
|
|
4322
4262
|
if (m.role !== "tool") return false;
|
|
4323
4263
|
if (isSummarizedToolPlaceholder(m.content)) return false;
|
|
4324
4264
|
if (isSyntheticSummaryMessage(m)) return false;
|
|
4325
|
-
const
|
|
4326
|
-
if (
|
|
4327
|
-
if (!histEntry?.retentionPolicy) {
|
|
4328
|
-
const byTool = toolResponsesConfigEarly.toolResponseRetentionByTool?.[m.name || ""];
|
|
4329
|
-
if ((byTool || toolResponsesConfigEarly.defaultPolicy) === "keep_full") return false;
|
|
4330
|
-
}
|
|
4265
|
+
const policy = resolveSummarizationRetention(m.name || "", resolved);
|
|
4266
|
+
if (policy === "keep_full") return false;
|
|
4331
4267
|
return true;
|
|
4332
4268
|
}
|
|
4333
4269
|
);
|
|
@@ -4507,7 +4443,8 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
4507
4443
|
break;
|
|
4508
4444
|
}
|
|
4509
4445
|
}
|
|
4510
|
-
const
|
|
4446
|
+
const archivedExecutions = [...state.toolHistoryArchived || []];
|
|
4447
|
+
const archivedIds = new Set(archivedExecutions.map((entry) => entry?.executionId).filter(Boolean));
|
|
4511
4448
|
const newMessages = messages.map((m) => {
|
|
4512
4449
|
if (m.role === "tool") {
|
|
4513
4450
|
if (isSyntheticSummaryMessage(m)) {
|
|
@@ -4520,23 +4457,38 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
4520
4457
|
if (isSummarizedToolPlaceholder(m.content)) return m;
|
|
4521
4458
|
if (toolCallId && protectedToolCallIds.has(toolCallId)) return m;
|
|
4522
4459
|
const toolName = m.name || "";
|
|
4460
|
+
const policy = resolveSummarizationRetention(toolName, resolved);
|
|
4461
|
+
if (policy === "keep_full") return m;
|
|
4523
4462
|
const historyEntry = findToolHistoryEntry(state, toolCallId, toolName);
|
|
4524
|
-
const
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4463
|
+
const rawOutput = historyEntry?.rawOutput ?? historyEntry?.output ?? m.content;
|
|
4464
|
+
const executionId = historyEntry?.executionId;
|
|
4465
|
+
const prebuiltSummary = historyEntry?.summary || summarizeObject(rawOutput);
|
|
4466
|
+
if ((policy === "summarize_archive" || policy === "drop") && historyEntry && executionId && !archivedIds.has(executionId)) {
|
|
4467
|
+
archivedExecutions.push({
|
|
4468
|
+
...historyEntry,
|
|
4469
|
+
summarized: true,
|
|
4470
|
+
retentionPolicy: policy,
|
|
4471
|
+
archiveId: executionId,
|
|
4472
|
+
summary: prebuiltSummary
|
|
4473
|
+
});
|
|
4474
|
+
archivedIds.add(executionId);
|
|
4530
4475
|
}
|
|
4531
4476
|
return {
|
|
4532
4477
|
...m,
|
|
4533
|
-
content:
|
|
4478
|
+
content: renderRetainedToolMessage({
|
|
4479
|
+
policy,
|
|
4480
|
+
rawOutput,
|
|
4481
|
+
toolName,
|
|
4482
|
+
toolCallId,
|
|
4483
|
+
executionId,
|
|
4484
|
+
prebuiltSummary
|
|
4485
|
+
})
|
|
4534
4486
|
};
|
|
4535
4487
|
}
|
|
4536
4488
|
return m;
|
|
4537
4489
|
}).filter((m) => m !== null);
|
|
4538
4490
|
const actuallyCompressed = newMessages.filter(
|
|
4539
|
-
(m) => m.role === "tool" &&
|
|
4491
|
+
(m) => m.role === "tool" && isSummarizedToolPlaceholder(m.content) && !messages.some((orig) => orig.tool_call_id === m.tool_call_id && isSummarizedToolPlaceholder(orig.content))
|
|
4540
4492
|
);
|
|
4541
4493
|
if (actuallyCompressed.length === 0) {
|
|
4542
4494
|
return {};
|
|
@@ -4615,7 +4567,8 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
4615
4567
|
return {
|
|
4616
4568
|
messages: finalMessages,
|
|
4617
4569
|
summaries,
|
|
4618
|
-
summaryRecords
|
|
4570
|
+
summaryRecords,
|
|
4571
|
+
toolHistoryArchived: archivedExecutions
|
|
4619
4572
|
};
|
|
4620
4573
|
};
|
|
4621
4574
|
}
|
|
@@ -4857,8 +4810,9 @@ function createContextTools(stateRef, opts) {
|
|
|
4857
4810
|
}
|
|
4858
4811
|
const getTool = createTool({
|
|
4859
4812
|
name: "get_tool_response",
|
|
4860
|
-
description: "RETRIEVE the full output of a tool execution whose response was archived, dropped, or later compacted in conversation history. When a tool response appears as 'ARCHIVED_TOOL_RESPONSE [executionId=xxx]', 'DROPPED_TOOL_RESPONSE [executionId=xxx]', or 'SUMMARIZED_TOOL_RESPONSE [...]', pass the referenced executionId to this tool to get the complete data. You can also pass the original tool_call_id from the tool call.",
|
|
4813
|
+
description: "RETRIEVE the full output of a tool execution whose response was archived, dropped, or later compacted in conversation history. Use this only when the preview or summary is missing a specific field, identifier, snippet, or exact payload you still need to finish the task. Do not call it reflexively for every archived response. When a tool response appears as 'ARCHIVED_TOOL_RESPONSE [executionId=xxx]', 'DROPPED_TOOL_RESPONSE [executionId=xxx]', or 'SUMMARIZED_TOOL_RESPONSE [...]', pass the referenced executionId to this tool to get the complete data. You can also pass the original tool_call_id from the tool call.",
|
|
4861
4814
|
schema: z.object({ executionId: z.string().describe("Tool execution id or original tool_call_id") }),
|
|
4815
|
+
maxExecutionsPerRun: 8,
|
|
4862
4816
|
func: async ({ executionId }) => {
|
|
4863
4817
|
const matchesExecution = (t) => t?.executionId === executionId || t?.tool_call_id === executionId;
|
|
4864
4818
|
let execution = stateRef.toolHistory?.find((t) => matchesExecution(t));
|