@cognipeer/agent-sdk 0.6.2 → 0.6.4
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 +248 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -4
- package/dist/index.d.ts +16 -4
- package/dist/index.mjs +246 -155
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -627,6 +627,7 @@ function buildSystemPrompt(extra, planning, name = "Agent", todoListPrompt) {
|
|
|
627
627
|
"- Keep privacy and safety: do not reveal secrets or sensitive data.",
|
|
628
628
|
"- If inputs are ambiguous or missing, ask one concise clarifying question.",
|
|
629
629
|
"- Reuse prior tool results already present in the conversation when sufficient.",
|
|
630
|
+
'- Use recovery tools such as "get_tool_response" only when the visible transcript explicitly shows a reduced tool-response marker (for example ARCHIVED_TOOL_RESPONSE, STRUCTURED_TOOL_RESPONSE, SUMMARIZED_TOOL_RESPONSE, DROPPED_TOOL_RESPONSE, or a truncation note with an executionId). Never use a recovery tool to re-fetch a normal tool result already visible in context.',
|
|
630
631
|
planningBlock,
|
|
631
632
|
extraTrimmed ? `Extra instructions: ${extraTrimmed}` : ""
|
|
632
633
|
].filter(Boolean).join("\n");
|
|
@@ -2238,6 +2239,7 @@ function normalizeSmartAgentOptions(opts) {
|
|
|
2238
2239
|
const summarizationOverride = typeof opts.summarization === "object" ? opts.summarization : {};
|
|
2239
2240
|
const planningMode = opts.planning?.mode ?? customProfile.planning?.mode ?? (useTodoList ? "todo" : preset.planning.mode);
|
|
2240
2241
|
const memoryStore = opts.memory?.store ?? customProfile.memory?.store;
|
|
2242
|
+
const contextToolResponsePolicy = opts.context?.toolResponsePolicy ?? customProfile.context?.toolResponsePolicy ?? preset.context.toolResponsePolicy;
|
|
2241
2243
|
return {
|
|
2242
2244
|
runtimeProfile,
|
|
2243
2245
|
baseProfile,
|
|
@@ -2260,7 +2262,7 @@ function normalizeSmartAgentOptions(opts) {
|
|
|
2260
2262
|
...customProfile.context?.budget || {},
|
|
2261
2263
|
...opts.context?.budget || {}
|
|
2262
2264
|
},
|
|
2263
|
-
toolResponsePolicy:
|
|
2265
|
+
toolResponsePolicy: contextToolResponsePolicy
|
|
2264
2266
|
},
|
|
2265
2267
|
planning: {
|
|
2266
2268
|
...preset.planning,
|
|
@@ -2283,6 +2285,7 @@ function normalizeSmartAgentOptions(opts) {
|
|
|
2283
2285
|
...preset.toolResponses,
|
|
2284
2286
|
...customProfile.toolResponses || {},
|
|
2285
2287
|
...opts.toolResponses || {},
|
|
2288
|
+
defaultPolicy: opts.toolResponses?.defaultPolicy ?? customProfile.toolResponses?.defaultPolicy ?? contextToolResponsePolicy,
|
|
2286
2289
|
toolResponseRetentionByTool: {
|
|
2287
2290
|
...preset.toolResponses.toolResponseRetentionByTool,
|
|
2288
2291
|
...customProfile.toolResponses?.toolResponseRetentionByTool || {},
|
|
@@ -2552,6 +2555,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
2552
2555
|
anyTool._stateRef.toolHistory = state.toolHistory;
|
|
2553
2556
|
anyTool._stateRef.toolHistoryArchived = state.toolHistoryArchived;
|
|
2554
2557
|
anyTool._stateRef.pendingApprovals = pendingApprovals;
|
|
2558
|
+
anyTool._stateRef.messages = state.messages;
|
|
2555
2559
|
anyTool._stateRef.ctx = state.ctx || (state.ctx = {});
|
|
2556
2560
|
anyTool._stateRef.__onEvent = onEvent;
|
|
2557
2561
|
}
|
|
@@ -4020,8 +4024,10 @@ function createAgent(opts) {
|
|
|
4020
4024
|
agentRuntime: res.agent || runtime,
|
|
4021
4025
|
status: "success"
|
|
4022
4026
|
});
|
|
4023
|
-
const
|
|
4024
|
-
const
|
|
4027
|
+
const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
|
|
4028
|
+
const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
|
|
4029
|
+
const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
|
|
4030
|
+
const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText2(finalAssistantMsg);
|
|
4025
4031
|
let parsed = void 0;
|
|
4026
4032
|
let outputError = void 0;
|
|
4027
4033
|
if (soManager) {
|
|
@@ -4034,17 +4040,19 @@ function createAgent(opts) {
|
|
|
4034
4040
|
} else {
|
|
4035
4041
|
outputError = fallbackResult.error;
|
|
4036
4042
|
}
|
|
4037
|
-
} else {
|
|
4043
|
+
} else if (!isTransientSummarizationExit) {
|
|
4038
4044
|
const noResult = soManager.noOutputResult(1);
|
|
4039
4045
|
if (!noResult.success) {
|
|
4040
4046
|
outputError = noResult.error;
|
|
4041
4047
|
}
|
|
4042
4048
|
}
|
|
4043
4049
|
}
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4050
|
+
if (!isTransientSummarizationExit && !finalIsSyntheticSummary) {
|
|
4051
|
+
emit({ type: "finalAnswer", content });
|
|
4052
|
+
if (streamEnabled && content) {
|
|
4053
|
+
onStream?.({ text: content, isFinal: true });
|
|
4054
|
+
emit({ type: "stream", text: content, isFinal: true });
|
|
4055
|
+
}
|
|
4048
4056
|
}
|
|
4049
4057
|
return {
|
|
4050
4058
|
content,
|
|
@@ -4842,6 +4850,13 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
4842
4850
|
};
|
|
4843
4851
|
};
|
|
4844
4852
|
}
|
|
4853
|
+
var TOOL_RESPONSE_RECOVERY_MARKERS = [
|
|
4854
|
+
/ARCHIVED_TOOL_RESPONSE\s*\[/,
|
|
4855
|
+
/STRUCTURED_TOOL_RESPONSE\s*\[/,
|
|
4856
|
+
/SUMMARIZED_TOOL_RESPONSE\b/,
|
|
4857
|
+
/DROPPED_TOOL_RESPONSE\s*\[/,
|
|
4858
|
+
/Use get_tool_response with executionId/i
|
|
4859
|
+
];
|
|
4845
4860
|
var todoStatusSchema = zod.z.enum(["not-started", "in-progress", "completed", "blocked"]);
|
|
4846
4861
|
var todoWriteItemSchema = zod.z.object({
|
|
4847
4862
|
id: zod.z.number().int().min(1).describe("Sequential id starting from 1"),
|
|
@@ -4910,180 +4925,223 @@ function formatTodoListSummary(todoList) {
|
|
|
4910
4925
|
}
|
|
4911
4926
|
return todoList.map((item) => `${item.id}. ${item.title || item.step || item.description || `Step ${item.id}`} [${item.status}]`).join("\n");
|
|
4912
4927
|
}
|
|
4913
|
-
function
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4928
|
+
function flattenRecoveryContent(content) {
|
|
4929
|
+
if (typeof content === "string") {
|
|
4930
|
+
return content;
|
|
4931
|
+
}
|
|
4932
|
+
if (Array.isArray(content)) {
|
|
4933
|
+
return content.map((part) => {
|
|
4934
|
+
if (typeof part === "string") {
|
|
4935
|
+
return part;
|
|
4936
|
+
}
|
|
4937
|
+
if (part && typeof part === "object") {
|
|
4938
|
+
if (typeof part.text === "string") {
|
|
4939
|
+
return part.text;
|
|
4940
|
+
}
|
|
4941
|
+
if (typeof part.content === "string") {
|
|
4942
|
+
return part.content;
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
return "";
|
|
4946
|
+
}).filter(Boolean).join("\n");
|
|
4947
|
+
}
|
|
4948
|
+
return "";
|
|
4949
|
+
}
|
|
4950
|
+
function hasToolResponseRecoveryReference(messages, executionId) {
|
|
4951
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
4952
|
+
return false;
|
|
4953
|
+
}
|
|
4954
|
+
return messages.some((message) => {
|
|
4955
|
+
if (message?.role === "system") {
|
|
4956
|
+
return false;
|
|
4957
|
+
}
|
|
4958
|
+
const content = flattenRecoveryContent(message?.content);
|
|
4959
|
+
if (!content) {
|
|
4960
|
+
return false;
|
|
4961
|
+
}
|
|
4962
|
+
const hasRecoveryMarker = TOOL_RESPONSE_RECOVERY_MARKERS.some((pattern) => pattern.test(content));
|
|
4963
|
+
if (!hasRecoveryMarker) {
|
|
4964
|
+
return false;
|
|
4965
|
+
}
|
|
4966
|
+
return executionId ? content.includes(executionId) : true;
|
|
4967
|
+
});
|
|
4968
|
+
}
|
|
4969
|
+
function createManageTodoTool(stateRef) {
|
|
4970
|
+
const manageTodo = createTool({
|
|
4971
|
+
name: "manage_todo_list",
|
|
4972
|
+
description: "Manage a structured todo list to track progress and plan tasks throughout your coding session.\n\nOperations:\n- read: return the current plan\n- write: replace the full plan with a complete ordered todoList\n- update: patch existing todo items by id without resending the whole plan\n\nRules:\n- Use write only when creating or fully rewriting the plan\n- After a plan exists, prefer update for status, evidence, or owner changes\n- Update payloads should contain only the changed items\n- When using update, pass expectedVersion to avoid overwriting a newer plan\n- Keep ids unique; write operations must keep ids sequential starting from 1\n- Keep at most ONE item in-progress at a time\n- If update fails due to version mismatch, read the latest plan and retry",
|
|
4973
|
+
schema: zod.z.object({
|
|
4974
|
+
operation: zod.z.enum(["write", "read", "update"]),
|
|
4975
|
+
expectedVersion: zod.z.number().int().min(0).optional(),
|
|
4976
|
+
todoList: zod.z.array(zod.z.union([todoWriteItemSchema, todoUpdateItemSchema])).optional()
|
|
4977
|
+
}),
|
|
4978
|
+
func: async ({ operation, expectedVersion, todoList }) => {
|
|
4979
|
+
const toolStateRef = manageTodo._stateRef;
|
|
4980
|
+
const onEvent = toolStateRef?.__onEvent;
|
|
4981
|
+
const emitPlanEvent = (list) => {
|
|
4982
|
+
const version = stateRef.planVersion || 1;
|
|
4983
|
+
const adherenceScore = stateRef.adherenceScore || 0;
|
|
4984
|
+
const planData = {
|
|
4985
|
+
source: "manage_todo_list",
|
|
4986
|
+
operation,
|
|
4987
|
+
version,
|
|
4988
|
+
adherenceScore,
|
|
4989
|
+
count: Array.isArray(list) ? list.length : 0
|
|
4990
|
+
};
|
|
4991
|
+
onEvent?.({ type: "plan", todoList: list, ...planData });
|
|
4992
|
+
const traceSession = toolStateRef?.ctx?.__traceSession;
|
|
4993
|
+
recordTraceEvent(traceSession, {
|
|
4994
|
+
type: "plan",
|
|
4995
|
+
label: `Plan ${operation}`,
|
|
4996
|
+
actor: { scope: "agent", name: "manage_todo_list", role: "planner" },
|
|
4997
|
+
sections: [
|
|
4998
|
+
{
|
|
4999
|
+
kind: "summary",
|
|
5000
|
+
label: "Todo List",
|
|
5001
|
+
content: formatTodoListSummary(list)
|
|
5002
|
+
},
|
|
5003
|
+
{
|
|
5004
|
+
kind: "metadata",
|
|
5005
|
+
label: "Plan Metadata",
|
|
5006
|
+
data: planData
|
|
5007
|
+
}
|
|
5008
|
+
],
|
|
5009
|
+
debug: planData
|
|
5010
|
+
});
|
|
5011
|
+
};
|
|
5012
|
+
const currentVersion = stateRef.planVersion || 0;
|
|
5013
|
+
if (operation === "read") {
|
|
5014
|
+
const list = stateRef.todoList || [];
|
|
5015
|
+
emitPlanEvent(list);
|
|
5016
|
+
return list;
|
|
5017
|
+
}
|
|
5018
|
+
if (typeof expectedVersion === "number" && expectedVersion !== currentVersion) {
|
|
5019
|
+
return {
|
|
5020
|
+
status: "error",
|
|
5021
|
+
operation,
|
|
5022
|
+
error: "Plan version mismatch. Read the latest plan and retry.",
|
|
5023
|
+
version: currentVersion,
|
|
5024
|
+
adherenceScore: stateRef.adherenceScore || 0
|
|
5025
|
+
};
|
|
5026
|
+
}
|
|
5027
|
+
if (!Array.isArray(todoList)) {
|
|
5028
|
+
return {
|
|
5029
|
+
status: "error",
|
|
5030
|
+
operation,
|
|
5031
|
+
error: "todoList is required for write and update operations.",
|
|
5032
|
+
version: currentVersion,
|
|
5033
|
+
adherenceScore: stateRef.adherenceScore || 0
|
|
5034
|
+
};
|
|
5035
|
+
}
|
|
5036
|
+
if (operation === "write") {
|
|
5037
|
+
const parsed = zod.z.array(todoWriteItemSchema).safeParse(todoList);
|
|
5038
|
+
if (!parsed.success) {
|
|
5039
|
+
return {
|
|
5040
|
+
status: "error",
|
|
4932
5041
|
operation,
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
5042
|
+
error: parsed.error.issues[0]?.message || "Invalid todoList for write.",
|
|
5043
|
+
version: currentVersion,
|
|
5044
|
+
adherenceScore: stateRef.adherenceScore || 0
|
|
4936
5045
|
};
|
|
4937
|
-
onEvent?.({ type: "plan", todoList: list, ...planData });
|
|
4938
|
-
const traceSession = toolStateRef?.ctx?.__traceSession;
|
|
4939
|
-
recordTraceEvent(traceSession, {
|
|
4940
|
-
type: "plan",
|
|
4941
|
-
label: `Plan ${operation}`,
|
|
4942
|
-
actor: { scope: "agent", name: "manage_todo_list", role: "planner" },
|
|
4943
|
-
sections: [
|
|
4944
|
-
{
|
|
4945
|
-
kind: "summary",
|
|
4946
|
-
label: "Todo List",
|
|
4947
|
-
content: formatTodoListSummary(list)
|
|
4948
|
-
},
|
|
4949
|
-
{
|
|
4950
|
-
kind: "metadata",
|
|
4951
|
-
label: "Plan Metadata",
|
|
4952
|
-
data: planData
|
|
4953
|
-
}
|
|
4954
|
-
],
|
|
4955
|
-
debug: planData
|
|
4956
|
-
});
|
|
4957
|
-
};
|
|
4958
|
-
const currentVersion = stateRef.planVersion || 0;
|
|
4959
|
-
if (operation === "read") {
|
|
4960
|
-
const list = stateRef.todoList || [];
|
|
4961
|
-
emitPlanEvent(list);
|
|
4962
|
-
return list;
|
|
4963
5046
|
}
|
|
4964
|
-
|
|
5047
|
+
const normalizedList = parsed.data.map((item) => normalizeTodoItem(item));
|
|
5048
|
+
const validation = validatePlanInvariants(normalizedList, true);
|
|
5049
|
+
if (!validation.ok) {
|
|
4965
5050
|
return {
|
|
4966
5051
|
status: "error",
|
|
4967
5052
|
operation,
|
|
4968
|
-
error:
|
|
5053
|
+
error: validation.error,
|
|
4969
5054
|
version: currentVersion,
|
|
4970
5055
|
adherenceScore: stateRef.adherenceScore || 0
|
|
4971
5056
|
};
|
|
4972
5057
|
}
|
|
4973
|
-
|
|
5058
|
+
stateRef.todoList = normalizedList;
|
|
5059
|
+
} else if (operation === "update") {
|
|
5060
|
+
const parsed = zod.z.array(todoUpdateItemSchema).safeParse(todoList);
|
|
5061
|
+
if (!parsed.success) {
|
|
4974
5062
|
return {
|
|
4975
5063
|
status: "error",
|
|
4976
5064
|
operation,
|
|
4977
|
-
error: "todoList
|
|
5065
|
+
error: parsed.error.issues[0]?.message || "Invalid todoList for update.",
|
|
4978
5066
|
version: currentVersion,
|
|
4979
5067
|
adherenceScore: stateRef.adherenceScore || 0
|
|
4980
5068
|
};
|
|
4981
5069
|
}
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
if (
|
|
4996
|
-
return {
|
|
4997
|
-
status: "error",
|
|
4998
|
-
operation,
|
|
4999
|
-
error: validation.error,
|
|
5000
|
-
version: currentVersion,
|
|
5001
|
-
adherenceScore: stateRef.adherenceScore || 0
|
|
5002
|
-
};
|
|
5003
|
-
}
|
|
5004
|
-
stateRef.todoList = normalizedList;
|
|
5005
|
-
} else if (operation === "update") {
|
|
5006
|
-
const parsed = zod.z.array(todoUpdateItemSchema).safeParse(todoList);
|
|
5007
|
-
if (!parsed.success) {
|
|
5008
|
-
return {
|
|
5009
|
-
status: "error",
|
|
5010
|
-
operation,
|
|
5011
|
-
error: parsed.error.issues[0]?.message || "Invalid todoList for update.",
|
|
5012
|
-
version: currentVersion,
|
|
5013
|
-
adherenceScore: stateRef.adherenceScore || 0
|
|
5014
|
-
};
|
|
5015
|
-
}
|
|
5016
|
-
const currentList = Array.isArray(stateRef.todoList) ? stateRef.todoList : [];
|
|
5017
|
-
if (currentList.length === 0) {
|
|
5070
|
+
const currentList = Array.isArray(stateRef.todoList) ? stateRef.todoList : [];
|
|
5071
|
+
if (currentList.length === 0) {
|
|
5072
|
+
return {
|
|
5073
|
+
status: "error",
|
|
5074
|
+
operation,
|
|
5075
|
+
error: "No existing plan to update. Use write first.",
|
|
5076
|
+
version: currentVersion,
|
|
5077
|
+
adherenceScore: stateRef.adherenceScore || 0
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
5080
|
+
const currentMap = new Map(currentList.map((item) => [item.id, item]));
|
|
5081
|
+
const patchMap = /* @__PURE__ */ new Map();
|
|
5082
|
+
for (const item of parsed.data) {
|
|
5083
|
+
if (patchMap.has(item.id)) {
|
|
5018
5084
|
return {
|
|
5019
5085
|
status: "error",
|
|
5020
5086
|
operation,
|
|
5021
|
-
error: "
|
|
5087
|
+
error: "Update payload contains duplicate todo ids.",
|
|
5022
5088
|
version: currentVersion,
|
|
5023
5089
|
adherenceScore: stateRef.adherenceScore || 0
|
|
5024
5090
|
};
|
|
5025
5091
|
}
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
for (const item of parsed.data) {
|
|
5029
|
-
if (patchMap.has(item.id)) {
|
|
5030
|
-
return {
|
|
5031
|
-
status: "error",
|
|
5032
|
-
operation,
|
|
5033
|
-
error: "Update payload contains duplicate todo ids.",
|
|
5034
|
-
version: currentVersion,
|
|
5035
|
-
adherenceScore: stateRef.adherenceScore || 0
|
|
5036
|
-
};
|
|
5037
|
-
}
|
|
5038
|
-
patchMap.set(item.id, item);
|
|
5039
|
-
if (!currentMap.has(item.id)) {
|
|
5040
|
-
return {
|
|
5041
|
-
status: "error",
|
|
5042
|
-
operation,
|
|
5043
|
-
error: `Cannot update missing todo id ${item.id}. Use write to replace the plan.`,
|
|
5044
|
-
version: currentVersion,
|
|
5045
|
-
adherenceScore: stateRef.adherenceScore || 0
|
|
5046
|
-
};
|
|
5047
|
-
}
|
|
5048
|
-
}
|
|
5049
|
-
const mergedList = currentList.map((item) => {
|
|
5050
|
-
const patch = patchMap.get(item.id);
|
|
5051
|
-
return patch ? normalizeTodoItem(patch, item) : item;
|
|
5052
|
-
});
|
|
5053
|
-
const validation = validatePlanInvariants(mergedList, false);
|
|
5054
|
-
if (!validation.ok) {
|
|
5092
|
+
patchMap.set(item.id, item);
|
|
5093
|
+
if (!currentMap.has(item.id)) {
|
|
5055
5094
|
return {
|
|
5056
5095
|
status: "error",
|
|
5057
5096
|
operation,
|
|
5058
|
-
error:
|
|
5097
|
+
error: `Cannot update missing todo id ${item.id}. Use write to replace the plan.`,
|
|
5059
5098
|
version: currentVersion,
|
|
5060
5099
|
adherenceScore: stateRef.adherenceScore || 0
|
|
5061
5100
|
};
|
|
5062
5101
|
}
|
|
5063
|
-
stateRef.todoList = mergedList;
|
|
5064
5102
|
}
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5103
|
+
const mergedList = currentList.map((item) => {
|
|
5104
|
+
const patch = patchMap.get(item.id);
|
|
5105
|
+
return patch ? normalizeTodoItem(patch, item) : item;
|
|
5106
|
+
});
|
|
5107
|
+
const validation = validatePlanInvariants(mergedList, false);
|
|
5108
|
+
if (!validation.ok) {
|
|
5109
|
+
return {
|
|
5110
|
+
status: "error",
|
|
5111
|
+
operation,
|
|
5112
|
+
error: validation.error,
|
|
5113
|
+
version: currentVersion,
|
|
5114
|
+
adherenceScore: stateRef.adherenceScore || 0
|
|
5115
|
+
};
|
|
5116
|
+
}
|
|
5117
|
+
stateRef.todoList = mergedList;
|
|
5118
|
+
}
|
|
5119
|
+
stateRef.planVersion = currentVersion + 1;
|
|
5120
|
+
stateRef.adherenceScore = calculateAdherenceScore(stateRef.todoList || []);
|
|
5121
|
+
const payload = {
|
|
5122
|
+
status: "ok",
|
|
5123
|
+
operation,
|
|
5124
|
+
count: Array.isArray(todoList) ? todoList.length : void 0,
|
|
5125
|
+
version: stateRef.planVersion || 1,
|
|
5126
|
+
adherenceScore: stateRef.adherenceScore || 0
|
|
5127
|
+
};
|
|
5128
|
+
emitPlanEvent(stateRef.todoList || []);
|
|
5129
|
+
return payload;
|
|
5130
|
+
}
|
|
5131
|
+
});
|
|
5132
|
+
manageTodo._stateRef = stateRef;
|
|
5133
|
+
return manageTodo;
|
|
5134
|
+
}
|
|
5135
|
+
function createGetToolResponseTool(stateRef) {
|
|
5081
5136
|
const getTool = createTool({
|
|
5082
5137
|
name: "get_tool_response",
|
|
5083
|
-
description: "RETRIEVE the full output of a tool execution whose response was archived, dropped, or later compacted in conversation history.
|
|
5138
|
+
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.",
|
|
5084
5139
|
schema: zod.z.object({ executionId: zod.z.string().describe("Tool execution id or original tool_call_id") }),
|
|
5085
5140
|
maxExecutionsPerRun: 8,
|
|
5086
5141
|
func: async ({ executionId }) => {
|
|
5142
|
+
if (!hasToolResponseRecoveryReference(stateRef.messages, executionId)) {
|
|
5143
|
+
return "Execution not recoverable from the visible transcript. Use this only when the conversation already shows a reduced tool-response marker for that executionId.";
|
|
5144
|
+
}
|
|
5087
5145
|
const matchesExecution = (t) => t?.executionId === executionId || t?.tool_call_id === executionId;
|
|
5088
5146
|
let execution = stateRef.toolHistory?.find((t) => matchesExecution(t));
|
|
5089
5147
|
if (!execution) {
|
|
@@ -5096,7 +5154,16 @@ function createContextTools(stateRef, opts) {
|
|
|
5096
5154
|
}
|
|
5097
5155
|
});
|
|
5098
5156
|
getTool._stateRef = stateRef;
|
|
5099
|
-
|
|
5157
|
+
return getTool;
|
|
5158
|
+
}
|
|
5159
|
+
function createContextTools(stateRef, opts) {
|
|
5160
|
+
const tools = [];
|
|
5161
|
+
if (opts?.planningEnabled) {
|
|
5162
|
+
tools.push(createManageTodoTool(stateRef));
|
|
5163
|
+
}
|
|
5164
|
+
if (opts?.includeGetToolResponse ?? true) {
|
|
5165
|
+
tools.push(createGetToolResponseTool(stateRef));
|
|
5166
|
+
}
|
|
5100
5167
|
return tools;
|
|
5101
5168
|
}
|
|
5102
5169
|
|
|
@@ -5264,9 +5331,11 @@ function createSmartAgent(opts) {
|
|
|
5264
5331
|
useTodoList: planningEnabled
|
|
5265
5332
|
};
|
|
5266
5333
|
const stateRef = { toolHistory: void 0, toolHistoryArchived: void 0, todoList: void 0, planVersion: 0, adherenceScore: 0 };
|
|
5267
|
-
const contextTools = createContextTools(stateRef, { planningEnabled });
|
|
5268
|
-
const
|
|
5269
|
-
const
|
|
5334
|
+
const contextTools = createContextTools(stateRef, { planningEnabled, includeGetToolResponse: false });
|
|
5335
|
+
const getToolResponseTool = createGetToolResponseTool(stateRef);
|
|
5336
|
+
const toolsWithoutRecovery = [...opts.tools ?? [], ...contextTools];
|
|
5337
|
+
const toolsWithRecovery = [...toolsWithoutRecovery, getToolResponseTool];
|
|
5338
|
+
const base = createAgent({ ...runtimeOpts, tools: toolsWithoutRecovery });
|
|
5270
5339
|
base.__runtime.runtimeProfile = resolved.runtimeProfile;
|
|
5271
5340
|
base.__runtime.smart = resolved;
|
|
5272
5341
|
const summarizationEnabled = resolved.summarization.enable !== false;
|
|
@@ -5324,6 +5393,27 @@ function createSmartAgent(opts) {
|
|
|
5324
5393
|
);
|
|
5325
5394
|
return { role: "system", content: sys };
|
|
5326
5395
|
}
|
|
5396
|
+
function syncRuntimeTools(currentState, currentMessages) {
|
|
5397
|
+
const needsRecoveryTool = hasToolResponseRecoveryReference(currentMessages);
|
|
5398
|
+
const nextTools = needsRecoveryTool ? toolsWithRecovery : toolsWithoutRecovery;
|
|
5399
|
+
const currentRuntime = currentState.agent || base.__runtime;
|
|
5400
|
+
if (currentRuntime.tools === nextTools) {
|
|
5401
|
+
return currentState;
|
|
5402
|
+
}
|
|
5403
|
+
return {
|
|
5404
|
+
...currentState,
|
|
5405
|
+
agent: {
|
|
5406
|
+
...currentRuntime,
|
|
5407
|
+
tools: nextTools
|
|
5408
|
+
}
|
|
5409
|
+
};
|
|
5410
|
+
}
|
|
5411
|
+
function producedTerminalAssistantTurn(messages) {
|
|
5412
|
+
const lastAssistant = [...messages].reverse().find((message) => message?.role === "assistant");
|
|
5413
|
+
if (!lastAssistant) return false;
|
|
5414
|
+
const toolCalls = Array.isArray(lastAssistant.tool_calls) ? lastAssistant.tool_calls : [];
|
|
5415
|
+
return toolCalls.length === 0;
|
|
5416
|
+
}
|
|
5327
5417
|
async function trySummarize(currentState, currentRawMessages) {
|
|
5328
5418
|
if (!summarizer) return { state: currentState, rawMessages: currentRawMessages, compressed: false };
|
|
5329
5419
|
const delta = await summarizer(currentState);
|
|
@@ -5345,13 +5435,13 @@ function createSmartAgent(opts) {
|
|
|
5345
5435
|
stateRef.adherenceScore = input.plan?.adherenceScore || 0;
|
|
5346
5436
|
const alreadyHasSystem = Array.isArray(input.messages) && input.messages[0]?.role === "system";
|
|
5347
5437
|
const seedMessages = alreadyHasSystem ? [...input.messages || []] : [systemMessage2(), ...input.messages || []];
|
|
5348
|
-
let state = await syncMemory({ ...input, messages: seedMessages });
|
|
5438
|
+
let state = syncRuntimeTools(await syncMemory({ ...input, messages: seedMessages }), seedMessages);
|
|
5349
5439
|
let lastResult = null;
|
|
5350
5440
|
let rawMessages = [...seedMessages];
|
|
5351
5441
|
const effectiveMaxToolCalls = config?.limits?.maxToolCalls ?? resolved.limits.maxToolCalls ?? 10;
|
|
5352
5442
|
const iterationLimit = Math.max(effectiveMaxToolCalls * 3 + 5, 30);
|
|
5353
5443
|
for (let i = 0; i < iterationLimit; i++) {
|
|
5354
|
-
state = { ...state, messages: rawMessages };
|
|
5444
|
+
state = syncRuntimeTools({ ...state, messages: rawMessages }, rawMessages);
|
|
5355
5445
|
const next = summarizationEnabled ? decideBefore(state) : "agent";
|
|
5356
5446
|
if (next === "contextSummarize" && summarizer) {
|
|
5357
5447
|
const result = await trySummarize(state, rawMessages);
|
|
@@ -5378,7 +5468,7 @@ function createSmartAgent(opts) {
|
|
|
5378
5468
|
if (currentPlan && !state.plan) {
|
|
5379
5469
|
state = { ...state, plan: currentPlan };
|
|
5380
5470
|
}
|
|
5381
|
-
state = syncPlanState(await syncMemory(state));
|
|
5471
|
+
state = syncRuntimeTools(syncPlanState(await syncMemory(state)), rawMessages);
|
|
5382
5472
|
stateRef.toolHistory = state.toolHistory;
|
|
5383
5473
|
stateRef.toolHistoryArchived = state.toolHistoryArchived;
|
|
5384
5474
|
if (state.ctx?.__needsSummarization && summarizer) {
|
|
@@ -5392,6 +5482,7 @@ function createSmartAgent(opts) {
|
|
|
5392
5482
|
}
|
|
5393
5483
|
if (state.ctx?.__finalizedDueToStructuredOutput) break;
|
|
5394
5484
|
if (opts.outputSchema && lastResult?.output != null) break;
|
|
5485
|
+
if (producedTerminalAssistantTurn(appendedMessages)) break;
|
|
5395
5486
|
if (summarizationEnabled) {
|
|
5396
5487
|
const after = decideAfter(state);
|
|
5397
5488
|
if (after === "contextSummarize" && summarizer) {
|
|
@@ -6040,7 +6131,7 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
6040
6131
|
if (request.tools?.length) {
|
|
6041
6132
|
body.tools = request.tools.map((t) => this.toOpenAITool(t));
|
|
6042
6133
|
}
|
|
6043
|
-
if (request.toolChoice != null) {
|
|
6134
|
+
if (request.toolChoice != null && request.tools?.length) {
|
|
6044
6135
|
if (typeof request.toolChoice === "string") {
|
|
6045
6136
|
body.tool_choice = request.toolChoice;
|
|
6046
6137
|
} else {
|
|
@@ -7321,7 +7412,7 @@ function fromNativeProvider(provider, options) {
|
|
|
7321
7412
|
const reasoningCfg = reasoningOverride ?? opts?.reasoning;
|
|
7322
7413
|
if (reasoningCfg) req.reasoning = reasoningCfg;
|
|
7323
7414
|
const tc = invokeOptions?.tool_choice ?? invokeOptions?.toolChoice;
|
|
7324
|
-
if (tc) {
|
|
7415
|
+
if (tc && tools?.length) {
|
|
7325
7416
|
req.toolChoice = tc;
|
|
7326
7417
|
}
|
|
7327
7418
|
const rf = invokeOptions?.response_format;
|
|
@@ -7691,8 +7782,10 @@ exports.createAgentNode = createAgentNode;
|
|
|
7691
7782
|
exports.createCodeGuardrail = createCodeGuardrail;
|
|
7692
7783
|
exports.createContextSummarizeNode = createContextSummarizeNode;
|
|
7693
7784
|
exports.createContextTools = createContextTools;
|
|
7785
|
+
exports.createGetToolResponseTool = createGetToolResponseTool;
|
|
7694
7786
|
exports.createGuardrail = createGuardrail;
|
|
7695
7787
|
exports.createJsonGuardrail = createJsonGuardrail;
|
|
7788
|
+
exports.createManageTodoTool = createManageTodoTool;
|
|
7696
7789
|
exports.createProvider = createProvider;
|
|
7697
7790
|
exports.createRegexGuardrail = createRegexGuardrail;
|
|
7698
7791
|
exports.createResolverNode = createResolverNode;
|
|
@@ -7714,6 +7807,7 @@ exports.generateTraceId = generateTraceId;
|
|
|
7714
7807
|
exports.getModelCapabilities = getModelCapabilities;
|
|
7715
7808
|
exports.getNestedValue = getNestedValue;
|
|
7716
7809
|
exports.getResolvedSmartConfig = getResolvedSmartConfig;
|
|
7810
|
+
exports.hasToolResponseRecoveryReference = hasToolResponseRecoveryReference;
|
|
7717
7811
|
exports.httpSink = httpSink;
|
|
7718
7812
|
exports.isSmartModel = isSmartModel;
|
|
7719
7813
|
exports.jsonSchemaRule = jsonSchemaRule;
|