@botbotgo/agent-harness 0.0.327 → 0.0.328

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.
Files changed (55) hide show
  1. package/dist/cli/main.js +30 -3
  2. package/dist/contracts/runtime-requests.d.ts +1 -2
  3. package/dist/contracts/runtime-scheduling.d.ts +1 -1
  4. package/dist/flow/flow-graph-upstream.js +3 -7
  5. package/dist/package-version.d.ts +1 -1
  6. package/dist/package-version.js +1 -1
  7. package/dist/projections/request-events.js +0 -1
  8. package/dist/resource/isolation.js +51 -10
  9. package/dist/resources/toolkit.mjs +183 -0
  10. package/dist/resources/tools/cancel_request.mjs +1 -1
  11. package/dist/resources/tools/fetch_url.mjs +1 -1
  12. package/dist/resources/tools/http_request.mjs +1 -1
  13. package/dist/resources/tools/inspect_approvals.mjs +1 -1
  14. package/dist/resources/tools/inspect_artifacts.mjs +1 -1
  15. package/dist/resources/tools/inspect_events.mjs +1 -1
  16. package/dist/resources/tools/inspect_requests.mjs +1 -1
  17. package/dist/resources/tools/inspect_sessions.mjs +1 -1
  18. package/dist/resources/tools/list_files.mjs +1 -1
  19. package/dist/resources/tools/read_artifact.mjs +1 -1
  20. package/dist/resources/tools/request_approval.mjs +1 -1
  21. package/dist/resources/tools/run_command.mjs +1 -1
  22. package/dist/resources/tools/schedule_task.mjs +1 -1
  23. package/dist/resources/tools/search_files.mjs +1 -1
  24. package/dist/resources/tools/send_message.mjs +1 -1
  25. package/dist/runtime/adapter/compat/deepagent-compat.d.ts +0 -9
  26. package/dist/runtime/adapter/compat/deepagent-compat.js +0 -22
  27. package/dist/runtime/adapter/flow/stream-runtime.d.ts +4 -0
  28. package/dist/runtime/adapter/flow/stream-runtime.js +239 -8
  29. package/dist/runtime/adapter/local-tool-invocation.js +53 -0
  30. package/dist/runtime/adapter/middleware-assembly.js +174 -29
  31. package/dist/runtime/adapter/runtime-adapter-support.js +1 -2
  32. package/dist/runtime/adapter/stream-event-projection.d.ts +17 -0
  33. package/dist/runtime/adapter/stream-event-projection.js +217 -4
  34. package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +0 -3
  35. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +37 -17
  36. package/dist/runtime/adapter/tool/resolved-tool.js +29 -3
  37. package/dist/runtime/agent-runtime-adapter.d.ts +3 -3
  38. package/dist/runtime/agent-runtime-adapter.js +12 -33
  39. package/dist/runtime/agent-runtime-assembly.d.ts +3 -21
  40. package/dist/runtime/agent-runtime-assembly.js +4 -56
  41. package/dist/runtime/harness/run/inspection.js +21 -5
  42. package/dist/runtime/harness/run/run-operations.js +2 -1
  43. package/dist/runtime/harness/run/stream-run.d.ts +3 -1
  44. package/dist/runtime/harness/run/stream-run.js +205 -29
  45. package/dist/runtime/harness.js +3 -0
  46. package/dist/runtime/parsing/output-content.js +11 -4
  47. package/dist/runtime/parsing/output-recovery.d.ts +3 -0
  48. package/dist/runtime/parsing/output-recovery.js +57 -11
  49. package/dist/runtime/parsing/output-tool-args.d.ts +4 -0
  50. package/dist/runtime/parsing/output-tool-args.js +122 -0
  51. package/dist/runtime/parsing/stream-event-parsing.js +37 -3
  52. package/dist/runtime/support/harness-support.d.ts +1 -0
  53. package/dist/runtime/support/harness-support.js +44 -2
  54. package/dist/tools.js +34 -4
  55. package/package.json +8 -8
@@ -37,7 +37,6 @@ export function summarizeBuiltinWriteTodosArgs(args) {
37
37
  completed: items.filter((item) => item.status === "completed").length,
38
38
  failed: items.filter((item) => item.status === "failed").length,
39
39
  cancelled: items.filter((item) => item.status === "cancelled").length,
40
- blocked: items.filter((item) => item.status === "blocked").length,
41
40
  };
