@botbotgo/agent-harness 0.0.365 → 0.0.367
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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
2
|
-
export declare const AGENT_HARNESS_RELEASE_DATE = "2026-04-
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.367";
|
|
2
|
+
export declare const AGENT_HARNESS_RELEASE_DATE = "2026-04-30";
|
package/dist/package-version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
2
|
-
export const AGENT_HARNESS_RELEASE_DATE = "2026-04-
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.367";
|
|
2
|
+
export const AGENT_HARNESS_RELEASE_DATE = "2026-04-30";
|
|
@@ -8,6 +8,19 @@ import { appendToolRecoveryInstruction, extractVisibleOutput, tryParseJson } fro
|
|
|
8
8
|
import { salvageJsonToolCalls } from "../../parsing/output-tool-args.js";
|
|
9
9
|
import { isEmptyFinalAiMessageError } from "../resilience.js";
|
|
10
10
|
import { AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, } from "../../prompts/runtime-prompts.js";
|
|
11
|
+
const CLOSE_REQUIRED_PLAN_RECOVERY_INSTRUCTION = [
|
|
12
|
+
"The current required todo board still has unfinished work.",
|
|
13
|
+
"Do not broaden the investigation, restart planning, or ask the user what to do next.",
|
|
14
|
+
"Use the existing tool evidence already available in this run.",
|
|
15
|
+
"Your next action must be write_todos: update every remaining pending or in_progress item to completed if evidence was gathered, or failed if it cannot be completed with the available tools.",
|
|
16
|
+
"After that write_todos call, provide the final answer required by the agent response format.",
|
|
17
|
+
].join("\n");
|
|
18
|
+
const INITIAL_REQUIRED_PLAN_INSTRUCTION = [
|
|
19
|
+
"This agent has a required visible planning contract.",
|
|
20
|
+
"Your first action for this request must be write_todos with concrete task steps and statuses.",
|
|
21
|
+
"Do not call any domain/evidence tool and do not provide a final answer before the initial write_todos call succeeds.",
|
|
22
|
+
"After each evidence step, update the todo board. Before the final answer, close every todo as completed or failed.",
|
|
23
|
+
].join("\n");
|
|
11
24
|
function readBindingExecutionParams(binding) {
|
|
12
25
|
const params = binding.execution?.params ?? binding.deepAgentParams ?? binding.langchainAgentParams;
|
|
13
26
|
return {
|
|
@@ -280,9 +293,13 @@ function appendUserRecoveryInstruction(input, instruction) {
|
|
|
280
293
|
export async function executeRequestInvocation(options) {
|
|
281
294
|
const history = options.history ?? [];
|
|
282
295
|
const invokeOptions = options.invokeOptions ?? {};
|
|
283
|
-
|
|
296
|
+
let request = options.resumePayload === undefined
|
|
284
297
|
? buildInvocationRequest(options.binding, history, options.input, invokeOptions)
|
|
285
298
|
: new Command({ resume: options.resumePayload });
|
|
299
|
+
if (options.resumePayload === undefined
|
|
300
|
+
&& options.binding.harnessRuntime.executionContract?.requiresPlan === true) {
|
|
301
|
+
request = appendToolRecoveryInstruction(request, INITIAL_REQUIRED_PLAN_INSTRUCTION);
|
|
302
|
+
}
|
|
286
303
|
const { primaryTools, toolNameMapping, executableTools, defersToUpstreamHitlExecution, } = buildBindingToolExecutionContext({
|
|
287
304
|
binding: options.binding,
|
|
288
305
|
resolveTools: options.resolveTools,
|
|
@@ -335,7 +352,7 @@ export async function executeRequestInvocation(options) {
|
|
|
335
352
|
? result.messages
|
|
336
353
|
: undefined;
|
|
337
354
|
const recoveryBase = messages ? { messages } : request;
|
|
338
|
-
const recoveredRequest = appendToolRecoveryInstruction(recoveryBase,
|
|
355
|
+
const recoveredRequest = appendToolRecoveryInstruction(recoveryBase, CLOSE_REQUIRED_PLAN_RECOVERY_INSTRUCTION);
|
|
339
356
|
const recoveredInvocation = await invokeOnce(recoveredRequest);
|
|
340
357
|
localOrUpstreamInvocation = recoveredInvocation;
|
|
341
358
|
result = recoveredInvocation.result;
|
|
@@ -343,8 +360,7 @@ export async function executeRequestInvocation(options) {
|
|
|
343
360
|
}
|
|
344
361
|
if (options.resumePayload === undefined
|
|
345
362
|
&& options.binding.harnessRuntime.executionContract?.requiresPlan === true
|
|
346
|
-
&& hasIncompleteUpstreamPlan(result)
|
|
347
|
-
&& !extractVisibleOutput(result).trim()) {
|
|
363
|
+
&& hasIncompleteUpstreamPlan(result)) {
|
|
348
364
|
const messages = Array.isArray(result.messages)
|
|
349
365
|
? result.messages
|
|
350
366
|
: undefined;
|
|
@@ -164,6 +164,11 @@ function hasDelegatedPlanEvidence(result) {
|
|
|
164
164
|
return Array.isArray(toolResults)
|
|
165
165
|
&& toolResults.some((item) => item.toolName === "write_todos" || item.toolName === "read_todos");
|
|
166
166
|
}
|
|
167
|
+
const DELEGATED_PLAN_EVIDENCE_RETRY_INSTRUCTION = [
|
|
168
|
+
"The delegated task requires visible TODO planning evidence.",
|
|
169
|
+
"Before any other tool call or final answer, call write_todos with concrete task steps and statuses.",
|
|
170
|
+
"Then continue the task to completion, update TODO statuses after evidence steps, and close every TODO as completed or failed before the final answer.",
|
|
171
|
+
].join("\n");
|
|
167
172
|
function resolveDelegatedResultOutput(result) {
|
|
168
173
|
const executedToolResults = Array.isArray(result.metadata?.executedToolResults)
|
|
169
174
|
? result.metadata.executedToolResults
|
|
@@ -936,21 +941,62 @@ export class AgentRuntimeAdapter {
|
|
|
936
941
|
delegatedResult = await runDelegatedRequest(requestText);
|
|
937
942
|
}
|
|
938
943
|
catch (error) {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
944
|
+
if (selectedBinding.harnessRuntime.executionContract?.requiresPlan === true) {
|
|
945
|
+
try {
|
|
946
|
+
delegatedResult = await runDelegatedRequest([requestText, DELEGATED_PLAN_EVIDENCE_RETRY_INSTRUCTION].filter(Boolean).join("\n\n"), ":plan-evidence-retry");
|
|
947
|
+
}
|
|
948
|
+
catch (recoveryError) {
|
|
949
|
+
const output = recoveryError instanceof Error ? recoveryError.message : String(recoveryError);
|
|
950
|
+
return {
|
|
951
|
+
toolOutput: output,
|
|
952
|
+
delegatedSubagentType: subagentType,
|
|
953
|
+
delegatedResult: {
|
|
954
|
+
sessionId,
|
|
955
|
+
requestId,
|
|
956
|
+
agentId: selectedBinding.agent.id,
|
|
957
|
+
state: "failed",
|
|
958
|
+
output,
|
|
959
|
+
finalMessageText: output,
|
|
960
|
+
},
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
else {
|
|
965
|
+
const output = error instanceof Error ? error.message : String(error);
|
|
966
|
+
return {
|
|
967
|
+
toolOutput: output,
|
|
968
|
+
delegatedSubagentType: subagentType,
|
|
969
|
+
delegatedResult: {
|
|
970
|
+
sessionId,
|
|
971
|
+
requestId,
|
|
972
|
+
agentId: selectedBinding.agent.id,
|
|
973
|
+
state: "failed",
|
|
974
|
+
output,
|
|
975
|
+
finalMessageText: output,
|
|
976
|
+
},
|
|
977
|
+
};
|
|
978
|
+
}
|
|
952
979
|
}
|
|
953
980
|
const targetRequiresExecutionToolEvidence = getBindingPrimaryTools(selectedBinding).length > 0;
|
|
981
|
+
if (selectedBinding.harnessRuntime.executionContract?.requiresPlan === true
|
|
982
|
+
&& !hasDelegatedPlanEvidence(delegatedResult)) {
|
|
983
|
+
try {
|
|
984
|
+
delegatedResult = await runDelegatedRequest([requestText, DELEGATED_PLAN_EVIDENCE_RETRY_INSTRUCTION].filter(Boolean).join("\n\n"), ":plan-evidence-retry");
|
|
985
|
+
}
|
|
986
|
+
catch (error) {
|
|
987
|
+
const output = error instanceof Error ? error.message : String(error);
|
|
988
|
+
return {
|
|
989
|
+
toolOutput: output,
|
|
990
|
+
delegatedSubagentType: subagentType,
|
|
991
|
+
delegatedResult: {
|
|
992
|
+
...delegatedResult,
|
|
993
|
+
state: "failed",
|
|
994
|
+
output,
|
|
995
|
+
finalMessageText: output,
|
|
996
|
+
},
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
}
|
|
954
1000
|
if (targetRequiresExecutionToolEvidence && !hasDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
955
1001
|
try {
|
|
956
1002
|
delegatedResult = await runDelegatedRequest([requestText, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION].filter(Boolean).join("\n\n"), ":tool-evidence-retry");
|
|
@@ -969,8 +1015,9 @@ export class AgentRuntimeAdapter {
|
|
|
969
1015
|
};
|
|
970
1016
|
}
|
|
971
1017
|
}
|
|
972
|
-
if (
|
|
973
|
-
|
|
1018
|
+
if (selectedBinding.harnessRuntime.executionContract?.requiresPlan === true
|
|
1019
|
+
&& !hasDelegatedPlanEvidence(delegatedResult)) {
|
|
1020
|
+
const output = "runtime_error=Delegated agent ended before producing required plan evidence.";
|
|
974
1021
|
return {
|
|
975
1022
|
toolOutput: output,
|
|
976
1023
|
delegatedSubagentType: subagentType,
|
|
@@ -982,10 +1029,8 @@ export class AgentRuntimeAdapter {
|
|
|
982
1029
|
},
|
|
983
1030
|
};
|
|
984
1031
|
}
|
|
985
|
-
if (
|
|
986
|
-
|
|
987
|
-
&& !hasDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
988
|
-
const output = "runtime_error=Delegated agent ended before producing required plan evidence.";
|
|
1032
|
+
if (targetRequiresExecutionToolEvidence && !hasDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1033
|
+
const output = `runtime_error=Delegated agent ${selectedBinding.agent.id} completed without tool execution evidence.`;
|
|
989
1034
|
return {
|
|
990
1035
|
toolOutput: output,
|
|
991
1036
|
delegatedSubagentType: subagentType,
|
|
@@ -1008,12 +1053,66 @@ export class AgentRuntimeAdapter {
|
|
|
1008
1053
|
const delegatedOutput = typeof compactDelegation.toolOutput === "string"
|
|
1009
1054
|
? [compactDelegation.toolOutput]
|
|
1010
1055
|
: [];
|
|
1056
|
+
const delegatedPayload = (() => {
|
|
1057
|
+
if (delegatedOutput.length === 0) {
|
|
1058
|
+
return undefined;
|
|
1059
|
+
}
|
|
1060
|
+
try {
|
|
1061
|
+
const parsed = JSON.parse(delegatedOutput[0]);
|
|
1062
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
1063
|
+
? parsed
|
|
1064
|
+
: undefined;
|
|
1065
|
+
}
|
|
1066
|
+
catch {
|
|
1067
|
+
return undefined;
|
|
1068
|
+
}
|
|
1069
|
+
})();
|
|
1070
|
+
const payloadStringArray = (key) => {
|
|
1071
|
+
const value = delegatedPayload?.[key];
|
|
1072
|
+
if (!Array.isArray(value)) {
|
|
1073
|
+
return undefined;
|
|
1074
|
+
}
|
|
1075
|
+
const items = value.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
1076
|
+
return items.length > 0 ? items : undefined;
|
|
1077
|
+
};
|
|
1078
|
+
const payloadReport = typeof delegatedPayload?.report === "string" && delegatedPayload.report.trim().length > 0
|
|
1079
|
+
? delegatedPayload.report
|
|
1080
|
+
: undefined;
|
|
1011
1081
|
const delegatedToolNames = Array.isArray(compactDelegation.delegatedResult?.metadata?.executedToolResults)
|
|
1012
1082
|
? compactDelegation.delegatedResult.metadata.executedToolResults
|
|
1013
1083
|
.filter((toolResult) => toolResult?.toolName)
|
|
1014
1084
|
.map((toolResult) => toolResult.toolName)
|
|
1015
1085
|
: [];
|
|
1016
1086
|
const state = compactDelegation.delegatedResult?.state === "failed" ? "failed" : "completed";
|
|
1087
|
+
const uniqueToolNames = [...new Set(delegatedToolNames)];
|
|
1088
|
+
const toolEvidence = uniqueToolNames.length > 0 ? uniqueToolNames.join(", ") : "none";
|
|
1089
|
+
const fallbackTodoTrace = [
|
|
1090
|
+
`1) TODO observed: delegated to ${delegatedSubagentType}.`,
|
|
1091
|
+
uniqueToolNames.includes("write_todos")
|
|
1092
|
+
? "2) TODO evidence: delegated specialist invoked write_todos."
|
|
1093
|
+
: "2) TODO evidence missing: delegated specialist did not expose write_todos in returned metadata.",
|
|
1094
|
+
state === "failed"
|
|
1095
|
+
? "3) TODO closed: delegated execution failed; blocker reported."
|
|
1096
|
+
: "3) TODO closed: delegated execution completed; synthesis returned.",
|
|
1097
|
+
];
|
|
1098
|
+
const fallbackStepResults = [
|
|
1099
|
+
`1) Delegation step: task invoked ${delegatedSubagentType}.`,
|
|
1100
|
+
`2) Evidence step: delegated tool evidence = ${toolEvidence}.`,
|
|
1101
|
+
state === "failed"
|
|
1102
|
+
? "3) Synthesis step: returned blocker report because delegated execution failed."
|
|
1103
|
+
: "3) Synthesis step: compact delegation report assembled from delegated output.",
|
|
1104
|
+
];
|
|
1105
|
+
const fallbackSummary = [
|
|
1106
|
+
state === "failed"
|
|
1107
|
+
? `子代理 ${delegatedSubagentType} 委托执行失败。`
|
|
1108
|
+
: `已完成子代理 ${delegatedSubagentType} 委托执行。`,
|
|
1109
|
+
];
|
|
1110
|
+
const fallbackFindings = payloadReport
|
|
1111
|
+
? ["子代理返回了结构化报告,详见 report。"]
|
|
1112
|
+
: delegatedOutput.length > 0
|
|
1113
|
+
? delegatedOutput.slice(0, 3)
|
|
1114
|
+
: ["none"];
|
|
1115
|
+
const report = payloadReport ?? (delegatedOutput.join("\n") || "委托已完成,未返回附加报告。");
|
|
1017
1116
|
return {
|
|
1018
1117
|
status: state,
|
|
1019
1118
|
routing: [
|
|
@@ -1026,18 +1125,18 @@ export class AgentRuntimeAdapter {
|
|
|
1026
1125
|
],
|
|
1027
1126
|
execution: [
|
|
1028
1127
|
`1) 调用 task 工具,目标子代理:${delegatedSubagentType}`,
|
|
1029
|
-
|
|
1030
|
-
? `2) 子代理返回工具证据:${
|
|
1128
|
+
uniqueToolNames.length > 0
|
|
1129
|
+
? `2) 子代理返回工具证据:${toolEvidence}`
|
|
1031
1130
|
: "2) 子代理返回文本结果。",
|
|
1032
1131
|
"3) 产出主编排汇总并返回结构化结果。",
|
|
1033
1132
|
],
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
findings:
|
|
1133
|
+
todoTrace: payloadStringArray("todoTrace") ?? fallbackTodoTrace,
|
|
1134
|
+
stepResults: payloadStringArray("stepResults") ?? fallbackStepResults,
|
|
1135
|
+
summary: payloadStringArray("summary") ?? fallbackSummary,
|
|
1136
|
+
findings: payloadStringArray("findings") ?? fallbackFindings,
|
|
1038
1137
|
blockers: state === "failed" ? ["子代理执行未能完成。"] : ["none"],
|
|
1039
1138
|
nextActions: ["如需更深入,可继续追问该次委托的细节。"],
|
|
1040
|
-
report
|
|
1139
|
+
report,
|
|
1041
1140
|
};
|
|
1042
1141
|
}
|
|
1043
1142
|
async *stream(binding, input, sessionId, history = [], options = {}) {
|