@botbotgo/agent-harness 0.0.52 → 0.0.54
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 +50 -67
- package/dist/api.d.ts +2 -2
- package/dist/api.js +5 -4
- package/dist/config/agents/direct.yaml +22 -1
- package/dist/config/agents/orchestra.yaml +20 -1
- package/dist/config/backends.yaml +2 -0
- package/dist/config/stores.yaml +7 -0
- package/dist/contracts/types.d.ts +0 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/declared-middleware.d.ts +9 -0
- package/dist/runtime/declared-middleware.js +75 -78
- package/dist/workspace/agent-binding-compiler.js +0 -1
- package/dist/workspace/object-loader.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,21 +6,21 @@
|
|
|
6
6
|
|
|
7
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 boundary is strict:
|
|
9
|
+
The product boundary is strict:
|
|
10
10
|
|
|
11
11
|
- LangChain v1 and DeepAgents own agent execution semantics
|
|
12
|
-
- `agent-harness` owns application-level orchestration and lifecycle management
|
|
12
|
+
- `agent-harness` owns application-level orchestration and lifecycle management stays in the harness
|
|
13
13
|
|
|
14
14
|
That means:
|
|
15
15
|
|
|
16
16
|
- public API stays small
|
|
17
17
|
- complex setup and operating policy live in YAML
|
|
18
|
-
- application-level orchestration and lifecycle management stays in the harness
|
|
19
18
|
- runtime lifecycle stays stable even if backend implementations change
|
|
19
|
+
- backend internals stay behind adapters
|
|
20
20
|
|
|
21
21
|
What the runtime provides:
|
|
22
22
|
|
|
23
|
-
- `createAgentHarness(
|
|
23
|
+
- `createAgentHarness(workspaceRoot)`, `run(...)`, `resolveApproval(...)`, `subscribe(...)`, inspection methods, and `stop(...)`
|
|
24
24
|
- YAML-defined workspace assembly for routing, models, tools, stores, backends, MCP, recovery, and maintenance
|
|
25
25
|
- backend-adapted execution with current LangChain v1 and DeepAgents adapters
|
|
26
26
|
- local `resources/tools/` and `resources/skills/` discovery
|
|
@@ -124,12 +124,12 @@ const result = await run(runtime, {
|
|
|
124
124
|
});
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
`run(runtime, { ... })` creates or continues a persisted thread and returns `threadId`, `runId`, `state`, and a
|
|
127
|
+
`run(runtime, { ... })` creates or continues a persisted thread and returns `threadId`, `runId`, `state`, and a compact text `output`. Richer upstream results remain available through `outputContent`, `contentBlocks`, and `structuredResponse` without expanding the main facade.
|
|
128
128
|
|
|
129
129
|
Use `invocation` as the runtime-facing request envelope:
|
|
130
130
|
|
|
131
131
|
- `invocation.context` for request-scoped execution context
|
|
132
|
-
- `invocation.inputs` for
|
|
132
|
+
- `invocation.inputs` for structured runtime inputs
|
|
133
133
|
- `invocation.attachments` for attachment-like payloads that the active backend can interpret
|
|
134
134
|
|
|
135
135
|
### Let The Runtime Route
|
|
@@ -141,7 +141,7 @@ const result = await run(runtime, {
|
|
|
141
141
|
});
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
`agentId: "auto"` evaluates ordered `
|
|
144
|
+
`agentId: "auto"` evaluates ordered routing rules in `config/workspace.yaml`, then `routing.defaultAgentId`, and only falls back to model routing when `routing.modelRouting: true`.
|
|
145
145
|
|
|
146
146
|
### Stream Output And Events
|
|
147
147
|
|
|
@@ -183,12 +183,20 @@ import {
|
|
|
183
183
|
getThread,
|
|
184
184
|
listApprovals,
|
|
185
185
|
listThreads,
|
|
186
|
+
resolveApproval,
|
|
186
187
|
} from "@botbotgo/agent-harness";
|
|
187
188
|
|
|
188
189
|
const threads = await listThreads(runtime);
|
|
189
190
|
const thread = await getThread(runtime, threads[0]!.threadId);
|
|
190
191
|
const approvals = await listApprovals(runtime, { status: "pending" });
|
|
191
192
|
const approval = approvals[0] ? await getApproval(runtime, approvals[0].approvalId) : null;
|
|
193
|
+
|
|
194
|
+
if (approval) {
|
|
195
|
+
await resolveApproval(runtime, {
|
|
196
|
+
approvalId: approval.approvalId,
|
|
197
|
+
decision: "approve",
|
|
198
|
+
});
|
|
199
|
+
}
|
|
192
200
|
```
|
|
193
201
|
|
|
194
202
|
These methods return runtime-facing records, not raw persistence or backend checkpoint objects.
|
|
@@ -258,6 +266,8 @@ There are three configuration layers:
|
|
|
258
266
|
- reusable object catalogs in `config/*.yaml`
|
|
259
267
|
- agent assembly in `config/agents/*.yaml`
|
|
260
268
|
|
|
269
|
+
The repository-owned default config layer is intentionally full-shaped. The shipped YAML keeps explicit default values for the main runtime knobs so teams can start from concrete config instead of reconstructing adapter defaults from code.
|
|
270
|
+
|
|
261
271
|
### `config/workspace.yaml`
|
|
262
272
|
|
|
263
273
|
Use this file for runtime-level policy shared by the whole workspace.
|
|
@@ -277,8 +287,6 @@ Primary fields:
|
|
|
277
287
|
|
|
278
288
|
If `runRoot` is omitted, the runtime defaults to `<workspace-root>/run-data`.
|
|
279
289
|
|
|
280
|
-
Queued runs are persisted under `runRoot` and continue after process restart. `running` runs are only replayed on startup when the bound tools are retryable.
|
|
281
|
-
|
|
282
290
|
### `config/agent-context.md`
|
|
283
291
|
|
|
284
292
|
Use this file for shared bootstrap context loaded into agents at construction time.
|
|
@@ -299,7 +307,7 @@ spec:
|
|
|
299
307
|
temperature: 0.2
|
|
300
308
|
```
|
|
301
309
|
|
|
302
|
-
These load as `model
|
|
310
|
+
These load as `model/default`.
|
|
303
311
|
|
|
304
312
|
### `config/embedding-models.yaml`
|
|
305
313
|
|
|
@@ -324,21 +332,12 @@ spec:
|
|
|
324
332
|
- kind: Checkpointer
|
|
325
333
|
name: default
|
|
326
334
|
checkpointerKind: MemorySaver
|
|
335
|
+
- kind: Checkpointer
|
|
336
|
+
name: sqlite
|
|
337
|
+
checkpointerKind: SqliteSaver
|
|
338
|
+
path: checkpoints.sqlite
|
|
327
339
|
```
|
|
328
340
|
|
|
329
|
-
Built-in store kinds today:
|
|
330
|
-
|
|
331
|
-
- `FileStore`
|
|
332
|
-
- `InMemoryStore`
|
|
333
|
-
|
|
334
|
-
Built-in checkpointer kinds today:
|
|
335
|
-
|
|
336
|
-
- `MemorySaver`
|
|
337
|
-
- `FileCheckpointer`
|
|
338
|
-
- `SqliteSaver`
|
|
339
|
-
|
|
340
|
-
If you need other store or checkpointer implementations, inject them through runtime resolvers instead of treating them as built-in harness features.
|
|
341
|
-
|
|
342
341
|
### `config/backends.yaml`
|
|
343
342
|
|
|
344
343
|
Use reusable DeepAgent backend presets so filesystem and long-term memory topology stays in YAML instead of application code:
|
|
@@ -352,6 +351,8 @@ spec:
|
|
|
352
351
|
backendKind: CompositeBackend
|
|
353
352
|
state:
|
|
354
353
|
kind: VfsSandbox
|
|
354
|
+
rootDir: .
|
|
355
|
+
virtualMode: true
|
|
355
356
|
timeout: 600
|
|
356
357
|
routes:
|
|
357
358
|
/memories/:
|
|
@@ -362,17 +363,9 @@ spec:
|
|
|
362
363
|
|
|
363
364
|
Use this file for reusable tool objects.
|
|
364
365
|
|
|
365
|
-
Supported tool families in the built-in runtime include
|
|
366
|
-
|
|
367
|
-
- function tools
|
|
368
|
-
- backend tools
|
|
369
|
-
- MCP tools
|
|
370
|
-
- provider-native tools
|
|
371
|
-
- bundles
|
|
366
|
+
Supported tool families in the built-in runtime include function tools, backend tools, MCP tools, provider-native tools, and bundles.
|
|
372
367
|
|
|
373
|
-
Provider-native tools are declared in YAML and resolved directly to upstream provider tool factories
|
|
374
|
-
|
|
375
|
-
Use `retryable` carefully. Mark a tool retryable only when repeated execution is safe or intentionally idempotent.
|
|
368
|
+
Provider-native tools are declared in YAML and resolved directly to upstream provider tool factories.
|
|
376
369
|
|
|
377
370
|
### `config/mcp.yaml`
|
|
378
371
|
|
|
@@ -397,12 +390,23 @@ kind: Agent
|
|
|
397
390
|
metadata:
|
|
398
391
|
name: direct
|
|
399
392
|
spec:
|
|
393
|
+
runtime:
|
|
394
|
+
runRoot: ./.agent
|
|
400
395
|
execution:
|
|
401
396
|
backend: langchain-v1
|
|
402
397
|
modelRef: model/default
|
|
398
|
+
tools: []
|
|
399
|
+
skills: []
|
|
400
|
+
memory: []
|
|
401
|
+
subagents: []
|
|
402
|
+
mcpServers: []
|
|
403
403
|
config:
|
|
404
404
|
checkpointer:
|
|
405
405
|
ref: checkpointer/default
|
|
406
|
+
store:
|
|
407
|
+
ref: store/default
|
|
408
|
+
interruptOn: {}
|
|
409
|
+
middleware: []
|
|
406
410
|
systemPrompt: Answer simple requests directly.
|
|
407
411
|
```
|
|
408
412
|
|
|
@@ -414,11 +418,17 @@ kind: Agent
|
|
|
414
418
|
metadata:
|
|
415
419
|
name: orchestra
|
|
416
420
|
spec:
|
|
421
|
+
runtime:
|
|
422
|
+
runRoot: ./.agent
|
|
417
423
|
execution:
|
|
418
424
|
backend: deepagent
|
|
419
425
|
modelRef: model/default
|
|
420
426
|
memory:
|
|
421
427
|
- path: config/agent-context.md
|
|
428
|
+
tools: []
|
|
429
|
+
skills: []
|
|
430
|
+
subagents: []
|
|
431
|
+
mcpServers: []
|
|
422
432
|
config:
|
|
423
433
|
store:
|
|
424
434
|
ref: store/default
|
|
@@ -426,36 +436,13 @@ spec:
|
|
|
426
436
|
ref: checkpointer/default
|
|
427
437
|
backend:
|
|
428
438
|
ref: backend/default
|
|
439
|
+
interruptOn: {}
|
|
440
|
+
middleware: []
|
|
441
|
+
generalPurposeAgent: true
|
|
442
|
+
taskDescription: Complete delegated sidecar work and return concise results.
|
|
429
443
|
```
|
|
430
444
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
- `metadata.name`
|
|
434
|
-
- `metadata.description`
|
|
435
|
-
- `spec.execution.backend`
|
|
436
|
-
- `spec.runtime.runRoot`
|
|
437
|
-
- `spec.execution.modelRef`
|
|
438
|
-
- `spec.execution.tools`
|
|
439
|
-
- `spec.execution.skills`
|
|
440
|
-
- `spec.execution.memory`
|
|
441
|
-
- `spec.execution.subagents`
|
|
442
|
-
- `spec.execution.mcpServers`
|
|
443
|
-
- `spec.execution.config.systemPrompt`
|
|
444
|
-
- `spec.execution.config.checkpointer`
|
|
445
|
-
- `spec.execution.config.store`
|
|
446
|
-
- `spec.execution.config.backend`
|
|
447
|
-
- `spec.execution.config.middleware`
|
|
448
|
-
- `spec.execution.config.responseFormat`
|
|
449
|
-
- `spec.execution.config.contextSchema`
|
|
450
|
-
- `spec.execution.config.stateSchema`
|
|
451
|
-
- `spec.execution.config.interruptOn`
|
|
452
|
-
- `spec.execution.config.filesystem`
|
|
453
|
-
- `spec.execution.config.taskDescription`
|
|
454
|
-
- `spec.execution.config.generalPurposeAgent`
|
|
455
|
-
- `spec.execution.config.includeAgentName`
|
|
456
|
-
- `spec.execution.config.version`
|
|
457
|
-
|
|
458
|
-
For backend-specific agent options, prefer passing the upstream concept directly inside `spec.execution.config`. The loader keeps a small stable product shape, but it also preserves adapter-facing passthrough fields so new LangChain v1 or DeepAgents parameters can flow into adapters without expanding the public API surface.
|
|
445
|
+
For backend-specific agent options, prefer the upstream concept directly inside `spec.execution.config`. Upstream feature coverage is tracked in [docs/upstream-feature-matrix.md](docs/upstream-feature-matrix.md).
|
|
459
446
|
|
|
460
447
|
### `resources/`
|
|
461
448
|
|
|
@@ -466,10 +453,6 @@ Use `resources/` for executable local extensions:
|
|
|
466
453
|
|
|
467
454
|
Tool modules are discovered from `resources/tools/*.js`, `resources/tools/*.mjs`, and `resources/tools/*.cjs`.
|
|
468
455
|
|
|
469
|
-
The preferred tool module format is exporting `tool({...})`.
|
|
470
|
-
|
|
471
|
-
SKILL packages are discovered from `resources/skills/` and attached to agents through YAML.
|
|
472
|
-
|
|
473
456
|
## Design Notes
|
|
474
457
|
|
|
475
458
|
- public runtime contract stays generic and small
|
|
@@ -477,6 +460,7 @@ SKILL packages are discovered from `resources/skills/` and attached to agents th
|
|
|
477
460
|
- upstream LangChain v1 and DeepAgents concepts should be expressed as directly as possible in YAML
|
|
478
461
|
- recovery, approvals, threads, runs, and events are runtime concepts, not backend-specific escape hatches
|
|
479
462
|
- backend implementation details should stay internal unless product requirements force exposure
|
|
463
|
+
- new LangChain v1 or DeepAgents public config should land in YAML passthrough and compatibility tests before adding new public runtime APIs
|
|
480
464
|
|
|
481
465
|
In short: `agent-harness` is a public runtime contract generic enough to survive backend changes, while the deep execution semantics stay upstream.
|
|
482
466
|
|
|
@@ -486,6 +470,7 @@ Primary exports:
|
|
|
486
470
|
|
|
487
471
|
- `createAgentHarness`
|
|
488
472
|
- `run`
|
|
473
|
+
- `resolveApproval`
|
|
489
474
|
- `subscribe`
|
|
490
475
|
- `listThreads`
|
|
491
476
|
- `getThread`
|
|
@@ -495,5 +480,3 @@ Primary exports:
|
|
|
495
480
|
- `createToolMcpServer`
|
|
496
481
|
- `serveToolsOverStdio`
|
|
497
482
|
- `stop`
|
|
498
|
-
|
|
499
|
-
`AgentHarnessRuntime` is the concrete runtime class behind the public facade.
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApprovalRecord, RunOptions, RuntimeAdapterOptions, ThreadSummary, ThreadRecord, WorkspaceLoadOptions
|
|
1
|
+
import type { ApprovalRecord, RunOptions, ResumeOptions, RuntimeAdapterOptions, ThreadSummary, ThreadRecord, WorkspaceLoadOptions } from "./contracts/types.js";
|
|
2
2
|
import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
3
3
|
import type { ToolMcpServerOptions } from "./mcp.js";
|
|
4
4
|
export { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
@@ -8,7 +8,6 @@ type CreateAgentHarnessOptions = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare function createAgentHarness(): Promise<AgentHarnessRuntime>;
|
|
10
10
|
export declare function createAgentHarness(workspaceRoot: string, options?: CreateAgentHarnessOptions): Promise<AgentHarnessRuntime>;
|
|
11
|
-
export declare function createAgentHarness(workspace: WorkspaceBundle, options?: CreateAgentHarnessOptions): Promise<AgentHarnessRuntime>;
|
|
12
11
|
export declare function run(runtime: AgentHarnessRuntime, options: RunOptions): Promise<import("./contracts/types.js").RunResult>;
|
|
13
12
|
export declare function subscribe(runtime: AgentHarnessRuntime, listener: Parameters<AgentHarnessRuntime["subscribe"]>[0]): () => void;
|
|
14
13
|
export declare function listThreads(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listThreads"]>[0]): Promise<ThreadSummary[]>;
|
|
@@ -16,6 +15,7 @@ export declare function getThread(runtime: AgentHarnessRuntime, threadId: string
|
|
|
16
15
|
export declare function deleteThread(runtime: AgentHarnessRuntime, threadId: string): Promise<boolean>;
|
|
17
16
|
export declare function listApprovals(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listApprovals"]>[0]): Promise<ApprovalRecord[]>;
|
|
18
17
|
export declare function getApproval(runtime: AgentHarnessRuntime, approvalId: string): Promise<ApprovalRecord | null>;
|
|
18
|
+
export declare function resolveApproval(runtime: AgentHarnessRuntime, options: ResumeOptions): Promise<import("./contracts/types.js").RunResult>;
|
|
19
19
|
export declare function stop(runtime: AgentHarnessRuntime): Promise<void>;
|
|
20
20
|
export declare function createToolMcpServer(runtime: AgentHarnessRuntime, options: ToolMcpServerOptions): Promise<import("@modelcontextprotocol/sdk/server/mcp.js").McpServer>;
|
|
21
21
|
export declare function serveToolsOverStdio(runtime: AgentHarnessRuntime, options: ToolMcpServerOptions): Promise<import("@modelcontextprotocol/sdk/server/mcp.js").McpServer>;
|
package/dist/api.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
2
2
|
import { loadWorkspace } from "./workspace/compile.js";
|
|
3
3
|
export { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
4
|
-
export async function createAgentHarness(
|
|
5
|
-
const workspace =
|
|
6
|
-
? await loadWorkspace(input, options.load ?? {})
|
|
7
|
-
: input;
|
|
4
|
+
export async function createAgentHarness(workspaceRoot = process.cwd(), options = {}) {
|
|
5
|
+
const workspace = await loadWorkspace(workspaceRoot, options.load ?? {});
|
|
8
6
|
const harness = new AgentHarnessRuntime(workspace, options.adapter ?? {});
|
|
9
7
|
await harness.initialize();
|
|
10
8
|
return harness;
|
|
@@ -30,6 +28,9 @@ export async function listApprovals(runtime, filter) {
|
|
|
30
28
|
export async function getApproval(runtime, approvalId) {
|
|
31
29
|
return runtime.getApproval(approvalId);
|
|
32
30
|
}
|
|
31
|
+
export async function resolveApproval(runtime, options) {
|
|
32
|
+
return runtime.resume(options);
|
|
33
|
+
}
|
|
33
34
|
export async function stop(runtime) {
|
|
34
35
|
return runtime.stop();
|
|
35
36
|
}
|
|
@@ -9,7 +9,10 @@ metadata:
|
|
|
9
9
|
# agent-harness feature: human-readable summary for inventory and UI.
|
|
10
10
|
description: Manual low-latency host for direct answers and lightweight inventory lookup. Do not use it as the default executor for tool-heavy or specialist-shaped tasks.
|
|
11
11
|
spec:
|
|
12
|
-
runtime:
|
|
12
|
+
runtime:
|
|
13
|
+
# agent-harness feature: host-level run data placement override.
|
|
14
|
+
# This matches the workspace default and keeps the default config shape explicit.
|
|
15
|
+
runRoot: ./.agent
|
|
13
16
|
# =====================
|
|
14
17
|
# Runtime Agent Features
|
|
15
18
|
# =====================
|
|
@@ -20,6 +23,16 @@ spec:
|
|
|
20
23
|
# This should point at a cheap, fast, general-purpose chat model, because `direct` is intended
|
|
21
24
|
# to be the low-latency path for simple requests.
|
|
22
25
|
modelRef: model/default
|
|
26
|
+
# Upstream execution feature: direct host starts with no attached explicit tools by default.
|
|
27
|
+
tools: []
|
|
28
|
+
# Upstream execution feature: direct host starts with no attached local skill packages by default.
|
|
29
|
+
skills: []
|
|
30
|
+
# Upstream execution feature: direct host does not bootstrap project memory by default.
|
|
31
|
+
memory: []
|
|
32
|
+
# Upstream execution feature: direct host does not predeclare specialist subagents by default.
|
|
33
|
+
subagents: []
|
|
34
|
+
# Upstream execution feature: direct host does not attach MCP servers by default.
|
|
35
|
+
mcpServers: []
|
|
23
36
|
config:
|
|
24
37
|
# Runtime execution feature: checkpointer config passed into the selected backend adapter.
|
|
25
38
|
# Even the lightweight direct path can benefit from resumable state during interactive use.
|
|
@@ -27,6 +40,14 @@ spec:
|
|
|
27
40
|
# `path` is only used by `FileCheckpointer` and `SqliteSaver`; omit it for `MemorySaver`.
|
|
28
41
|
checkpointer:
|
|
29
42
|
ref: checkpointer/default
|
|
43
|
+
# Upstream execution feature: LangGraph store available to middleware and runtime context hooks.
|
|
44
|
+
# The default direct host keeps this enabled so middleware can use the same durable store surface as other hosts.
|
|
45
|
+
store:
|
|
46
|
+
ref: store/default
|
|
47
|
+
# Upstream execution feature: no declarative HITL tool routing by default.
|
|
48
|
+
interruptOn: {}
|
|
49
|
+
# Upstream execution feature: no extra declarative middleware beyond the runtime's automatic injections.
|
|
50
|
+
middleware: []
|
|
30
51
|
# Upstream execution feature: system prompt for the lightweight direct-response host.
|
|
31
52
|
# This prompt should keep the agent focused on:
|
|
32
53
|
# - answering simple requests in one turn
|
|
@@ -9,7 +9,10 @@ metadata:
|
|
|
9
9
|
# agent-harness feature: human-readable summary for inventory and UI.
|
|
10
10
|
description: Default execution host. Answer directly when possible, use local tools and skills first, and delegate only when a specialist is a better fit. Not a reflex delegation-only planner.
|
|
11
11
|
spec:
|
|
12
|
-
runtime:
|
|
12
|
+
runtime:
|
|
13
|
+
# agent-harness feature: host-level run data placement override.
|
|
14
|
+
# This matches the workspace default and keeps the default config shape explicit.
|
|
15
|
+
runRoot: ./.agent
|
|
13
16
|
# =====================
|
|
14
17
|
# Runtime Agent Features
|
|
15
18
|
# =====================
|
|
@@ -29,6 +32,14 @@ spec:
|
|
|
29
32
|
# Updating these files changes future agent constructions, but they are still bootstrap inputs rather than
|
|
30
33
|
# self-updating runtime memory.
|
|
31
34
|
- path: config/agent-context.md
|
|
35
|
+
# Upstream execution feature: top-level host starts with no extra direct tool refs beyond discovered workspace tools.
|
|
36
|
+
tools: []
|
|
37
|
+
# Upstream execution feature: top-level host starts with no explicit skill package refs in the default workspace.
|
|
38
|
+
skills: []
|
|
39
|
+
# Upstream execution feature: specialist topology is empty in the repository default and can be filled in YAML.
|
|
40
|
+
subagents: []
|
|
41
|
+
# Upstream execution feature: host-level MCP servers are opt-in and empty by default.
|
|
42
|
+
mcpServers: []
|
|
32
43
|
config:
|
|
33
44
|
# Runtime execution feature: checkpointer config passed into the selected backend adapter.
|
|
34
45
|
# This persists resumable graph state for this agent.
|
|
@@ -52,6 +63,14 @@ spec:
|
|
|
52
63
|
# The harness injects the resolved store/checkpointer instances, but the backend topology itself stays upstream-shaped.
|
|
53
64
|
backend:
|
|
54
65
|
ref: backend/default
|
|
66
|
+
# Upstream execution feature: no extra declarative HITL rules by default.
|
|
67
|
+
interruptOn: {}
|
|
68
|
+
# Upstream execution feature: no extra declarative middleware beyond upstream deepagents defaults by default.
|
|
69
|
+
middleware: []
|
|
70
|
+
# Upstream execution feature: keep the built-in general-purpose subagent enabled.
|
|
71
|
+
generalPurposeAgent: true
|
|
72
|
+
# Upstream execution feature: bias the general-purpose subagent toward bounded sidecar work and context isolation.
|
|
73
|
+
taskDescription: Complete delegated sidecar work and return concise results without bloating the parent context.
|
|
55
74
|
# Upstream execution feature: system prompt for the orchestration host.
|
|
56
75
|
# This becomes the top-level instruction block for the selected execution backend and should hold the
|
|
57
76
|
# agent's durable role, priorities, and behavioral guardrails rather than bulky project facts.
|
package/dist/config/stores.yaml
CHANGED
|
@@ -15,3 +15,10 @@ spec:
|
|
|
15
15
|
name: default
|
|
16
16
|
description: Default in-memory checkpointer preset for lightweight local development.
|
|
17
17
|
checkpointerKind: MemorySaver
|
|
18
|
+
|
|
19
|
+
# agent-harness feature: reusable sqlite checkpointer preset for longer-lived local runs.
|
|
20
|
+
- kind: Checkpointer
|
|
21
|
+
name: sqlite
|
|
22
|
+
description: Default sqlite-backed checkpointer preset for durable local graph state and maintenance sweeps.
|
|
23
|
+
checkpointerKind: SqliteSaver
|
|
24
|
+
path: checkpoints.sqlite
|
|
@@ -196,7 +196,6 @@ export type CompiledAgentBinding = {
|
|
|
196
196
|
config: Record<string, unknown>;
|
|
197
197
|
};
|
|
198
198
|
langchainAgentParams?: LangChainAgentParams;
|
|
199
|
-
directAgentParams?: LangChainAgentParams;
|
|
200
199
|
deepAgentParams?: DeepAgentParams;
|
|
201
200
|
harnessRuntime: {
|
|
202
201
|
runRoot: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, getApproval, getThread, listApprovals, listThreads, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
1
|
+
export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, getApproval, getThread, listApprovals, listThreads, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
2
|
export type { ToolMcpServerOptions } from "./mcp.js";
|
|
3
3
|
export { tool } from "./tools.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, getApproval, getThread, listApprovals, listThreads, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
1
|
+
export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, getApproval, getThread, listApprovals, listThreads, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
2
|
export { tool } from "./tools.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.53";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.53";
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { CompiledAgentBinding, CompiledModel } from "../contracts/types.js";
|
|
2
|
+
type MiddlewareConfig = Record<string, unknown>;
|
|
3
|
+
type MiddlewareFactoryContext = {
|
|
4
|
+
config: MiddlewareConfig;
|
|
5
|
+
resolveModel: (model: CompiledModel) => Promise<unknown>;
|
|
6
|
+
};
|
|
7
|
+
type MiddlewareFactory = (context: MiddlewareFactoryContext) => Promise<unknown | unknown[] | null | undefined>;
|
|
8
|
+
export declare const DECLARATIVE_MIDDLEWARE_REGISTRY: Record<string, MiddlewareFactory>;
|
|
9
|
+
export declare const SUPPORTED_DECLARATIVE_MIDDLEWARE_KINDS: readonly string[];
|
|
2
10
|
export declare function resolveDeclaredMiddleware(middlewareConfigs: unknown[] | undefined, options: {
|
|
3
11
|
resolveModel: (model: CompiledModel) => Promise<unknown>;
|
|
4
12
|
resolveCustom?: (input: {
|
|
@@ -9,3 +17,4 @@ export declare function resolveDeclaredMiddleware(middlewareConfigs: unknown[] |
|
|
|
9
17
|
}) => unknown | unknown[] | null | undefined | Promise<unknown | unknown[] | null | undefined>;
|
|
10
18
|
binding?: CompiledAgentBinding;
|
|
11
19
|
}): Promise<unknown[]>;
|
|
20
|
+
export {};
|
|
@@ -25,6 +25,52 @@ async function resolveReferencedModelList(values, options) {
|
|
|
25
25
|
}
|
|
26
26
|
return Promise.all(values.map((value) => resolveReferencedModel(value, options)));
|
|
27
27
|
}
|
|
28
|
+
async function createSummarizationMiddleware({ config, resolveModel }) {
|
|
29
|
+
const runtimeConfig = { ...config };
|
|
30
|
+
runtimeConfig.model = await resolveReferencedModel(runtimeConfig.model, { resolveModel });
|
|
31
|
+
if (runtimeConfig.model === undefined) {
|
|
32
|
+
throw new Error("summarization middleware requires model or modelRef");
|
|
33
|
+
}
|
|
34
|
+
return summarizationMiddleware(runtimeConfig);
|
|
35
|
+
}
|
|
36
|
+
async function createLlmToolSelectorMiddleware({ config, resolveModel }) {
|
|
37
|
+
const runtimeConfig = { ...config };
|
|
38
|
+
runtimeConfig.model = await resolveReferencedModel(runtimeConfig.model, { resolveModel });
|
|
39
|
+
return llmToolSelectorMiddleware(runtimeConfig);
|
|
40
|
+
}
|
|
41
|
+
async function createModelFallbackDeclarativeMiddleware({ config, resolveModel }) {
|
|
42
|
+
const fallbackModels = (await resolveReferencedModelList(config.fallbackModels, { resolveModel })) ??
|
|
43
|
+
(await resolveReferencedModelList(config.models, { resolveModel }));
|
|
44
|
+
if (!fallbackModels || fallbackModels.length === 0) {
|
|
45
|
+
throw new Error("modelFallback middleware requires fallbackModels or models");
|
|
46
|
+
}
|
|
47
|
+
return modelFallbackMiddleware(...fallbackModels);
|
|
48
|
+
}
|
|
49
|
+
async function createPiiDeclarativeMiddleware({ config }) {
|
|
50
|
+
const piiType = typeof config.piiType === "string" ? config.piiType : undefined;
|
|
51
|
+
if (!piiType) {
|
|
52
|
+
throw new Error("pii middleware requires piiType");
|
|
53
|
+
}
|
|
54
|
+
const { piiType: _piiType, ...piiOptions } = config;
|
|
55
|
+
return piiMiddleware(piiType, piiOptions);
|
|
56
|
+
}
|
|
57
|
+
export const DECLARATIVE_MIDDLEWARE_REGISTRY = {
|
|
58
|
+
summarization: createSummarizationMiddleware,
|
|
59
|
+
llmToolSelector: createLlmToolSelectorMiddleware,
|
|
60
|
+
modelRetry: async ({ config }) => modelRetryMiddleware(config),
|
|
61
|
+
modelFallback: createModelFallbackDeclarativeMiddleware,
|
|
62
|
+
toolRetry: async ({ config }) => toolRetryMiddleware(config),
|
|
63
|
+
toolCallLimit: async ({ config }) => toolCallLimitMiddleware(config),
|
|
64
|
+
modelCallLimit: async ({ config }) => modelCallLimitMiddleware(config),
|
|
65
|
+
todoList: async ({ config }) => todoListMiddleware(config),
|
|
66
|
+
contextEditing: async ({ config }) => contextEditingMiddleware(config),
|
|
67
|
+
toolEmulator: async ({ config }) => toolEmulatorMiddleware(config),
|
|
68
|
+
humanInTheLoop: async ({ config }) => humanInTheLoopMiddleware(config),
|
|
69
|
+
openAIModeration: async ({ config }) => openAIModerationMiddleware(config),
|
|
70
|
+
pii: createPiiDeclarativeMiddleware,
|
|
71
|
+
anthropicPromptCaching: async ({ config }) => anthropicPromptCachingMiddleware(config),
|
|
72
|
+
};
|
|
73
|
+
export const SUPPORTED_DECLARATIVE_MIDDLEWARE_KINDS = Object.freeze(Object.keys(DECLARATIVE_MIDDLEWARE_REGISTRY).sort());
|
|
28
74
|
export async function resolveDeclaredMiddleware(middlewareConfigs, options) {
|
|
29
75
|
const resolved = [];
|
|
30
76
|
for (const rawConfig of middlewareConfigs ?? []) {
|
|
@@ -34,87 +80,38 @@ export async function resolveDeclaredMiddleware(middlewareConfigs, options) {
|
|
|
34
80
|
}
|
|
35
81
|
const kind = requireKind(config);
|
|
36
82
|
const runtimeConfig = omitKind(config);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
const registeredFactory = DECLARATIVE_MIDDLEWARE_REGISTRY[kind];
|
|
84
|
+
if (registeredFactory) {
|
|
85
|
+
const resolvedBuiltin = await registeredFactory({
|
|
86
|
+
config: runtimeConfig,
|
|
87
|
+
resolveModel: options.resolveModel,
|
|
88
|
+
});
|
|
89
|
+
if (Array.isArray(resolvedBuiltin)) {
|
|
90
|
+
resolved.push(...resolvedBuiltin);
|
|
91
|
+
continue;
|
|
45
92
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
break;
|
|
50
|
-
case "modelRetry":
|
|
51
|
-
resolved.push(modelRetryMiddleware(runtimeConfig));
|
|
52
|
-
break;
|
|
53
|
-
case "modelFallback": {
|
|
54
|
-
const fallbackModels = (await resolveReferencedModelList(runtimeConfig.fallbackModels, options)) ??
|
|
55
|
-
(await resolveReferencedModelList(runtimeConfig.models, options));
|
|
56
|
-
if (!fallbackModels || fallbackModels.length === 0) {
|
|
57
|
-
throw new Error("modelFallback middleware requires fallbackModels or models");
|
|
58
|
-
}
|
|
59
|
-
resolved.push(modelFallbackMiddleware(...fallbackModels));
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
case "toolRetry":
|
|
63
|
-
resolved.push(toolRetryMiddleware(runtimeConfig));
|
|
64
|
-
break;
|
|
65
|
-
case "toolCallLimit":
|
|
66
|
-
resolved.push(toolCallLimitMiddleware(runtimeConfig));
|
|
67
|
-
break;
|
|
68
|
-
case "modelCallLimit":
|
|
69
|
-
resolved.push(modelCallLimitMiddleware(runtimeConfig));
|
|
70
|
-
break;
|
|
71
|
-
case "todoList":
|
|
72
|
-
resolved.push(todoListMiddleware(runtimeConfig));
|
|
73
|
-
break;
|
|
74
|
-
case "contextEditing":
|
|
75
|
-
resolved.push(contextEditingMiddleware(runtimeConfig));
|
|
76
|
-
break;
|
|
77
|
-
case "toolEmulator":
|
|
78
|
-
resolved.push(toolEmulatorMiddleware(runtimeConfig));
|
|
79
|
-
break;
|
|
80
|
-
case "humanInTheLoop":
|
|
81
|
-
resolved.push(humanInTheLoopMiddleware(runtimeConfig));
|
|
82
|
-
break;
|
|
83
|
-
case "openAIModeration":
|
|
84
|
-
resolved.push(openAIModerationMiddleware(runtimeConfig));
|
|
85
|
-
break;
|
|
86
|
-
case "pii": {
|
|
87
|
-
const piiType = typeof runtimeConfig.piiType === "string" ? runtimeConfig.piiType : undefined;
|
|
88
|
-
if (!piiType) {
|
|
89
|
-
throw new Error("pii middleware requires piiType");
|
|
90
|
-
}
|
|
91
|
-
const { piiType: _piiType, ...piiOptions } = runtimeConfig;
|
|
92
|
-
resolved.push(piiMiddleware(piiType, piiOptions));
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
case "anthropicPromptCaching":
|
|
96
|
-
resolved.push(anthropicPromptCachingMiddleware(runtimeConfig));
|
|
97
|
-
break;
|
|
98
|
-
default: {
|
|
99
|
-
const customResolved = options.resolveCustom
|
|
100
|
-
? await options.resolveCustom({
|
|
101
|
-
kind,
|
|
102
|
-
config: runtimeConfig,
|
|
103
|
-
binding: options.binding,
|
|
104
|
-
resolveModel: options.resolveModel,
|
|
105
|
-
})
|
|
106
|
-
: undefined;
|
|
107
|
-
if (Array.isArray(customResolved)) {
|
|
108
|
-
resolved.push(...customResolved);
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
if (customResolved) {
|
|
112
|
-
resolved.push(customResolved);
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
throw new Error(`Unsupported declarative middleware kind ${kind}`);
|
|
93
|
+
if (resolvedBuiltin) {
|
|
94
|
+
resolved.push(resolvedBuiltin);
|
|
95
|
+
continue;
|
|
116
96
|
}
|
|
117
97
|
}
|
|
98
|
+
const customResolved = options.resolveCustom
|
|
99
|
+
? await options.resolveCustom({
|
|
100
|
+
kind,
|
|
101
|
+
config: runtimeConfig,
|
|
102
|
+
binding: options.binding,
|
|
103
|
+
resolveModel: options.resolveModel,
|
|
104
|
+
})
|
|
105
|
+
: undefined;
|
|
106
|
+
if (Array.isArray(customResolved)) {
|
|
107
|
+
resolved.push(...customResolved);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (customResolved) {
|
|
111
|
+
resolved.push(customResolved);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
throw new Error(`Unsupported declarative middleware kind ${kind}`);
|
|
118
115
|
}
|
|
119
116
|
return resolved;
|
|
120
117
|
}
|
|
@@ -242,11 +242,12 @@ function readPassthroughConfig(item, consumedKeys) {
|
|
|
242
242
|
}
|
|
243
243
|
function resolveExecutionBackend(item, current) {
|
|
244
244
|
const execution = readExecutionConfig(item.execution) ?? readExecutionConfig(current?.execution);
|
|
245
|
+
if (typeof execution?.mode === "string" && execution.mode.trim().length > 0) {
|
|
246
|
+
throw new Error("Agent execution.mode is no longer supported; use execution.backend");
|
|
247
|
+
}
|
|
245
248
|
const backend = typeof execution?.backend === "string"
|
|
246
249
|
? execution.backend.trim().toLowerCase()
|
|
247
|
-
:
|
|
248
|
-
? execution.mode.trim().toLowerCase()
|
|
249
|
-
: undefined;
|
|
250
|
+
: undefined;
|
|
250
251
|
if (backend === "langchain-v1") {
|
|
251
252
|
return "langchain-v1";
|
|
252
253
|
}
|