@botbotgo/agent-harness 0.0.297 → 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 +13 -6
@@ -0,0 +1,400 @@
1
+ function createEmptyPlanSummary() {
2
+ return {
3
+ total: 0,
4
+ pending: 0,
5
+ inProgress: 0,
6
+ completed: 0,
7
+ failed: 0,
8
+ cancelled: 0,
9
+ blocked: 0,
10
+ };
11
+ }
12
+ function resolveTodoKey(content, id, index) {
13
+ if (typeof id === "string" && id.length > 0) {
14
+ return id;
15
+ }
16
+ return `${index}:${content}`;
17
+ }
18
+ function resolveActiveTodoKey(items) {
19
+ const active = items.find((item) => item.status === "in_progress");
20
+ return active?.key;
21
+ }
22
+ function countStructuredTodoIds(items) {
23
+ return items.filter((item) => typeof item.id === "string" && item.id.length > 0).length;
24
+ }
25
+ function shouldReplacePlanItems(currentItems, nextItems) {
26
+ if (currentItems.length === 0) {
27
+ return true;
28
+ }
29
+ if (nextItems.length === 0) {
30
+ return false;
31
+ }
32
+ const currentStructuredIds = countStructuredTodoIds(currentItems);
33
+ const nextStructuredIds = countStructuredTodoIds(nextItems);
34
+ if (currentStructuredIds > 0
35
+ && nextStructuredIds === 0
36
+ && nextItems.length < currentItems.length) {
37
+ return false;
38
+ }
39
+ return true;
40
+ }
41
+ function cloneSteps(steps) {
42
+ return steps.map((step) => ({
43
+ ...step,
44
+ ...(step.detail ? { detail: { ...step.detail } } : {}),
45
+ }));
46
+ }
47
+ function buildPlanItems(snapshot, planItems) {
48
+ const previousSteps = new Map(snapshot.plan.items.map((item) => [item.key, cloneSteps(item.events)]));
49
+ return planItems.map((item, index) => {
50
+ const key = resolveTodoKey(item.content, item.id, index);
51
+ return {
52
+ ...item,
53
+ key,
54
+ events: previousSteps.get(key) ?? [],
55
+ };
56
+ });
57
+ }
58
+ function buildStepEventKey(input) {
59
+ return `${input.kind}:${input.id}`;
60
+ }
61
+ function applyPlanState(snapshot, planState) {
62
+ if (!shouldReplacePlanItems(snapshot.plan.items, planState.items)) {
63
+ return {
64
+ ...snapshot,
65
+ sessionId: planState.sessionId,
66
+ requestId: planState.requestId,
67
+ updatedAt: planState.updatedAt,
68
+ };
69
+ }
70
+ const items = buildPlanItems(snapshot, planState.items);
71
+ return {
72
+ ...snapshot,
73
+ sessionId: planState.sessionId,
74
+ requestId: planState.requestId,
75
+ updatedAt: planState.updatedAt,
76
+ plan: {
77
+ version: planState.version,
78
+ updatedAt: planState.updatedAt,
79
+ summary: planState.summary,
80
+ items,
81
+ },
82
+ activeTodoKey: resolveActiveTodoKey(items),
83
+ };
84
+ }
85
+ function appendStep(steps, nextStep, timestamp) {
86
+ return [
87
+ ...steps,
88
+ {
89
+ ...nextStep,
90
+ ...(timestamp ? { occurredAt: nextStep.occurredAt ?? timestamp } : {}),
91
+ },
92
+ ];
93
+ }
94
+ function applySurfaceItem(snapshot, surfaceItem, timestamp) {
95
+ const nextStep = {
96
+ id: surfaceItem.id,
97
+ kind: surfaceItem.kind,
98
+ name: surfaceItem.name,
99
+ action: surfaceItem.action,
100
+ status: surfaceItem.status,
101
+ ...(surfaceItem.agentId ? { agentId: surfaceItem.agentId } : {}),
102
+ ...(surfaceItem.agentName ? { agentName: surfaceItem.agentName } : {}),
103
+ ...(surfaceItem.ownerAgentId ? { ownerAgentId: surfaceItem.ownerAgentId } : {}),
104
+ ...(surfaceItem.ownerAgentName ? { ownerAgentName: surfaceItem.ownerAgentName } : {}),
105
+ ...(surfaceItem.sourceEventId ? { sourceEventId: surfaceItem.sourceEventId } : {}),
106
+ ...(surfaceItem.detail ? { detail: surfaceItem.detail } : {}),
107
+ };
108
+ const targetTodoKey = snapshot.activeTodoKey;
109
+ if (!targetTodoKey) {
110
+ const activeEventKey = buildStepEventKey(nextStep);
111
+ return {
112
+ ...snapshot,
113
+ updatedAt: timestamp,
114
+ events: appendStep(snapshot.events, nextStep, timestamp),
115
+ activeEventId: surfaceItem.status === "started" ? activeEventKey : snapshot.activeEventId,
116
+ };
117
+ }
118
+ const activeEventKey = buildStepEventKey(nextStep);
119
+ return {
120
+ ...snapshot,
121
+ updatedAt: timestamp,
122
+ plan: {
123
+ ...snapshot.plan,
124
+ items: snapshot.plan.items.map((item) => item.key === targetTodoKey
125
+ ? {
126
+ ...item,
127
+ events: appendStep(item.events, nextStep, timestamp),
128
+ }
129
+ : item),
130
+ },
131
+ activeEventId: surfaceItem.status === "started" ? activeEventKey : snapshot.activeEventId,
132
+ };
133
+ }
134
+ function applyToolResult(snapshot, item, timestamp) {
135
+ const summary = typeof item.output === "object" && item.output !== null
136
+ ? item.output.summary
137
+ : undefined;
138
+ const hasStructuredSummary = typeof summary === "object"
139
+ && summary !== null
140
+ && Array.isArray(summary.items)
141
+ && typeof summary.summary === "object"
142
+ && summary.summary !== null;
143
+ if (hasStructuredSummary) {
144
+ const typedSummary = summary;
145
+ if (!shouldReplacePlanItems(snapshot.plan.items, typedSummary.items)) {
146
+ return {
147
+ ...snapshot,
148
+ sessionId: item.sessionId,
149
+ requestId: item.requestId,
150
+ agentId: item.agentId,
151
+ updatedAt: timestamp,
152
+ };
153
+ }
154
+ const items = buildPlanItems(snapshot, typedSummary.items);
155
+ return {
156
+ ...snapshot,
157
+ sessionId: item.sessionId,
158
+ requestId: item.requestId,
159
+ agentId: item.agentId,
160
+ updatedAt: timestamp,
161
+ plan: {
162
+ version: snapshot.plan.version + 1,
163
+ updatedAt: timestamp,
164
+ summary: typedSummary.summary,
165
+ items,
166
+ },
167
+ activeTodoKey: resolveActiveTodoKey(items),
168
+ };
169
+ }
170
+ return {
171
+ ...snapshot,
172
+ sessionId: item.sessionId,
173
+ requestId: item.requestId,
174
+ agentId: item.agentId,
175
+ updatedAt: timestamp,
176
+ };
177
+ }
178
+ function applyLifecycleEvent(snapshot, event) {
179
+ const next = {
180
+ ...snapshot,
181
+ sessionId: event.sessionId,
182
+ requestId: event.requestId,
183
+ updatedAt: event.timestamp,
184
+ };
185
+ if (event.eventType === "request.created") {
186
+ return {
187
+ ...next,
188
+ state: "running",
189
+ ...(typeof event.payload.selectedAgentId === "string" ? { agentId: event.payload.selectedAgentId } : {}),
190
+ };
191
+ }
192
+ if (event.eventType === "request.state.changed") {
193
+ return {
194
+ ...next,
195
+ state: typeof event.payload.state === "string" ? event.payload.state : next.state,
196
+ };
197
+ }
198
+ if (event.eventType === "request.resumed") {
199
+ return {
200
+ ...next,
201
+ state: typeof event.payload.state === "string" ? event.payload.state : "resuming",
202
+ };
203
+ }
204
+ if (event.eventType === "approval.requested") {
205
+ const approval = {
206
+ ...(typeof event.payload.approvalId === "string" ? { approvalId: event.payload.approvalId } : {}),
207
+ ...(typeof event.payload.pendingActionId === "string" ? { pendingActionId: event.payload.pendingActionId } : {}),
208
+ ...(typeof event.payload.toolName === "string" ? { toolName: event.payload.toolName } : {}),
209
+ status: "pending",
210
+ ...(Array.isArray(event.payload.allowedDecisions) ? { allowedDecisions: event.payload.allowedDecisions } : {}),
211
+ };
212
+ return {
213
+ ...next,
214
+ state: "waiting_for_approval",
215
+ approval,
216
+ };
217
+ }
218
+ if (event.eventType === "approval.resolved") {
219
+ const decision = typeof event.payload.decision === "string" ? event.payload.decision : undefined;
220
+ const approvalStatus = decision === "approve" ? "approved"
221
+ : decision === "edit" ? "edited"
222
+ : decision === "reject" ? "rejected"
223
+ : snapshot.approval?.status;
224
+ return {
225
+ ...next,
226
+ approval: {
227
+ ...(snapshot.approval ?? {}),
228
+ ...(typeof event.payload.approvalId === "string" ? { approvalId: event.payload.approvalId } : {}),
229
+ ...(typeof event.payload.pendingActionId === "string" ? { pendingActionId: event.payload.pendingActionId } : {}),
230
+ ...(typeof event.payload.toolName === "string" ? { toolName: event.payload.toolName } : {}),
231
+ ...(approvalStatus ? { status: approvalStatus } : {}),
232
+ },
233
+ };
234
+ }
235
+ return next;
236
+ }
237
+ export function createInitialRequestEventSnapshot() {
238
+ const now = new Date().toISOString();
239
+ return {
240
+ sessionId: "",
241
+ requestId: "",
242
+ updatedAt: now,
243
+ state: "running",
244
+ plan: {
245
+ version: 0,
246
+ updatedAt: now,
247
+ summary: createEmptyPlanSummary(),
248
+ items: [],
249
+ },
250
+ output: "",
251
+ events: [],
252
+ };
253
+ }
254
+ export function applyRequestStreamItemToSnapshot(snapshot, item) {
255
+ const now = new Date().toISOString();
256
+ switch (item.type) {
257
+ case "event":
258
+ return applyLifecycleEvent(snapshot, item.event);
259
+ case "content":
260
+ return {
261
+ ...snapshot,
262
+ sessionId: item.sessionId,
263
+ requestId: item.requestId,
264
+ updatedAt: now,
265
+ agentId: item.agentId,
266
+ output: snapshot.output + item.content,
267
+ };
268
+ case "commentary":
269
+ return {
270
+ ...snapshot,
271
+ sessionId: item.sessionId,
272
+ requestId: item.requestId,
273
+ updatedAt: now,
274
+ agentId: item.agentId,
275
+ };
276
+ case "content-blocks":
277
+ return {
278
+ ...snapshot,
279
+ sessionId: item.sessionId,
280
+ requestId: item.requestId,
281
+ updatedAt: now,
282
+ agentId: item.agentId,
283
+ contentBlocks: item.contentBlocks,
284
+ };
285
+ case "tool-result":
286
+ return applyToolResult({
287
+ ...snapshot,
288
+ sessionId: item.sessionId,
289
+ requestId: item.requestId,
290
+ agentId: item.agentId,
291
+ }, item, now);
292
+ case "plan-state":
293
+ return applyPlanState({
294
+ ...snapshot,
295
+ agentId: item.agentId,
296
+ }, item.planState);
297
+ case "upstream-event":
298
+ return item.surfaceItem
299
+ ? applySurfaceItem({
300
+ ...snapshot,
301
+ sessionId: item.sessionId,
302
+ requestId: item.requestId,
303
+ }, item.surfaceItem, now)
304
+ : {
305
+ ...snapshot,
306
+ sessionId: item.sessionId,
307
+ requestId: item.requestId,
308
+ updatedAt: now,
309
+ };
310
+ case "profile-step":
311
+ const activeEventKey = buildStepEventKey(item.step);
312
+ return {
313
+ ...snapshot,
314
+ sessionId: item.sessionId,
315
+ requestId: item.requestId,
316
+ updatedAt: now,
317
+ events: appendStep(snapshot.events, item.step, now),
318
+ activeEventId: item.step.status === "started"
319
+ ? activeEventKey
320
+ : snapshot.activeEventId,
321
+ };
322
+ case "result":
323
+ return {
324
+ ...snapshot,
325
+ sessionId: item.result.sessionId,
326
+ requestId: item.result.requestId,
327
+ updatedAt: now,
328
+ state: item.result.state,
329
+ agentId: item.result.agentId ?? snapshot.agentId,
330
+ output: item.result.output || snapshot.output,
331
+ ...(item.result.contentBlocks ? { contentBlocks: item.result.contentBlocks } : {}),
332
+ ...(item.result.structuredResponse !== undefined ? { structuredResponse: item.result.structuredResponse } : {}),
333
+ ...(item.result.interruptContent !== undefined ? { interruptContent: item.result.interruptContent } : {}),
334
+ ...(item.result.approvalId || item.result.pendingActionId
335
+ ? {
336
+ approval: {
337
+ ...(snapshot.approval ?? {}),
338
+ ...(item.result.approvalId ? { approvalId: item.result.approvalId } : {}),
339
+ ...(item.result.pendingActionId ? { pendingActionId: item.result.pendingActionId } : {}),
340
+ },
341
+ }
342
+ : {}),
343
+ };
344
+ }
345
+ }
346
+ export function toRequestDataEvent(item) {
347
+ switch (item.type) {
348
+ case "commentary":
349
+ return {
350
+ type: "progress.commentary",
351
+ sessionId: item.sessionId,
352
+ requestId: item.requestId,
353
+ agentId: item.agentId,
354
+ text: item.content,
355
+ };
356
+ case "content":
357
+ return {
358
+ type: "output.text.delta",
359
+ sessionId: item.sessionId,
360
+ requestId: item.requestId,
361
+ agentId: item.agentId,
362
+ text: item.content,
363
+ };
364
+ case "content-blocks":
365
+ return {
366
+ type: "output.content-blocks",
367
+ sessionId: item.sessionId,
368
+ requestId: item.requestId,
369
+ agentId: item.agentId,
370
+ contentBlocks: item.contentBlocks,
371
+ };
372
+ case "tool-result":
373
+ return {
374
+ type: "tool.result",
375
+ sessionId: item.sessionId,
376
+ requestId: item.requestId,
377
+ agentId: item.agentId,
378
+ toolName: item.toolName,
379
+ output: item.output,
380
+ ...(item.isError !== undefined ? { isError: item.isError } : {}),
381
+ };
382
+ case "upstream-event":
383
+ return {
384
+ type: "debug.upstream",
385
+ sessionId: item.sessionId,
386
+ requestId: item.requestId,
387
+ ...(item.surfaceItem ? { surfaceItem: item.surfaceItem } : {}),
388
+ event: item.event,
389
+ };
390
+ case "profile-step":
391
+ return {
392
+ type: "debug.profile",
393
+ sessionId: item.sessionId,
394
+ requestId: item.requestId,
395
+ step: item.step,
396
+ };
397
+ default:
398
+ return null;
399
+ }
400
+ }
@@ -4,6 +4,8 @@ import path from "node:path";
4
4
  import { createHash, randomUUID } from "node:crypto";
