@botbotgo/agent-harness 0.0.298 → 0.0.299

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 (166) hide show
  1. package/README.md +77 -37
  2. package/README.zh.md +79 -30
  3. package/dist/acp.d.ts +3 -0
  4. package/dist/acp.js +10 -2
  5. package/dist/api.d.ts +14 -2
  6. package/dist/api.js +19 -3
  7. package/dist/cli.d.ts +18 -1
  8. package/dist/cli.js +1408 -319
  9. package/dist/client/acp.d.ts +9 -3
  10. package/dist/client/acp.js +55 -1
  11. package/dist/client/in-process.d.ts +5 -2
  12. package/dist/client/in-process.js +4 -6
  13. package/dist/client/index.d.ts +1 -1
  14. package/dist/client/types.d.ts +6 -5
  15. package/dist/config/agents/direct.yaml +7 -17
  16. package/dist/config/agents/orchestra.yaml +9 -65
  17. package/dist/config/catalogs/embedding-models.yaml +1 -1
  18. package/dist/config/catalogs/stores.yaml +1 -1
  19. package/dist/config/knowledge/knowledge-runtime.yaml +36 -2
  20. package/dist/config/knowledge/procedural-memory-runtime.yaml +78 -0
  21. package/dist/config/{catalogs/models.yaml → models.yaml} +2 -2
  22. package/dist/config/prompts/direct-system.md +16 -0
  23. package/dist/config/prompts/orchestra-system.md +62 -0
  24. package/dist/config/prompts/routing-system.md +14 -0
  25. package/dist/config/runtime/runtime-memory.yaml +39 -5
  26. package/dist/config/runtime/workspace.yaml +7 -16
  27. package/dist/contracts/runtime.d.ts +242 -1
  28. package/dist/contracts/workspace.d.ts +2 -0
  29. package/dist/index.d.ts +5 -3
  30. package/dist/index.js +2 -1
  31. package/dist/init-project.js +178 -33
  32. package/dist/knowledge/contracts.d.ts +5 -0
  33. package/dist/knowledge/module.d.ts +5 -0
  34. package/dist/knowledge/module.js +340 -18
  35. package/dist/package-version.d.ts +1 -1
  36. package/dist/package-version.js +1 -1
  37. package/dist/persistence/file-store.d.ts +5 -1
  38. package/dist/persistence/file-store.js +16 -0
  39. package/dist/persistence/sqlite-store.d.ts +4 -1
  40. package/dist/persistence/sqlite-store.js +88 -14
  41. package/dist/persistence/types.d.ts +4 -1
  42. package/dist/procedural/config.d.ts +63 -0
  43. package/dist/procedural/config.js +125 -0
  44. package/dist/procedural/index.d.ts +2 -0
  45. package/dist/procedural/index.js +1 -0
  46. package/dist/protocol/ag-ui/http.d.ts +3 -0
  47. package/dist/protocol/ag-ui/http.js +10 -0
  48. package/dist/request-events.d.ts +63 -0
  49. package/dist/request-events.js +400 -0
  50. package/dist/resource/isolation.js +11 -0
  51. package/dist/resource/resource-impl.d.ts +1 -0
  52. package/dist/resource/resource-impl.js +103 -12
  53. package/dist/resources/init-templates/agent-context/deep-research.md +5 -0
  54. package/dist/resources/init-templates/prompts/research-analyst-basic.md +1 -0
  55. package/dist/resources/init-templates/prompts/research-analyst-web-search.md +1 -0
  56. package/dist/resources/init-templates/prompts/research-host-deep-research-basic.md +1 -0
  57. package/dist/resources/init-templates/prompts/research-host-deep-research-web-search.md +1 -0
  58. package/dist/resources/init-templates/prompts/research-host-single-agent-basic.md +1 -0
  59. package/dist/resources/init-templates/prompts/research-host-single-agent-web-search.md +1 -0
  60. package/dist/resources/prompts/runtime/browser-capability-disclaimer-recovery.md +1 -0
  61. package/dist/resources/prompts/runtime/default-subagent.md +2 -0
  62. package/dist/resources/prompts/runtime/durable-memory-context.md +7 -0
  63. package/dist/resources/prompts/runtime/execution-with-tool-evidence-retry.md +1 -0
  64. package/dist/resources/prompts/runtime/execution-with-tool-evidence.md +1 -0
  65. package/dist/resources/prompts/runtime/invalid-tool-selection-recovery.md +1 -0
  66. package/dist/resources/prompts/runtime/memory-manager.md +31 -0
  67. package/dist/resources/prompts/runtime/memory-mutation-reconciliation.md +22 -0
  68. package/dist/resources/prompts/runtime/slash-command-skill.md +6 -0
  69. package/dist/resources/prompts/runtime/strict-tool-json.md +1 -0
  70. package/dist/resources/prompts/runtime/workspace-boundary-guidance.md +3 -0
  71. package/dist/resources/prompts/runtime/workspace-relative-path.md +1 -0
  72. package/dist/resources/prompts/runtime/write-todos-descriptive-content.md +1 -0
  73. package/dist/resources/prompts/runtime/write-todos-full-entry.md +1 -0
  74. package/dist/resources/prompts/runtime/write-todos-non-empty-initial-list.md +1 -0
  75. package/dist/resources/tools/_runtime_tool_helpers.mjs +152 -0
  76. package/dist/resources/tools/cancel_request.mjs +21 -0
  77. package/dist/resources/tools/fetch_url.mjs +23 -0
  78. package/dist/resources/tools/http_request.mjs +30 -0
  79. package/dist/resources/tools/inspect_approvals.mjs +27 -0
  80. package/dist/resources/tools/inspect_artifacts.mjs +21 -0
  81. package/dist/resources/tools/inspect_events.mjs +21 -0
  82. package/dist/resources/tools/inspect_requests.mjs +27 -0
  83. package/dist/resources/tools/inspect_sessions.mjs +21 -0
  84. package/dist/resources/tools/list_files.mjs +27 -0
  85. package/dist/resources/tools/read_artifact.mjs +22 -0
  86. package/dist/resources/tools/request_approval.mjs +27 -0
  87. package/dist/resources/tools/run_command.mjs +21 -0
  88. package/dist/resources/tools/schedule_task.mjs +76 -0
  89. package/dist/resources/tools/search_files.mjs +47 -0
  90. package/dist/resources/tools/send_message.mjs +23 -0
  91. package/dist/runtime/adapter/direct-builtin-utility.d.ts +1 -0
  92. package/dist/runtime/adapter/direct-builtin-utility.js +90 -0
  93. package/dist/runtime/adapter/flow/execution-context.d.ts +1 -1
  94. package/dist/runtime/adapter/flow/execution-context.js +1 -1
  95. package/dist/runtime/adapter/flow/invocation-flow.d.ts +1 -0
  96. package/dist/runtime/adapter/flow/invocation-flow.js +9 -1
  97. package/dist/runtime/adapter/flow/invoke-runtime.d.ts +1 -1
  98. package/dist/runtime/adapter/flow/stream-runtime.d.ts +5 -1
  99. package/dist/runtime/adapter/flow/stream-runtime.js +556 -35
  100. package/dist/runtime/adapter/invocation-result.js +3 -2
  101. package/dist/runtime/adapter/local-tool-invocation.d.ts +1 -1
  102. package/dist/runtime/adapter/local-tool-invocation.js +28 -4
  103. package/dist/runtime/adapter/middleware-assembly.js +3 -1
  104. package/dist/runtime/adapter/model/invocation-request.d.ts +4 -1
  105. package/dist/runtime/adapter/model/invocation-request.js +138 -16
  106. package/dist/runtime/adapter/model/message-assembly.js +2 -6
  107. package/dist/runtime/adapter/model/model-providers.js +103 -5
  108. package/dist/runtime/adapter/resilience.js +17 -2
  109. package/dist/runtime/adapter/runtime-adapter-support.d.ts +11 -7
  110. package/dist/runtime/adapter/runtime-adapter-support.js +39 -5
  111. package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +63 -1
  112. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +193 -21
  113. package/dist/runtime/adapter/tool/tool-arguments.d.ts +3 -1
  114. package/dist/runtime/adapter/tool/tool-arguments.js +52 -17
  115. package/dist/runtime/adapter/tool-resolution.d.ts +1 -0
  116. package/dist/runtime/adapter/tool-resolution.js +4 -2
  117. package/dist/runtime/agent-runtime-adapter.d.ts +27 -0
  118. package/dist/runtime/agent-runtime-adapter.js +163 -11
  119. package/dist/runtime/harness/events/event-bus.d.ts +1 -0
  120. package/dist/runtime/harness/events/event-bus.js +3 -0
  121. package/dist/runtime/harness/events/event-sink.d.ts +3 -0
  122. package/dist/runtime/harness/events/event-sink.js +16 -7
  123. package/dist/runtime/harness/events/streaming.d.ts +18 -1
  124. package/dist/runtime/harness/events/streaming.js +23 -10
  125. package/dist/runtime/harness/run/inspection.js +26 -5
  126. package/dist/runtime/harness/run/stream-run.d.ts +13 -4
  127. package/dist/runtime/harness/run/stream-run.js +448 -4
  128. package/dist/runtime/harness/run/surface-semantics.js +7 -34
  129. package/dist/runtime/harness/system/runtime-memory-manager.d.ts +3 -0
  130. package/dist/runtime/harness/system/runtime-memory-manager.js +384 -69
  131. package/dist/runtime/harness/system/runtime-memory-policy.d.ts +20 -1
  132. package/dist/runtime/harness/system/runtime-memory-policy.js +65 -17
  133. package/dist/runtime/harness/system/runtime-memory-records.js +100 -0
  134. package/dist/runtime/harness/system/runtime-memory-sync.js +2 -2
  135. package/dist/runtime/harness/system/store.d.ts +4 -0
  136. package/dist/runtime/harness/system/store.js +153 -0
  137. package/dist/runtime/harness.d.ts +9 -1
  138. package/dist/runtime/harness.js +141 -7
  139. package/dist/runtime/maintenance/sqlite-checkpoint-saver.d.ts +8 -3
  140. package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +152 -53
  141. package/dist/runtime/parsing/output-parsing.d.ts +10 -2
  142. package/dist/runtime/parsing/output-parsing.js +223 -16
  143. package/dist/runtime/parsing/stream-event-parsing.d.ts +7 -0
  144. package/dist/runtime/parsing/stream-event-parsing.js +51 -1
  145. package/dist/runtime/scheduling/system-schedule-manager.d.ts +41 -0
  146. package/dist/runtime/scheduling/system-schedule-manager.js +532 -0
  147. package/dist/runtime/support/embedding-models.d.ts +1 -1
  148. package/dist/runtime/support/embedding-models.js +5 -2
  149. package/dist/runtime/support/runtime-factories.js +1 -1
  150. package/dist/runtime/support/runtime-layout.d.ts +3 -0
  151. package/dist/runtime/support/runtime-layout.js +10 -1
  152. package/dist/runtime/support/runtime-prompts.d.ts +30 -0
  153. package/dist/runtime/support/runtime-prompts.js +55 -0
  154. package/dist/runtime/support/vector-stores.d.ts +1 -1
  155. package/dist/runtime/support/vector-stores.js +5 -2
  156. package/dist/upstream-events.js +8 -7
  157. package/dist/utils/bundled-text.d.ts +3 -0
  158. package/dist/utils/bundled-text.js +25 -0
  159. package/dist/utils/id.js +3 -2
  160. package/dist/workspace/agent-binding-compiler.js +53 -13
  161. package/dist/workspace/object-loader.js +64 -2
  162. package/dist/workspace/support/workspace-ref-utils.d.ts +2 -1
  163. package/dist/workspace/support/workspace-ref-utils.js +24 -5
  164. package/dist/workspace/yaml-object-reader.d.ts +1 -0
  165. package/dist/workspace/yaml-object-reader.js +95 -17
  166. package/package.json +11 -5
