@botbotgo/agent-harness 0.0.18 → 0.0.20
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 +87 -490
- 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 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,14 +31,14 @@ 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/
|
|
39
|
+
agent-context.md
|
|
40
|
+
workspace.yaml
|
|
51
41
|
models.yaml
|
|
52
|
-
runtime.yaml
|
|
53
42
|
agents/
|
|
54
43
|
direct.yaml
|
|
55
44
|
orchestra.yaml
|
|
@@ -77,29 +66,23 @@ try {
|
|
|
77
66
|
}
|
|
78
67
|
```
|
|
79
68
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
## How To Use
|
|
83
|
-
|
|
84
|
-
There are two common ways to use the framework.
|
|
85
|
-
|
|
86
|
-
### 1. Use It As A Library
|
|
87
|
-
|
|
88
|
-
Load a workspace from disk and run requests through the public API.
|
|
89
|
-
|
|
90
|
-
#### SDK Surface
|
|
69
|
+
## Feature List
|
|
91
70
|
|
|
92
|
-
|
|
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`
|
|
93
80
|
|
|
94
|
-
|
|
95
|
-
- `run(...)`: start a new run or answer an approval request
|
|
96
|
-
- `subscribe(...)`: observe runtime events for logging or UI updates
|
|
97
|
-
- `getThread(...)`: fetch persisted thread state and messages
|
|
98
|
-
- `stop(...)`: release runtime resources when your process is done
|
|
81
|
+
## How To Use
|
|
99
82
|
|
|
100
|
-
|
|
83
|
+
### Create A Harness
|
|
101
84
|
|
|
102
|
-
|
|
85
|
+
Pass a workspace root:
|
|
103
86
|
|
|
104
87
|
```ts
|
|
105
88
|
import { createAgentHarness } from "@botbotgo/agent-harness";
|
|
@@ -107,519 +90,133 @@ import { createAgentHarness } from "@botbotgo/agent-harness";
|
|
|
107
90
|
const harness = await createAgentHarness("/absolute/path/to/workspace");
|
|
108
91
|
```
|
|
109
92
|
|
|
110
|
-
|
|
93
|
+
Or pass a prebuilt `WorkspaceBundle`:
|
|
111
94
|
|
|
112
95
|
```ts
|
|
113
|
-
const harness = await createAgentHarness();
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
#### Create A Harness From A Prebuilt WorkspaceBundle
|
|
117
|
-
|
|
118
|
-
If your application compiles a workspace in code, or you want tighter control in tests, you can pass a `WorkspaceBundle` directly.
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
import { createAgentHarness } from "@botbotgo/agent-harness";
|
|
122
|
-
|
|
123
96
|
const harness = await createAgentHarness(workspaceBundle);
|
|
124
97
|
```
|
|
125
98
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
Use `run(...)` with an `agentId` and plain-text `input`. The return value includes:
|
|
129
|
-
|
|
130
|
-
- `threadId`: stable conversation id
|
|
131
|
-
- `runId`: the current execution id
|
|
132
|
-
- `state`: final state such as `completed` or `waiting_for_approval`
|
|
133
|
-
- `output`: final visible model output
|
|
99
|
+
### Run A Request
|
|
134
100
|
|
|
135
101
|
```ts
|
|
136
|
-
import {
|
|
102
|
+
import { run } from "@botbotgo/agent-harness";
|
|
137
103
|
|
|
138
|
-
const
|
|
104
|
+
const result = await run(harness, {
|
|
105
|
+
agentId: "direct",
|
|
106
|
+
input: "Explain the available agents in this workspace.",
|
|
107
|
+
});
|
|
108
|
+
```
|
|
139
109
|
|
|
140
|
-
|
|
141
|
-
const result = await run(harness, {
|
|
142
|
-
agentId: "direct",
|
|
143
|
-
input: "Summarize what this workspace is for.",
|
|
144
|
-
});
|
|
110
|
+
The result includes:
|
|
145
111
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
} finally {
|
|
151
|
-
await stop(harness);
|
|
152
|
-
}
|
|
153
|
-
```
|
|
112
|
+
- `threadId`
|
|
113
|
+
- `runId`
|
|
114
|
+
- `state`
|
|
115
|
+
- `output`
|
|
154
116
|
|
|
155
|
-
|
|
117
|
+
### Let The Harness Choose The Host Agent
|
|
156
118
|
|
|
157
|
-
|
|
119
|
+
Use `agentId: "auto"` when your workspace defines routing:
|
|
158
120
|
|
|
159
121
|
```ts
|
|
160
122
|
const result = await run(harness, {
|
|
161
123
|
agentId: "auto",
|
|
162
|
-
input: "Inspect this repository and explain
|
|
124
|
+
input: "Inspect this repository and explain the release flow.",
|
|
163
125
|
});
|
|
164
126
|
```
|
|
165
127
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
#### Stream Chunks And Runtime Events
|
|
169
|
-
|
|
170
|
-
`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
|
|
171
129
|
|
|
172
130
|
```ts
|
|
173
131
|
const result = await run(harness, {
|
|
174
132
|
agentId: "orchestra",
|
|
175
|
-
input: "Inspect the workspace and explain the available
|
|
133
|
+
input: "Inspect the workspace and explain the available tools.",
|
|
176
134
|
listeners: {
|
|
177
135
|
onChunk(chunk) {
|
|
178
136
|
process.stdout.write(chunk);
|
|
179
137
|
},
|
|
180
138
|
onEvent(event) {
|
|
181
|
-
console.log(
|
|
182
|
-
},
|
|
183
|
-
onStep(step) {
|
|
184
|
-
console.log("step:", step);
|
|
185
|
-
},
|
|
186
|
-
onToolResult(item) {
|
|
187
|
-
console.log("tool:", item.toolName, item.output);
|
|
139
|
+
console.log(event.eventType, event.payload);
|
|
188
140
|
},
|
|
189
141
|
},
|
|
190
142
|
});
|
|
191
143
|
```
|
|
192
144
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
- `onChunk`: streamed user-visible response text
|
|
196
|
-
- `onEvent`: raw runtime events
|
|
197
|
-
- `onStep`: higher-level execution step messages
|
|
198
|
-
- `onToolResult`: completed tool outputs
|
|
199
|
-
- `onReasoning`: reasoning-channel text when available from the runtime
|
|
200
|
-
|
|
201
|
-
#### Subscribe To Global Harness Events
|
|
202
|
-
|
|
203
|
-
Use `subscribe(...)` when you want a process-wide event feed rather than per-run listeners.
|
|
204
|
-
|
|
205
|
-
```ts
|
|
206
|
-
import { subscribe } from "@botbotgo/agent-harness";
|
|
207
|
-
|
|
208
|
-
const unsubscribe = subscribe(harness, (event) => {
|
|
209
|
-
console.log(event.threadId, event.runId, event.eventType);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
// later
|
|
213
|
-
unsubscribe();
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
This is useful when one process is handling multiple runs or updating a central UI.
|
|
217
|
-
|
|
218
|
-
#### Continue An Existing Thread
|
|
219
|
-
|
|
220
|
-
Pass an existing `threadId` to keep the conversation on the same persisted thread.
|
|
221
|
-
|
|
222
|
-
```ts
|
|
223
|
-
const first = await run(harness, {
|
|
224
|
-
agentId: "direct",
|
|
225
|
-
input: "Remember that the release branch is master.",
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
const second = await run(harness, {
|
|
229
|
-
agentId: "direct",
|
|
230
|
-
threadId: first.threadId,
|
|
231
|
-
input: "What did I just tell you about the release branch?",
|
|
232
|
-
});
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
#### Read Back Thread State
|
|
236
|
-
|
|
237
|
-
Use `getThread(...)` to fetch persisted thread data after a run completes.
|
|
145
|
+
### Read Back Thread State
|
|
238
146
|
|
|
239
147
|
```ts
|
|
240
148
|
import { getThread } from "@botbotgo/agent-harness";
|
|
241
149
|
|
|
242
150
|
const thread = await getThread(harness, result.threadId);
|
|
243
|
-
|
|
244
|
-
console.log(thread?.threadId);
|
|
245
151
|
console.log(thread?.messages.at(-1)?.content);
|
|
246
152
|
```
|
|
247
153
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
#### Handle Approval Or Interrupt Flows
|
|
251
|
-
|
|
252
|
-
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.
|
|
253
|
-
|
|
254
|
-
```ts
|
|
255
|
-
const pending = await run(harness, {
|
|
256
|
-
agentId: "orchestra",
|
|
257
|
-
input: "Run the protected action if approval is required.",
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
if (pending.state === "waiting_for_approval" && pending.approvalId) {
|
|
261
|
-
const resumed = await run(harness, {
|
|
262
|
-
threadId: pending.threadId,
|
|
263
|
-
runId: pending.runId,
|
|
264
|
-
approvalId: pending.approvalId,
|
|
265
|
-
decision: "approve",
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
console.log(resumed.output);
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Use `decision: "edit"` plus `editedInput` when your application exposes approval-time parameter editing.
|
|
273
|
-
|
|
274
|
-
#### Always Stop The Harness
|
|
275
|
-
|
|
276
|
-
Call `stop(...)` before process exit so the runtime can close adapters and flush state cleanly.
|
|
154
|
+
### Subscribe To Global Events
|
|
277
155
|
|
|
278
156
|
```ts
|
|
279
|
-
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
For most applications, the safe pattern is `try/finally`.
|
|
283
|
-
|
|
284
|
-
#### Complete SDK CLI Example
|
|
285
|
-
|
|
286
|
-
The following example shows a small CLI-style integration that:
|
|
287
|
-
|
|
288
|
-
- loads a workspace from disk
|
|
289
|
-
- starts a first run with streaming output
|
|
290
|
-
- continues the same thread
|
|
291
|
-
- reads the saved thread state back
|
|
292
|
-
- shuts the harness down cleanly
|
|
293
|
-
|
|
294
|
-
```ts
|
|
295
|
-
import { createAgentHarness, getThread, run, stop } from "@botbotgo/agent-harness";
|
|
296
|
-
|
|
297
|
-
const workspaceRoot = "/absolute/path/to/workspace";
|
|
298
|
-
const harness = await createAgentHarness(workspaceRoot);
|
|
299
|
-
|
|
300
|
-
try {
|
|
301
|
-
const first = await run(harness, {
|
|
302
|
-
agentId: "auto",
|
|
303
|
-
input: "Explain what agents and tools are available in this workspace.",
|
|
304
|
-
listeners: {
|
|
305
|
-
onChunk(chunk) {
|
|
306
|
-
process.stdout.write(chunk);
|
|
307
|
-
},
|
|
308
|
-
onStep(step) {
|
|
309
|
-
console.log("\n[step]", step);
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
console.log("\nfirst run:", first.runId, first.state);
|
|
315
|
-
|
|
316
|
-
const second = await run(harness, {
|
|
317
|
-
agentId: "auto",
|
|
318
|
-
threadId: first.threadId,
|
|
319
|
-
input: "Now give me the shortest possible summary in 3 bullets.",
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
console.log("\nsecond run output:\n", second.output);
|
|
323
|
-
|
|
324
|
-
const thread = await getThread(harness, first.threadId);
|
|
325
|
-
console.log("\nthread message count:", thread?.messages.length ?? 0);
|
|
326
|
-
} finally {
|
|
327
|
-
await stop(harness);
|
|
328
|
-
}
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
For a real CLI entrypoint, wrap this in an async `main()` and feed the prompt from `process.argv`.
|
|
332
|
-
|
|
333
|
-
```ts
|
|
334
|
-
import { createAgentHarness, getThread, run, subscribe, stop } from "@botbotgo/agent-harness";
|
|
335
|
-
|
|
336
|
-
const harness = await createAgentHarness("/absolute/path/to/workspace");
|
|
157
|
+
import { subscribe } from "@botbotgo/agent-harness";
|
|
337
158
|
|
|
338
159
|
const unsubscribe = subscribe(harness, (event) => {
|
|
339
|
-
console.log(event.
|
|
160
|
+
console.log(event.threadId, event.runId, event.eventType);
|
|
340
161
|
});
|
|
341
|
-
|
|
342
|
-
try {
|
|
343
|
-
const firstRun = await run(harness, {
|
|
344
|
-
agentId: "orchestra",
|
|
345
|
-
input: "Inspect the workspace and explain the available agents.",
|
|
346
|
-
listeners: {
|
|
347
|
-
onChunk(chunk) {
|
|
348
|
-
process.stdout.write(chunk);
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
const thread = await getThread(harness, firstRun.threadId);
|
|
354
|
-
console.log(thread?.messages.at(-1)?.content);
|
|
355
|
-
} finally {
|
|
356
|
-
unsubscribe();
|
|
357
|
-
await stop(harness);
|
|
358
|
-
}
|
|
359
162
|
```
|
|
360
163
|
|
|
361
|
-
###
|
|
362
|
-
|
|
363
|
-
The example app in [`examples/stock-research-app`](/Users/boqiang.liang/900-project/agent-harness/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
|
|
364
165
|
|
|
365
|
-
|
|
166
|
+
```ts
|
|
167
|
+
import { stop } from "@botbotgo/agent-harness";
|
|
366
168
|
|
|
367
|
-
|
|
368
|
-
cd examples/stock-research-app
|
|
369
|
-
npm install
|
|
370
|
-
npm run start -- "Investigate NVDA and produce a balanced stock research brief."
|
|
169
|
+
await stop(harness);
|
|
371
170
|
```
|
|
372
171
|
|
|
373
172
|
## How To Configure
|
|
374
173
|
|
|
375
|
-
|
|
174
|
+
Core workspace files:
|
|
376
175
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
- `
|
|
380
|
-
- `config/
|
|
381
|
-
- `config/runtime.yaml`: workspace-wide runtime defaults such as `runRoot` and host routing
|
|
382
|
-
- `config/agents/direct.yaml`: lightweight direct-response host agent
|
|
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
|
|
383
180
|
- `config/agents/orchestra.yaml`: default orchestration host agent
|
|
384
|
-
- `
|
|
385
|
-
- `
|
|
386
|
-
- `resources/
|
|
387
|
-
- `resources/tools/`: local code-authored tools discovered automatically
|
|
388
|
-
- `resources/skills/`: local skills and skill-local assets
|
|
389
|
-
|
|
390
|
-
### Minimal Model Config
|
|
391
|
-
|
|
392
|
-
```yaml
|
|
393
|
-
apiVersion: agent-harness/v1alpha1
|
|
394
|
-
kind: Models
|
|
395
|
-
spec:
|
|
396
|
-
- name: default
|
|
397
|
-
provider: ollama
|
|
398
|
-
model: gpt-oss:latest
|
|
399
|
-
init:
|
|
400
|
-
baseUrl: http://localhost:11434
|
|
401
|
-
temperature: 0.2
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
### Runtime Routing
|
|
405
|
-
|
|
406
|
-
`config/runtime.yaml` controls shared runtime behavior. In this repo it defines:
|
|
407
|
-
|
|
408
|
-
- `runRoot`: where thread state, run artifacts, approvals, and indexes are stored
|
|
409
|
-
- `routing.systemPrompt`: how the harness chooses between the primary and secondary host agents when `agentId: "auto"` is used
|
|
181
|
+
- `resources/package.json`: resource package boundary
|
|
182
|
+
- `resources/tools/`: local tool modules
|
|
183
|
+
- `resources/skills/`: local skills
|
|
410
184
|
|
|
411
|
-
###
|
|
185
|
+
### `config/workspace.yaml`
|
|
412
186
|
|
|
413
|
-
|
|
187
|
+
Use this file for workspace-wide behavior such as:
|
|
414
188
|
|
|
415
|
-
- `
|
|
416
|
-
- `
|
|
189
|
+
- `runRoot`
|
|
190
|
+
- routing via `routing.systemPrompt`
|
|
191
|
+
- background checkpoint maintenance via `maintenance.checkpoints.*`
|
|
417
192
|
|
|
418
|
-
|
|
193
|
+
### `config/agent-context.md`
|
|
419
194
|
|
|
420
|
-
|
|
421
|
-
- `metadata.description`
|
|
422
|
-
- `spec.modelRef`
|
|
423
|
-
- `spec.systemPrompt`
|
|
424
|
-
- `spec.tools`
|
|
425
|
-
- `spec.mcpServers`
|
|
426
|
-
- `spec.checkpointer`
|
|
427
|
-
- `spec.memory`
|
|
428
|
-
- `spec.store`
|
|
429
|
-
- `spec.backend`
|
|
195
|
+
Use this file for shared bootstrap context that agents should read at construction time.
|
|
430
196
|
|
|
431
|
-
|
|
197
|
+
Put stable project context here, not long-term mutable memory.
|
|
432
198
|
|
|
433
|
-
|
|
199
|
+
If a runnable app workspace also includes `AGENTS.md`, treat that file as workspace-level operating guidance. It complements `config/agents/*.yaml` rather than replacing it: `AGENTS.md` carries durable behavioral rules, while `config/agents/` defines agent topology and runtime configuration.
|
|
434
200
|
|
|
435
|
-
|
|
201
|
+
### Agent YAML
|
|
436
202
|
|
|
437
|
-
`
|
|
203
|
+
Use `config/agents/*.yaml` to configure agents. Common fields include:
|
|
438
204
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
```js
|
|
442
|
-
import { z } from "zod";
|
|
443
|
-
import { tool } from "@botbotgo/agent-harness/tools";
|
|
444
|
-
|
|
445
|
-
export const stock_lookup = tool({
|
|
446
|
-
description: "Lookup a ticker.",
|
|
447
|
-
schema: {
|
|
448
|
-
ticker: z.string().min(1),
|
|
449
|
-
},
|
|
450
|
-
async invoke(input) {
|
|
451
|
-
return input.ticker.toUpperCase();
|
|
452
|
-
},
|
|
453
|
-
});
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
Then reference the tool from the agent:
|
|
457
|
-
|
|
458
|
-
```yaml
|
|
459
|
-
spec:
|
|
460
|
-
tools:
|
|
461
|
-
- tool/stock_lookup
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
### MCP Servers On Agents
|
|
465
|
-
|
|
466
|
-
MCP servers are configured directly on the agent. The framework connects to each server, lists its remote tools, and automatically exposes the selected ones on that agent.
|
|
467
|
-
|
|
468
|
-
```yaml
|
|
469
|
-
spec:
|
|
470
|
-
modelRef: model/default
|
|
471
|
-
mcpServers:
|
|
472
|
-
- name: chrome-devtools
|
|
473
|
-
command: npx
|
|
474
|
-
args:
|
|
475
|
-
- chrome-devtools-mcp@latest
|
|
476
|
-
toolFilter:
|
|
477
|
-
- ^page_
|
|
478
|
-
- ^network_
|
|
479
|
-
excludeToolFilter:
|
|
480
|
-
- _deprecated$
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
Supported MCP fields:
|
|
484
|
-
|
|
485
|
-
- `name`
|
|
486
|
-
- `command`, `args`, `env`, `cwd`
|
|
487
|
-
- `transport`, `url`, `token`, `headers`
|
|
205
|
+
- `modelRef`
|
|
206
|
+
- `systemPrompt`
|
|
488
207
|
- `tools`
|
|
489
|
-
- `
|
|
490
|
-
- `
|
|
491
|
-
- `
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
The extension model is filesystem-based. You extend the harness by adding new config objects, new discovery roots, or new resource packages.
|
|
496
|
-
|
|
497
|
-
### Add More Agents
|
|
498
|
-
|
|
499
|
-
Agents live under config roots such as `config/agents/`. The discovery layer supports:
|
|
500
|
-
|
|
501
|
-
- local filesystem paths
|
|
502
|
-
- external resource sources
|
|
503
|
-
- builtin discovery paths
|
|
208
|
+
- `skills`
|
|
209
|
+
- `memory`
|
|
210
|
+
- `checkpointer`
|
|
211
|
+
- `store`
|
|
212
|
+
- `backend`
|
|
213
|
+
- `subagents`
|
|
504
214
|
|
|
505
|
-
|
|
215
|
+
### Resource Package
|
|
506
216
|
|
|
507
|
-
|
|
217
|
+
Use `resources/` for executable extensions:
|
|
508
218
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
- a direct `SKILL.md`
|
|
512
|
-
- child directories where each directory contains its own `SKILL.md`
|
|
513
|
-
|
|
514
|
-
`SKILL.md` should use YAML frontmatter. The harness reads `name` and the standard `stack` field from frontmatter, then exposes that metadata through runtime inventory helpers such as `listAgentSkills(...)` and `builtin.list_available_skills`.
|
|
515
|
-
|
|
516
|
-
Example:
|
|
517
|
-
|
|
518
|
-
```md
|
|
519
|
-
---
|
|
520
|
-
name: code-review
|
|
521
|
-
description: Review code changes for correctness and regression risk.
|
|
522
|
-
stack:
|
|
523
|
-
- typescript
|
|
524
|
-
- vitest
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
# Code Review
|
|
528
|
-
|
|
529
|
-
Use this skill when the user wants a correctness-focused review of a patch.
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
Notes:
|
|
533
|
-
|
|
534
|
-
- `name` should be stable and unique within the discovered skill set
|
|
535
|
-
- `stack` should be a list of technologies, frameworks, or platforms the skill is designed for
|
|
536
|
-
- if `stack` is omitted, the runtime treats it as an empty list
|
|
537
|
-
|
|
538
|
-
A practical layout looks like this:
|
|
539
|
-
|
|
540
|
-
```text
|
|
541
|
-
your-workspace/
|
|
542
|
-
resources/
|
|
543
|
-
skills/
|
|
544
|
-
code-review/
|
|
545
|
-
SKILL.md
|
|
546
|
-
release-check/
|
|
547
|
-
SKILL.md
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
### Add Tools
|
|
551
|
-
|
|
552
|
-
Tools can come from:
|
|
553
|
-
|
|
554
|
-
- local modules under `resources/tools/`
|
|
555
|
-
- external sources
|
|
556
|
-
- builtin resources
|
|
557
|
-
- MCP servers declared on an agent under `spec.mcpServers`
|
|
558
|
-
|
|
559
|
-
The example application demonstrates the local pattern: keep app-specific tools under `resources/tools/` and keep one tool per module.
|
|
560
|
-
|
|
561
|
-
Dependency rule:
|
|
562
|
-
|
|
563
|
-
- declare tool runtime dependencies in `resources/package.json`
|
|
564
|
-
- do not rely on the app root `package.json` for modules imported by files under `resources/tools/`
|
|
565
|
-
- keep reusable helper modules for tools under `resources/` so they stay inside the same package boundary
|
|
566
|
-
|
|
567
|
-
### Add Retrieval
|
|
568
|
-
|
|
569
|
-
If your workspace needs RAG-style behavior:
|
|
570
|
-
|
|
571
|
-
1. add an `EmbeddingModel`
|
|
572
|
-
2. add a `VectorStore`
|
|
573
|
-
3. point retrieval-oriented tools at those refs
|
|
574
|
-
|
|
575
|
-
This repo already includes `config/embedding-model.yaml` and `config/vector-store.yaml` as the default pattern.
|
|
576
|
-
|
|
577
|
-
### Extend The Runtime In Code
|
|
578
|
-
|
|
579
|
-
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.
|
|
580
|
-
|
|
581
|
-
## Suggested Workspace Layout
|
|
582
|
-
|
|
583
|
-
```text
|
|
584
|
-
your-workspace/
|
|
585
|
-
AGENTS.md
|
|
586
|
-
config/
|
|
587
|
-
models.yaml
|
|
588
|
-
runtime.yaml
|
|
589
|
-
agents/
|
|
590
|
-
direct.yaml
|
|
591
|
-
orchestra.yaml
|
|
592
|
-
embedding-model.yaml
|
|
593
|
-
vector-store.yaml
|
|
594
|
-
resources/
|
|
595
|
-
package.json
|
|
596
|
-
skills/
|
|
597
|
-
tools/
|
|
598
|
-
.agent/
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
## Release Flow
|
|
602
|
-
|
|
603
|
-
Publishing is automated from `master`.
|
|
604
|
-
|
|
605
|
-
When a commit lands on `master`, the GitHub `Release` workflow:
|
|
606
|
-
|
|
607
|
-
1. runs `npm ci`, `npm run build`, `npm run check`, and `npm test`
|
|
608
|
-
2. bumps the package with `npm version patch --no-git-tag-version`
|
|
609
|
-
3. syncs `examples/stock-research-app/package.json` to the new package version
|
|
610
|
-
4. commits the version change back to `master` and creates a matching `v*` tag
|
|
611
|
-
5. verifies the tarball and publishes to npm
|
|
612
|
-
|
|
613
|
-
That means normal feature and fix commits should not manually edit the package version. Version bumps are owned by the release workflow.
|
|
614
|
-
|
|
615
|
-
## Development
|
|
616
|
-
|
|
617
|
-
Build and test this package locally:
|
|
618
|
-
|
|
619
|
-
```bash
|
|
620
|
-
npm run build
|
|
621
|
-
npm run check
|
|
622
|
-
npm test
|
|
623
|
-
```
|
|
219
|
+
- `resources/tools/` for local tool modules
|
|
220
|
+
- `resources/skills/` for skill packages
|
|
624
221
|
|
|
625
|
-
|
|
222
|
+
Each resource package should include its own `package.json`.
|