42
41
  return {
43
42
  items,
@@ -56,7 +55,7 @@ export function formatBuiltinTodoSnapshot(snapshot) {
56
55
  return "No todos tracked.";
57
56
  }
58
57
  const lines = [
59
- `Tracked ${snapshot.summary.total} todo item(s): ${snapshot.summary.pending + snapshot.summary.inProgress + snapshot.summary.blocked} pending, ${snapshot.summary.completed} completed.`,
58
+ `Tracked ${snapshot.summary.total} todo item(s): ${snapshot.summary.pending + snapshot.summary.inProgress} pending, ${snapshot.summary.completed} completed.`,
60
59
  ...snapshot.items.map((item, index) => `${index + 1}. [${item.status}] ${item.content}`),
61
60
  ];
62
61
  return truncateLines(lines);
@@ -5,6 +5,21 @@ export type StreamEventProjectionState = {
5
5
  emittedOutput: string;
6
6
  emittedToolError: boolean;
7
7
  emittedToolResult: boolean;
8
+ emittedSuccessfulToolResult: boolean;
9
+ emittedSuccessfulTaskResult: boolean;
10
+ emittedPlaceholderTaskResult: boolean;
11
+ hasFailedTaskDelegation: boolean;
12
+ emittedNonTodoToolResult: boolean;
13
+ emittedSuccessfulNonTodoToolResult: boolean;
14
+ sawDelegatedAgentWithConfiguredTools: boolean;
15
+ emittedDelegatedExecutionToolResult: boolean;
16
+ emittedSuccessfulDelegatedExecutionToolResult: boolean;
17
+ emittedDelegatedTerminalOutput: boolean;
18
+ sawPlanState: boolean;
19
+ hasIncompletePlanState: boolean;
20
+ openTaskDelegations: number;
21
+ openToolCapableTaskDelegations: number;
22
+ taskDelegationHasToolsStack: boolean[];
8
23
  seenTerminalOutputs: Set<string>;
9
24
  };
10
25
  export declare function createStreamEventProjectionState(): StreamEventProjectionState;
@@ -12,6 +27,8 @@ export declare function projectRuntimeStreamEvent(params: {
12
27
  event: unknown;
13
28
  allowVisibleStreamDeltas: boolean;
14
29
  includeStateStreamOutput: boolean;
30
+ rootAgentId?: string;
31
+ countConfiguredToolsForAgentId?: (agentId: string) => number;
15
32
  toolNameMapping: ToolNameMapping;
16
33
  primaryTools: CompiledTool[];
17
34
  state: StreamEventProjectionState;
@@ -6,15 +6,190 @@ export function createStreamEventProjectionState() {
6
6
  emittedOutput: "",
7
7
  emittedToolError: false,
8
8
  emittedToolResult: false,
9
+ emittedSuccessfulToolResult: false,
10
+ emittedSuccessfulTaskResult: false,
11
+ emittedPlaceholderTaskResult: false,
12
+ hasFailedTaskDelegation: false,
13
+ emittedNonTodoToolResult: false,
14
+ emittedSuccessfulNonTodoToolResult: false,
15
+ sawDelegatedAgentWithConfiguredTools: false,
16
+ emittedDelegatedExecutionToolResult: false,
17
+ emittedSuccessfulDelegatedExecutionToolResult: false,
18
+ emittedDelegatedTerminalOutput: false,
19
+ sawPlanState: false,
20
+ hasIncompletePlanState: false,
21
+ openTaskDelegations: 0,
22
+ openToolCapableTaskDelegations: 0,
23
+ taskDelegationHasToolsStack: [],
9
24
  seenTerminalOutputs: new Set(),
10
25
  };
11
26
  }
27
+ function readSummaryCounts(summary) {
28
+ if (typeof summary !== "object" || summary === null) {
29
+ return null;
30
+ }
31
+ const typed = summary;
32
+ const hasAnyCountField = typeof typed.pending === "number"
33
+ || typeof typed.inProgress === "number";
34
+ if (!hasAnyCountField) {
35
+ return null;
36
+ }
37
+ return {
38
+ pending: typeof typed.pending === "number" ? typed.pending : 0,
39
+ inProgress: typeof typed.inProgress === "number" ? typed.inProgress : 0,
40
+ };
41
+ }
42
+ function hasIncompleteTodosArray(value) {
43
+ if (!Array.isArray(value)) {
44
+ return null;
45
+ }
46
+ return value.some((item) => {
47
+ if (typeof item !== "object" || item === null) {
48
+ return false;
49
+ }
50
+ const status = item.status;
51
+ return status === "pending" || status === "in_progress";
52
+ });
53
+ }
54
+ function getPlanStateCompleteness(value) {
55
+ if (typeof value !== "object" || value === null) {
56
+ return null;
57
+ }
58
+ const typed = value;
59
+ const summaryCounts = readSummaryCounts(typed.summary);
60
+ if (summaryCounts) {
61
+ return summaryCounts.pending > 0 || summaryCounts.inProgress > 0;
62
+ }
63
+ if (typeof typed.summary === "object" && typed.summary !== null) {
64
+ const nestedSummary = getPlanStateCompleteness(typed.summary);
65
+ if (nestedSummary !== null) {
66
+ return nestedSummary;
67
+ }
68
+ }
69
+ const directTodos = hasIncompleteTodosArray(typed.todos);
70
+ if (directTodos !== null) {
71
+ return directTodos;
72
+ }
73
+ if (typeof typed.update === "object" && typed.update !== null) {
74
+ const nestedTodos = hasIncompleteTodosArray(typed.update.todos);
75
+ if (nestedTodos !== null) {
76
+ return nestedTodos;
77
+ }
78
+ }
79
+ if (typeof typed.output === "object" && typed.output !== null) {
80
+ const nestedOutput = getPlanStateCompleteness(typed.output);
81
+ if (nestedOutput !== null) {
82
+ return nestedOutput;
83
+ }
84
+ }
85
+ if (typeof typed.data === "object" && typed.data !== null) {
86
+ const nestedData = getPlanStateCompleteness(typed.data);
87
+ if (nestedData !== null) {
88
+ return nestedData;
89
+ }
90
+ }
91
+ return null;
92
+ }
93
+ function parseMaybeJsonString(value) {
94
+ const trimmed = value.trim();
95
+ if (!trimmed || (!trimmed.startsWith("{") && !trimmed.startsWith("["))) {
96
+ return value;
97
+ }
98
+ try {
99
+ return JSON.parse(trimmed);
100
+ }
101
+ catch {
102
+ return value;
103
+ }
104
+ }
105
+ function unwrapPossibleToolInput(value) {
106
+ if (typeof value === "string") {
107
+ return parseMaybeJsonString(value);
108
+ }
109
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
110
+ return value;
111
+ }
112
+ const typed = value;
113
+ if (typed.args !== undefined) {
114
+ return unwrapPossibleToolInput(typed.args);
115
+ }
116
+ if (typed.input !== undefined) {
117
+ return unwrapPossibleToolInput(typed.input);
118
+ }
119
+ return value;
120
+ }
121
+ function readTaskSubagentType(value) {
122
+ const unwrapped = unwrapPossibleToolInput(value);
123
+ if (typeof unwrapped !== "object" || unwrapped === null || Array.isArray(unwrapped)) {
124
+ return null;
125
+ }
126
+ const typed = unwrapped;
127
+ return typeof typed.subagent_type === "string" && typed.subagent_type.trim().length > 0
128
+ ? typed.subagent_type.trim()
129
+ : null;
130
+ }
131
+ function isUpstreamPlaceholderTaskResult(value) {
132
+ if (typeof value === "string") {
133
+ return value.trim() === "Task completed";
134
+ }
135
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
136
+ return false;
137
+ }
138
+ const typed = value;
139
+ const messages = Array.isArray(typed.update?.messages) ? typed.update.messages : [];
140
+ if (messages.length !== 1) {
141
+ return false;
142
+ }
143
+ const message = messages[0];
144
+ return typed.lg_name === "Command"
145
+ && typed.lc_direct_tool_output === true
146
+ && message?.name === "task"
147
+ && message?.type === "tool"
148
+ && typeof message?.tool_call_id === "string"
149
+ && message?.content === "Task completed";
150
+ }
151
+ function updateDelegationState(state, event, countConfiguredToolsForAgentId) {
152
+ if (typeof event !== "object" || event === null) {
153
+ return;
154
+ }
155
+ const typed = event;
156
+ const eventName = typeof typed.event === "string" ? typed.event : "";
157
+ const toolName = typeof typed.name === "string" ? typed.name : "";
158
+ const runType = typeof typed.run_type === "string" ? typed.run_type : "";
159
+ const isTaskStart = toolName === "task" && (eventName === "on_tool_start" || (eventName === "on_chain_start" && runType === "tool"));
160
+ const isTaskEnd = toolName === "task" && (eventName === "on_tool_end" || (eventName === "on_chain_end" && runType === "tool"));
161
+ const isTaskError = toolName === "task" && (eventName === "on_tool_error" || (eventName === "on_chain_error" && runType === "tool"));
162
+ if (isTaskStart) {
163
+ state.openTaskDelegations += 1;
164
+ const delegatedSubagentType = readTaskSubagentType(typed.data?.input);
165
+ const delegatedTaskHasTools = !!delegatedSubagentType
166
+ && !!countConfiguredToolsForAgentId
167
+ && countConfiguredToolsForAgentId(delegatedSubagentType) > 0;
168
+ state.taskDelegationHasToolsStack.push(delegatedTaskHasTools);
169
+ if (delegatedTaskHasTools) {
170
+ state.sawDelegatedAgentWithConfiguredTools = true;
171
+ state.openToolCapableTaskDelegations += 1;
172
+ }
173
+ return;
174
+ }
175
+ if (isTaskEnd || isTaskError) {
176
+ state.openTaskDelegations = Math.max(0, state.openTaskDelegations - 1);
177
+ const delegatedTaskHadTools = state.taskDelegationHasToolsStack.pop() === true;
178
+ if (delegatedTaskHadTools) {
179
+ state.openToolCapableTaskDelegations = Math.max(0, state.openToolCapableTaskDelegations - 1);
180
+ }
181
+ if (isTaskError) {
182
+ state.hasFailedTaskDelegation = true;
183
+ }
184
+ }
185
+ }
12
186
  export function projectRuntimeStreamEvent(params) {
13
- const { event, allowVisibleStreamDeltas, includeStateStreamOutput, toolNameMapping, primaryTools, state, } = params;
187
+ const { event, allowVisibleStreamDeltas, includeStateStreamOutput, rootAgentId, countConfiguredToolsForAgentId, toolNameMapping, primaryTools, state, } = params;
14
188
  const chunks = [{
15
189
  kind: "upstream-event",
16
190
  event: sanitizeRetainedUpstreamEvent(event),
17
191
  }];
192
+ updateDelegationState(state, event, countConfiguredToolsForAgentId);
18
193
  const interruptPayload = extractInterruptPayload(event);
19
194
  if (interruptPayload) {
20
195
  chunks.push({ kind: "interrupt", content: interruptPayload });
@@ -24,7 +199,24 @@ export function projectRuntimeStreamEvent(params) {
24
199
  if (reasoning) {
25
200
  chunks.push({ kind: "reasoning", content: reasoning });
26
201
  }
27
- if (allowVisibleStreamDeltas) {
202
+ const planStateCompleteness = getPlanStateCompleteness(event);
203
+ if (planStateCompleteness !== null) {
204
+ state.sawPlanState = true;
205
+ state.hasIncompletePlanState = planStateCompleteness;
206
+ }
207
+ const eventAgentId = typeof event === "object" && event !== null && typeof event.agentId === "string"
208
+ ? event.agentId.trim()
209
+ : "";
210
+ const isDelegatedAgentEvent = !!rootAgentId && !!eventAgentId && eventAgentId !== rootAgentId;
211
+ if (isDelegatedAgentEvent
212
+ && countConfiguredToolsForAgentId
213
+ && countConfiguredToolsForAgentId(eventAgentId) > 0) {
214
+ state.sawDelegatedAgentWithConfiguredTools = true;
215
+ }
216
+ const isRootVisibleEvent = !rootAgentId || !eventAgentId || eventAgentId === rootAgentId;
217
+ const allowVisibleContent = isRootVisibleEvent && state.openTaskDelegations === 0;
218
+ const allowStreamedVisibleContent = allowVisibleContent && !state.emittedToolResult && !state.emittedToolError;
219
+ if (allowVisibleStreamDeltas && allowStreamedVisibleContent) {
28
220
  const visibleStreamOutput = extractVisibleStreamOutput(event);
29
221
  if (visibleStreamOutput) {
30
222
  const nextOutput = computeIncrementalOutput(state.emittedOutput, visibleStreamOutput);
@@ -34,7 +226,7 @@ export function projectRuntimeStreamEvent(params) {
34
226
  }
35
227
  }
36
228
  }
37
- if (includeStateStreamOutput) {
229
+ if (includeStateStreamOutput && allowVisibleContent) {
38
230
  const stateStreamOutput = extractStateStreamOutput(event);
39
231
  if (stateStreamOutput) {
40
232
  const nextOutput = computeIncrementalOutput(state.emittedOutput, sanitizeVisibleText(stateStreamOutput));
@@ -46,8 +238,23 @@ export function projectRuntimeStreamEvent(params) {
46
238
  }
47
239
  const toolResult = extractToolResult(event);
48
240
  if (toolResult) {
241
+ const isTodoTool = toolResult.toolName === "write_todos" || toolResult.toolName === "read_todos";
242
+ const isSuccessfulTaskResult = toolResult.toolName === "task" && toolResult.isError !== true;
243
+ const isPlaceholderTaskResult = isSuccessfulTaskResult && isUpstreamPlaceholderTaskResult(toolResult.output);
244
+ const isDelegatedExecutionTool = (isDelegatedAgentEvent || state.openToolCapableTaskDelegations > 0)
245
+ && toolResult.toolName !== "write_todos"
246
+ && toolResult.toolName !== "read_todos"
247
+ && toolResult.toolName !== "task";
49
248
  state.emittedToolResult = true;
50
249
  state.emittedToolError = state.emittedToolError || toolResult.isError === true;
250
+ state.emittedSuccessfulToolResult = state.emittedSuccessfulToolResult || toolResult.isError !== true;
251
+ state.emittedSuccessfulTaskResult = state.emittedSuccessfulTaskResult || isSuccessfulTaskResult;
252
+ state.emittedPlaceholderTaskResult = state.emittedPlaceholderTaskResult || isPlaceholderTaskResult;
253
+ state.emittedNonTodoToolResult = state.emittedNonTodoToolResult || !isTodoTool;
254
+ state.emittedSuccessfulNonTodoToolResult = state.emittedSuccessfulNonTodoToolResult || (!isTodoTool && toolResult.isError !== true);
255
+ state.emittedDelegatedExecutionToolResult = state.emittedDelegatedExecutionToolResult || isDelegatedExecutionTool;
256
+ state.emittedSuccessfulDelegatedExecutionToolResult =
257
+ state.emittedSuccessfulDelegatedExecutionToolResult || (isDelegatedExecutionTool && toolResult.isError !== true);
51
258
  chunks.push({
52
259
  kind: "tool-result",
53
260
  toolName: resolveModelFacingToolName(toolResult.toolName, toolNameMapping, primaryTools),
@@ -55,7 +262,13 @@ export function projectRuntimeStreamEvent(params) {
55
262
  isError: toolResult.isError,
56
263
  });
57
264
  }
58
- const output = extractTerminalStreamOutput(event);
265
+ const output = allowVisibleContent ? extractTerminalStreamOutput(event) : "";
266
+ if (!allowVisibleContent) {
267
+ const delegatedTerminalOutput = extractTerminalStreamOutput(event);
268
+ if (delegatedTerminalOutput) {
269
+ state.emittedDelegatedTerminalOutput = true;
270
+ }
271
+ }
59
272
  if (output) {
60
273
  const outputKey = normalizeTerminalOutputKey(output);
61
274
  if (!outputKey || !state.seenTerminalOutputs.has(outputKey)) {
@@ -242,9 +242,6 @@ export declare const BUILTIN_MIDDLEWARE_TOOL_DESCRIPTORS: readonly [{
242
242
  }, {
243
243
  readonly name: "task";
244
244
  readonly description: "Delegate a bounded task to a subagent.";
245
- }, {
246
- readonly name: "delegate_task";
247
- readonly description: "Delegate a bounded task to a subagent.";
248
245
  }];
249
246
  export declare function createBuiltinMiddlewareTools(backend: BuiltinMiddlewareBackend, options: {
250
247
  includeTaskTool: boolean;
@@ -4,6 +4,28 @@ import { isSandboxBackend } from "deepagents";
4
4
  import { isRecord } from "../../../utils/object.js";
5
5
  import { formatBuiltinTodoSnapshot, isLowSignalTodoContent, summarizeBuiltinWriteTodosArgs, truncateLines } from "../runtime-adapter-support.js";
6
6
  import { maybePersistLargeToolOutput, resolveToolRuntimeContext } from "./tool-output-artifacts.js";
7
+ const taskToolSchema = z.preprocess((value) => {
8
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
9
+ return value;
10
+ }
11
+ return normalizeTaskToolInput(value);
12
+ }, z.object({
13
+ description: z.string(),
14
+ subagent_type: z.string(),
15
+ }).passthrough());
16
+ function normalizeTaskToolInput(typed) {
17
+ const description = typeof typed.description === "string" && typed.description.trim().length > 0
18
+ ? typed.description
19
+ : undefined;
20
+ const subagentType = typeof typed.subagent_type === "string" && typed.subagent_type.trim().length > 0
21
+ ? typed.subagent_type
22
+ : undefined;
23
+ return {
24
+ ...typed,
25
+ ...(description !== undefined ? { description } : {}),
26
+ ...(subagentType !== undefined ? { subagent_type: subagentType } : {}),
27
+ };
28
+ }
7
29
  export const BUILTIN_MIDDLEWARE_TOOL_DESCRIPTORS = [
8
30
  { name: "write_todos", description: "Create and update the runtime todo board for multi-step work." },
9
31
  { name: "read_todos", description: "Read the current runtime todo board." },
@@ -23,7 +45,6 @@ export const BUILTIN_MIDDLEWARE_TOOL_DESCRIPTORS = [
23
45
  { name: "request_approval", description: "Request an approval decision from the runtime." },
24
46
  { name: "schedule_task", description: "Create, inspect, update, list, and delete system-level scheduled tasks." },
25
47
  { name: "task", description: "Delegate a bounded task to a subagent." },
26
- { name: "delegate_task", description: "Delegate a bounded task to a subagent." },
27
48
  ];
28
49
  function toDisplayContent(content) {
29
50
  if (typeof content === "string") {
@@ -181,7 +202,6 @@ export async function createBuiltinMiddlewareTools(backend, options) {
181
202
  completed: 0,
182
203
  failed: 0,
183
204
  cancelled: 0,
184
- blocked: 0,
185
205
  },
186
206
  };
187
207
  const finalizeOutput = async (toolName, output, toolConfig) => maybePersistLargeToolOutput({
@@ -193,7 +213,17 @@ export async function createBuiltinMiddlewareTools(backend, options) {
193
213
  name: "write_todos",
194
214
  description: "Create and update the runtime todo board for multi-step work.",
195
215
  schema: z.object({
196
- todos: z.array(z.object({}).passthrough()).optional(),
216
+ todos: z.array(z.object({
217
+ id: z.string().optional(),
218
+ content: z.string().optional(),
219
+ description: z.string().optional(),
220
+ status: z.enum(["pending", "in_progress", "completed", "failed", "cancelled"]).optional(),
221
+ ownerAgentId: z.string().optional(),
222
+ startedAt: z.string().optional(),
223
+ endedAt: z.string().optional(),
224
+ result: z.unknown().optional(),
225
+ metadata: z.record(z.string(), z.unknown()).optional(),
226
+ }).passthrough()).optional(),
197
227
  }).passthrough(),
198
228
  invoke: async (input) => {
199
229
  const args = isRecord(input) ? input : {};
@@ -584,20 +614,10 @@ export async function createBuiltinMiddlewareTools(backend, options) {
584
614
  tools.set("task", {
585
615
  name: "task",
586
616
  description: "Delegate a bounded task to a subagent.",
587
- schema: z.object({
588
- description: z.string(),
589
- subagent_type: z.string(),
590
- }).passthrough(),
591
- invoke: options.invokeTaskTool,
592
- });
593
- tools.set("delegate_task", {
594
- name: "delegate_task",
595
- description: "Delegate a bounded task to a subagent.",
596
- schema: z.object({
597
- description: z.string(),
598
- subagent_type: z.string(),
599
- }).passthrough(),
600
- invoke: async (input) => tools.get("task").invoke(input),
617
+ schema: taskToolSchema,
618
+ invoke: async (input, config) => options.invokeTaskTool(typeof input === "object" && input !== null && !Array.isArray(input)
619
+ ? normalizeTaskToolInput(input)
620
+ : {}),
601
621
  });
602
622
  }
603
623
  return tools;
@@ -19,6 +19,9 @@ function getZodLikeTypeName(value) {
19
19
  return undefined;
20
20
  }
21
21
  const typed = value;
22
+ if (typeof typed.def?.type === "string") {
23
+ return typed.def.type;
24
+ }
22
25
  if (typeof typed._zod?.def?.type === "string") {
23
26
  return typed._zod.def.type;
24
27
  }
@@ -32,7 +35,21 @@ function getZodLikeInnerSchema(value) {
32
35
  return undefined;
33
36
  }
34
37
  const typed = value;
35
- return typed._zod?.def?.innerType ?? typed._zod?.def?.element ?? typed._zod?.def?.valueType ?? typed._def?.innerType ?? typed._def?.type ?? typed._def?.valueType;
38
+ return typed.def?.innerType
39
+ ?? typed.def?.element
40
+ ?? typed.def?.valueType
41
+ ?? typed.def?.schema
42
+ ?? typed.def?.out
43
+ ?? typed.def?.in
44
+ ?? typed._zod?.def?.innerType
45
+ ?? typed._zod?.def?.element
46
+ ?? typed._zod?.def?.valueType
47
+ ?? typed._def?.innerType
48
+ ?? typed._def?.schema
49
+ ?? typed._def?.type
50
+ ?? typed._def?.valueType
51
+ ?? typed._def?.in
52
+ ?? typed._def?.out;
36
53
  }
37
54
  function getZodLikeObjectShape(value) {
38
55
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
@@ -58,7 +75,13 @@ function isZodLikeOptional(value) {
58
75
  if (!typeName) {
59
76
  return false;
60
77
  }
61
- return typeName === "optional" || typeName === "default" || typeName === "catch";
78
+ if (typeName === "optional" || typeName === "default" || typeName === "catch") {
79
+ return true;
80
+ }
81
+ if (typeName === "effects" || typeName === "pipeline" || typeName === "pipe" || typeName === "transform") {
82
+ return isZodLikeOptional(getZodLikeInnerSchema(value));
83
+ }
84
+ return false;
62
85
  }
63
86
  function buildBestEffortJsonSchema(value) {
64
87
  const shape = isZodRawShape(value) ? value : getZodLikeObjectShape(value);
@@ -70,7 +93,7 @@ function buildBestEffortJsonSchema(value) {
70
93
  return {
71
94
  type: "object",
72
95
  properties,
73
- ...(required.length > 0 ? { required } : {}),
96
+ required,
74
97
  };
75
98
  }
76
99
  const typeName = getZodLikeTypeName(value);
@@ -101,6 +124,9 @@ function buildBestEffortJsonSchema(value) {
101
124
  additionalProperties: buildBestEffortJsonSchema(getZodLikeInnerSchema(value)) ?? {},
102
125
  };
103
126
  }
127
+ if (typeName === "effects" || typeName === "pipeline" || typeName === "pipe" || typeName === "transform") {
128
+ return buildBestEffortJsonSchema(getZodLikeInnerSchema(value)) ?? {};
129
+ }
104
130
  return {};
105
131
  }
106
132
  function jsonSchemaPreservesShape(schema, expectedKeys) {
@@ -1,8 +1,8 @@
1
1
  import type { CompiledAgentBinding, MessageContent, RequestResult, RuntimeAdapterOptions, TranscriptMessage } from "../contracts/types.js";
2
2
  import { type RuntimeStreamChunk } from "./parsing/stream-event-parsing.js";
3
- import { AGENT_INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, buildMinimalDeepAgentCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, shouldUseMinimalDeepAgentAssembly } from "./agent-runtime-assembly.js";
3
+ import { AGENT_INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn } from "./agent-runtime-assembly.js";
4
4
  import { RuntimeOperationTimeoutError } from "./adapter/runtime-shell.js";
5
- export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, resolveDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, shouldRelaxDeepAgentDelegationPrompt, } from "./adapter/compat/deepagent-compat.js";
5
+ export { materializeDeepAgentSkillSourcePaths, resolveDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, } from "./adapter/compat/deepagent-compat.js";
6
6
  export { buildAuthOmittingFetch, normalizeOpenAICompatibleInit } from "./adapter/compat/openai-compatible.js";
7
7
  export { buildToolNameMapping, createModelFacingToolNameCandidates, createModelFacingToolNameLookupCandidates, resolveModelFacingToolName, sanitizeToolNameForModel, } from "./adapter/tool/tool-name-mapping.js";
8
8
  export { computeRemainingTimeoutMs, isRetryableProviderError, resolveBindingTimeout, resolveProviderRetryPolicy, resolveStreamIdleTimeout, resolveTimeoutMs, } from "./adapter/resilience.js";
@@ -66,4 +66,4 @@ export declare class AgentRuntimeAdapter {
66
66
  toolRuntimeContext?: Record<string, unknown>;
67
67
  }): AsyncGenerator<RuntimeStreamChunk | string>;
68
68
  }
69
- export { AgentRuntimeAdapter as RuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX, AGENT_INTERRUPT_SENTINEL_PREFIX as INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, buildMinimalDeepAgentCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, shouldUseMinimalDeepAgentAssembly, RuntimeOperationTimeoutError, };
69
+ export { AgentRuntimeAdapter as RuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX, AGENT_INTERRUPT_SENTINEL_PREFIX as INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, RuntimeOperationTimeoutError, };
@@ -2,7 +2,7 @@ import path from "node:path";
2
2
  import { createDeepAgent, FilesystemBackend, } from "deepagents";
3
3
  import { createAgent } from "langchain";
4
4
  import { wrapResolvedModel, } from "./parsing/output-parsing.js";
5
- import { AGENT_INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, buildMinimalDeepAgentCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, shouldAttachMinimalDeepAgentBackend, shouldAttachMinimalDeepAgentCheckpointer, shouldAttachMinimalDeepAgentStore, shouldUseMinimalDeepAgentAssembly, } from "./agent-runtime-assembly.js";
5
+ import { AGENT_INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, shouldAttachDeepAgentBackend, shouldAttachDeepAgentCheckpointer, shouldAttachDeepAgentStore, } from "./agent-runtime-assembly.js";
6
6
  import { resolveDeepAgentSkillSourcePaths, } from "./adapter/compat/deepagent-compat.js";
7
7
  import { buildToolNameMapping, } from "./adapter/tool/tool-name-mapping.js";
8
8
  import { executeRequestInvocation } from "./adapter/flow/invocation-flow.js";
@@ -15,7 +15,7 @@ import { renderDirectWorkspaceListing, shouldDirectlyListWorkspaceFiles } from "
15
15
  import { resolveAdapterTools } from "./adapter/tool-resolution.js";
16
16
  import { resolveRuntimeStreamExecutionContext, } from "./adapter/flow/execution-context.js";
17
17
  import { isRetryableProviderError } from "./adapter/resilience.js";
18
- export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, resolveDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, shouldRelaxDeepAgentDelegationPrompt, } from "./adapter/compat/deepagent-compat.js";
18
+ export { materializeDeepAgentSkillSourcePaths, resolveDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, } from "./adapter/compat/deepagent-compat.js";
19
19
  export { buildAuthOmittingFetch, normalizeOpenAICompatibleInit } from "./adapter/compat/openai-compatible.js";
20
20
  export { buildToolNameMapping, createModelFacingToolNameCandidates, createModelFacingToolNameLookupCandidates, resolveModelFacingToolName, sanitizeToolNameForModel, } from "./adapter/tool/tool-name-mapping.js";
21
21
  export { computeRemainingTimeoutMs, isRetryableProviderError, resolveBindingTimeout, resolveProviderRetryPolicy, resolveStreamIdleTimeout, resolveTimeoutMs, } from "./adapter/resilience.js";
@@ -354,18 +354,11 @@ export class AgentRuntimeAdapter {
354
354
  const resolvedMiddleware = await this.resolveMiddleware(binding);
355
355
  const resolvedSubagents = await this.resolveDeepAgentSubagents(getBindingDeepAgentSubagents(binding), binding);
356
356
  const resolvedInterruptOn = resolveRunnableInterruptOn(binding);
357
- const substrateMode = this.options.deepAgentUpstreamSubstrateMode ?? "minimal";
358
- const resolvedCheckpointer = substrateMode === "minimal"
359
- ? (shouldAttachMinimalDeepAgentCheckpointer(binding, resolvedInterruptOn)
360
- ? resolveRunnableCheckpointer(this.options, binding)
361
- : undefined)
362
- : resolveRunnableCheckpointer(this.options, binding);
363
- const resolvedStore = substrateMode === "minimal"
364
- ? (shouldAttachMinimalDeepAgentStore(binding) ? this.options.storeResolver?.(binding) : undefined)
365
- : this.options.storeResolver?.(binding);
366
- const resolvedBackend = substrateMode === "minimal"
367
- ? (shouldAttachMinimalDeepAgentBackend(binding) ? this.options.backendResolver?.(binding) : undefined)
368
- : this.options.backendResolver?.(binding);
357
+ const resolvedCheckpointer = shouldAttachDeepAgentCheckpointer(binding, resolvedInterruptOn)
358
+ ? resolveRunnableCheckpointer(this.options, binding)
359
+ : undefined;
360
+ const resolvedStore = shouldAttachDeepAgentStore(binding) ? this.options.storeResolver?.(binding) : undefined;
361
+ const resolvedBackend = shouldAttachDeepAgentBackend(binding) ? this.options.backendResolver?.(binding) : undefined;
369
362
  const resolvedSkills = resolveDeepAgentSkillSourcePaths({
370
363
  workspaceRoot: binding.harnessRuntime.workspaceRoot,
371
364
  runtimeRoot: binding.harnessRuntime.runtimeRoot,
@@ -384,24 +377,6 @@ export class AgentRuntimeAdapter {
384
377
  resolvedInterruptOn,
385
378
  resolvedSkills,
386
379
  });
387
- if (shouldUseMinimalDeepAgentAssembly({
388
- binding,
389
- resolvedMiddleware,
390
- resolvedSubagents,
391
- resolvedInterruptOn,
392
- resolvedSkills,
393
- resolvedBackend,
394
- })) {
395
- const minimalDeepAgentConfig = buildMinimalDeepAgentCreateParams({
396
- binding,
397
- resolvedModel,
398
- resolvedTools: [...resolvedTools, ...builtinMiddlewareTools],
399
- resolvedCheckpointer,
400
- resolvedStore,
401
- resolvedBackend,
402
- });
403
- return createAgent(minimalDeepAgentConfig);
404
- }
405
380
  return createDeepAgent(deepAgentConfig);
406
381
  }
407
382
  buildRunnableCacheKey(binding, sessionId) {
@@ -559,7 +534,11 @@ export class AgentRuntimeAdapter {
559
534
  isLangChainBinding,
560
535
  isDeepAgentBinding,
561
536
  countConfiguredTools: getBindingToolCount,
537
+ countConfiguredToolsForAgentId: (agentId) => {
538
+ const resolved = this.options.bindingResolver?.(agentId);
539
+ return resolved ? getBindingToolCount(resolved) : 0;
540
+ },
562
541
  });
563
542
  }
564
543
  }
565
- export { AgentRuntimeAdapter as RuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX, AGENT_INTERRUPT_SENTINEL_PREFIX as INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, buildMinimalDeepAgentCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, shouldUseMinimalDeepAgentAssembly, RuntimeOperationTimeoutError, };
544
+ export { AgentRuntimeAdapter as RuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX, AGENT_INTERRUPT_SENTINEL_PREFIX as INTERRUPT_SENTINEL_PREFIX, buildDeepAgentCreateParams, buildLangChainCreateParams, materializeModelExposedBuiltinMiddlewareTools, resolveLangChainInvocationConfig, resolveRunnableCheckpointer, resolveRunnableInterruptOn, RuntimeOperationTimeoutError, };
@@ -42,26 +42,8 @@ export declare function buildDeepAgentCreateParams(input: {
42
42
  }>;
43
43
  resolvedSkills: string[];
44
44
  }): Record<string, unknown>;
45
- export declare function shouldUseMinimalDeepAgentAssembly(input: {
46
- binding: CompiledAgentBinding;
47
- resolvedMiddleware: unknown[];
48
- resolvedSubagents: Array<UpstreamSubagentConfig | CompiledAsyncSubAgent>;
49
- resolvedInterruptOn?: Record<string, {
50
- allowedDecisions: Array<"approve" | "edit" | "reject">;
51
- }>;
52
- resolvedSkills: string[];
53
- resolvedBackend?: unknown;
54
- }): boolean;
55
- export declare function buildMinimalDeepAgentCreateParams(input: {
56
- binding: CompiledAgentBinding;
57
- resolvedModel: unknown;
58
- resolvedTools: unknown[];
59
- resolvedCheckpointer?: unknown;
60
- resolvedStore?: unknown;
61
- resolvedBackend: unknown;
62
- }): Record<string, unknown>;
63
- export declare function shouldAttachMinimalDeepAgentCheckpointer(binding: CompiledAgentBinding, resolvedInterruptOn?: Record<string, {
45
+ export declare function shouldAttachDeepAgentCheckpointer(binding: CompiledAgentBinding, resolvedInterruptOn?: Record<string, {
64
46
  allowedDecisions: Array<"approve" | "edit" | "reject">;
65
47
  }>): boolean;
66
- export declare function shouldAttachMinimalDeepAgentStore(binding: CompiledAgentBinding): boolean;
67
- export declare function shouldAttachMinimalDeepAgentBackend(binding: CompiledAgentBinding): boolean;
48
+ export declare function shouldAttachDeepAgentStore(binding: CompiledAgentBinding): boolean;
49
+ export declare function shouldAttachDeepAgentBackend(binding: CompiledAgentBinding): boolean;