5
5
  import { existsSync } from "node:fs";
6
6
  import { cp, mkdir, readFile, stat, symlink } from "node:fs/promises";
7
+ const HARNESS_PACKAGE_NAME = "@botbotgo/agent-harness";
8
+ const HARNESS_PACKAGE_ROOT = path.resolve(import.meta.dirname, "..", "..");
7
9
  const isolatedResourceRootCache = new Map();
8
10
  const isolatedResourceRootBuilds = new Map();
9
11
  function isolationCacheRoot() {
@@ -81,6 +83,14 @@ async function linkDeclaredDependencies(isolatedRoot, packageRoot, manifest) {
81
83
  await symlink(resolved, targetPath, "junction");
82
84
  }
83
85
  }
86
+ async function linkHarnessPackage(isolatedRoot) {
87
+ const targetPath = dependencyLinkPath(isolatedRoot, HARNESS_PACKAGE_NAME);
88
+ if (existsSync(targetPath)) {
89
+ return;
90
+ }
91
+ await mkdir(path.dirname(targetPath), { recursive: true });
92
+ await symlink(HARNESS_PACKAGE_ROOT, targetPath, "junction");
93
+ }
84
94
  async function buildIsolatedResourceRoot(packageRoot) {
85
95
  const packageJsonPath = path.join(packageRoot, "package.json");
86
96
  const manifest = JSON.parse(await readFile(packageJsonPath, "utf8"));
@@ -93,6 +103,7 @@ async function buildIsolatedResourceRoot(packageRoot) {
93
103
  });
