@botbotgo/agent-harness 0.0.17 → 0.0.19
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.
- package/README.md +95 -387
- package/dist/api.d.ts +3 -0
- package/dist/api.js +7 -0
- package/dist/config/agent-context.md +8 -0
- package/dist/config/orchestra.yaml +11 -8
- package/dist/config/{runtime.yaml → workspace.yaml} +23 -0
- package/dist/contracts/types.d.ts +14 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/mcp.d.ts +12 -0
- package/dist/mcp.js +112 -0
- package/dist/resource/isolation.d.ts +2 -0
- package/dist/resource/isolation.js +79 -0
- package/dist/resource/resource-impl.d.ts +18 -0
- package/dist/resource/resource-impl.js +179 -11
- package/dist/resource/sources.d.ts +3 -0
- package/dist/resource/sources.js +105 -25
- package/dist/runtime/checkpoint-maintenance.d.ts +36 -0
- package/dist/runtime/checkpoint-maintenance.js +223 -0
- package/dist/runtime/harness.d.ts +10 -1
- package/dist/runtime/harness.js +38 -2
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/sqlite-maintained-checkpoint-saver.d.ts +9 -0
- package/dist/runtime/sqlite-maintained-checkpoint-saver.js +39 -0
- package/dist/runtime/support/runtime-factories.js +3 -1
- package/dist/tool-modules.d.ts +17 -0
- package/dist/tool-modules.js +143 -0
- package/dist/tools.d.ts +20 -0
- package/dist/tools.js +17 -0
- package/dist/workspace/compile.js +124 -5
- package/dist/workspace/object-loader.js +90 -24
- package/dist/workspace/resource-compilers.d.ts +3 -1
- package/dist/workspace/resource-compilers.js +72 -5
- package/package.json +10 -3
package/README.md
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# @botbotgo/agent-harness
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Slogan
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Declarative agent workspaces for LangChain v1 and DeepAgents.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
## Product Overview
|
|
8
|
+
|
|
9
|
+
`@botbotgo/agent-harness` is a TypeScript framework for loading a local workspace from disk, compiling it into runnable agent bindings, and executing requests through either a LangChain v1 path or a DeepAgent path.
|
|
10
|
+
|
|
11
|
+
The framework is workspace-first:
|
|
12
|
+
|
|
13
|
+
- agents are declared in YAML
|
|
14
|
+
- tools and skills are discovered from `resources/`
|
|
15
|
+
- workspace-wide behavior is declared in `config/workspace.yaml`
|
|
16
|
+
- agent bootstrap context is declared in `config/agent-context.md`
|
|
9
17
|
|
|
10
18
|
The public API stays intentionally small:
|
|
11
19
|
|
|
@@ -15,25 +23,6 @@ The public API stays intentionally small:
|
|
|
15
23
|
- `getThread(...)`
|
|
16
24
|
- `stop(...)`
|
|
17
25
|
|
|
18
|
-
## Product Overview
|
|
19
|
-
|
|
20
|
-
Agent Harness loads a workspace from disk, compiles its config into runnable agent bindings, and executes requests through either a lightweight LangChain v1 path or a DeepAgent path.
|
|
21
|
-
|
|
22
|
-
Out of the box, the framework supports:
|
|
23
|
-
|
|
24
|
-
- workspace loading from a directory root
|
|
25
|
-
- declarative `Model`, `EmbeddingModel`, `VectorStore`, `LangChainAgent`, `DeepAgent`, and `Runtime` objects
|
|
26
|
-
- host-agent routing between a direct path and an orchestration path
|
|
27
|
-
- tool loading from resource packages and external sources
|
|
28
|
-
- skill discovery from filesystem roots
|
|
29
|
-
- subagent discovery from filesystem roots
|
|
30
|
-
- thread persistence, run history, and resumable state
|
|
31
|
-
|
|
32
|
-
The default package config in this repo shows the intended model:
|
|
33
|
-
|
|
34
|
-
- `direct`: low-latency host for simple one-step requests
|
|
35
|
-
- `orchestra`: default host for multi-step work, tools, skills, and delegation
|
|
36
|
-
|
|
37
26
|
## Quick Start
|
|
38
27
|
|
|
39
28
|
Install the package:
|
|
@@ -42,16 +31,20 @@ Install the package:
|
|
|
42
31
|
npm install @botbotgo/agent-harness
|
|
43
32
|
```
|
|
44
33
|
|
|
45
|
-
Create a workspace
|
|
34
|
+
Create a workspace:
|
|
46
35
|
|
|
47
36
|
```text
|
|
48
37
|
your-workspace/
|
|
49
|
-
AGENTS.md
|
|
50
38
|
config/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
agent-context.md
|
|
40
|
+
workspace.yaml
|
|
41
|
+
models.yaml
|
|
42
|
+
agents/
|
|
43
|
+
direct.yaml
|
|
44
|
+
orchestra.yaml
|
|
45
|
+
resources/
|
|
46
|
+
package.json
|
|
47
|
+
tools/
|
|
55
48
|
```
|
|
56
49
|
|
|
57
50
|
Minimal usage:
|
|
@@ -73,29 +66,23 @@ try {
|
|
|
73
66
|
}
|
|
74
67
|
```
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
## How To Use
|
|
79
|
-
|
|
80
|
-
There are two common ways to use the framework.
|
|
81
|
-
|
|
82
|
-
### 1. Use It As A Library
|
|
83
|
-
|
|
84
|
-
Load a workspace from disk and run requests through the public API.
|
|
69
|
+
## Feature List
|
|
85
70
|
|
|
86
|
-
|
|
71
|
+
- Declarative `Model`, `EmbeddingModel`, `VectorStore`, `LangChainAgent`, `DeepAgent`, and `Runtime` objects
|
|
72
|
+
- Workspace loading from disk with framework defaults and workspace overrides
|
|
73
|
+
- LangChain v1 agents for lightweight tool-calling flows
|
|
74
|
+
- DeepAgents for planning, filesystem-backed execution, subagents, skills, and long-term memory
|
|
75
|
+
- Resource package loading from `resources/tools/` and `resources/skills/`
|
|
76
|
+
- Host-agent routing between a direct lane and an orchestration lane
|
|
77
|
+
- Persistent thread state, approvals, run history, and resumable execution
|
|
78
|
+
- Store-backed `/memories/*` long-term memory
|
|
79
|
+
- Background checkpoint maintenance for `SqliteSaver`
|
|
87
80
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
- `createAgentHarness(...)`: load a workspace and initialize the runtime
|
|
91
|
-
- `run(...)`: start a new run or answer an approval request
|
|
92
|
-
- `subscribe(...)`: observe runtime events for logging or UI updates
|
|
93
|
-
- `getThread(...)`: fetch persisted thread state and messages
|
|
94
|
-
- `stop(...)`: release runtime resources when your process is done
|
|
81
|
+
## How To Use
|
|
95
82
|
|
|
96
|
-
|
|
83
|
+
### Create A Harness
|
|
97
84
|
|
|
98
|
-
|
|
85
|
+
Pass a workspace root:
|
|
99
86
|
|
|
100
87
|
```ts
|
|
101
88
|
import { createAgentHarness } from "@botbotgo/agent-harness";
|
|
@@ -103,410 +90,131 @@ import { createAgentHarness } from "@botbotgo/agent-harness";
|
|
|
103
90
|
const harness = await createAgentHarness("/absolute/path/to/workspace");
|
|
104
91
|
```
|
|
105
92
|
|
|
106
|
-
|
|
93
|
+
Or pass a prebuilt `WorkspaceBundle`:
|
|
107
94
|
|
|
108
95
|
```ts
|
|
109
|
-
const harness = await createAgentHarness();
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
#### Create A Harness From A Prebuilt WorkspaceBundle
|
|
113
|
-
|
|
114
|
-
If your application already compiled a workspace, or you want tighter control in tests, you can pass a `WorkspaceBundle` directly instead of a filesystem path.
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
import { createAgentHarness } from "@botbotgo/agent-harness";
|
|
118
|
-
|
|
119
96
|
const harness = await createAgentHarness(workspaceBundle);
|
|
120
97
|
```
|
|
121
98
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Use `run(...)` with an `agentId` and plain-text `input`. The return value includes:
|
|
125
|
-
|
|
126
|
-
- `threadId`: stable conversation id
|
|
127
|
-
- `runId`: the current execution id
|
|
128
|
-
- `state`: final state such as `completed` or `waiting_for_approval`
|
|
129
|
-
- `output`: final visible model output
|
|
99
|
+
### Run A Request
|
|
130
100
|
|
|
131
101
|
```ts
|
|
132
|
-
import {
|
|
102
|
+
import { run } from "@botbotgo/agent-harness";
|
|
133
103
|
|
|
134
|
-
const
|
|
104
|
+
const result = await run(harness, {
|
|
105
|
+
agentId: "direct",
|
|
106
|
+
input: "Explain the available agents in this workspace.",
|
|
107
|
+
});
|
|
108
|
+
```
|
|
135
109
|
|
|
136
|
-
|
|
137
|
-
const result = await run(harness, {
|
|
138
|
-
agentId: "direct",
|
|
139
|
-
input: "Summarize what this workspace is for.",
|
|
140
|
-
});
|
|
110
|
+
The result includes:
|
|
141
111
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
} finally {
|
|
147
|
-
await stop(harness);
|
|
148
|
-
}
|
|
149
|
-
```
|
|
112
|
+
- `threadId`
|
|
113
|
+
- `runId`
|
|
114
|
+
- `state`
|
|
115
|
+
- `output`
|
|
150
116
|
|
|
151
|
-
|
|
117
|
+
### Let The Harness Choose The Host Agent
|
|
152
118
|
|
|
153
|
-
|
|
119
|
+
Use `agentId: "auto"` when your workspace defines routing:
|
|
154
120
|
|
|
155
121
|
```ts
|
|
156
122
|
const result = await run(harness, {
|
|
157
123
|
agentId: "auto",
|
|
158
|
-
input: "Inspect this repository and explain
|
|
124
|
+
input: "Inspect this repository and explain the release flow.",
|
|
159
125
|
});
|
|
160
126
|
```
|
|
161
127
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
#### Stream Chunks And Runtime Events
|
|
165
|
-
|
|
166
|
-
`run(...)` accepts listeners for streamed output and runtime activity. This is the main SDK path for CLIs, chat UIs, and debug logging.
|
|
128
|
+
### Stream Output And Events
|
|
167
129
|
|
|
168
130
|
```ts
|
|
169
131
|
const result = await run(harness, {
|
|
170
132
|
agentId: "orchestra",
|
|
171
|
-
input: "Inspect the workspace and explain the available
|
|
133
|
+
input: "Inspect the workspace and explain the available tools.",
|
|
172
134
|
listeners: {
|
|
173
135
|
onChunk(chunk) {
|
|
174
136
|
process.stdout.write(chunk);
|
|
175
137
|
},
|
|
176
138
|
onEvent(event) {
|
|
177
|
-
console.log(
|
|
178
|
-
},
|
|
179
|
-
onStep(step) {
|
|
180
|
-
console.log("step:", step);
|
|
181
|
-
},
|
|
182
|
-
onToolResult(item) {
|
|
183
|
-
console.log("tool:", item.toolName, item.output);
|
|
139
|
+
console.log(event.eventType, event.payload);
|
|
184
140
|
},
|
|
185
141
|
},
|
|
186
142
|
});
|
|
187
143
|
```
|
|
188
144
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
- `onChunk`: streamed user-visible response text
|
|
192
|
-
- `onEvent`: raw runtime events
|
|
193
|
-
- `onStep`: higher-level execution step messages
|
|
194
|
-
- `onToolResult`: completed tool outputs
|
|
195
|
-
- `onReasoning`: reasoning-channel text when available from the runtime
|
|
196
|
-
|
|
197
|
-
#### Subscribe To Global Harness Events
|
|
198
|
-
|
|
199
|
-
Use `subscribe(...)` when you want a process-wide event feed rather than per-run listeners.
|
|
200
|
-
|
|
201
|
-
```ts
|
|
202
|
-
import { subscribe } from "@botbotgo/agent-harness";
|
|
203
|
-
|
|
204
|
-
const unsubscribe = subscribe(harness, (event) => {
|
|
205
|
-
console.log(event.threadId, event.runId, event.eventType);
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// later
|
|
209
|
-
unsubscribe();
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
This is useful when one process is handling multiple runs or updating a central UI.
|
|
213
|
-
|
|
214
|
-
#### Continue An Existing Thread
|
|
215
|
-
|
|
216
|
-
Pass an existing `threadId` to keep the conversation on the same persisted thread.
|
|
217
|
-
|
|
218
|
-
```ts
|
|
219
|
-
const first = await run(harness, {
|
|
220
|
-
agentId: "direct",
|
|
221
|
-
input: "Remember that the release branch is master.",
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
const second = await run(harness, {
|
|
225
|
-
agentId: "direct",
|
|
226
|
-
threadId: first.threadId,
|
|
227
|
-
input: "What did I just tell you about the release branch?",
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
#### Read Back Thread State
|
|
232
|
-
|
|
233
|
-
Use `getThread(...)` to fetch persisted thread data after a run completes.
|
|
145
|
+
### Read Back Thread State
|
|
234
146
|
|
|
235
147
|
```ts
|
|
236
148
|
import { getThread } from "@botbotgo/agent-harness";
|
|
237
149
|
|
|
238
150
|
const thread = await getThread(harness, result.threadId);
|
|
239
|
-
|
|
240
|
-
console.log(thread?.threadId);
|
|
241
151
|
console.log(thread?.messages.at(-1)?.content);
|
|
242
152
|
```
|
|
243
153
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
#### Handle Approval Or Interrupt Flows
|
|
247
|
-
|
|
248
|
-
Some runs can pause with `state: "waiting_for_approval"`. In that case, call `run(...)` again with the thread or approval decision payload instead of starting a new request.
|
|
154
|
+
### Subscribe To Global Events
|
|
249
155
|
|
|
250
156
|
```ts
|
|
251
|
-
|
|
252
|
-
agentId: "orchestra",
|
|
253
|
-
input: "Run the protected action if approval is required.",
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
if (pending.state === "waiting_for_approval" && pending.approvalId) {
|
|
257
|
-
const resumed = await run(harness, {
|
|
258
|
-
threadId: pending.threadId,
|
|
259
|
-
runId: pending.runId,
|
|
260
|
-
approvalId: pending.approvalId,
|
|
261
|
-
decision: "approve",
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
console.log(resumed.output);
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Use `decision: "edit"` plus `editedInput` when your application exposes approval-time parameter editing.
|
|
269
|
-
|
|
270
|
-
#### Always Stop The Harness
|
|
271
|
-
|
|
272
|
-
Call `stop(...)` before process exit so the runtime can close adapters and flush state cleanly.
|
|
273
|
-
|
|
274
|
-
```ts
|
|
275
|
-
await stop(harness);
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
For most applications, the safe pattern is `try/finally`.
|
|
279
|
-
|
|
280
|
-
#### Complete SDK CLI Example
|
|
281
|
-
|
|
282
|
-
The following example shows a small CLI-style integration that:
|
|
283
|
-
|
|
284
|
-
- loads a workspace from disk
|
|
285
|
-
- starts a first run with streaming output
|
|
286
|
-
- continues the same thread
|
|
287
|
-
- reads the saved thread state back
|
|
288
|
-
- shuts the harness down cleanly
|
|
289
|
-
|
|
290
|
-
```ts
|
|
291
|
-
import { createAgentHarness, getThread, run, stop } from "@botbotgo/agent-harness";
|
|
292
|
-
|
|
293
|
-
const workspaceRoot = "/absolute/path/to/workspace";
|
|
294
|
-
const harness = await createAgentHarness(workspaceRoot);
|
|
295
|
-
|
|
296
|
-
try {
|
|
297
|
-
const first = await run(harness, {
|
|
298
|
-
agentId: "auto",
|
|
299
|
-
input: "Explain what agents and tools are available in this workspace.",
|
|
300
|
-
listeners: {
|
|
301
|
-
onChunk(chunk) {
|
|
302
|
-
process.stdout.write(chunk);
|
|
303
|
-
},
|
|
304
|
-
onStep(step) {
|
|
305
|
-
console.log("\n[step]", step);
|
|
306
|
-
},
|
|
307
|
-
},
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
console.log("\nfirst run:", first.runId, first.state);
|
|
311
|
-
|
|
312
|
-
const second = await run(harness, {
|
|
313
|
-
agentId: "auto",
|
|
314
|
-
threadId: first.threadId,
|
|
315
|
-
input: "Now give me the shortest possible summary in 3 bullets.",
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
console.log("\nsecond run output:\n", second.output);
|
|
319
|
-
|
|
320
|
-
const thread = await getThread(harness, first.threadId);
|
|
321
|
-
console.log("\nthread message count:", thread?.messages.length ?? 0);
|
|
322
|
-
} finally {
|
|
323
|
-
await stop(harness);
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
For a real CLI entrypoint, wrap this in an async `main()` and feed the prompt from `process.argv`.
|
|
328
|
-
|
|
329
|
-
```ts
|
|
330
|
-
import { createAgentHarness, getThread, run, subscribe, stop } from "@botbotgo/agent-harness";
|
|
331
|
-
|
|
332
|
-
const harness = await createAgentHarness("/absolute/path/to/workspace");
|
|
157
|
+
import { subscribe } from "@botbotgo/agent-harness";
|
|
333
158
|
|
|
334
159
|
const unsubscribe = subscribe(harness, (event) => {
|
|
335
|
-
console.log(event.
|
|
160
|
+
console.log(event.threadId, event.runId, event.eventType);
|
|
336
161
|
});
|
|
337
|
-
|
|
338
|
-
try {
|
|
339
|
-
const firstRun = await run(harness, {
|
|
340
|
-
agentId: "orchestra",
|
|
341
|
-
input: "Inspect the workspace and explain the available agents.",
|
|
342
|
-
listeners: {
|
|
343
|
-
onChunk(chunk) {
|
|
344
|
-
process.stdout.write(chunk);
|
|
345
|
-
},
|
|
346
|
-
},
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
const thread = await getThread(harness, firstRun.threadId);
|
|
350
|
-
console.log(thread?.messages.at(-1)?.content);
|
|
351
|
-
} finally {
|
|
352
|
-
unsubscribe();
|
|
353
|
-
await stop(harness);
|
|
354
|
-
}
|
|
355
162
|
```
|
|
356
163
|
|
|
357
|
-
###
|
|
358
|
-
|
|
359
|
-
The example app in [`examples/stock-research-app`](/Users/boqiang.liang/900-project/agent-harness3/examples/stock-research-app/README.md) is the reference shape for an application workspace. It keeps the framework package separate from app-specific agents, tools, and skills.
|
|
164
|
+
### Stop The Harness
|
|
360
165
|
|
|
361
|
-
|
|
166
|
+
```ts
|
|
167
|
+
import { stop } from "@botbotgo/agent-harness";
|
|
362
168
|
|
|
363
|
-
|
|
364
|
-
cd examples/stock-research-app
|
|
365
|
-
npm install
|
|
366
|
-
npm run start -- "Investigate NVDA and produce a balanced stock research brief."
|
|
169
|
+
await stop(harness);
|
|
367
170
|
```
|
|
368
171
|
|
|
369
172
|
## How To Configure
|
|
370
173
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
### Core Files
|
|
374
|
-
|
|
375
|
-
- `AGENTS.md`: durable instructions and operating rules loaded into agent memory where configured
|
|
376
|
-
- `config/model.yaml`: default chat model
|
|
377
|
-
- `config/runtime.yaml`: workspace-wide runtime defaults such as `runRoot` and host routing
|
|
378
|
-
- `config/direct.yaml`: lightweight direct-response host agent
|
|
379
|
-
- `config/orchestra.yaml`: default orchestration host agent
|
|
380
|
-
- `config/embedding-model.yaml`: embeddings preset for retrieval flows
|
|
381
|
-
- `config/vector-store.yaml`: vector store preset for retrieval flows
|
|
382
|
-
|
|
383
|
-
### Minimal Model Config
|
|
384
|
-
|
|
385
|
-
```yaml
|
|
386
|
-
apiVersion: agent-harness/v1alpha1
|
|
387
|
-
kind: Model
|
|
388
|
-
metadata:
|
|
389
|
-
name: default
|
|
390
|
-
spec:
|
|
391
|
-
provider: ollama
|
|
392
|
-
model: gpt-oss:latest
|
|
393
|
-
init:
|
|
394
|
-
baseUrl: http://localhost:11434
|
|
395
|
-
temperature: 0.2
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### Runtime Routing
|
|
399
|
-
|
|
400
|
-
`config/runtime.yaml` controls shared runtime behavior. In this repo it defines:
|
|
401
|
-
|
|
402
|
-
- `runRoot`: where thread state, run artifacts, approvals, and indexes are stored
|
|
403
|
-
- `routing.systemPrompt`: how the harness chooses between the primary and secondary host agents when `agentId: "auto"` is used
|
|
404
|
-
|
|
405
|
-
### Agent Config
|
|
406
|
-
|
|
407
|
-
Agent objects are declarative YAML files. The package currently supports:
|
|
174
|
+
Core workspace files:
|
|
408
175
|
|
|
409
|
-
- `
|
|
410
|
-
- `
|
|
176
|
+
- `config/workspace.yaml`: workspace-wide defaults such as `runRoot`, routing, and maintenance
|
|
177
|
+
- `config/agent-context.md`: shared bootstrap context for agents
|
|
178
|
+
- `config/models.yaml`: named model presets
|
|
179
|
+
- `config/agents/direct.yaml`: lightweight host agent
|
|
180
|
+
- `config/agents/orchestra.yaml`: default orchestration host agent
|
|
181
|
+
- `resources/package.json`: resource package boundary
|
|
182
|
+
- `resources/tools/`: local tool modules
|
|
183
|
+
- `resources/skills/`: local skills
|
|
411
184
|
|
|
412
|
-
|
|
185
|
+
### `config/workspace.yaml`
|
|
413
186
|
|
|
414
|
-
-
|
|
415
|
-
- `metadata.description`
|
|
416
|
-
- `spec.modelRef`
|
|
417
|
-
- `spec.systemPrompt`
|
|
418
|
-
- `spec.checkpointer`
|
|
419
|
-
- `spec.memory`
|
|
420
|
-
- `spec.store`
|
|
421
|
-
- `spec.backend`
|
|
187
|
+
Use this file for workspace-wide behavior such as:
|
|
422
188
|
|
|
423
|
-
|
|
189
|
+
- `runRoot`
|
|
190
|
+
- routing via `routing.systemPrompt`
|
|
191
|
+
- background checkpoint maintenance via `maintenance.checkpoints.*`
|
|
424
192
|
|
|
425
|
-
|
|
193
|
+
### `config/agent-context.md`
|
|
426
194
|
|
|
427
|
-
|
|
195
|
+
Use this file for shared bootstrap context that agents should read at construction time.
|
|
428
196
|
|
|
429
|
-
|
|
197
|
+
Put stable project context here, not long-term mutable memory.
|
|
430
198
|
|
|
431
|
-
|
|
199
|
+
### Agent YAML
|
|
432
200
|
|
|
433
|
-
|
|
434
|
-
- external resource sources
|
|
435
|
-
- builtin discovery paths
|
|
436
|
-
|
|
437
|
-
The harness scans YAML files under the discovered agent roots and adds them to the workspace graph.
|
|
438
|
-
|
|
439
|
-
### Add Skills
|
|
440
|
-
|
|
441
|
-
Skills are discovered from roots that contain either:
|
|
442
|
-
|
|
443
|
-
- a direct `SKILL.md`
|
|
444
|
-
- child directories where each directory contains its own `SKILL.md`
|
|
445
|
-
|
|
446
|
-
A practical layout looks like this:
|
|
447
|
-
|
|
448
|
-
```text
|
|
449
|
-
your-workspace/
|
|
450
|
-
resources/
|
|
451
|
-
skills/
|
|
452
|
-
code-review/
|
|
453
|
-
SKILL.md
|
|
454
|
-
release-check/
|
|
455
|
-
SKILL.md
|
|
456
|
-
```
|
|
201
|
+
Use `config/agents/*.yaml` to configure agents. Common fields include:
|
|
457
202
|
|
|
458
|
-
|
|
203
|
+
- `modelRef`
|
|
204
|
+
- `systemPrompt`
|
|
205
|
+
- `tools`
|
|
206
|
+
- `skills`
|
|
207
|
+
- `memory`
|
|
208
|
+
- `checkpointer`
|
|
209
|
+
- `store`
|
|
210
|
+
- `backend`
|
|
211
|
+
- `subagents`
|
|
459
212
|
|
|
460
|
-
|
|
213
|
+
### Resource Package
|
|
461
214
|
|
|
462
|
-
|
|
463
|
-
- external sources
|
|
464
|
-
- builtin resources
|
|
465
|
-
- declarative tool objects that bundle or reference other tools
|
|
215
|
+
Use `resources/` for executable extensions:
|
|
466
216
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
### Add Retrieval
|
|
470
|
-
|
|
471
|
-
If your workspace needs RAG-style behavior:
|
|
472
|
-
|
|
473
|
-
1. add an `EmbeddingModel`
|
|
474
|
-
2. add a `VectorStore`
|
|
475
|
-
3. point retrieval-oriented tools at those refs
|
|
476
|
-
|
|
477
|
-
This repo already includes `config/embedding-model.yaml` and `config/vector-store.yaml` as the default pattern.
|
|
478
|
-
|
|
479
|
-
### Extend The Runtime In Code
|
|
480
|
-
|
|
481
|
-
The public API also accepts a prebuilt `WorkspaceBundle`, which lets you compile or inject workspace data yourself before creating the harness. That path is useful when you need tighter control in tests or in a higher-level product.
|
|
482
|
-
|
|
483
|
-
## Suggested Workspace Layout
|
|
484
|
-
|
|
485
|
-
```text
|
|
486
|
-
your-workspace/
|
|
487
|
-
AGENTS.md
|
|
488
|
-
config/
|
|
489
|
-
model.yaml
|
|
490
|
-
runtime.yaml
|
|
491
|
-
direct.yaml
|
|
492
|
-
orchestra.yaml
|
|
493
|
-
embedding-model.yaml
|
|
494
|
-
vector-store.yaml
|
|
495
|
-
resources/
|
|
496
|
-
agents/
|
|
497
|
-
skills/
|
|
498
|
-
tools/
|
|
499
|
-
.agent/
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
## Development
|
|
503
|
-
|
|
504
|
-
Build and test this package locally:
|
|
505
|
-
|
|
506
|
-
```bash
|
|
507
|
-
npm run build
|
|
508
|
-
npm run check
|
|
509
|
-
npm test
|
|
510
|
-
```
|
|
217
|
+
- `resources/tools/` for local tool modules
|
|
218
|
+
- `resources/skills/` for skill packages
|
|
511
219
|
|
|
512
|
-
|
|
220
|
+
Each resource package should include its own `package.json`.
|
package/dist/api.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentHarnessHandle, RunOptions, RuntimeAdapterOptions, ThreadRecord, WorkspaceLoadOptions, WorkspaceBundle } from "./contracts/types.js";
|
|
2
2
|
import { AgentHarness } from "./runtime/harness.js";
|
|
3
|
+
import type { ToolMcpServerOptions } from "./mcp.js";
|
|
3
4
|
type CreateAgentHarnessOptions = {
|
|
4
5
|
load?: WorkspaceLoadOptions;
|
|
5
6
|
adapter?: RuntimeAdapterOptions;
|
|
@@ -11,4 +12,6 @@ export declare function run(harness: AgentHarnessHandle, options: RunOptions): P
|
|
|
11
12
|
export declare function subscribe(harness: AgentHarnessHandle, listener: Parameters<AgentHarness["subscribe"]>[0]): () => void;
|
|
12
13
|
export declare function getThread(harness: AgentHarnessHandle, threadId: string): Promise<ThreadRecord | null>;
|
|
13
14
|
export declare function stop(harness: AgentHarnessHandle): Promise<void>;
|
|
15
|
+
export declare function createToolMcpServer(harness: AgentHarnessHandle, options: ToolMcpServerOptions): Promise<import("@modelcontextprotocol/sdk/server/mcp.js").McpServer>;
|
|
16
|
+
export declare function serveToolsOverStdio(harness: AgentHarnessHandle, options: ToolMcpServerOptions): Promise<import("@modelcontextprotocol/sdk/server/mcp.js").McpServer>;
|
|
14
17
|
export {};
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AgentHarness } from "./runtime/harness.js";
|
|
2
|
+
import { createToolMcpServerFromHarness, serveToolsOverStdioFromHarness } from "./mcp.js";
|
|
2
3
|
import { loadWorkspace } from "./workspace/compile.js";
|
|
3
4
|
const HARNESS_INSTANCE = Symbol.for("@botbotgo/agent-harness/instance");
|
|
4
5
|
function registerHarness(harness) {
|
|
@@ -45,3 +46,9 @@ export async function stop(harness) {
|
|
|
45
46
|
const instance = requireHarness(harness);
|
|
46
47
|
return instance.close();
|
|
47
48
|
}
|
|
49
|
+
export async function createToolMcpServer(harness, options) {
|
|
50
|
+
return createToolMcpServerFromHarness(requireHarness(harness), options);
|
|
51
|
+
}
|
|
52
|
+
export async function serveToolsOverStdio(harness, options) {
|
|
53
|
+
return serveToolsOverStdioFromHarness(requireHarness(harness), options);
|
|
54
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Agent Context
|
|
2
|
+
|
|
3
|
+
This file is the default shared bootstrap context for agents in this workspace.
|
|
4
|
+
|
|
5
|
+
- Put stable workspace conventions here.
|
|
6
|
+
- Put durable project background here.
|
|
7
|
+
- Keep role and hard behavioral rules in `systemPrompt`.
|
|
8
|
+
- Put long-term, runtime-learned knowledge in `/memories/*`, not here.
|
|
@@ -24,13 +24,15 @@ spec:
|
|
|
24
24
|
kind: MemorySaver
|
|
25
25
|
memory:
|
|
26
26
|
# DeepAgents aligned feature: bootstrap memory sources supplied to the deep agent at construction time.
|
|
27
|
-
# These
|
|
28
|
-
#
|
|
29
|
-
# - `
|
|
30
|
-
# - `
|
|
31
|
-
# -
|
|
32
|
-
# - the harness checkpointer
|
|
33
|
-
|
|
27
|
+
# These paths resolve relative to the workspace root unless they are already absolute.
|
|
28
|
+
# Treat this as agent-owned startup context, not as a dynamic long-term memory sink:
|
|
29
|
+
# - keep `systemPrompt` for stable role, boundaries, and hard behavioral rules
|
|
30
|
+
# - use `memory:` for stable project knowledge, operating conventions, and shared or agent-specific context files
|
|
31
|
+
# - use `/memories/*` via the backend/store below for durable knowledge learned from prior runs
|
|
32
|
+
# - use the harness checkpointer for resumable graph state for an in-flight run
|
|
33
|
+
# Updating these files changes future agent constructions, but they are still bootstrap inputs rather than
|
|
34
|
+
# self-updating runtime memory.
|
|
35
|
+
- path: config/agent-context.md
|
|
34
36
|
# DeepAgents aligned feature: store config passed into `createDeepAgent({ store })`.
|
|
35
37
|
# This is the LangGraph store used by `StoreBackend` routes inside the DeepAgents backend.
|
|
36
38
|
# Available `kind` options in this harness: `FileStore`, `InMemoryStore`, `RedisStore`, `PostgresStore`.
|
|
@@ -56,7 +58,8 @@ spec:
|
|
|
56
58
|
# Available route backend `kind` options today: `StoreBackend`.
|
|
57
59
|
kind: StoreBackend
|
|
58
60
|
# DeepAgents aligned feature: system prompt for the orchestration deep agent.
|
|
59
|
-
# This becomes the top-level instruction block for the upstream DeepAgents runtime
|
|
61
|
+
# This becomes the top-level instruction block for the upstream DeepAgents runtime and should hold the
|
|
62
|
+
# agent's durable role, priorities, and behavioral guardrails rather than bulky project facts.
|
|
60
63
|
systemPrompt: |-
|
|
61
64
|
You are the orchestra agent.
|
|
62
65
|
|