@botbotgo/agent-harness 0.0.48 → 0.0.50
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 +129 -321
- package/dist/contracts/types.d.ts +18 -3
- package/dist/extensions.js +38 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/presentation.d.ts +0 -14
- package/dist/presentation.js +0 -146
- package/dist/resource/resource-impl.js +0 -6
- package/dist/runtime/agent-runtime-adapter.d.ts +2 -0
- package/dist/runtime/agent-runtime-adapter.js +90 -7
- package/dist/runtime/declared-middleware.js +13 -1
- package/dist/runtime/harness.d.ts +1 -0
- package/dist/runtime/harness.js +22 -3
- package/dist/runtime/parsing/output-parsing.d.ts +2 -0
- package/dist/runtime/parsing/output-parsing.js +75 -2
- package/dist/workspace/agent-binding-compiler.js +22 -0
- package/dist/workspace/object-loader.js +51 -21
- package/dist/workspace/resource-compilers.js +11 -4
- package/dist/workspace/support/agent-capabilities.js +2 -2
- package/dist/workspace/support/workspace-ref-utils.d.ts +0 -5
- package/dist/workspace/support/workspace-ref-utils.js +1 -11
- package/dist/workspace/validate.js +6 -0
- package/package.json +4 -10
package/README.md
CHANGED
|
@@ -4,20 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
`@botbotgo/agent-harness` is a workspace-shaped application runtime for real agent products.
|
|
6
6
|
|
|
7
|
-
It is not a new agent framework. It is the layer
|
|
7
|
+
It is not a new agent framework. It is the runtime layer around LangChain v1 and DeepAgents that turns one workspace into one operable application runtime.
|
|
8
8
|
|
|
9
|
-
The
|
|
9
|
+
The product boundary is:
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
- application runtime
|
|
11
|
+
- LangChain v1 and DeepAgents own agent execution semantics
|
|
12
|
+
- `agent-harness` owns application runtime semantics
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
That means:
|
|
15
15
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
- public API stays small
|
|
17
|
+
- complex assembly and policy live in YAML
|
|
18
|
+
- runtime lifecycle stays stable even if the backend implementation changes
|
|
19
|
+
|
|
20
|
+
What the runtime provides:
|
|
21
|
+
|
|
22
|
+
- `createAgentHarness(...)`, `run(...)`, `subscribe(...)`, inspection methods, and `stop(...)`
|
|
23
|
+
- YAML-defined workspace assembly for routing, models, tools, stores, MCP, recovery, and maintenance
|
|
24
|
+
- backend-adapted execution with current LangChain v1 and DeepAgents adapters
|
|
25
|
+
- local `resources/tools/` and `resources/skills/` discovery
|
|
26
|
+
- persisted threads, runs, approvals, events, queue state, and recovery metadata
|
|
21
27
|
|
|
22
28
|
## Quick Start
|
|
23
29
|
|
|
@@ -32,8 +38,8 @@ Workspace layout:
|
|
|
32
38
|
```text
|
|
33
39
|
your-workspace/
|
|
34
40
|
config/
|
|
35
|
-
agent-context.md
|
|
36
41
|
workspace.yaml
|
|
42
|
+
agent-context.md
|
|
37
43
|
models.yaml
|
|
38
44
|
embedding-models.yaml
|
|
39
45
|
vector-stores.yaml
|
|
@@ -71,15 +77,16 @@ try {
|
|
|
71
77
|
## Feature List
|
|
72
78
|
|
|
73
79
|
- Workspace runtime for multi-agent applications
|
|
74
|
-
-
|
|
75
|
-
- YAML-defined host routing
|
|
80
|
+
- Small public runtime contract
|
|
81
|
+
- YAML-defined host routing and runtime policy
|
|
82
|
+
- LangChain v1 and DeepAgents backend adaptation
|
|
76
83
|
- Auto-discovered local tools and SKILL packages
|
|
84
|
+
- provider-native tools, MCP tools, and workspace-local tool modules
|
|
85
|
+
- persisted threads, runs, approvals, lifecycle events, and queued runs
|
|
86
|
+
- runtime-managed recovery and checkpoint maintenance
|
|
87
|
+
- structured output and multimodal content preservation in run results
|
|
77
88
|
- MCP bridge support for agent-declared MCP servers
|
|
78
89
|
- MCP server support for exposing harness tools outward
|
|
79
|
-
- Persisted threads, runs, approvals, and lifecycle events
|
|
80
|
-
- Recovery policy and resumable checkpoints
|
|
81
|
-
- Background checkpoint maintenance
|
|
82
|
-
- Runtime-level concurrency control and queued-run persistence
|
|
83
90
|
|
|
84
91
|
## How To Use
|
|
85
92
|
|
|
@@ -91,8 +98,6 @@ import { AgentHarnessRuntime, createAgentHarness } from "@botbotgo/agent-harness
|
|
|
91
98
|
const runtime: AgentHarnessRuntime = await createAgentHarness("/absolute/path/to/workspace");
|
|
92
99
|
```
|
|
93
100
|
|
|
94
|
-
You can also create a runtime from a precompiled `WorkspaceBundle`.
|
|
95
|
-
|
|
96
101
|
`createAgentHarness(...)` loads one workspace, resolves `resources/`, initializes persistence under `runRoot`, and starts runtime maintenance.
|
|
97
102
|
|
|
98
103
|
### Run A Request
|
|
@@ -103,25 +108,28 @@ import { run } from "@botbotgo/agent-harness";
|
|
|
103
108
|
const result = await run(runtime, {
|
|
104
109
|
agentId: "orchestra",
|
|
105
110
|
input: "Summarize the runtime design.",
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
invocation: {
|
|
112
|
+
context: {
|
|
113
|
+
requestId: "req-123",
|
|
114
|
+
},
|
|
115
|
+
inputs: {
|
|
116
|
+
visitCount: 1,
|
|
117
|
+
},
|
|
118
|
+
attachments: {
|
|
119
|
+
"/tmp/spec.md": { content: "draft" },
|
|
120
|
+
},
|
|
111
121
|
},
|
|
112
122
|
});
|
|
113
123
|
```
|
|
114
124
|
|
|
115
|
-
|
|
125
|
+
`run(runtime, { ... })` creates or continues a persisted thread and returns `threadId`, `runId`, `state`, and a simple text `output`. When upstream returns richer output, the runtime also preserves `outputContent`, `contentBlocks`, and `structuredResponse` without making the basic API larger.
|
|
116
126
|
|
|
117
|
-
|
|
127
|
+
Use `invocation` as the runtime-facing request envelope:
|
|
118
128
|
|
|
119
|
-
- `invocation.context` for request-scoped context
|
|
129
|
+
- `invocation.context` for request-scoped execution context
|
|
120
130
|
- `invocation.inputs` for additional structured runtime inputs
|
|
121
131
|
- `invocation.attachments` for attachment-like payloads that the active backend can interpret
|
|
122
132
|
|
|
123
|
-
For compatibility, `context`, `state`, and `files` are still accepted as existing aliases and are normalized into the same runtime invocation envelope.
|
|
124
|
-
|
|
125
133
|
### Let The Runtime Route
|
|
126
134
|
|
|
127
135
|
```ts
|
|
@@ -143,6 +151,9 @@ const result = await run(runtime, {
|
|
|
143
151
|
onChunk(chunk) {
|
|
144
152
|
process.stdout.write(chunk);
|
|
145
153
|
},
|
|
154
|
+
onContentBlocks(blocks) {
|
|
155
|
+
console.log(blocks);
|
|
156
|
+
},
|
|
146
157
|
onEvent(event) {
|
|
147
158
|
console.log(event.eventType, event.payload);
|
|
148
159
|
},
|
|
@@ -152,7 +163,7 @@ const result = await run(runtime, {
|
|
|
152
163
|
|
|
153
164
|
`subscribe(...)` is a read-only observer surface over stored lifecycle events.
|
|
154
165
|
|
|
155
|
-
The event stream includes:
|
|
166
|
+
The runtime event stream includes:
|
|
156
167
|
|
|
157
168
|
- `run.created`
|
|
158
169
|
- `run.queued`
|
|
@@ -183,14 +194,18 @@ These methods return runtime-facing records, not raw persistence or backend chec
|
|
|
183
194
|
### Bridge MCP Servers Into Agents
|
|
184
195
|
|
|
185
196
|
```yaml
|
|
197
|
+
apiVersion: agent-harness/v1alpha1
|
|
198
|
+
kind: Agent
|
|
199
|
+
metadata:
|
|
200
|
+
name: orchestra
|
|
186
201
|
spec:
|
|
202
|
+
execution:
|
|
203
|
+
backend: deepagent
|
|
204
|
+
modelRef: model/default
|
|
187
205
|
mcpServers:
|
|
188
206
|
- name: browser
|
|
189
207
|
command: node
|
|
190
208
|
args: ["./mcp-browser-server.mjs"]
|
|
191
|
-
- name: docs
|
|
192
|
-
transport: http
|
|
193
|
-
url: https://example.com/mcp
|
|
194
209
|
```
|
|
195
210
|
|
|
196
211
|
The runtime discovers MCP tools, filters them through agent configuration, and exposes them like other tools.
|
|
@@ -214,6 +229,11 @@ await stop(runtime);
|
|
|
214
229
|
|
|
215
230
|
## How To Configure
|
|
216
231
|
|
|
232
|
+
Use Kubernetes-style YAML:
|
|
233
|
+
|
|
234
|
+
- collection files use `apiVersion`, plural `kind`, and `spec: []`
|
|
235
|
+
- single-object files use `apiVersion`, singular `kind`, `metadata`, and `spec`
|
|
236
|
+
|
|
217
237
|
Core workspace files:
|
|
218
238
|
|
|
219
239
|
- `config/workspace.yaml`
|
|
@@ -226,24 +246,12 @@ Core workspace files:
|
|
|
226
246
|
- `config/mcp.yaml`
|
|
227
247
|
- `config/agents/direct.yaml`
|
|
228
248
|
- `config/agents/orchestra.yaml`
|
|
229
|
-
- `resources/package.json`
|
|
230
249
|
- `resources/tools/`
|
|
231
250
|
- `resources/skills/`
|
|
232
251
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- collection files use `apiVersion`, plural `kind`, and `spec: []`
|
|
236
|
-
- single-object files use `apiVersion`, singular `kind`, `metadata`, and `spec`
|
|
252
|
+
There are three configuration layers:
|
|
237
253
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
### Client-Configurable YAML Reference
|
|
241
|
-
|
|
242
|
-
This section is the client-facing explanation of what can be configured in YAML today and what each field changes at runtime.
|
|
243
|
-
|
|
244
|
-
There are three layers of client configuration:
|
|
245
|
-
|
|
246
|
-
- runtime-level policy in `config/workspace.yaml`
|
|
254
|
+
- runtime policy in `config/workspace.yaml`
|
|
247
255
|
- reusable object catalogs in `config/*.yaml`
|
|
248
256
|
- agent assembly in `config/agents/*.yaml`
|
|
249
257
|
|
|
@@ -253,92 +261,30 @@ Use this file for runtime-level policy shared by the whole workspace.
|
|
|
253
261
|
|
|
254
262
|
Primary fields:
|
|
255
263
|
|
|
256
|
-
- `runRoot
|
|
257
|
-
- `
|
|
258
|
-
- `routing.
|
|
259
|
-
- `routing.
|
|
260
|
-
- `routing.
|
|
261
|
-
- `
|
|
262
|
-
- `
|
|
263
|
-
- `recovery.
|
|
264
|
-
- `recovery.resumeResumingRunsOnStartup
|
|
265
|
-
- `recovery.maxRecoveryAttempts
|
|
266
|
-
- `maintenance.checkpoints.enabled`: turns on background checkpoint cleanup
|
|
267
|
-
- `maintenance.checkpoints.schedule.intervalSeconds`: maintenance loop interval
|
|
268
|
-
- `maintenance.checkpoints.schedule.runOnStartup`: run checkpoint cleanup during startup
|
|
269
|
-
- `maintenance.checkpoints.policies.maxAgeSeconds`: age-based checkpoint cleanup
|
|
270
|
-
- `maintenance.checkpoints.policies.maxBytes`: size-based checkpoint cleanup
|
|
271
|
-
- `maintenance.checkpoints.sqlite.sweepBatchSize`: batch size for SQLite cleanup scans
|
|
272
|
-
- `maintenance.checkpoints.sqlite.vacuum`: vacuum SQLite after deletions
|
|
264
|
+
- `runRoot`
|
|
265
|
+
- `concurrency.maxConcurrentRuns`
|
|
266
|
+
- `routing.defaultAgentId`
|
|
267
|
+
- `routing.rules`
|
|
268
|
+
- `routing.systemPrompt`
|
|
269
|
+
- `routing.modelRouting`
|
|
270
|
+
- `maintenance.checkpoints`
|
|
271
|
+
- `recovery.enabled`
|
|
272
|
+
- `recovery.resumeResumingRunsOnStartup`
|
|
273
|
+
- `recovery.maxRecoveryAttempts`
|
|
273
274
|
|
|
274
275
|
If `runRoot` is omitted, the runtime defaults to `<workspace-root>/run-data`.
|
|
275
276
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
```yaml
|
|
279
|
-
apiVersion: agent-harness/v1alpha1
|
|
280
|
-
kind: Runtime
|
|
281
|
-
metadata:
|
|
282
|
-
name: default
|
|
283
|
-
spec:
|
|
284
|
-
runRoot: ./.agent
|
|
285
|
-
concurrency:
|
|
286
|
-
maxConcurrentRuns: 3
|
|
287
|
-
routing:
|
|
288
|
-
defaultAgentId: orchestra
|
|
289
|
-
modelRouting: false
|
|
290
|
-
rules:
|
|
291
|
-
- agentId: orchestra
|
|
292
|
-
contains: ["latest", "recent", "today", "news"]
|
|
293
|
-
- agentId: orchestra
|
|
294
|
-
regex:
|
|
295
|
-
- "\\b(create|build|implement|fix|debug|review|inspect)\\b"
|
|
296
|
-
maintenance:
|
|
297
|
-
checkpoints:
|
|
298
|
-
enabled: true
|
|
299
|
-
schedule:
|
|
300
|
-
intervalSeconds: 3600
|
|
301
|
-
runOnStartup: true
|
|
302
|
-
policies:
|
|
303
|
-
maxAgeSeconds: 604800
|
|
304
|
-
sqlite:
|
|
305
|
-
sweepBatchSize: 200
|
|
306
|
-
vacuum: false
|
|
307
|
-
recovery:
|
|
308
|
-
enabled: true
|
|
309
|
-
resumeResumingRunsOnStartup: true
|
|
310
|
-
maxRecoveryAttempts: 3
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
Notes:
|
|
314
|
-
|
|
315
|
-
- `routing.rules` only choose the starting host agent; they do not replace backend planning semantics
|
|
316
|
-
- queued runs are persisted under `runRoot` and continue after process restart
|
|
317
|
-
- `running` runs are only replayed on startup when the bound tools are retryable
|
|
277
|
+
Queued runs are persisted under `runRoot` and continue after process restart. `running` runs are only replayed on startup when the bound tools are retryable.
|
|
318
278
|
|
|
319
279
|
### `config/agent-context.md`
|
|
320
280
|
|
|
321
|
-
Use this file for shared
|
|
281
|
+
Use this file for shared bootstrap context loaded into agents at construction time.
|
|
322
282
|
|
|
323
283
|
Put stable project context here. Do not use it as mutable long-term memory.
|
|
324
284
|
|
|
325
|
-
Good uses:
|
|
326
|
-
|
|
327
|
-
- product positioning
|
|
328
|
-
- codebase conventions
|
|
329
|
-
- stable domain vocabulary
|
|
330
|
-
- organization-specific rules
|
|
331
|
-
|
|
332
|
-
Bad uses:
|
|
333
|
-
|
|
334
|
-
- transient scratch notes
|
|
335
|
-
- per-run execution state
|
|
336
|
-
- approval packets
|
|
337
|
-
- long-term memory that should live in the store
|
|
338
|
-
|
|
339
285
|
### `config/models.yaml`
|
|
340
286
|
|
|
341
|
-
Use
|
|
287
|
+
Use named chat-model presets:
|
|
342
288
|
|
|
343
289
|
```yaml
|
|
344
290
|
apiVersion: agent-harness/v1alpha1
|
|
@@ -348,80 +294,21 @@ spec:
|
|
|
348
294
|
provider: openai
|
|
349
295
|
model: gpt-4.1
|
|
350
296
|
temperature: 0.2
|
|
351
|
-
- name: planner
|
|
352
|
-
provider: openai
|
|
353
|
-
model: gpt-4.1-mini
|
|
354
297
|
```
|
|
355
298
|
|
|
356
|
-
These load as `model
|
|
357
|
-
|
|
358
|
-
Client-configurable model fields:
|
|
359
|
-
|
|
360
|
-
- `name`: catalog name referenced by `model/<name>`
|
|
361
|
-
- `provider`: provider family such as `openai`, `openai-compatible`, `ollama`, `anthropic`, or `google`
|
|
362
|
-
- `model`: provider model id
|
|
363
|
-
- top-level provider init fields such as `temperature`, `baseUrl`, API-specific settings, and client options
|
|
364
|
-
- `clientRef`: optional external client reference
|
|
365
|
-
- `fallbacks`: optional fallback model refs
|
|
366
|
-
- `metadata`: optional model metadata
|
|
299
|
+
These load as `model/<name>`.
|
|
367
300
|
|
|
368
301
|
### `config/embedding-models.yaml`
|
|
369
302
|
|
|
370
|
-
Use
|
|
371
|
-
|
|
372
|
-
```yaml
|
|
373
|
-
apiVersion: agent-harness/v1alpha1
|
|
374
|
-
kind: EmbeddingModels
|
|
375
|
-
spec:
|
|
376
|
-
- name: default
|
|
377
|
-
provider: ollama
|
|
378
|
-
model: nomic-embed-text
|
|
379
|
-
baseUrl: http://localhost:11434
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
Client-configurable embedding fields:
|
|
383
|
-
|
|
384
|
-
- `name`
|
|
385
|
-
- `provider`
|
|
386
|
-
- `model`
|
|
387
|
-
- top-level provider init fields such as `baseUrl`
|
|
388
|
-
- `clientRef`
|
|
389
|
-
- `metadata`
|
|
390
|
-
|
|
391
|
-
These load as `embedding-model/default`.
|
|
303
|
+
Use named embedding-model presets for retrieval-oriented tools.
|
|
392
304
|
|
|
393
305
|
### `config/vector-stores.yaml`
|
|
394
306
|
|
|
395
|
-
Use
|
|
396
|
-
|
|
397
|
-
```yaml
|
|
398
|
-
apiVersion: agent-harness/v1alpha1
|
|
399
|
-
kind: VectorStores
|
|
400
|
-
spec:
|
|
401
|
-
- name: default
|
|
402
|
-
storeKind: LibSQLVectorStore
|
|
403
|
-
url: file:.agent/vector-store.db
|
|
404
|
-
table: rag_chunks
|
|
405
|
-
column: embedding
|
|
406
|
-
embeddingModelRef: embedding-model/default
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
Client-configurable vector store fields:
|
|
410
|
-
|
|
411
|
-
- `name`
|
|
412
|
-
- `storeKind`
|
|
413
|
-
- `url`
|
|
414
|
-
- `authToken`
|
|
415
|
-
- `table`
|
|
416
|
-
- `column`
|
|
417
|
-
- `embeddingModelRef`
|
|
418
|
-
- `metadata`
|
|
419
|
-
|
|
420
|
-
These load as `vector-store/default`.
|
|
307
|
+
Use named vector-store presets referenced by retrieval tools.
|
|
421
308
|
|
|
422
309
|
### `config/stores.yaml`
|
|
423
310
|
|
|
424
|
-
Use
|
|
311
|
+
Use reusable store and checkpointer presets:
|
|
425
312
|
|
|
426
313
|
```yaml
|
|
427
314
|
apiVersion: agent-harness/v1alpha1
|
|
@@ -436,119 +323,31 @@ spec:
|
|
|
436
323
|
checkpointerKind: MemorySaver
|
|
437
324
|
```
|
|
438
325
|
|
|
439
|
-
These load as `store/default` and `checkpointer/default`.
|
|
440
|
-
|
|
441
|
-
Client-configurable store fields:
|
|
442
|
-
|
|
443
|
-
- `kind: Store` for backend stores
|
|
444
|
-
- `kind: Checkpointer` for resumable execution state
|
|
445
|
-
- `name` for refs
|
|
446
|
-
- `storeKind` such as `FileStore`, `InMemoryStore`, `RedisStore`, `PostgresStore`
|
|
447
|
-
- `checkpointerKind` such as `MemorySaver`, `FileCheckpointer`, `SqliteSaver`
|
|
448
|
-
- storage-specific fields such as `path`, connection strings, auth, and provider options
|
|
449
|
-
|
|
450
326
|
### `config/tools.yaml`
|
|
451
327
|
|
|
452
|
-
Use this file for reusable tool
|
|
453
|
-
|
|
454
|
-
Minimal collection form:
|
|
328
|
+
Use this file for reusable tool objects.
|
|
455
329
|
|
|
456
|
-
|
|
457
|
-
apiVersion: agent-harness/v1alpha1
|
|
458
|
-
kind: Tools
|
|
459
|
-
spec:
|
|
460
|
-
- kind: Tool
|
|
461
|
-
name: fetch_docs
|
|
462
|
-
type: function
|
|
463
|
-
description: Fetch a documentation page.
|
|
464
|
-
```
|
|
330
|
+
Supported tool families in the built-in runtime include:
|
|
465
331
|
|
|
466
|
-
|
|
332
|
+
- function tools
|
|
333
|
+
- backend tools
|
|
334
|
+
- MCP tools
|
|
335
|
+
- provider-native tools
|
|
336
|
+
- bundles
|
|
467
337
|
|
|
468
|
-
-
|
|
469
|
-
- `type`: `function`, `backend`, `mcp`, or `bundle`
|
|
470
|
-
- `description`
|
|
471
|
-
- `implementationName` for local JS tool modules
|
|
472
|
-
- `inputSchema.ref`
|
|
473
|
-
- `backend.operation`
|
|
474
|
-
- `mcp.ref` or `mcp.tool`
|
|
475
|
-
- `refs` for bundle composition
|
|
476
|
-
- `hitl.enabled` and `hitl.allow` for approval-gated tools
|
|
477
|
-
- `retryable: true` for tools that are safe to replay during startup recovery
|
|
478
|
-
- `config` for tool-specific options
|
|
338
|
+
Provider-native tools are declared in YAML and resolved directly to upstream provider tool factories such as OpenAI and Anthropic tool objects.
|
|
479
339
|
|
|
480
340
|
Use `retryable` carefully. Mark a tool retryable only when repeated execution is safe or intentionally idempotent.
|
|
481
341
|
|
|
482
342
|
### `config/mcp.yaml`
|
|
483
343
|
|
|
484
|
-
Use this file for
|
|
485
|
-
|
|
486
|
-
```yaml
|
|
487
|
-
apiVersion: agent-harness/v1alpha1
|
|
488
|
-
kind: McpServers
|
|
489
|
-
spec:
|
|
490
|
-
- name: docs
|
|
491
|
-
transport: http
|
|
492
|
-
url: https://example.com/mcp
|
|
493
|
-
- name: local-browser
|
|
494
|
-
transport: stdio
|
|
495
|
-
command: node
|
|
496
|
-
args: ["./mcp-browser-server.mjs"]
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
Client-configurable MCP fields:
|
|
500
|
-
|
|
501
|
-
- `name`
|
|
502
|
-
- `transport`: `stdio`, `http`, `sse`, or `websocket`
|
|
503
|
-
- `command`, `args`, `env`, `cwd` for stdio servers
|
|
504
|
-
- `url`, `token`, `headers` for network servers
|
|
505
|
-
|
|
506
|
-
These load as `mcp/<name>`.
|
|
344
|
+
Use this file for named MCP server presets.
|
|
507
345
|
|
|
508
346
|
### `config/agents/*.yaml`
|
|
509
347
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
```yaml
|
|
513
|
-
apiVersion: agent-harness/v1alpha1
|
|
514
|
-
kind: Agent
|
|
515
|
-
metadata:
|
|
516
|
-
name: orchestra
|
|
517
|
-
spec:
|
|
518
|
-
modelRef: model/default
|
|
519
|
-
execution:
|
|
520
|
-
backend: deepagent
|
|
521
|
-
systemPrompt: Coordinate the request.
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
Only `kind: Agent` is supported for agent objects. Select the concrete backend with `spec.execution.backend`.
|
|
525
|
-
|
|
526
|
-
Common client-configurable agent fields:
|
|
527
|
-
|
|
528
|
-
- `metadata.name`
|
|
529
|
-
- `metadata.description`
|
|
530
|
-
- `spec.execution.backend`
|
|
531
|
-
- `spec.modelRef`
|
|
532
|
-
- `spec.systemPrompt`
|
|
533
|
-
- `spec.tools`
|
|
534
|
-
- `spec.skills`
|
|
535
|
-
- `spec.memory`
|
|
536
|
-
- `spec.checkpointer`
|
|
537
|
-
- `spec.store`
|
|
538
|
-
- `spec.backend`
|
|
539
|
-
- `spec.middleware`
|
|
540
|
-
- `spec.subagents`
|
|
541
|
-
- `spec.mcpServers`
|
|
542
|
-
- `spec.responseFormat`
|
|
543
|
-
- `spec.contextSchema`
|
|
544
|
-
|
|
545
|
-
Typical patterns:
|
|
546
|
-
|
|
547
|
-
- use `direct` as a lightweight host for simple one-turn requests
|
|
548
|
-
- use `orchestra` as the main execution host for tools, multi-step work, and delegation
|
|
549
|
-
- keep routing policy in `config/workspace.yaml`, not buried in prompts
|
|
348
|
+
Agents are always declared with `kind: Agent` and `spec.execution.backend`.
|
|
550
349
|
|
|
551
|
-
Example
|
|
350
|
+
Example lightweight host:
|
|
552
351
|
|
|
553
352
|
```yaml
|
|
554
353
|
apiVersion: agent-harness/v1alpha1
|
|
@@ -561,12 +360,10 @@ spec:
|
|
|
561
360
|
modelRef: model/default
|
|
562
361
|
checkpointer:
|
|
563
362
|
ref: checkpointer/default
|
|
564
|
-
systemPrompt:
|
|
565
|
-
You are the direct agent.
|
|
566
|
-
Answer simple requests directly.
|
|
363
|
+
systemPrompt: Answer simple requests directly.
|
|
567
364
|
```
|
|
568
365
|
|
|
569
|
-
Example
|
|
366
|
+
Example main execution host:
|
|
570
367
|
|
|
571
368
|
```yaml
|
|
572
369
|
apiVersion: agent-harness/v1alpha1
|
|
@@ -593,6 +390,27 @@ spec:
|
|
|
593
390
|
kind: StoreBackend
|
|
594
391
|
```
|
|
595
392
|
|
|
393
|
+
Client-configurable agent fields include:
|
|
394
|
+
|
|
395
|
+
- `metadata.name`
|
|
396
|
+
- `metadata.description`
|
|
397
|
+
- `spec.execution.backend`
|
|
398
|
+
- `spec.modelRef`
|
|
399
|
+
- `spec.systemPrompt`
|
|
400
|
+
- `spec.tools`
|
|
401
|
+
- `spec.skills`
|
|
402
|
+
- `spec.memory`
|
|
403
|
+
- `spec.checkpointer`
|
|
404
|
+
- `spec.store`
|
|
405
|
+
- `spec.backend`
|
|
406
|
+
- `spec.middleware`
|
|
407
|
+
- `spec.subagents`
|
|
408
|
+
- `spec.mcpServers`
|
|
409
|
+
- `spec.responseFormat`
|
|
410
|
+
- `spec.contextSchema`
|
|
411
|
+
|
|
412
|
+
For backend-specific agent options, prefer passing the upstream concept directly in YAML. The loader keeps a small stable product shape, but it also preserves agent-level passthrough fields so new LangChain v1 or DeepAgents parameters can flow into adapters without expanding the public API surface.
|
|
413
|
+
|
|
596
414
|
### `resources/`
|
|
597
415
|
|
|
598
416
|
Use `resources/` for executable local extensions:
|
|
@@ -604,43 +422,33 @@ Tool modules are discovered from `resources/tools/*.js`, `resources/tools/*.mjs`
|
|
|
604
422
|
|
|
605
423
|
The preferred tool module format is exporting `tool({...})`.
|
|
606
424
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
```js
|
|
610
|
-
import { z } from "zod";
|
|
611
|
-
import { tool } from "@botbotgo/agent-harness/tools";
|
|
612
|
-
|
|
613
|
-
export const local_lookup = tool({
|
|
614
|
-
description: "Lookup a ticker from a local tool module.",
|
|
615
|
-
retryable: true,
|
|
616
|
-
schema: {
|
|
617
|
-
ticker: z.string().min(1),
|
|
618
|
-
},
|
|
619
|
-
async invoke(input) {
|
|
620
|
-
return input.ticker.toUpperCase();
|
|
621
|
-
},
|
|
622
|
-
});
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
Keep runtime extension source under `resources/`. Keep tests outside the published source tree, for example under repository `test/`.
|
|
425
|
+
SKILL packages are discovered from `resources/skills/` and attached to agents through YAML.
|
|
626
426
|
|
|
627
427
|
## Design Notes
|
|
628
428
|
|
|
629
|
-
-
|
|
630
|
-
- agent-level execution behavior stays upstream
|
|
429
|
+
- public runtime contract stays generic and small
|
|
631
430
|
- application-level orchestration and lifecycle management stays in the harness
|
|
632
|
-
-
|
|
633
|
-
-
|
|
431
|
+
- upstream LangChain v1 and DeepAgents concepts should be expressed as directly as possible in YAML
|
|
432
|
+
- recovery, approvals, threads, runs, and events are runtime concepts, not backend-specific escape hatches
|
|
433
|
+
- backend implementation details should stay internal unless product requirements force exposure
|
|
434
|
+
- application-level orchestration and lifecycle management stays in the harness
|
|
435
|
+
|
|
436
|
+
In short: `agent-harness` is a public runtime contract generic enough to survive backend changes, while the deep execution semantics stay upstream.
|
|
634
437
|
|
|
635
438
|
## API Summary
|
|
636
439
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
- `
|
|
640
|
-
- `
|
|
641
|
-
- `
|
|
642
|
-
- `
|
|
643
|
-
- `
|
|
644
|
-
- `
|
|
645
|
-
- `
|
|
646
|
-
- `
|
|
440
|
+
Primary exports:
|
|
441
|
+
|
|
442
|
+
- `createAgentHarness`
|
|
443
|
+
- `run`
|
|
444
|
+
- `subscribe`
|
|
445
|
+
- `listThreads`
|
|
446
|
+
- `getThread`
|
|
447
|
+
- `deleteThread`
|
|
448
|
+
- `listApprovals`
|
|
449
|
+
- `getApproval`
|
|
450
|
+
- `createToolMcpServer`
|
|
451
|
+
- `serveToolsOverStdio`
|
|
452
|
+
- `stop`
|
|
453
|
+
|
|
454
|
+
`AgentHarnessRuntime` is the concrete runtime class behind the public facade.
|
|
@@ -96,6 +96,12 @@ export type LangChainAgentParams = {
|
|
|
96
96
|
responseFormat?: unknown;
|
|
97
97
|
contextSchema?: unknown;
|
|
98
98
|
middleware?: Array<Record<string, unknown>>;
|
|
99
|
+
passthrough?: Record<string, unknown>;
|
|
100
|
+
subagents?: CompiledSubAgent[];
|
|
101
|
+
memory?: string[];
|
|
102
|
+
skills?: string[];
|
|
103
|
+
generalPurposeAgent?: boolean;
|
|
104
|
+
taskDescription?: string;
|
|
99
105
|
includeAgentName?: "inline";
|
|
100
106
|
version?: "v1" | "v2";
|
|
101
107
|
name?: string;
|
|
@@ -113,6 +119,7 @@ export type CompiledSubAgent = {
|
|
|
113
119
|
responseFormat?: unknown;
|
|
114
120
|
contextSchema?: unknown;
|
|
115
121
|
middleware?: Array<Record<string, unknown>>;
|
|
122
|
+
passthrough?: Record<string, unknown>;
|
|
116
123
|
};
|
|
117
124
|
export type DeepAgentParams = {
|
|
118
125
|
model: CompiledModel;
|
|
@@ -121,6 +128,7 @@ export type DeepAgentParams = {
|
|
|
121
128
|
responseFormat?: unknown;
|
|
122
129
|
contextSchema?: unknown;
|
|
123
130
|
middleware?: Array<Record<string, unknown>>;
|
|
131
|
+
passthrough?: Record<string, unknown>;
|
|
124
132
|
description: string;
|
|
125
133
|
subagents: CompiledSubAgent[];
|
|
126
134
|
interruptOn?: Record<string, boolean | object>;
|
|
@@ -252,6 +260,9 @@ export type RunResult = {
|
|
|
252
260
|
state: RunState;
|
|
253
261
|
output: string;
|
|
254
262
|
finalMessageText?: string;
|
|
263
|
+
outputContent?: unknown;
|
|
264
|
+
contentBlocks?: unknown[];
|
|
265
|
+
structuredResponse?: unknown;
|
|
255
266
|
interruptContent?: string;
|
|
256
267
|
agentId?: string;
|
|
257
268
|
approvalId?: string;
|
|
@@ -262,6 +273,7 @@ export type RunResult = {
|
|
|
262
273
|
};
|
|
263
274
|
export type RunListeners = {
|
|
264
275
|
onChunk?: (chunk: string) => void | Promise<void>;
|
|
276
|
+
onContentBlocks?: (blocks: unknown[]) => void | Promise<void>;
|
|
265
277
|
onEvent?: (event: HarnessEvent) => void | Promise<void>;
|
|
266
278
|
onReasoning?: (chunk: string) => void | Promise<void>;
|
|
267
279
|
onStep?: (step: string) => void | Promise<void>;
|
|
@@ -290,9 +302,6 @@ export type RunStartOptions = {
|
|
|
290
302
|
input: MessageContent;
|
|
291
303
|
threadId?: string;
|
|
292
304
|
invocation?: InvocationEnvelope;
|
|
293
|
-
context?: Record<string, unknown>;
|
|
294
|
-
state?: Record<string, unknown>;
|
|
295
|
-
files?: Record<string, unknown>;
|
|
296
305
|
listeners?: RunListeners;
|
|
297
306
|
};
|
|
298
307
|
export type RunDecisionOptions = {
|
|
@@ -316,6 +325,12 @@ export type HarnessStreamItem = {
|
|
|
316
325
|
runId: string;
|
|
317
326
|
agentId: string;
|
|
318
327
|
content: string;
|
|
328
|
+
} | {
|
|
329
|
+
type: "content-blocks";
|
|
330
|
+
threadId: string;
|
|
331
|
+
runId: string;
|
|
332
|
+
agentId: string;
|
|
333
|
+
contentBlocks: unknown[];
|
|
319
334
|
} | {
|
|
320
335
|
type: "reasoning";
|
|
321
336
|
threadId: string;
|