94
104
  await mkdir(path.join(isolatedRoot, "node_modules"), { recursive: true });
95
105
  await linkDeclaredDependencies(isolatedRoot, packageRoot, manifest);
106
+ await linkHarnessPackage(isolatedRoot);
96
107
  return isolatedRoot;
97
108
  }
98
109
  async function rebuildIsolatedResourcePackageRoot(packageRoot) {
@@ -1,6 +1,7 @@
1
1
  import type { RuntimeAdapterOptions, WorkspaceBundle } from "../contracts/types.js";
2
2
  export { getOrCreateMcpClient, listRemoteMcpTools, readMcpServerConfig, type McpServerConfig, type McpToolDescriptor, } from "./mcp-tool-support.js";
3
3
  export declare function resolveLocalResourceProviderEntry(currentResourceDir: string, resolveInstalledEntry?: () => string | null): string;
4
+ export declare function normalizeWorkspaceScopedPath(rootDir: string, inputPath: string): string;
4
5
  export type ResourceToolInfo = {
5
6
  toolPath: string;
6
7
  backendOperation: string;
@@ -6,6 +6,7 @@ import { stat } from "node:fs/promises";
6
6
  import { readFile } from "node:fs/promises";
7
7
  import { fileURLToPath, pathToFileURL } from "node:url";
8
8
  import { CompositeBackend, LangSmithSandbox, LocalShellBackend, StateBackend, StoreBackend } from "deepagents";
9
+ import { UPSTREAM_REQUEST_CONFIG_KEY, UPSTREAM_SESSION_CONFIG_KEY } from "../runtime/adapter/upstream-configurable-keys.js";
9
10
  import { getBindingBackendConfig, getBindingExecutionView, getBindingPrimaryModel } from "../runtime/support/compiled-binding.js";
10
11
  import { resolveCompiledEmbeddingModelRef } from "../runtime/support/embedding-models.js";
11
12
  import { createRuntimeEnv } from "../runtime/support/runtime-env.js";
@@ -65,6 +66,82 @@ function normalizeVirtualExecuteCommand(command, rootDir) {
65
66
  return `${prefix}${quote}${translatedPath}${quote}`;
66
67
  });
67
68
  }
