@botbotgo/agent-harness 0.0.453 → 0.0.455
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.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.455";
|
|
2
2
|
export declare const AGENT_HARNESS_RELEASE_DATE = "2026-05-04";
|
package/dist/package-version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.455";
|
|
2
2
|
export const AGENT_HARNESS_RELEASE_DATE = "2026-05-04";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AIMessage, HumanMessage
|
|
1
|
+
import { AIMessage, HumanMessage } from "@langchain/core/messages";
|
|
2
2
|
import { createMemoryMiddleware, createFilesystemMiddleware, createPatchToolCallsMiddleware, createSkillsMiddleware, createSubAgentMiddleware, createSummarizationMiddleware, StateBackend, } from "deepagents";
|
|
3
3
|
import { createAgent, humanInTheLoopMiddleware, todoListMiddleware } from "langchain";
|
|
4
4
|
import { createBuiltinMiddlewareTools } from "./tool/builtin-middleware-tools.js";
|
|
@@ -9,7 +9,7 @@ import { resolveDeclaredMiddleware } from "./tool/declared-middleware.js";
|
|
|
9
9
|
import { UPSTREAM_SESSION_CONFIG_KEY } from "./upstream-configurable-keys.js";
|
|
10
10
|
import { bindingHasLangChainSubagentSupport, bindingHasMiddlewareKind, getBindingBuiltinToolsConfig, getBindingExecutionKind, getBindingGeneralPurposeAgent, getBindingDeepAgentSubagents, getBindingInterruptCompatibilityRules, getBindingMiddlewareConfigs, getBindingMemorySources, getBindingPrimaryModel, getBindingPrimaryTools, getBindingSkills, getBindingSubagents, getBindingTaskDescription, isDeepAgentBinding, isLangChainBinding, } from "../support/compiled-binding.js";
|
|
11
11
|
import { materializeDeepAgentSkillSourcePaths } from "./compat/deepagent-compat.js";
|
|
12
|
-
import { DEFAULT_SUBAGENT_PROMPT
|
|
12
|
+
import { DEFAULT_SUBAGENT_PROMPT } from "../prompts/runtime-prompts.js";
|
|
13
13
|
import { createContextHygieneMiddleware } from "./middleware/context-hygiene.js";
|
|
14
14
|
const INVALID_TOOL_MESSAGE_BLOCK_TYPES = new Set(["tool_use", "thinking", "redacted_thinking"]);
|
|
15
15
|
const DEFAULT_BUILTIN_TASK_TIMEOUT_MS = 180_000;
|
|
@@ -58,364 +58,6 @@ function extractDeepAgentTaskContent(result) {
|
|
|
58
58
|
}
|
|
59
59
|
return undefined;
|
|
60
60
|
}
|
|
61
|
-
function readMessageType(message) {
|
|
62
|
-
if (typeof message !== "object" || message === null) {
|
|
63
|
-
return "";
|
|
64
|
-
}
|
|
65
|
-
if (typeof message._getType === "function") {
|
|
66
|
-
const typeName = message._getType();
|
|
67
|
-
return typeof typeName === "string" ? typeName : "";
|
|
68
|
-
}
|
|
69
|
-
const typed = message;
|
|
70
|
-
if (typeof typed.type === "string") {
|
|
71
|
-
return typed.type;
|
|
72
|
-
}
|
|
73
|
-
const kwargs = typeof typed.kwargs === "object" && typed.kwargs !== null
|
|
74
|
-
? typed.kwargs
|
|
75
|
-
: undefined;
|
|
76
|
-
if (typeof kwargs?.type === "string") {
|
|
77
|
-
return kwargs.type;
|
|
78
|
-
}
|
|
79
|
-
const lcKwargs = typeof typed.lc_kwargs === "object" && typed.lc_kwargs !== null
|
|
80
|
-
? typed.lc_kwargs
|
|
81
|
-
: undefined;
|
|
82
|
-
return typeof lcKwargs?.type === "string" ? lcKwargs.type : "";
|
|
83
|
-
}
|
|
84
|
-
function readMessageName(message) {
|
|
85
|
-
if (typeof message !== "object" || message === null) {
|
|
86
|
-
return "";
|
|
87
|
-
}
|
|
88
|
-
const typed = message;
|
|
89
|
-
if (typeof typed.name === "string") {
|
|
90
|
-
return typed.name;
|
|
91
|
-
}
|
|
92
|
-
const kwargs = typeof typed.kwargs === "object" && typed.kwargs !== null
|
|
93
|
-
? typed.kwargs
|
|
94
|
-
: undefined;
|
|
95
|
-
if (typeof kwargs?.name === "string") {
|
|
96
|
-
return kwargs.name;
|
|
97
|
-
}
|
|
98
|
-
const lcKwargs = typeof typed.lc_kwargs === "object" && typed.lc_kwargs !== null
|
|
99
|
-
? typed.lc_kwargs
|
|
100
|
-
: undefined;
|
|
101
|
-
return typeof lcKwargs?.name === "string" ? lcKwargs.name : "";
|
|
102
|
-
}
|
|
103
|
-
function readMessages(result) {
|
|
104
|
-
if (typeof result !== "object" || result === null) {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
const messages = result.messages;
|
|
108
|
-
return Array.isArray(messages) ? messages : [];
|
|
109
|
-
}
|
|
110
|
-
function readToolNames(tools) {
|
|
111
|
-
if (!Array.isArray(tools)) {
|
|
112
|
-
return new Set();
|
|
113
|
-
}
|
|
114
|
-
return new Set(tools
|
|
115
|
-
.map((tool) => {
|
|
116
|
-
if (typeof tool !== "object" || tool === null) {
|
|
117
|
-
return "";
|
|
118
|
-
}
|
|
119
|
-
const name = tool.name;
|
|
120
|
-
return typeof name === "string" ? name : "";
|
|
121
|
-
})
|
|
122
|
-
.filter((name) => name.length > 0));
|
|
123
|
-
}
|
|
124
|
-
function readResolvedEvidenceTools(tools) {
|
|
125
|
-
if (!Array.isArray(tools)) {
|
|
126
|
-
return [];
|
|
127
|
-
}
|
|
128
|
-
return tools
|
|
129
|
-
.map((tool) => {
|
|
130
|
-
if (typeof tool !== "object" || tool === null) {
|
|
131
|
-
return undefined;
|
|
132
|
-
}
|
|
133
|
-
const typed = tool;
|
|
134
|
-
if (typeof typed.name !== "string" || typed.name.trim().length === 0) {
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
const handler = [typed.invoke, typed.call, typed.func]
|
|
138
|
-
.find((candidate) => typeof candidate === "function");
|
|
139
|
-
return {
|
|
140
|
-
name: typed.name,
|
|
141
|
-
...(typeof typed.description === "string" ? { description: typed.description } : {}),
|
|
142
|
-
schema: typed.schema,
|
|
143
|
-
...(handler ? { invoke: (input, config) => handler.call(tool, input, config) } : {}),
|
|
144
|
-
};
|
|
145
|
-
})
|
|
146
|
-
.filter((tool) => tool !== undefined);
|
|
147
|
-
}
|
|
148
|
-
function hasSubagentExecutionToolEvidence(result, resolvedTools, configuredTools) {
|
|
149
|
-
const requiredToolNames = new Set([
|
|
150
|
-
...readToolNames(configuredTools),
|
|
151
|
-
...readToolNames(resolvedTools),
|
|
152
|
-
]);
|
|
153
|
-
if (requiredToolNames.size === 0) {
|
|
154
|
-
return true;
|
|
155
|
-
}
|
|
156
|
-
for (const message of readMessages(result)) {
|
|
157
|
-
const typeName = readMessageType(message);
|
|
158
|
-
if (typeName !== "tool" && typeName !== "ToolMessage") {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
const name = readMessageName(message);
|
|
162
|
-
if (name === "write_todos" || name === "read_todos") {
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
if (requiredToolNames.has(name)) {
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
function stringifyTaskState(value) {
|
|
172
|
-
try {
|
|
173
|
-
return JSON.stringify(value);
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
return String(value ?? "");
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function extractUrls(value) {
|
|
180
|
-
return [...new Set((value.match(/https?:\/\/[^\s<>"')\]}]+/giu) ?? [])
|
|
181
|
-
.map((url) => url.replace(/[.,;:!?]+$/u, "")))];
|
|
182
|
-
}
|
|
183
|
-
function readSchemaObjectShape(schema) {
|
|
184
|
-
if (!isRecord(schema)) {
|
|
185
|
-
return undefined;
|
|
186
|
-
}
|
|
187
|
-
if (isRecord(schema.properties)) {
|
|
188
|
-
return schema.properties;
|
|
189
|
-
}
|
|
190
|
-
const candidates = [
|
|
191
|
-
schema._def?.shape,
|
|
192
|
-
schema._zod?.def?.shape,
|
|
193
|
-
schema.def?.shape,
|
|
194
|
-
];
|
|
195
|
-
for (const candidate of candidates) {
|
|
196
|
-
const shape = typeof candidate === "function" ? candidate() : candidate;
|
|
197
|
-
if (isRecord(shape)) {
|
|
198
|
-
return shape;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return undefined;
|
|
202
|
-
}
|
|
203
|
-
function buildUrlSourceArgs(urls) {
|
|
204
|
-
return urls.map((url) => ({ type: "url", url, timeoutMs: 30000 }));
|
|
205
|
-
}
|
|
206
|
-
function buildEvidenceToolArgs(tool, taskText, evidenceText = taskText) {
|
|
207
|
-
const urls = extractUrls(evidenceText);
|
|
208
|
-
if (urls.length === 0) {
|
|
209
|
-
return {};
|
|
210
|
-
}
|
|
211
|
-
const shape = readSchemaObjectShape(tool.schema);
|
|
212
|
-
if (!shape) {
|
|
213
|
-
return {};
|
|
214
|
-
}
|
|
215
|
-
const args = {};
|
|
216
|
-
if ("sources" in shape) {
|
|
217
|
-
args.sources = buildUrlSourceArgs(urls);
|
|
218
|
-
}
|
|
219
|
-
if ("url" in shape) {
|
|
220
|
-
args.url = urls[0];
|
|
221
|
-
}
|
|
222
|
-
if ("urls" in shape) {
|
|
223
|
-
args.urls = urls;
|
|
224
|
-
}
|
|
225
|
-
if ("question" in shape) {
|
|
226
|
-
args.question = taskText.trim() || evidenceText.trim();
|
|
227
|
-
}
|
|
228
|
-
return args;
|
|
229
|
-
}
|
|
230
|
-
function escapeRegExp(value) {
|
|
231
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
232
|
-
}
|
|
233
|
-
function textExplicitlyNamesTool(text, toolName) {
|
|
234
|
-
const name = toolName.trim();
|
|
235
|
-
if (!name) {
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
const pattern = new RegExp(`(?:^|[^\\p{L}\\p{N}_-])${escapeRegExp(name)}(?:$|[^\\p{L}\\p{N}_-])`, "iu");
|
|
239
|
-
return pattern.test(text);
|
|
240
|
-
}
|
|
241
|
-
function resolveCommittedEvidenceTools(input) {
|
|
242
|
-
const availableTools = readResolvedEvidenceTools(input.resolvedTools)
|
|
243
|
-
.filter((tool) => tool.name !== "write_todos" && tool.name !== "read_todos" && typeof tool.invoke === "function");
|
|
244
|
-
if (availableTools.length === 0) {
|
|
245
|
-
return [];
|
|
246
|
-
}
|
|
247
|
-
const stateText = `${input.taskText}\n${stringifyTaskState(readMessages(input.result))}`;
|
|
248
|
-
const selected = [];
|
|
249
|
-
for (const tool of availableTools) {
|
|
250
|
-
if (!textExplicitlyNamesTool(stateText, tool.name)) {
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
selected.push({
|
|
254
|
-
tool,
|
|
255
|
-
args: buildEvidenceToolArgs(tool, input.taskText, stateText),
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
if (selected.length > 0) {
|
|
259
|
-
return selected.slice(0, 3);
|
|
260
|
-
}
|
|
261
|
-
return [];
|
|
262
|
-
}
|
|
263
|
-
async function appendCommittedEvidenceToolResults(input) {
|
|
264
|
-
const toolCalls = resolveCommittedEvidenceTools({
|
|
265
|
-
result: input.result,
|
|
266
|
-
taskText: input.taskText,
|
|
267
|
-
resolvedTools: input.resolvedTools,
|
|
268
|
-
});
|
|
269
|
-
if (process.env.AGENT_HARNESS_PROMPTED_JSON_DEBUG === "1") {
|
|
270
|
-
console.error(JSON.stringify({
|
|
271
|
-
type: "builtin-task-committed-evidence",
|
|
272
|
-
selectedTools: toolCalls.map((item) => item.tool.name),
|
|
273
|
-
availableTools: readResolvedEvidenceTools(input.resolvedTools).map((tool) => ({
|
|
274
|
-
name: tool.name,
|
|
275
|
-
hasInvoke: typeof tool.invoke === "function",
|
|
276
|
-
})),
|
|
277
|
-
}));
|
|
278
|
-
}
|
|
279
|
-
if (toolCalls.length === 0) {
|
|
280
|
-
return input.result;
|
|
281
|
-
}
|
|
282
|
-
const messages = [...readMessages(input.result)];
|
|
283
|
-
for (const [index, item] of toolCalls.entries()) {
|
|
284
|
-
const toolCallId = `committed-evidence-${item.tool.name}-${index + 1}`;
|
|
285
|
-
messages.push(new AIMessage({
|
|
286
|
-
content: "",
|
|
287
|
-
tool_calls: [{
|
|
288
|
-
id: toolCallId,
|
|
289
|
-
name: item.tool.name,
|
|
290
|
-
args: item.args,
|
|
291
|
-
type: "tool_call",
|
|
292
|
-
}],
|
|
293
|
-
}));
|
|
294
|
-
try {
|
|
295
|
-
const output = await item.tool.invoke(item.args, input.invokeConfig);
|
|
296
|
-
messages.push(new ToolMessage({
|
|
297
|
-
name: item.tool.name,
|
|
298
|
-
tool_call_id: toolCallId,
|
|
299
|
-
content: stringifyVisibleTaskContent(output) || stringifyTaskState(output),
|
|
300
|
-
}));
|
|
301
|
-
}
|
|
302
|
-
catch (error) {
|
|
303
|
-
messages.push(new ToolMessage({
|
|
304
|
-
name: item.tool.name,
|
|
305
|
-
tool_call_id: toolCallId,
|
|
306
|
-
content: error instanceof Error ? error.message : String(error),
|
|
307
|
-
}));
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
return {
|
|
311
|
-
...(typeof input.result === "object" && input.result !== null ? input.result : {}),
|
|
312
|
-
messages,
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
function hasFinalAssistantAfterExecutionTool(result) {
|
|
316
|
-
const messages = readMessages(result);
|
|
317
|
-
const lastMessage = messages.at(-1);
|
|
318
|
-
const lastTypeName = readMessageType(lastMessage);
|
|
319
|
-
if (lastTypeName === "tool" || lastTypeName === "ToolMessage") {
|
|
320
|
-
return false;
|
|
321
|
-
}
|
|
322
|
-
let sawExecutionTool = false;
|
|
323
|
-
for (const message of messages) {
|
|
324
|
-
const typeName = readMessageType(message);
|
|
325
|
-
if (typeName === "tool" || typeName === "ToolMessage") {
|
|
326
|
-
const name = readMessageName(message);
|
|
327
|
-
if (name !== "write_todos" && name !== "read_todos") {
|
|
328
|
-
sawExecutionTool = true;
|
|
329
|
-
}
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (!sawExecutionTool) {
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
if (typeName === "ai" || typeName === "AIMessage" || typeName === "assistant") {
|
|
336
|
-
const content = typeof message === "object" && message !== null && "content" in message
|
|
337
|
-
? message.content
|
|
338
|
-
: undefined;
|
|
339
|
-
if (typeof content === "string" && content.trim().length > 0) {
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
if (Array.isArray(content) && content.length > 0) {
|
|
343
|
-
return true;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
return false;
|
|
348
|
-
}
|
|
349
|
-
const FINALIZE_AFTER_TOOL_EVIDENCE_INSTRUCTION = [
|
|
350
|
-
"You have already gathered the required non-planning tool evidence.",
|
|
351
|
-
"Now produce the final answer for the delegated task.",
|
|
352
|
-
"Do not return raw command stdout as the final answer.",
|
|
353
|
-
"Do not stop at a tool result.",
|
|
354
|
-
"Update TODO statuses if needed, then return the configured response format with concise findings, blockers, next actions, and report.",
|
|
355
|
-
].join("\n");
|
|
356
|
-
function stringifyVisibleTaskContent(value) {
|
|
357
|
-
if (typeof value === "string") {
|
|
358
|
-
return value;
|
|
359
|
-
}
|
|
360
|
-
if (Array.isArray(value)) {
|
|
361
|
-
return value
|
|
362
|
-
.map((block) => {
|
|
363
|
-
if (typeof block === "string") {
|
|
364
|
-
return block;
|
|
365
|
-
}
|
|
366
|
-
if (isRecord(block) && typeof block.text === "string") {
|
|
367
|
-
return block.text;
|
|
368
|
-
}
|
|
369
|
-
return "";
|
|
370
|
-
})
|
|
371
|
-
.filter(Boolean)
|
|
372
|
-
.join("\n");
|
|
373
|
-
}
|
|
374
|
-
return "";
|
|
375
|
-
}
|
|
376
|
-
function looksLikeRawToolOutput(value) {
|
|
377
|
-
const normalized = value.trim();
|
|
378
|
-
return /^(?:stdout|stderr)\s*:/iu.test(normalized)
|
|
379
|
-
|| /(?:^|\n)\s*(?:stdout|stderr)\s*:/iu.test(normalized)
|
|
380
|
-
|| /(?:^|\n)\s*exitCode\s*:\s*-?\d+\s*$/iu.test(normalized);
|
|
381
|
-
}
|
|
382
|
-
function collectNonPlanningToolNames(result) {
|
|
383
|
-
const names = [];
|
|
384
|
-
for (const message of readMessages(result)) {
|
|
385
|
-
const typeName = readMessageType(message);
|
|
386
|
-
if (typeName !== "tool" && typeName !== "ToolMessage") {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
const name = readMessageName(message);
|
|
390
|
-
if (!name || name === "write_todos" || name === "read_todos") {
|
|
391
|
-
continue;
|
|
392
|
-
}
|
|
393
|
-
if (!names.includes(name)) {
|
|
394
|
-
names.push(name);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
return names;
|
|
398
|
-
}
|
|
399
|
-
function formatDelegatedRawToolEvidenceReport(input) {
|
|
400
|
-
const toolNames = collectNonPlanningToolNames(input.result);
|
|
401
|
-
const excerpt = input.output.trim().slice(0, 4000);
|
|
402
|
-
return JSON.stringify({
|
|
403
|
-
status: "completed",
|
|
404
|
-
routing: [`task delegated to ${input.subagentName}`],
|
|
405
|
-
plan: ["Delegate to specialist", "Collect required tool evidence", "Return synthesized result"],
|
|
406
|
-
execution: [
|
|
407
|
-
`task invoked ${input.subagentName}`,
|
|
408
|
-
`tool evidence: ${toolNames.length > 0 ? toolNames.join(", ") : "non-planning tool"}`,
|
|
409
|
-
],
|
|
410
|
-
todoTrace: ["specialist TODO plan was created and completed"],
|
|
411
|
-
stepResults: [`${input.subagentName} completed delegated tool evidence collection`],
|
|
412
|
-
summary: ["Delegated specialist completed the required evidence tool path."],
|
|
413
|
-
findings: ["The delegated agent ended on raw tool output, so the runtime wrapped that evidence in a structured completion report."],
|
|
414
|
-
blockers: ["none"],
|
|
415
|
-
nextActions: ["Use the captured evidence for final parent synthesis."],
|
|
416
|
-
report: excerpt,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
61
|
export function extractSubagentRequestText(state) {
|
|
420
62
|
if (!isRecord(state)) {
|
|
421
63
|
return "";
|
|
@@ -693,27 +335,7 @@ export async function invokeBuiltinTaskTool(input) {
|
|
|
693
335
|
new HumanMessage({ content }),
|
|
694
336
|
],
|
|
695
337
|
}, invokeConfig), taskTimeoutMs, selectedSubagent.name);
|
|
696
|
-
|
|
697
|
-
if (!hasSubagentExecutionToolEvidence(result, resolvedSubagentTools, selectedCompiledSubagent?.tools)) {
|
|
698
|
-
result = await invokeSubagent([description, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION].filter(Boolean).join("\n\n"));
|
|
699
|
-
if (!hasSubagentExecutionToolEvidence(result, resolvedSubagentTools, selectedCompiledSubagent?.tools)) {
|
|
700
|
-
result = await appendCommittedEvidenceToolResults({
|
|
701
|
-
result,
|
|
702
|
-
taskText: description,
|
|
703
|
-
resolvedTools: resolvedSubagentTools,
|
|
704
|
-
invokeConfig,
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
if (!hasSubagentExecutionToolEvidence(result, resolvedSubagentTools, selectedCompiledSubagent?.tools)) {
|
|
708
|
-
throw new Error(`Delegated agent ${selectedSubagent.name} completed without tool execution evidence: lacked non-planning tool evidence.`);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
if (!hasFinalAssistantAfterExecutionTool(result)
|
|
712
|
-
|| looksLikeRawToolOutput(stringifyVisibleTaskContent(extractDeepAgentTaskContent(result)))
|
|
713
|
-
|| looksLikeRawToolOutput(extractVisibleOutput(result))
|
|
714
|
-
|| looksLikeRawToolOutput(extractToolFallbackContext(result))) {
|
|
715
|
-
result = await invokeSubagent(FINALIZE_AFTER_TOOL_EVIDENCE_INSTRUCTION, readMessages(result));
|
|
716
|
-
}
|
|
338
|
+
const result = await invokeSubagent(description);
|
|
717
339
|
const structuredResponse = typeof result === "object" && result !== null && "structuredResponse" in result
|
|
718
340
|
? result.structuredResponse
|
|
719
341
|
: undefined;
|
|
@@ -721,14 +343,6 @@ export async function invokeBuiltinTaskTool(input) {
|
|
|
721
343
|
return JSON.stringify(structuredResponse);
|
|
722
344
|
}
|
|
723
345
|
const taskContent = extractDeepAgentTaskContent(result);
|
|
724
|
-
const taskContentText = stringifyVisibleTaskContent(taskContent);
|
|
725
|
-
if (looksLikeRawToolOutput(taskContentText)) {
|
|
726
|
-
return formatDelegatedRawToolEvidenceReport({
|
|
727
|
-
subagentName: selectedSubagent.name,
|
|
728
|
-
output: taskContentText,
|
|
729
|
-
result,
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
346
|
if (Array.isArray(taskContent)) {
|
|
733
347
|
const filtered = taskContent.filter((block) => {
|
|
734
348
|
const blockType = typeof block === "object" && block !== null && "type" in block
|
|
@@ -744,24 +358,10 @@ export async function invokeBuiltinTaskTool(input) {
|
|
|
744
358
|
return taskContent;
|
|
745
359
|
}
|
|
746
360
|
const visibleOutput = extractVisibleOutput(result);
|
|
747
|
-
if (looksLikeRawToolOutput(visibleOutput)) {
|
|
748
|
-
return formatDelegatedRawToolEvidenceReport({
|
|
749
|
-
subagentName: selectedSubagent.name,
|
|
750
|
-
output: visibleOutput,
|
|
751
|
-
result,
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
361
|
if (visibleOutput) {
|
|
755
362
|
return visibleOutput;
|
|
756
363
|
}
|
|
757
364
|
const fallbackOutput = extractToolFallbackContext(result);
|
|
758
|
-
if (looksLikeRawToolOutput(fallbackOutput)) {
|
|
759
|
-
return formatDelegatedRawToolEvidenceReport({
|
|
760
|
-
subagentName: selectedSubagent.name,
|
|
761
|
-
output: fallbackOutput,
|
|
762
|
-
result,
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
365
|
return fallbackOutput || "Task completed";
|
|
766
366
|
}
|
|
767
367
|
export async function resolveBuiltinMiddlewareTools(input) {
|
|
@@ -38,60 +38,8 @@ function hasDelegatedExecutionToolEvidence(result) {
|
|
|
38
38
|
return executedToolResults.some((toolResult) => (toolResult.isError !== true
|
|
39
39
|
&& !isPlanToolName(toolResult.toolName)));
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
function collectSuccessfulDelegatedExecutionToolNames(result) {
|
|
45
|
-
const executedToolResults = Array.isArray(result.metadata?.executedToolResults)
|
|
46
|
-
? result.metadata.executedToolResults
|
|
47
|
-
: [];
|
|
48
|
-
return new Set(executedToolResults
|
|
49
|
-
.filter((toolResult) => toolResult.isError !== true && !isPlanToolName(toolResult.toolName))
|
|
50
|
-
.map((toolResult) => normalizeEvidenceToolName(toolResult.toolName))
|
|
51
|
-
.filter((toolName) => toolName.length > 0));
|
|
52
|
-
}
|
|
53
|
-
function textExplicitlyNamesConfiguredTool(text, toolName) {
|
|
54
|
-
const name = toolName.trim();
|
|
55
|
-
if (!name) {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
const pattern = new RegExp(`(?:^|[^\\p{L}\\p{N}_-])${escapeRegExp(name)}(?:$|[^\\p{L}\\p{N}_-])`, "iu");
|
|
59
|
-
return pattern.test(text);
|
|
60
|
-
}
|
|
61
|
-
function resolveExplicitRequestedExecutionToolNames(binding, requestText) {
|
|
62
|
-
const text = requestText.trim();
|
|
63
|
-
if (!text) {
|
|
64
|
-
return [];
|
|
65
|
-
}
|
|
66
|
-
return getBindingPrimaryTools(binding)
|
|
67
|
-
.map((tool) => tool.name)
|
|
68
|
-
.filter((toolName) => typeof toolName === "string" && toolName.trim().length > 0)
|
|
69
|
-
.filter((toolName) => !isPlanToolName(toolName))
|
|
70
|
-
.filter((toolName) => textExplicitlyNamesConfiguredTool(text, toolName));
|
|
71
|
-
}
|
|
72
|
-
function listMissingDelegatedExecutionToolEvidence(result, requiredToolNames = []) {
|
|
73
|
-
if (requiredToolNames.length === 0) {
|
|
74
|
-
return hasDelegatedExecutionToolEvidence(result) ? [] : ["configured non-planning tools"];
|
|
75
|
-
}
|
|
76
|
-
const observed = collectSuccessfulDelegatedExecutionToolNames(result);
|
|
77
|
-
return requiredToolNames.filter((toolName) => !observed.has(normalizeEvidenceToolName(toolName)));
|
|
78
|
-
}
|
|
79
|
-
function hasRequiredDelegatedExecutionToolEvidence(result, requiredToolNames = []) {
|
|
80
|
-
return hasDelegatedExecutionToolEvidence(result)
|
|
81
|
-
&& listMissingDelegatedExecutionToolEvidence(result, requiredToolNames).length === 0;
|
|
82
|
-
}
|
|
83
|
-
function buildExplicitExecutionToolRetryInstruction(missingToolNames) {
|
|
84
|
-
const tools = missingToolNames
|
|
85
|
-
.filter((toolName) => toolName !== "configured non-planning tools")
|
|
86
|
-
.join(", ");
|
|
87
|
-
if (!tools) {
|
|
88
|
-
return "";
|
|
89
|
-
}
|
|
90
|
-
return [
|
|
91
|
-
`The request explicitly named configured evidence tool(s): ${tools}.`,
|
|
92
|
-
"Before the final answer, call every listed non-planning tool that has not already produced a successful tool result.",
|
|
93
|
-
"Do not substitute a different evidence tool for an explicitly named configured tool unless that tool invocation itself fails and the blocker is reported.",
|
|
94
|
-
].join("\n");
|
|
41
|
+
function hasRequiredDelegatedExecutionToolEvidence(result) {
|
|
42
|
+
return hasDelegatedExecutionToolEvidence(result);
|
|
95
43
|
}
|
|
96
44
|
function buildDelegatedPlanEvidenceBlocker(agentId) {
|
|
97
45
|
return JSON.stringify({
|
|
@@ -329,9 +277,6 @@ function buildDelegatedOwnedTaskInstruction(input) {
|
|
|
329
277
|
"Close every TODO as completed or failed before final output.",
|
|
330
278
|
].filter(Boolean).join("\n");
|
|
331
279
|
}
|
|
332
|
-
function escapeRegExp(value) {
|
|
333
|
-
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
334
|
-
}
|
|
335
280
|
function isDelegationOnlyDeepAgentBinding(binding) {
|
|
336
281
|
return isDeepAgentBinding(binding)
|
|
337
282
|
&& getBindingSubagents(binding).length > 0
|
|
@@ -752,15 +697,12 @@ export class AgentRuntimeAdapter {
|
|
|
752
697
|
const runDelegatedRequest = (text, requestSuffix = "") => this.invoke(targetBinding, text, childSessionId, `${childRequestId}${requestSuffix}`, undefined, [], invokeOptions);
|
|
753
698
|
let result = await runDelegatedRequest(requestText);
|
|
754
699
|
const targetRequiresExecutionToolEvidence = getBindingPrimaryTools(targetBinding).length > 0;
|
|
755
|
-
|
|
756
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(result, requiredExecutionToolNames)) {
|
|
757
|
-
const missingToolNames = listMissingDelegatedExecutionToolEvidence(result, requiredExecutionToolNames);
|
|
700
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(result)) {
|
|
758
701
|
result = await runDelegatedRequest([
|
|
759
702
|
requestText,
|
|
760
703
|
EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION,
|
|
761
|
-
buildExplicitExecutionToolRetryInstruction(missingToolNames),
|
|
762
704
|
].filter(Boolean).join("\n\n"), ":tool-evidence-retry");
|
|
763
|
-
if (!hasRequiredDelegatedExecutionToolEvidence(result
|
|
705
|
+
if (!hasRequiredDelegatedExecutionToolEvidence(result)) {
|
|
764
706
|
throw new DelegatedExecutionNoToolEvidenceError(targetBinding.agent.id);
|
|
765
707
|
}
|
|
766
708
|
}
|
|
@@ -1304,7 +1246,6 @@ export class AgentRuntimeAdapter {
|
|
|
1304
1246
|
}
|
|
1305
1247
|
}
|
|
1306
1248
|
const targetRequiresExecutionToolEvidence = getBindingPrimaryTools(selectedBinding).length > 0;
|
|
1307
|
-
const requiredExecutionToolNames = resolveExplicitRequestedExecutionToolNames(selectedBinding, requestText);
|
|
1308
1249
|
if (selectedBinding.harnessRuntime.executionContract?.requiresPlan === true
|
|
1309
1250
|
&& !hasDelegatedPlanEvidence(delegatedResult)) {
|
|
1310
1251
|
try {
|
|
@@ -1324,13 +1265,11 @@ export class AgentRuntimeAdapter {
|
|
|
1324
1265
|
};
|
|
1325
1266
|
}
|
|
1326
1267
|
}
|
|
1327
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult
|
|
1328
|
-
const missingToolNames = listMissingDelegatedExecutionToolEvidence(delegatedResult, requiredExecutionToolNames);
|
|
1268
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1329
1269
|
try {
|
|
1330
1270
|
delegatedResult = await runDelegatedRequest([
|
|
1331
1271
|
requestText,
|
|
1332
1272
|
EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION,
|
|
1333
|
-
buildExplicitExecutionToolRetryInstruction(missingToolNames),
|
|
1334
1273
|
].filter(Boolean).join("\n\n"), ":tool-evidence-retry", selectedBinding.harnessRuntime.executionContract?.requiresPlan === true
|
|
1335
1274
|
? {
|
|
1336
1275
|
suppressInitialRequiredPlanInstruction: true,
|
|
@@ -1366,10 +1305,8 @@ export class AgentRuntimeAdapter {
|
|
|
1366
1305
|
},
|
|
1367
1306
|
};
|
|
1368
1307
|
}
|
|
1369
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult
|
|
1370
|
-
const output = buildDelegatedExecutionEvidenceBlocker(selectedBinding.agent.id,
|
|
1371
|
-
? requiredExecutionToolNames
|
|
1372
|
-
: getBindingPrimaryTools(selectedBinding).map((tool) => tool.name));
|
|
1308
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1309
|
+
const output = buildDelegatedExecutionEvidenceBlocker(selectedBinding.agent.id, getBindingPrimaryTools(selectedBinding).map((tool) => tool.name));
|
|
1373
1310
|
return {
|
|
1374
1311
|
toolOutput: output,
|
|
1375
1312
|
delegatedSubagentType: subagentType,
|
|
@@ -1764,16 +1701,11 @@ export class AgentRuntimeAdapter {
|
|
|
1764
1701
|
delegatedResult = mergeDelegatedResultToolEvidence(yield* runPlannedDelegation(planned.subagentType, [delegatedText, DELEGATED_PLAN_EVIDENCE_RETRY_INSTRUCTION].filter(Boolean).join("\n\n"), ":plan-evidence-retry"), previousDelegatedResult);
|
|
1765
1702
|
}
|
|
1766
1703
|
const targetRequiresExecutionToolEvidence = selectedBinding ? getBindingPrimaryTools(selectedBinding).length > 0 : false;
|
|
1767
|
-
|
|
1768
|
-
? resolveExplicitRequestedExecutionToolNames(selectedBinding, planned.description)
|
|
1769
|
-
: [];
|
|
1770
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult, requiredExecutionToolNames)) {
|
|
1771
|
-
const missingToolNames = listMissingDelegatedExecutionToolEvidence(delegatedResult, requiredExecutionToolNames);
|
|
1704
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1772
1705
|
const previousDelegatedResult = delegatedResult;
|
|
1773
1706
|
delegatedResult = mergeDelegatedResultToolEvidence(yield* runPlannedDelegation(planned.subagentType, [
|
|
1774
1707
|
delegatedText,
|
|
1775
1708
|
EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION,
|
|
1776
|
-
buildExplicitExecutionToolRetryInstruction(missingToolNames),
|
|
1777
1709
|
].filter(Boolean).join("\n\n"), ":tool-evidence-retry"), previousDelegatedResult);
|
|
1778
1710
|
}
|
|
1779
1711
|
if (selectedBinding?.harnessRuntime.executionContract?.requiresPlan === true && !hasDelegatedPlanEvidence(delegatedResult)) {
|
|
@@ -1785,10 +1717,8 @@ export class AgentRuntimeAdapter {
|
|
|
1785
1717
|
finalMessageText: output,
|
|
1786
1718
|
};
|
|
1787
1719
|
}
|
|
1788
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult
|
|
1789
|
-
const output = buildDelegatedExecutionEvidenceBlocker(selectedBinding.agent.id,
|
|
1790
|
-
? requiredExecutionToolNames
|
|
1791
|
-
: getBindingPrimaryTools(selectedBinding).map((tool) => tool.name));
|
|
1720
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1721
|
+
const output = buildDelegatedExecutionEvidenceBlocker(selectedBinding.agent.id, getBindingPrimaryTools(selectedBinding).map((tool) => tool.name));
|
|
1792
1722
|
delegatedResult = {
|
|
1793
1723
|
...delegatedResult,
|
|
1794
1724
|
state: "failed",
|
|
@@ -1981,19 +1911,16 @@ export class AgentRuntimeAdapter {
|
|
|
1981
1911
|
});
|
|
1982
1912
|
let delegatedResult = yield* runDelegatedStreamAttempt(delegatedText);
|
|
1983
1913
|
const targetRequiresExecutionToolEvidence = getBindingPrimaryTools(selectedBinding).length > 0;
|
|
1984
|
-
const requiredExecutionToolNames = resolveExplicitRequestedExecutionToolNames(selectedBinding, requestText);
|
|
1985
1914
|
if (selectedBinding.harnessRuntime.executionContract?.requiresPlan === true
|
|
1986
1915
|
&& !hasDelegatedPlanEvidence(delegatedResult)) {
|
|
1987
1916
|
const previousDelegatedResult = delegatedResult;
|
|
1988
1917
|
delegatedResult = mergeDelegatedResultToolEvidence(yield* runDelegatedStreamAttempt([delegatedText, DELEGATED_PLAN_EVIDENCE_RETRY_INSTRUCTION].filter(Boolean).join("\n\n"), ":plan-evidence-retry"), previousDelegatedResult);
|
|
1989
1918
|
}
|
|
1990
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult
|
|
1991
|
-
const missingToolNames = listMissingDelegatedExecutionToolEvidence(delegatedResult, requiredExecutionToolNames);
|
|
1919
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1992
1920
|
const previousDelegatedResult = delegatedResult;
|
|
1993
1921
|
delegatedResult = mergeDelegatedResultToolEvidence(yield* runDelegatedStreamAttempt([
|
|
1994
1922
|
delegatedText,
|
|
1995
1923
|
EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION,
|
|
1996
|
-
buildExplicitExecutionToolRetryInstruction(missingToolNames),
|
|
1997
1924
|
].filter(Boolean).join("\n\n"), ":tool-evidence-retry"), previousDelegatedResult);
|
|
1998
1925
|
}
|
|
1999
1926
|
if (selectedBinding.harnessRuntime.executionContract?.requiresPlan === true
|
|
@@ -2006,10 +1933,8 @@ export class AgentRuntimeAdapter {
|
|
|
2006
1933
|
finalMessageText: output,
|
|
2007
1934
|
};
|
|
2008
1935
|
}
|
|
2009
|
-
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult
|
|
2010
|
-
const output = buildDelegatedExecutionEvidenceBlocker(selectedBinding.agent.id,
|
|
2011
|
-
? requiredExecutionToolNames
|
|
2012
|
-
: getBindingPrimaryTools(selectedBinding).map((tool) => tool.name));
|
|
1936
|
+
if (targetRequiresExecutionToolEvidence && !hasRequiredDelegatedExecutionToolEvidence(delegatedResult)) {
|
|
1937
|
+
const output = buildDelegatedExecutionEvidenceBlocker(selectedBinding.agent.id, getBindingPrimaryTools(selectedBinding).map((tool) => tool.name));
|
|
2013
1938
|
delegatedResult = {
|
|
2014
1939
|
...delegatedResult,
|
|
2015
1940
|
state: "failed",
|