@@ -1,7 +1,29 @@
1
+ import path from "node:path";
1
2
  import { z } from "zod";
2
3
  import { isSandboxBackend } from "deepagents";
3
4
  import { isRecord } from "../../../utils/object.js";
4
- import { formatBuiltinTodoSnapshot, summarizeBuiltinWriteTodosArgs, truncateLines } from "../runtime-adapter-support.js";
5
+ import { formatBuiltinTodoSnapshot, isLowSignalTodoContent, summarizeBuiltinWriteTodosArgs, truncateLines } from "../runtime-adapter-support.js";
6
+ export const BUILTIN_MIDDLEWARE_TOOL_DESCRIPTORS = [
7
+ { name: "write_todos", description: "Create and update the runtime todo board for multi-step work." },
8
+ { name: "read_todos", description: "Read the current runtime todo board." },
9
+ { name: "ls", description: "List files in a directory." },
10
+ { name: "list_files", description: "List files in a directory." },
11
+ { name: "read_file", description: "Read a file from the workspace filesystem." },
12
+ { name: "write_file", description: "Write a file in the workspace filesystem." },
13
+ { name: "edit_file", description: "Replace exact text inside a workspace file." },
14
+ { name: "glob", description: "Find files matching a glob pattern." },
15
+ { name: "grep", description: "Search for text across workspace files." },
16
+ { name: "search_files", description: "Search for text across workspace files." },
17
+ { name: "execute", description: "Run a shell command in the workspace sandbox." },
18
+ { name: "run_command", description: "Run a shell command in the workspace sandbox." },
19
+ { name: "fetch_url", description: "Fetch a URL and return the response body." },
20
+ { name: "http_request", description: "Send a structured HTTP request." },
21
+ { name: "send_message", description: "Send a message through the configured backend." },
22
+ { name: "request_approval", description: "Request an approval decision from the runtime." },
23
+ { name: "schedule_task", description: "Create, inspect, update, list, and delete system-level scheduled tasks." },
24
+ { name: "task", description: "Delegate a bounded task to a subagent." },
25
+ { name: "delegate_task", description: "Delegate a bounded task to a subagent." },
26
+ ];
5
27
  function toDisplayContent(content) {
6
28
  if (typeof content === "string") {
7
29
  return content;
@@ -14,6 +36,34 @@ function toDisplayContent(content) {
14
36
  function notAvailable(toolName, capability) {
15
37
  return `Error: ${toolName} is not available. This backend does not support ${capability}.`;
16
38
  }
39
+ function resolveWorkspaceRoot(backend) {
40
+ const typed = backend;
41
+ if (typeof typed.rootDir === "string" && typed.rootDir.trim().length > 0) {
42
+ return typed.rootDir.trim();
43
+ }
44
+ if (typeof typed.root === "string" && typed.root.trim().length > 0) {
45
+ return typed.root.trim();
46
+ }
47
+ if (typeof typed.cwd === "string" && typed.cwd.trim().length > 0) {
48
+ return typed.cwd.trim();
49
+ }
50
+ return undefined;
51
+ }
52
+ function normalizeWorkspacePathOrThrow(backend, inputPath) {
53
+ if (!inputPath) {
54
+ return inputPath;
55
+ }
56
+ const workspaceRoot = resolveWorkspaceRoot(backend);
57
+ if (!workspaceRoot || !path.isAbsolute(inputPath)) {
58
+ return inputPath;
59
+ }
60
+ const normalizedWorkspaceRoot = path.resolve(workspaceRoot);
61
+ const normalizedInputPath = path.resolve(inputPath);
62
+ if (normalizedInputPath === normalizedWorkspaceRoot || normalizedInputPath.startsWith(`${normalizedWorkspaceRoot}${path.sep}`)) {
63
+ return path.relative(normalizedWorkspaceRoot, normalizedInputPath) || ".";
64
+ }
65
+ throw new Error(`Path '${inputPath}' is outside the workspace root '${normalizedWorkspaceRoot}'. Use a workspace-relative path instead.`);
66
+ }
17
67
  function formatHttpResponse(result) {
18
68
  if (result?.error) {
19
69
  return result.error;
@@ -28,33 +78,77 @@ function formatHttpResponse(result) {
28
78
  ];
29
79
  return lines.length > 0 ? lines.join("\n") : "Request completed.";
30
80
  }
81
+ function parseScheduleWhen(value) {
82
+ const normalized = value.trim().toLowerCase();
83
+ if (!normalized) {
84
+ return undefined;
85
+ }
86
+ const intervalMatch = /^every\s+(\d+)\s*(minute|minutes|min|mins|hour|hours|hr|hrs)$/u.exec(normalized);
87
+ if (intervalMatch) {
88
+ const quantity = Number.parseInt(intervalMatch[1], 10);
89
+ const unit = intervalMatch[2];
90
+ return {
91
+ type: "interval",
92
+ everyMinutes: unit.startsWith("h") ? quantity * 60 : quantity,
93
+ };
94
+ }
95
+ if (normalized === "hourly" || normalized === "every hour") {
96
+ return {
97
+ type: "interval",
98
+ everyMinutes: 60,
99
+ };
100
+ }
101
+ return {
102
+ type: "cron",
103
+ expression: value,
104
+ };
105
+ }
31
106
  export async function createBuiltinMiddlewareTools(backend, options) {
32
107
  const tools = new Map();
108
+ const pathScopedBackend = options.workspaceRoot
109
+ ? { ...backend, rootDir: options.workspaceRoot }
110
+ : backend;
33
111
  let todoSnapshot = {
34
- total: 0,
35
- pending: 0,
36
- completed: 0,
37
112
  items: [],
113
+ summary: {
114
+ total: 0,
115
+ pending: 0,
116
+ inProgress: 0,
117
+ completed: 0,
118
+ failed: 0,
119
+ cancelled: 0,
120
+ blocked: 0,
121
+ },
38
122
  };
39
123
  tools.set("write_todos", {
40
124
  name: "write_todos",
125
+ description: "Create and update the runtime todo board for multi-step work.",
41
126
  schema: z.object({
42
127
  todos: z.array(z.object({}).passthrough()).optional(),
43
128
  }).passthrough(),
44
129
  invoke: async (input) => {
45
130
  const args = isRecord(input) ? input : {};
46
131
  const summary = summarizeBuiltinWriteTodosArgs(args);
132
+ if (summary.summary.total === 0 && todoSnapshot.summary.total === 0) {
133
+ throw new Error("Initial write_todos call cannot use an empty todo list. Send the concrete task steps with both content and status.");
134
+ }
135
+ if (summary.summary.total > 0 &&
136
+ todoSnapshot.summary.total === 0 &&
137
+ summary.items.every((item) => isLowSignalTodoContent(item.content))) {
138
+ throw new Error("Initial write_todos call must use descriptive task content. Do not use placeholder entries like '1', '2', or 'step 1'.");
139
+ }
47
140
  todoSnapshot = summary;
48
141
  return {
49
142
  ok: true,
50
143
  tool: "write_todos",
51
- message: `Tracked ${summary.total} todo item(s).`,
144
+ message: `Tracked ${summary.summary.total} todo item(s).`,
52
145
  summary,
53
146
  };
54
147
  },
55
148
  });
56
149
  tools.set("read_todos", {
57
150
  name: "read_todos",
151
+ description: "Read the current runtime todo board.",
58
152
  schema: z.object({}).passthrough(),
59
153
  invoke: async () => ({
60
154
  ok: true,
@@ -65,9 +159,10 @@ export async function createBuiltinMiddlewareTools(backend, options) {
65
159
  });
66
160
  tools.set("ls", {
67
161
  name: "ls",
162
+ description: "List files in a directory.",
68
163
  schema: z.object({ path: z.string().optional().default("/") }).passthrough(),
69
164
  invoke: async (input) => {
70
- const targetPath = isRecord(input) && typeof input.path === "string" ? input.path : "/";
165
+ const targetPath = normalizeWorkspacePathOrThrow(pathScopedBackend, isRecord(input) && typeof input.path === "string" ? input.path : "/");
71
166
  const legacyInfos = (await Promise.resolve(backend.lsInfo?.(targetPath))) ?? [];
72
167
  const infos = legacyInfos.length > 0
73
168
  ? legacyInfos
@@ -84,11 +179,13 @@ export async function createBuiltinMiddlewareTools(backend, options) {
84
179
  });
85
180
  tools.set("list_files", {
86
181
  name: "list_files",
182
+ description: "List files in a directory.",
87
183
  schema: z.object({ path: z.string().optional().default("/") }).passthrough(),
88
184
  invoke: async (input) => tools.get("ls").invoke(input),
89
185
  });
90
186
  tools.set("read_file", {
91
187
  name: "read_file",
188
+ description: "Read a file from the workspace filesystem.",
92
189
  schema: z.object({
93
190
  file_path: z.string(),
94
191
  offset: z.number().optional(),
@@ -96,27 +193,30 @@ export async function createBuiltinMiddlewareTools(backend, options) {
96
193
  }).passthrough(),
97
194
  invoke: async (input) => {
98
195
  const typed = isRecord(input) ? input : {};
99
- const filePath = typeof typed.file_path === "string" ? typed.file_path : "";
196
+ const filePath = normalizeWorkspacePathOrThrow(pathScopedBackend, typeof typed.file_path === "string" ? typed.file_path : "");
100
197
  const offset = typeof typed.offset === "number" ? typed.offset : 0;
101
198
  const limit = typeof typed.limit === "number" ? typed.limit : 500;
102
199
  const result = await Promise.resolve(backend.read?.(filePath, offset, limit));
103
200
  if (typeof result === "string") {
104
201
  return result;
105
202
  }
106
- return toDisplayContent(result?.content);
203
+ return result?.error ?? toDisplayContent(result?.content);
107
204
  },
108
205
  });
109
206
  tools.set("write_file", {
110
207
  name: "write_file",
208
+ description: "Write a file in the workspace filesystem.",
111
209
  schema: z.object({ file_path: z.string(), content: z.string().optional() }).passthrough(),
112
210
  invoke: async (input) => {
113
211
  const typed = isRecord(input) ? input : {};
114
- const result = await Promise.resolve(backend.write?.(typeof typed.file_path === "string" ? typed.file_path : "", typeof typed.content === "string" ? typed.content : ""));
115
- return result?.error ?? `Successfully wrote to '${result?.path ?? (typed.file_path ?? "")}'`;
212
+ const filePath = normalizeWorkspacePathOrThrow(pathScopedBackend, typeof typed.file_path === "string" ? typed.file_path : "");
213
+ const result = await Promise.resolve(backend.write?.(filePath, typeof typed.content === "string" ? typed.content : ""));
214
+ return result?.error ?? `Successfully wrote to '${result?.path ?? filePath}'`;
116
215
  },
117
216
  });
118
217
  tools.set("edit_file", {
119
218
  name: "edit_file",
219
+ description: "Replace exact text inside a workspace file.",
120
220
  schema: z.object({
121
221
  file_path: z.string(),
122
222
  old_string: z.string(),
@@ -125,17 +225,19 @@ export async function createBuiltinMiddlewareTools(backend, options) {
125
225
  }).passthrough(),
126
226
  invoke: async (input) => {
127
227
  const typed = isRecord(input) ? input : {};
128
- const result = await Promise.resolve(backend.edit?.(typeof typed.file_path === "string" ? typed.file_path : "", typeof typed.old_string === "string" ? typed.old_string : "", typeof typed.new_string === "string" ? typed.new_string : "", typed.replace_all === true));
129
- return result?.error ?? `Successfully replaced ${result?.occurrences ?? 0} occurrence(s) in '${result?.path ?? (typed.file_path ?? "")}'`;
228
+ const filePath = normalizeWorkspacePathOrThrow(pathScopedBackend, typeof typed.file_path === "string" ? typed.file_path : "");
229
+ const result = await Promise.resolve(backend.edit?.(filePath, typeof typed.old_string === "string" ? typed.old_string : "", typeof typed.new_string === "string" ? typed.new_string : "", typed.replace_all === true));
230
+ return result?.error ?? `Successfully replaced ${result?.occurrences ?? 0} occurrence(s) in '${result?.path ?? filePath}'`;
130
231
  },
131
232
  });
132
233
  tools.set("glob", {
133
234
  name: "glob",
235
+ description: "Find files matching a glob pattern.",
134
236
  schema: z.object({ pattern: z.string(), path: z.string().optional().default("/") }).passthrough(),
135
237
  invoke: async (input) => {
136
238
  const typed = isRecord(input) ? input : {};
137
239
  const pattern = typeof typed.pattern === "string" ? typed.pattern : "";
138
- const targetPath = typeof typed.path === "string" ? typed.path : "/";
240
+ const targetPath = normalizeWorkspacePathOrThrow(pathScopedBackend, typeof typed.path === "string" ? typed.path : "/");
139
241
  const legacyInfos = (await Promise.resolve(backend.globInfo?.(pattern, targetPath))) ?? [];
140
242
  const infos = legacyInfos.length > 0
141
243
  ? legacyInfos
@@ -148,6 +250,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
148
250
  });
149
251
  tools.set("grep", {
150
252
  name: "grep",
253
+ description: "Search for text across workspace files.",
151
254
  schema: z.object({
152
255
  pattern: z.string(),
153
256
  path: z.string().optional().default("/"),
@@ -155,8 +258,9 @@ export async function createBuiltinMiddlewareTools(backend, options) {
155
258
  }).passthrough(),
156
259
  invoke: async (input) => {
157
260
  const typed = isRecord(input) ? input : {};
158
- const legacyResult = await Promise.resolve(backend.grepRaw?.(typeof typed.pattern === "string" ? typed.pattern : "", typeof typed.path === "string" ? typed.path : "/", typeof typed.glob === "string" ? typed.glob : null));
159
- const structuredResult = await Promise.resolve(backend.grep?.(typeof typed.pattern === "string" ? typed.pattern : "", typeof typed.path === "string" ? typed.path : "/", typeof typed.glob === "string" ? typed.glob : null));
261
+ const targetPath = normalizeWorkspacePathOrThrow(pathScopedBackend, typeof typed.path === "string" ? typed.path : "/");
262
+ const legacyResult = await Promise.resolve(backend.grepRaw?.(typeof typed.pattern === "string" ? typed.pattern : "", targetPath, typeof typed.glob === "string" ? typed.glob : null));
263
+ const structuredResult = await Promise.resolve(backend.grep?.(typeof typed.pattern === "string" ? typed.pattern : "", targetPath, typeof typed.glob === "string" ? typed.glob : null));
160
264
  const normalizedStructuredMatches = structuredResult?.matches?.map((match) => ({
161
265
  path: match.path,
162
266
  line: match.lineNumber ?? match.line_number ?? match.line ?? 0,
@@ -183,6 +287,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
183
287
  });
184
288
  tools.set("search_files", {
185
289
  name: "search_files",
290
+ description: "Search for text across workspace files.",
186
291
  schema: z.object({
187
292
  query: z.string(),
188
293
  path: z.string().optional().default("/"),
@@ -192,16 +297,17 @@ export async function createBuiltinMiddlewareTools(backend, options) {
192
297
  invoke: async (input) => {
193
298
  const typed = isRecord(input) ? input : {};
194
299
  const query = typeof typed.query === "string" ? typed.query : "";
195
- const path = typeof typed.path === "string" ? typed.path : "/";
300
+ const searchPath = normalizeWorkspacePathOrThrow(pathScopedBackend, typeof typed.path === "string" ? typed.path : "/");
196
301
  const globPattern = typeof typed.glob === "string" ? typed.glob : null;
197
302
  const searchType = typed.search_type === "path" ? "path" : "content";
198
303
  return searchType === "path"
199
- ? tools.get("glob").invoke({ pattern: query, path })
200
- : tools.get("grep").invoke({ pattern: query, path, glob: globPattern });
304
+ ? tools.get("glob").invoke({ pattern: query, path: searchPath })
305
+ : tools.get("grep").invoke({ pattern: query, path: searchPath, glob: globPattern });
201
306
  },
202
307
  });
203
308
  tools.set("execute", {
204
309
  name: "execute",
310
+ description: "Run a shell command in the workspace sandbox.",
205
311
  schema: z.object({ command: z.string() }).passthrough(),
206
312
  invoke: async (input) => {
207
313
  if (!isSandboxBackend(backend) || typeof backend.execute !== "function") {
@@ -221,11 +327,13 @@ export async function createBuiltinMiddlewareTools(backend, options) {
221
327
  });
222
328
  tools.set("run_command", {
223
329
  name: "run_command",
330
+ description: "Run a shell command in the workspace sandbox.",
224
331
  schema: z.object({ command: z.string() }).passthrough(),
225
332
  invoke: async (input) => tools.get("execute").invoke(input),
226
333
  });
227
334
  tools.set("fetch_url", {
228
335
  name: "fetch_url",
336
+ description: "Fetch a URL and return the response body.",
229
337
  schema: z.object({ url: z.string() }).passthrough(),
230
338
  invoke: async (input) => {
231
339
  if (typeof backend.fetchUrl !== "function") {
@@ -241,6 +349,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
241
349
  });
242
350
  tools.set("http_request", {
243
351
  name: "http_request",
352
+ description: "Send a structured HTTP request.",
244
353
  schema: z.object({
245
354
  url: z.string(),
246
355
  method: z.string().optional(),
@@ -268,6 +377,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
268
377
  });
269
378
  tools.set("send_message", {
270
379
  name: "send_message",
380
+ description: "Send a message through the configured backend.",
271
381
  schema: z.object({
272
382
  destination: z.string(),
273
383
  message: z.string(),
@@ -293,6 +403,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
293
403
  });
294
404
  tools.set("request_approval", {
295
405
  name: "request_approval",
406
+ description: "Request an approval decision from the runtime.",
296
407
  schema: z.object({
297
408
  action: z.string(),
298
409
  reason: z.string().optional(),
@@ -321,17 +432,76 @@ export async function createBuiltinMiddlewareTools(backend, options) {
321
432
  });
322
433
  tools.set("schedule_task", {
323
434
  name: "schedule_task",
435
+ description: "Create, inspect, update, list, and delete system-level scheduled tasks.",
324
436
  schema: z.object({
325
- instruction: z.string(),
326
- when: z.string(),
437
+ operation: z.enum(["create", "list", "get", "update", "delete"]).optional(),
438
+ scheduleId: z.string().optional(),
327
439
  name: z.string().optional(),
440
+ instruction: z.string().optional(),
441
+ agentId: z.string().optional(),
442
+ when: z.string().optional(),
443
+ schedule: z.object({
444
+ type: z.enum(["cron", "interval", "daily", "weekly"]),
445
+ expression: z.string().optional(),
446
+ everyMinutes: z.number().int().positive().optional(),
447
+ time: z.string().optional(),
448
+ days: z.array(z.string()).optional(),
449
+ }).optional(),
450
+ filters: z.object({
451
+ scheduleId: z.string().optional(),
452
+ name: z.string().optional(),
453
+ agentId: z.string().optional(),
454
+ source: z.enum(["crontab", "schtasks"]).optional(),
455
+ status: z.enum(["active", "missing"]).optional(),
456
+ query: z.string().optional(),
457
+ }).optional(),
328
458
  metadata: z.record(z.string(), z.unknown()).optional(),
329
459
  }).passthrough(),
330
460
  invoke: async (input) => {
461
+ const typed = isRecord(input) ? input : {};
462
+ const operation = typeof typed.operation === "string" ? typed.operation : "create";
463
+ const normalizedSchedule = isRecord(typed.schedule) && typeof typed.schedule.type === "string"
464
+ ? {
465
+ type: typed.schedule.type,
466
+ ...(typeof typed.schedule.expression === "string" ? { expression: typed.schedule.expression } : {}),
467
+ ...(typeof typed.schedule.everyMinutes === "number" ? { everyMinutes: typed.schedule.everyMinutes } : {}),
468
+ ...(typeof typed.schedule.time === "string" ? { time: typed.schedule.time } : {}),
469
+ ...(Array.isArray(typed.schedule.days)
470
+ ? {
471
+ days: typed.schedule.days.filter((day) => typeof day === "string"),
472
+ }
473
+ : {}),
474
+ }
475
+ : typeof typed.when === "string"
476
+ ? parseScheduleWhen(typed.when)
477
+ : undefined;
478
+ if (typeof backend.manageSchedule === "function") {
479
+ return backend.manageSchedule({
480
+ operation: operation,
481
+ scheduleId: typeof typed.scheduleId === "string" ? typed.scheduleId : undefined,
482
+ name: typeof typed.name === "string" ? typed.name : undefined,
483
+ instruction: typeof typed.instruction === "string" ? typed.instruction : undefined,
484
+ agentId: typeof typed.agentId === "string" ? typed.agentId : undefined,
485
+ schedule: normalizedSchedule,
486
+ filters: isRecord(typed.filters)
487
+ ? {
488
+ ...(typeof typed.filters.scheduleId === "string" ? { scheduleId: typed.filters.scheduleId } : {}),
489
+ ...(typeof typed.filters.name === "string" ? { name: typed.filters.name } : {}),
490
+ ...(typeof typed.filters.agentId === "string" ? { agentId: typed.filters.agentId } : {}),
491
+ ...(typed.filters.source === "crontab" || typed.filters.source === "schtasks" ? { source: typed.filters.source } : {}),
492
+ ...(typed.filters.status === "active" || typed.filters.status === "missing" ? { status: typed.filters.status } : {}),
493
+ ...(typeof typed.filters.query === "string" ? { query: typed.filters.query } : {}),
494
+ }
495
+ : undefined,
496
+ metadata: isRecord(typed.metadata) ? typed.metadata : undefined,
497
+ });
498
+ }
331
499
  if (typeof backend.scheduleTask !== "function") {
332
500
  return notAvailable("schedule_task", "task scheduling");
333
501
  }
334
- const typed = isRecord(input) ? input : {};
502
+ if (operation !== "create") {
503
+ return "Error: schedule_task only supports create on this backend.";
504
+ }
335
505
  const result = await Promise.resolve(backend.scheduleTask({
336
506
  instruction: typeof typed.instruction === "string" ? typed.instruction : "",
337
507
  when: typeof typed.when === "string" ? typed.when : "",
@@ -347,6 +517,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
347
517
  if (options.includeTaskTool && options.invokeTaskTool) {
348
518
  tools.set("task", {
349
519
  name: "task",
520
+ description: "Delegate a bounded task to a subagent.",
350
521
  schema: z.object({
351
522
  description: z.string(),
352
523
  subagent_type: z.string(),
@@ -355,6 +526,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
355
526
  });
356
527
  tools.set("delegate_task", {
357
528
  name: "delegate_task",
529
+ description: "Delegate a bounded task to a subagent.",
358
530
  schema: z.object({
359
531
  description: z.string(),
360
532
  subagent_type: z.string(),
@@ -1,5 +1,7 @@
1
1
  export declare function stringifyToolOutput(output: unknown): string;
2
- export declare function normalizeToolArgsForSchema(args: Record<string, unknown>, schema: unknown, rawArgsInput?: unknown): Record<string, unknown>;
2
+ export declare function normalizeToolArgsForSchema(args: Record<string, unknown>, schema: unknown, rawArgsInput?: unknown, options?: {
3
+ latestUserInput?: string;
4
+ }): Record<string, unknown>;
3
5
  export declare function extractToolCallsFromResult(result: unknown): Array<{
4
6
  id?: string;
5
7
  name: string;
@@ -1,17 +1,31 @@
1
1
  import { salvageToolArgs } from "../../parsing/output-parsing.js";
2
2
  import { isRecord } from "../../../utils/object.js";
3
+ import { extractExplicitResourceReferences, hasExplicitResourceReference } from "../../harness/system/runtime-memory-policy.js";
3
4
  function isObject(value) {
4
5
  return isRecord(value);
5
6
  }
6
7
  export function stringifyToolOutput(output) {
8
+ let rendered;
7
9
  if (typeof output === "string") {
8
- return output;
10
+ rendered = output;
11
+ }
12
+ else {
13
+ try {
14
+ rendered = JSON.stringify(output);
15
+ }
16
+ catch {
17
+ rendered = `${String(output)}`;
18
+ }
19
+ }
20
+ const maxChars = 4_000;
21
+ if (rendered.length <= maxChars) {
22
+ return rendered;
9
23
  }
10
24
  try {
11
- return JSON.stringify(output);
25
+ return `${rendered.slice(0, maxChars - 15)}\n...[truncated]`;
12
26
  }
13
27
  catch {
14
- return `${String(output)}`;
28
+ return rendered;
15
29
  }
16
30
  }
17
31
  function mapSingleFieldScalarArg(args, expectedKey, rawArgsInput) {
@@ -36,7 +50,27 @@ function mapSingleFieldScalarArg(args, expectedKey, rawArgsInput) {
36
50
  }
37
51
  return args;
38
52
  }
39
- export function normalizeToolArgsForSchema(args, schema, rawArgsInput) {
53
+ function isScalarLikeValue(value) {
54
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
55
+ }
56
+ function mapSingleRemainingScalarArg(args, expectedKey) {
57
+ if (expectedKey in args) {
58
+ return args;
59
+ }
60
+ const entries = Object.entries(args).filter(([, value]) => isScalarLikeValue(value));
61
+ if (entries.length !== 1) {
62
+ return args;
63
+ }
64
+ const [, value] = entries[0];
65
+ if (typeof value === "string" && value.trim().length === 0) {
66
+ return args;
67
+ }
68
+ return {
69
+ ...args,
70
+ [expectedKey]: value,
71
+ };
72
+ }
73
+ export function normalizeToolArgsForSchema(args, schema, rawArgsInput, options = {}) {
40
74
  const schemaDef = isObject(schema) ? schema._def : undefined;
41
75
  const zodShape = schemaDef
42
76
  ? isRecord(schemaDef.shape)
@@ -64,20 +98,21 @@ export function normalizeToolArgsForSchema(args, schema, rawArgsInput) {
64
98
  if (expectedKey in scalarMappedArgs) {
65
99
  return scalarMappedArgs;
66
100
  }
67
- const aliasesByExpected = {
68
- city: ["location", "locality", "place"],
69
- location: ["city", "city_name"],
70
- query: ["question", "prompt", "text", "request"],
71
- };
72
- const aliases = aliasesByExpected[expectedKey] ?? [];
73
- const aliasKey = aliases.find((candidate) => candidate in scalarMappedArgs);
74
- if (!aliasKey || !(aliasKey in scalarMappedArgs)) {
75
- return scalarMappedArgs;
101
+ if (Object.keys(scalarMappedArgs).length === 0 && typeof options.latestUserInput === "string") {
102
+ const userInput = options.latestUserInput.trim();
103
+ const resourceRefs = extractExplicitResourceReferences(userInput);
104
+ if (resourceRefs.length === 1 && hasExplicitResourceReference(userInput)) {
105
+ return {
106
+ ...scalarMappedArgs,
107
+ [expectedKey]: resourceRefs[0],
108
+ };
109
+ }
76
110
  }
77
- return {
78
- ...scalarMappedArgs,
79
- [expectedKey]: scalarMappedArgs[aliasKey],
80
- };
111
+ const genericScalarMappedArgs = mapSingleRemainingScalarArg(scalarMappedArgs, expectedKey);
112
+ if (expectedKey in genericScalarMappedArgs) {
113
+ return genericScalarMappedArgs;
114
+ }
115
+ return genericScalarMappedArgs;
81
116
  }
82
117
  export function extractToolCallsFromResult(result) {
83
118
  const messages = isRecord(result) && Array.isArray(result.messages) ? result.messages : [];
@@ -10,5 +10,6 @@ export declare function buildExecutableToolMap(input: {
10
10
  primaryTools: CompiledTool[];
11
11
  resolvedTools: unknown[];
12
12
  toolNameMapping?: ToolNameMapping;
13
+ toolConfig?: Record<string, unknown>;
13
14
  context?: Record<string, unknown>;
14
15
  }): Map<string, ExecutableTool>;
@@ -29,7 +29,7 @@ export function buildExecutableToolMap(input) {
29
29
  continue;
30
30
  }
31
31
  const callableTool = resolvedTool;
32
- const handler = async (toolInput) => {
32
+ const handler = async (toolInput, toolConfig) => {
33
33
  const callable = typeof callableTool.invoke === "function"
34
34
  ? callableTool.invoke
35
35
  : typeof callableTool.call === "function"
@@ -38,7 +38,9 @@ export function buildExecutableToolMap(input) {
38
38
  if (!callable) {
39
39
  throw new Error(`Tool ${compiledTool.name} has no callable handler.`);
40
40
  }
41
- return Promise.resolve(callable.call(callableTool, toolInput, input.context ? { context: input.context } : undefined));
41
+ return Promise.resolve(callable.call(callableTool, toolInput, toolConfig
42
+ ?? input.toolConfig
43
+ ?? (input.context ? { context: input.context } : undefined)));
42
44
  };
43
45
  const modelFacingName = toolNameMapping.originalToModelFacing.get(compiledTool.name) ?? compiledTool.name;
44
46
  const schema = normalizeResolvedToolSchema(callableTool);
@@ -1,5 +1,6 @@
1
1
  import type { CompiledAgentBinding, CompiledAsyncSubAgent, MessageContent, RequestResult, RuntimeAdapterOptions, TranscriptMessage } from "../contracts/types.js";
2
2
  import { type RuntimeStreamChunk } from "./parsing/stream-event-parsing.js";
3
+ import type { ExecutableTool } from "./adapter/flow/invoke-runtime.js";
3
4
  import { RuntimeOperationTimeoutError } from "./adapter/runtime-shell.js";
4
5
  import { type UpstreamSubagentConfig } from "./adapter/middleware-assembly.js";
5
6
  export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, resolveDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, shouldRelaxDeepAgentDelegationPrompt, } from "./adapter/compat/deepagent-compat.js";
@@ -12,6 +13,10 @@ type RunnableLike = {
12
13
  streamEvents?: (input: unknown, config?: Record<string, unknown>) => Promise<AsyncIterable<unknown>>;
13
14
  };
14
15
  declare const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
16
+ export declare function materializeModelExposedBuiltinMiddlewareTools(input: {
17
+ builtinTools: Map<string, ExecutableTool>;
18
+ explicitToolNames?: string[];
19
+ }): unknown[];
15
20
  export declare function resolveRunnableCheckpointer(options: RuntimeAdapterOptions, binding: CompiledAgentBinding): unknown;
16
21
  export declare function resolveRunnableInterruptOn(binding: CompiledAgentBinding): Record<string, {
17
22
  allowedDecisions: import("./adapter/tool/interrupt-policy.js").InterruptDecision[];
@@ -32,6 +37,7 @@ export declare function resolveLangChainInvocationConfig(binding: CompiledAgentB
32
37
  legacySessionId?: string;
33
38
  legacyRequestId?: string;
34
39
  context?: Record<string, unknown>;
40
+ toolRuntimeContext?: Record<string, unknown>;
35
41
  }): Record<string, unknown>;
36
42
  export declare function buildDeepAgentCreateParams(input: {
37
43
  binding: CompiledAgentBinding;
@@ -47,6 +53,24 @@ export declare function buildDeepAgentCreateParams(input: {
47
53
  }>;
48
54
  resolvedSkills: string[];
49
55
  }): Record<string, unknown>;
56
+ export declare function shouldUseMinimalDeepAgentAssembly(input: {
57
+ binding: CompiledAgentBinding;
58
+ resolvedMiddleware: unknown[];
59
+ resolvedSubagents: Array<UpstreamSubagentConfig | CompiledAsyncSubAgent>;
60
+ resolvedInterruptOn?: Record<string, {
61
+ allowedDecisions: Array<"approve" | "edit" | "reject">;
62
+ }>;
63
+ resolvedSkills: string[];
64
+ resolvedBackend?: unknown;
65
+ }): boolean;
66
+ export declare function buildMinimalDeepAgentCreateParams(input: {
67
+ binding: CompiledAgentBinding;
68
+ resolvedModel: unknown;
69
+ resolvedTools: unknown[];
70
+ resolvedCheckpointer?: unknown;
71
+ resolvedStore?: unknown;
72
+ resolvedBackend: unknown;
73
+ }): Record<string, unknown>;
50
74
  export declare class AgentRuntimeAdapter {
51
75
  private readonly options;
52
76
  private readonly modelCache;
@@ -67,6 +91,7 @@ export declare class AgentRuntimeAdapter {
67
91
  private resolveFilesystemBackend;
68
92
  private resolveFilesystemRootDir;
69
93
  private resolveBuiltinMiddlewareBackend;
94
+ private buildFunctionToolRuntimeContext;
70
95
  private createDeclaredMiddlewareResolverOptions;
71
96
  private createAssemblyResolvers;
72
97
  private invokeBuiltinTaskTool;
@@ -96,6 +121,8 @@ export declare class AgentRuntimeAdapter {
96
121
  files?: Record<string, unknown>;
97
122
  requestId?: string;
98
123
  memoryContext?: string;
124
+ profiling?: boolean;
125
+ toolRuntimeContext?: Record<string, unknown>;
99
126
  }): AsyncGenerator<RuntimeStreamChunk | string>;
100
127
  }
101
128
  export { AgentRuntimeAdapter as RuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX, AGENT_INTERRUPT_SENTINEL_PREFIX as INTERRUPT_SENTINEL_PREFIX, RuntimeOperationTimeoutError, };