69
+ export function normalizeWorkspaceScopedPath(rootDir, inputPath) {
70
+ if (typeof inputPath !== "string" || inputPath.length === 0 || !path.isAbsolute(inputPath)) {
71
+ return inputPath;
72
+ }
73
+ if (inputPath === "/") {
74
+ return ".";
75
+ }
76
+ const virtualSegments = inputPath.replace(/\/+/g, "/").split("/").filter((segment) => segment.length > 0);
77
+ if (virtualSegments.length > 0) {
78
+ const rootEntries = listVirtualRootEntries(rootDir);
79
+ const firstSegment = virtualSegments[0];
80
+ if (rootEntries.has(firstSegment)) {
81
+ return path.join(...virtualSegments);
82
+ }
83
+ }
84
+ const normalizedRootDir = path.resolve(rootDir);
85
+ const normalizedInputPath = path.resolve(inputPath);
86
+ if (normalizedInputPath === normalizedRootDir || normalizedInputPath.startsWith(`${normalizedRootDir}${path.sep}`)) {
87
+ return path.relative(normalizedRootDir, normalizedInputPath) || ".";
88
+ }
89
+ throw new Error(`Path '${inputPath}' is outside the workspace root '${normalizedRootDir}'. Use a workspace-relative path instead.`);
90
+ }
91
+ function normalizeWorkspaceScopedNullablePath(rootDir, inputPath) {
92
+ return typeof inputPath === "string" ? normalizeWorkspaceScopedPath(rootDir, inputPath) : inputPath;
93
+ }
94
+ class WorkspaceScopedBackend {
95
+ backend;
96
+ id;
97
+ cwd;
98
+ rootDir;
99
+ root;
100
+ virtualMode;
101
+ execute;
102
+ constructor(backend, rootDir) {
103
+ this.backend = backend;
104
+ this.rootDir = path.resolve(rootDir);
105
+ this.root = this.rootDir;
106
+ this.cwd = this.rootDir;
107
+ this.id = typeof backend.id === "string" ? backend.id : undefined;
108
+ this.virtualMode = backend.virtualMode === true;
109
+ this.execute = typeof backend.execute === "function"
110
+ ? (command) => backend.execute(command)
111
+ : undefined;
112
+ }
113
+ ls(filePath) {
114
+ return this.backend.ls(normalizeWorkspaceScopedPath(this.rootDir, filePath));
115
+ }
116
+ read(filePath, offset, limit) {
117
+ return this.backend.read(normalizeWorkspaceScopedPath(this.rootDir, filePath), offset, limit);
118
+ }
119
+ readRaw(filePath) {
120
+ return this.backend.readRaw(normalizeWorkspaceScopedPath(this.rootDir, filePath));
121
+ }
122
+ grep(pattern, filePath, glob) {
123
+ return this.backend.grep(pattern, normalizeWorkspaceScopedNullablePath(this.rootDir, filePath), glob);
124
+ }
125
+ grepRaw(pattern, filePath, glob) {
126
+ return this.backend.grepRaw(pattern, normalizeWorkspaceScopedNullablePath(this.rootDir, filePath), glob);
127
+ }
128
+ glob(pattern, filePath) {
129
+ return this.backend.glob(pattern, typeof filePath === "string" ? normalizeWorkspaceScopedPath(this.rootDir, filePath) : filePath);
130
+ }
131
+ write(filePath, content) {
132
+ return this.backend.write(normalizeWorkspaceScopedPath(this.rootDir, filePath), content);
133
+ }
134
+ edit(filePath, oldString, newString, replaceAll) {
135
+ return this.backend.edit(normalizeWorkspaceScopedPath(this.rootDir, filePath), oldString, newString, replaceAll);
136
+ }
137
+ uploadFiles(files) {
138
+ return this.backend.uploadFiles(files);
139
+ }
140
+ downloadFiles(paths) {
141
+ const normalizedPaths = Array.isArray(paths) ? paths.map((currentPath) => normalizeWorkspaceScopedPath(this.rootDir, currentPath)) : paths;
142
+ return this.backend.downloadFiles(normalizedPaths);
143
+ }
144
+ }
68
145
  async function loadLocalResource(entry) {
69
146
  if (!existsSync(entry)) {
70
147
  return null;
@@ -202,14 +279,14 @@ function createLocalShellStyleBackend(workspaceRoot, config, options) {
202
279
  const rootDir = resolveInlineBackendRootDir(workspaceRoot, config?.rootDir);
203
280
  mkdirSync(rootDir, { recursive: true });
204
281
  const inheritedEnv = config?.inheritEnv === false ? {} : process.env;
205
- return new LocalShellBackend({
282
+ return new WorkspaceScopedBackend(new LocalShellBackend({
206
283
  rootDir,
207
284
  virtualMode: options.virtualMode,
208
285
  timeout: typeof config?.timeout === "number" ? config.timeout : undefined,
209
286
  maxOutputBytes: typeof config?.maxOutputBytes === "number" ? config.maxOutputBytes : undefined,
210
287
  env: createRuntimeEnv(readStringRecord(config?.env), inheritedEnv),
211
288
  inheritEnv: config?.inheritEnv !== false,
212
- });
289
+ }), rootDir);
213
290
  }
214
291
  function createInlineBackendInstance(workspaceRoot, kind, config, runtimeLike) {
215
292
  switch (kind) {
@@ -262,7 +339,7 @@ function createInlineBackendResolver(workspace) {
262
339
  const routeKind = typeof routeConfig?.kind === "string" ? routeConfig.kind : "StoreBackend";
263
340
  return [route, createInlineBackendInstance(workspace.workspaceRoot, routeKind, routeConfig, runtimeLike)];
264
341
  }));
265
- return new CompatibleCompositeBackend(createInlineBackendInstance(workspace.workspaceRoot, defaultBackendKind, stateConfig, runtimeLike), mappedRoutes);
342
+ return new WorkspaceScopedBackend(new CompatibleCompositeBackend(createInlineBackendInstance(workspace.workspaceRoot, defaultBackendKind, stateConfig, runtimeLike), mappedRoutes), workspace.workspaceRoot);
266
343
  }
267
344
  default:
268
345
  return unsupportedInlineBackend(kind);
@@ -504,7 +581,7 @@ function createFunctionToolResolver(workspace) {
504
581
  description: tool.description,
505
582
  schema: tool.modelSchema,
506
583
  modelSchema: tool.modelSchema,
507
- async invoke(input) {
584
+ async invoke(input, config) {
508
585
  const loaded = await loadFunctionToolModule(tool);
509
586
  const parsedInput = loaded.schema.parse(input ?? {});
510
587
  const toolPackageRoot = await findPackageRoot(tool.sourcePath);
@@ -520,7 +597,13 @@ function createFunctionToolResolver(workspace) {
520
597
  ? resolveCompiledEmbeddingModelRef(workspace, effectiveEmbeddingModelRef)
521
598
  : undefined;
522
599
  const model = binding ? getBindingPrimaryModel(binding) : undefined;
523
- const toolContext = {
600
+ const configurable = typeof config?.configurable === "object" && config.configurable !== null
601
+ ? config.configurable
602
+ : {};
603
+ const dynamicToolRuntimeContext = typeof config?.toolRuntimeContext === "object" && config.toolRuntimeContext !== null
604
+ ? config.toolRuntimeContext
605
+ : {};
606
+ const baseToolContext = {
524
607
  appRoot: workspace.workspaceRoot,
525
608
  toolId: tool.id,
526
609
  toolPath: tool.sourcePath,
@@ -530,6 +613,12 @@ function createFunctionToolResolver(workspace) {
530
613
  runtime: {
531
614
  workspaceRoot: workspace.workspaceRoot,
532
615
  runtimeRoot: binding?.harnessRuntime.runtimeRoot,
616
+ ...(typeof configurable[UPSTREAM_SESSION_CONFIG_KEY] === "string"
617
+ ? { sessionId: configurable[UPSTREAM_SESSION_CONFIG_KEY] }
618
+ : {}),
619
+ ...(typeof configurable[UPSTREAM_REQUEST_CONFIG_KEY] === "string"
620
+ ? { requestId: configurable[UPSTREAM_REQUEST_CONFIG_KEY] }
621
+ : {}),
533
622
  },
534
623
  agent: binding
535
624
  ? {
@@ -562,9 +651,16 @@ function createFunctionToolResolver(workspace) {
562
651
  subprocess: effectiveSubprocess,
563
652
  }, workspace.workspaceRoot, loaded.isolatedSourcePath);
564
653
  if (subprocessConfig) {
565
- return runFunctionToolInSubprocess(subprocessConfig, parsedInput, toolContext);
654
+ return runFunctionToolInSubprocess(subprocessConfig, parsedInput, baseToolContext);
566
655
  }
567
- return loaded.invoke(parsedInput, toolContext);
656
+ return loaded.invoke(parsedInput, {
657
+ ...baseToolContext,
658
+ ...dynamicToolRuntimeContext,
659
+ runtime: {
660
+ ...(typeof baseToolContext.runtime === "object" && baseToolContext.runtime ? baseToolContext.runtime : {}),
661
+ ...(typeof dynamicToolRuntimeContext.runtime === "object" && dynamicToolRuntimeContext.runtime ? dynamicToolRuntimeContext.runtime : {}),
662
+ },
663
+ });
568
664
  },
569
665
  },
570
666
  ];
@@ -662,9 +758,6 @@ export function defaultResourceConfigRoot() {
662
758
  export async function listResourceTools(sources = [], workspaceRoot = process.cwd()) {
663
759
  await ensureResourceSources(sources, workspaceRoot);
664
760
  const deduped = new Map();
665
- for (const tool of listProviderTools(localResource)) {
666
- deduped.set(tool.toolPath, tool);
667
- }
668
761
  for (const source of sources) {
669
762
  for (const tool of listProviderTools(remoteResourceCache.get(source) ?? undefined)) {
670
763
  deduped.set(tool.toolPath, tool);
@@ -689,13 +782,11 @@ export function createResourceBackendResolver(workspace) {
689
782
  export function createResourceToolResolver(workspace, options = {}) {
690
783
  const functionResolver = createFunctionToolResolver(workspace);
691
784
  const mcpResolver = createMcpToolResolver(workspace);
692
- const localResolver = createProviderToolResolver(localResource, workspace, options);
693
785
  const remoteResolvers = createWorkspaceProviderResolvers(workspace, (provider) => createProviderToolResolver(provider, workspace, options));
694
786
  return (toolIds, binding) => {
695
787
  const resolved = [
696
788
  ...functionResolver(toolIds, binding),
697
789
  ...mcpResolver(toolIds, binding),
698
- ...(localResolver?.(toolIds, binding) ?? []),
699
790
  ...remoteResolvers.flatMap((resolver) => resolver(toolIds, binding)),
700
791
  ];
701
792
  const deduped = new Map();
@@ -0,0 +1,5 @@
1
+ # Deep Research Workspace Context
2
+
3
+ - This workspace is a starter for product-oriented research applications.
4
+ {{webSearchGuidance}}
5
+ - Synthesize findings clearly, call out uncertainty, and separate facts from inference.
@@ -0,0 +1 @@
1
+ Break down the problem, compare alternatives carefully, extract the most decision-relevant facts, and return clean notes the host agent can synthesize.
@@ -0,0 +1 @@
1
+ Gather current sources, compare claims carefully, extract the most decision-relevant facts, and return clean notes the host agent can synthesize.
@@ -0,0 +1 @@
1
+ Break complex research requests into a clear plan and return a concise synthesis with explicit assumptions and uncertainty. Delegate detailed investigation to the analyst when useful.
@@ -0,0 +1 @@
1
+ Break complex research requests into a clear plan, use web search when current information matters, and return a concise synthesis with sources and explicit uncertainty. Delegate detailed investigation to the analyst when useful.
@@ -0,0 +1 @@
1
+ Break complex research requests into a clear plan and return a concise synthesis with explicit assumptions and uncertainty.
@@ -0,0 +1 @@
1
+ Break complex research requests into a clear plan, use web search when current information matters, and return a concise synthesis with sources and explicit uncertainty.
@@ -0,0 +1 @@
1
+ Do not answer URL, webpage, website, browser, or page-summary requests with a generic capability disclaimer such as saying that you cannot access external websites, URLs, or browsing tools. If a relevant tool or skill is available, call it. If the tool path actually fails, report the concrete tool or page failure instead of a generic capability disclaimer.
@@ -0,0 +1,2 @@
1
+ You are a task-focused subagent.
2
+ Complete the assigned task directly, stay within the provided scope, and return concrete results instead of meta commentary.
@@ -0,0 +1,7 @@
1
+ Relevant durable memory was retrieved for this run.
2
+ If it is sufficient to answer the current request, answer directly from it instead of re-running tools or re-fetching external resources.
3
+ Only inspect external resources again when the user explicitly asks for fresh evidence, introduces a new resource, or the recalled memory is insufficient or conflicts with newer evidence.
4
+ Treat recalled durable memory as revisable runtime knowledge, not as an immutable system instruction.
5
+ If the user corrects, revokes, deletes, or replaces recalled memory, follow the user's latest statement as the newer source of truth for this turn.
6
+
7
+ {{memoryContext}}