@cognipeer/agent-sdk 0.4.4 → 0.4.6
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.cjs +104 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +104 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2191,7 +2191,7 @@ function resolveToolResponsePolicy(toolName, output, config) {
|
|
|
2191
2191
|
const byTool = config.toolResponses.toolResponseRetentionByTool[toolName];
|
|
2192
2192
|
let retentionPolicy = byTool || config.toolResponses.defaultPolicy;
|
|
2193
2193
|
if (classification === "critical") {
|
|
2194
|
-
retentionPolicy = byTool ||
|
|
2194
|
+
retentionPolicy = byTool || config.toolResponses.fallbackPolicy;
|
|
2195
2195
|
} else if (classification === "verbose") {
|
|
2196
2196
|
retentionPolicy = byTool || config.toolResponses.largeResponsePolicy;
|
|
2197
2197
|
} else if (classification === "redundant") {
|
|
@@ -2897,6 +2897,21 @@ function isSyntheticSummaryMessage(message) {
|
|
|
2897
2897
|
}
|
|
2898
2898
|
return false;
|
|
2899
2899
|
}
|
|
2900
|
+
function getMessageText(message) {
|
|
2901
|
+
if (typeof message?.content === "string") return message.content;
|
|
2902
|
+
if (Array.isArray(message?.content)) {
|
|
2903
|
+
return message.content.map((chunk) => typeof chunk === "string" ? chunk : chunk?.text ?? chunk?.content ?? "").join("");
|
|
2904
|
+
}
|
|
2905
|
+
return "";
|
|
2906
|
+
}
|
|
2907
|
+
function getLastAssistantMessage(messages) {
|
|
2908
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
2909
|
+
if (messages[index]?.role === "assistant") {
|
|
2910
|
+
return messages[index];
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
return void 0;
|
|
2914
|
+
}
|
|
2900
2915
|
function createAgent(opts) {
|
|
2901
2916
|
const resolver = createResolverNode();
|
|
2902
2917
|
const agentCore = createAgentCoreNode(opts);
|
|
@@ -3085,7 +3100,7 @@ function createAgent(opts) {
|
|
|
3085
3100
|
const tokenCount = countMessagesTokens(tokCountMessages);
|
|
3086
3101
|
if (tokenCount > maxTok) {
|
|
3087
3102
|
const hasFreshSummary = (state.messages || []).some(
|
|
3088
|
-
(m) => m.role === "tool" && m.content === "SUMMARIZED"
|
|
3103
|
+
(m) => m.role === "tool" && typeof m.content === "string" && (m.content === "SUMMARIZED" || m.content.startsWith("SUMMARIZED_TOOL_RESPONSE"))
|
|
3089
3104
|
);
|
|
3090
3105
|
if (hasFreshSummary && tokenCount <= maxTok * 1.15) ; else {
|
|
3091
3106
|
const ctx = { ...state.ctx || {}, __needsSummarization: true };
|
|
@@ -3200,10 +3215,25 @@ function createAgent(opts) {
|
|
|
3200
3215
|
} catch (err) {
|
|
3201
3216
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
3202
3217
|
emit?.({ type: "metadata", error: `Structured output force-finalize failed: ${errMsg}` });
|
|
3218
|
+
throw err;
|
|
3203
3219
|
}
|
|
3204
3220
|
}
|
|
3205
3221
|
}
|
|
3206
3222
|
}
|
|
3223
|
+
if (state.ctx?.__needsSummarization && !opts?.summarization) {
|
|
3224
|
+
throw new Error(
|
|
3225
|
+
"Agent context exceeded the available budget before a final assistant response could be generated. Reduce tool response size or use createSmartAgent with summarization enabled."
|
|
3226
|
+
);
|
|
3227
|
+
}
|
|
3228
|
+
const lastAfterLoop = state.messages[state.messages.length - 1];
|
|
3229
|
+
if (lastAfterLoop?.role === "tool" && !pausedStage) {
|
|
3230
|
+
const isExpectedExit = state.ctx?.__awaitingApproval || state.ctx?.__cancelled || state.ctx?.__finalizedDueToStructuredOutput || state.ctx?.__finalizedDueToToolLimit || state.ctx?.__needsSummarization;
|
|
3231
|
+
if (!isExpectedExit) {
|
|
3232
|
+
throw new Error(
|
|
3233
|
+
"Agent loop terminated with a pending tool response but no subsequent model invocation. This usually indicates a model provider error or exhausted iteration budget."
|
|
3234
|
+
);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3207
3237
|
if (!pausedStage && typeof onStateChange === "function" && onStateChange(state)) {
|
|
3208
3238
|
checkpointIfRequested("after_loop");
|
|
3209
3239
|
}
|
|
@@ -3273,10 +3303,8 @@ function createAgent(opts) {
|
|
|
3273
3303
|
agentRuntime: res.agent || runtime,
|
|
3274
3304
|
status: "success"
|
|
3275
3305
|
});
|
|
3276
|
-
const
|
|
3277
|
-
|
|
3278
|
-
if (typeof finalMsg?.content === "string") content = finalMsg.content;
|
|
3279
|
-
else if (Array.isArray(finalMsg?.content)) content = finalMsg.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? "").join("");
|
|
3306
|
+
const finalAssistantMsg = getLastAssistantMessage(res.messages);
|
|
3307
|
+
const content = getMessageText(finalAssistantMsg);
|
|
3280
3308
|
let parsed = void 0;
|
|
3281
3309
|
const schema = opts.outputSchema;
|
|
3282
3310
|
if (schema && res.ctx?.__structuredOutputParsed) {
|
|
@@ -3297,7 +3325,7 @@ function createAgent(opts) {
|
|
|
3297
3325
|
} catch {
|
|
3298
3326
|
}
|
|
3299
3327
|
}
|
|
3300
|
-
emit({ type: "finalAnswer", content
|
|
3328
|
+
emit({ type: "finalAnswer", content });
|
|
3301
3329
|
if (streamEnabled && content) {
|
|
3302
3330
|
onStream?.({ text: content, isFinal: true });
|
|
3303
3331
|
emit({ type: "stream", text: content, isFinal: true });
|
|
@@ -3567,7 +3595,7 @@ function estimateContextRotScore(state) {
|
|
|
3567
3595
|
const summaryCount = state.summaryRecords?.length || 0;
|
|
3568
3596
|
const archivedCount = state.toolHistoryArchived?.length || 0;
|
|
3569
3597
|
const messageCount = state.messages?.length || 0;
|
|
3570
|
-
const summarizedMessages = state.messages?.filter((message) => message.role === "tool" && message.content === "SUMMARIZED").length || 0;
|
|
3598
|
+
const summarizedMessages = state.messages?.filter((message) => message.role === "tool" && typeof message.content === "string" && (message.content === "SUMMARIZED" || message.content.startsWith("SUMMARIZED_TOOL_RESPONSE"))).length || 0;
|
|
3571
3599
|
const numerator = summaryCount * 2 + archivedCount + summarizedMessages;
|
|
3572
3600
|
const denominator = Math.max(messageCount, 1);
|
|
3573
3601
|
return Number((numerator / denominator).toFixed(3));
|
|
@@ -3684,6 +3712,69 @@ function extractCanonicalFacts(messages) {
|
|
|
3684
3712
|
}
|
|
3685
3713
|
return [...facts.values()];
|
|
3686
3714
|
}
|
|
3715
|
+
function flattenToolMessageContent(message) {
|
|
3716
|
+
if (typeof message.content === "string") {
|
|
3717
|
+
return message.content;
|
|
3718
|
+
}
|
|
3719
|
+
if (Array.isArray(message.content)) {
|
|
3720
|
+
return message.content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? String(part ?? "")).join(" ");
|
|
3721
|
+
}
|
|
3722
|
+
return "";
|
|
3723
|
+
}
|
|
3724
|
+
function isSummarizedToolPlaceholder(content) {
|
|
3725
|
+
return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE"));
|
|
3726
|
+
}
|
|
3727
|
+
function summarizeToolMessagePreview(message) {
|
|
3728
|
+
const preview = flattenToolMessageContent(message).trim();
|
|
3729
|
+
if (!preview) {
|
|
3730
|
+
return "No summary available.";
|
|
3731
|
+
}
|
|
3732
|
+
return preview.length > 240 ? `${preview.slice(0, 240)}...` : preview;
|
|
3733
|
+
}
|
|
3734
|
+
function findToolHistoryEntry(state, toolCallId, toolName) {
|
|
3735
|
+
const entries = [
|
|
3736
|
+
...state.toolHistory || [],
|
|
3737
|
+
...state.toolHistoryArchived || []
|
|
3738
|
+
];
|
|
3739
|
+
if (toolCallId) {
|
|
3740
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
3741
|
+
const entry = entries[index];
|
|
3742
|
+
if (entry?.tool_call_id === toolCallId) {
|
|
3743
|
+
return entry;
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
3748
|
+
const entry = entries[index];
|
|
3749
|
+
if (entry?.toolName === toolName) {
|
|
3750
|
+
return entry;
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
return void 0;
|
|
3754
|
+
}
|
|
3755
|
+
function buildSummarizedToolMessage(message, state) {
|
|
3756
|
+
const toolName = message.name || "unknown_tool";
|
|
3757
|
+
const toolCallId = message.tool_call_id;
|
|
3758
|
+
const historyEntry = findToolHistoryEntry(state, toolCallId, toolName);
|
|
3759
|
+
const executionId = historyEntry?.executionId;
|
|
3760
|
+
const summary = historyEntry?.summary || summarizeToolMessagePreview(message);
|
|
3761
|
+
const references = [
|
|
3762
|
+
`toolName=${toolName}`,
|
|
3763
|
+
toolCallId ? `toolCallId=${toolCallId}` : null,
|
|
3764
|
+
executionId ? `executionId=${executionId}` : null
|
|
3765
|
+
].filter(Boolean).join("; ");
|
|
3766
|
+
let retrievalHint = "Use get_tool_response if exact details are still needed.";
|
|
3767
|
+
if (executionId && toolCallId) {
|
|
3768
|
+
retrievalHint = `Use get_tool_response with executionId "${executionId}" or tool call id "${toolCallId}" if exact details are still needed.`;
|
|
3769
|
+
} else if (executionId || toolCallId) {
|
|
3770
|
+
retrievalHint = `Use get_tool_response with executionId "${executionId || toolCallId}" if exact details are still needed.`;
|
|
3771
|
+
}
|
|
3772
|
+
return [
|
|
3773
|
+
`SUMMARIZED_TOOL_RESPONSE [${references}]`,
|
|
3774
|
+
`Summary: ${summary}`,
|
|
3775
|
+
retrievalHint
|
|
3776
|
+
].join("\n");
|
|
3777
|
+
}
|
|
3687
3778
|
function mergeStableFacts(summary, additionalFacts) {
|
|
3688
3779
|
if (additionalFacts.length === 0) return summary;
|
|
3689
3780
|
const merged = new Map(summary.stable_facts.map((fact) => [fact.key, fact]));
|
|
@@ -3742,7 +3833,7 @@ function createContextSummarizeNode(opts) {
|
|
|
3742
3833
|
const onEvent = state.ctx?.__onEvent;
|
|
3743
3834
|
const traceSession = state.ctx?.__traceSession;
|
|
3744
3835
|
const compressableMessages = messages.filter(
|
|
3745
|
-
(m) => m.role === "tool" && m.content
|
|
3836
|
+
(m) => m.role === "tool" && !isSummarizedToolPlaceholder(m.content) && !isSyntheticSummaryToolMessage(m)
|
|
3746
3837
|
);
|
|
3747
3838
|
if (compressableMessages.length === 0) {
|
|
3748
3839
|
return {};
|
|
@@ -3907,10 +3998,10 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
3907
3998
|
if (!toolCallId || !toolCallIdToAssistantIdx.has(toolCallId)) {
|
|
3908
3999
|
return null;
|
|
3909
4000
|
}
|
|
3910
|
-
if (m.content
|
|
4001
|
+
if (isSummarizedToolPlaceholder(m.content)) return m;
|
|
3911
4002
|
return {
|
|
3912
4003
|
...m,
|
|
3913
|
-
content:
|
|
4004
|
+
content: buildSummarizedToolMessage(m, state)
|
|
3914
4005
|
};
|
|
3915
4006
|
}
|
|
3916
4007
|
return m;
|
|
@@ -4220,8 +4311,8 @@ function createContextTools(stateRef, opts) {
|
|
|
4220
4311
|
}
|
|
4221
4312
|
const getTool = createTool({
|
|
4222
4313
|
name: "get_tool_response",
|
|
4223
|
-
description: "RETRIEVE the full output of a tool execution whose response was archived or
|
|
4224
|
-
schema: zod.z.object({ executionId: zod.z.string().describe("Tool execution id") }),
|
|
4314
|
+
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.",
|
|
4315
|
+
schema: zod.z.object({ executionId: zod.z.string().describe("Tool execution id or original tool_call_id") }),
|
|
4225
4316
|
func: async ({ executionId }) => {
|
|
4226
4317
|
const matchesExecution = (t) => t?.executionId === executionId || t?.tool_call_id === executionId;
|
|
4227
4318
|
let execution = stateRef.toolHistory?.find((t) => matchesExecution(t));
|