@botbotgo/agent-harness 0.0.51 → 0.0.52

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 CHANGED
@@ -6,7 +6,7 @@
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 product boundary is simple:
9
+ The boundary is strict:
10
10
 
11
11
  - LangChain v1 and DeepAgents own agent execution semantics
12
12
  - `agent-harness` owns application-level orchestration and lifecycle management
@@ -15,12 +15,13 @@ 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
18
19
  - runtime lifecycle stays stable even if backend implementations change
19
20
 
20
21
  What the runtime provides:
21
22
 
22
23
  - `createAgentHarness(...)`, `run(...)`, `subscribe(...)`, inspection methods, and `stop(...)`
23
- - YAML-defined workspace assembly for routing, models, tools, stores, MCP, recovery, and maintenance
24
+ - YAML-defined workspace assembly for routing, models, tools, stores, backends, MCP, recovery, and maintenance
24
25
  - backend-adapted execution with current LangChain v1 and DeepAgents adapters
25
26
  - local `resources/tools/` and `resources/skills/` discovery
26
27
  - persisted threads, runs, approvals, events, queue state, and recovery metadata
@@ -44,6 +45,7 @@ your-workspace/
44
45
  embedding-models.yaml
45
46
  vector-stores.yaml
46
47
  stores.yaml
48
+ backends.yaml
47
49
  tools.yaml
48
50
  mcp.yaml
49
51
  agents/
@@ -242,6 +244,7 @@ Core workspace files:
242
244
  - `config/embedding-models.yaml`
243
245
  - `config/vector-stores.yaml`
244
246
  - `config/stores.yaml`
247
+ - `config/backends.yaml`
245
248
  - `config/tools.yaml`
246
249
  - `config/mcp.yaml`
247
250
  - `config/agents/direct.yaml`
@@ -323,6 +326,38 @@ spec:
323
326
  checkpointerKind: MemorySaver
324
327
  ```
325
328
 
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
+ ### `config/backends.yaml`
343
+
344
+ Use reusable DeepAgent backend presets so filesystem and long-term memory topology stays in YAML instead of application code:
345
+
346
+ ```yaml
347
+ apiVersion: agent-harness/v1alpha1
348
+ kind: Backends
349
+ spec:
350
+ - kind: Backend
351
+ name: default
352
+ backendKind: CompositeBackend
353
+ state:
354
+ kind: VfsSandbox
355
+ timeout: 600
356
+ routes:
357
+ /memories/:
358
+ kind: StoreBackend
359
+ ```
360
+
326
361
  ### `config/tools.yaml`
327
362
 
328
363
  Use this file for reusable tool objects.
@@ -390,13 +425,7 @@ spec:
390
425
  checkpointer:
391
426
  ref: checkpointer/default
392
427
  backend:
393
- kind: CompositeBackend
394
- state:
395
- kind: VfsSandbox
396
- timeout: 600
397
- routes:
398
- /memories/:
399
- kind: StoreBackend
428
+ ref: backend/default
400
429
  ```
401
430
 
402
431
  Client-configurable agent fields include:
@@ -39,27 +39,19 @@ spec:
39
39
  ref: checkpointer/default
40
40
  # Upstream execution feature: store config passed into the selected backend adapter.
41
41
  # In the default deepagent adapter this is the LangGraph store used by `StoreBackend` routes.
42
- # Available `kind` options in this harness: `FileStore`, `InMemoryStore`, `RedisStore`, `PostgresStore`.
42
+ # Built-in kinds in this harness today: `FileStore`, `InMemoryStore`.
43
+ # Other store kinds should flow through a custom runtime resolver instead of being claimed as built in.
43
44
  store:
44
45
  ref: store/default
45
46
  # Upstream execution feature: backend config passed into the selected backend adapter.
46
- # This directly defines the backend topology for this agent:
47
+ # Prefer a reusable backend preset via `ref` so backend topology stays declarative and reusable in YAML.
48
+ # The default preset keeps DeepAgent execution semantics upstream-owned:
47
49
  # - workspace execution uses a lightweight VFS sandbox
48
50
  # - long-term memory under `/memories/*` uses `StoreBackend`
49
51
  # - `CompositeBackend` composes those backend instances together
50
- # The harness also injects a persistent file-backed store and a file-backed checkpointer so that
51
- # `/memories/*` and resumable run state survive restarts in the default setup.
52
- # Available top-level `kind` options in this harness: `CompositeBackend`, `StateBackend`, `StoreBackend`.
52
+ # The harness injects the resolved store/checkpointer instances, but the backend topology itself stays upstream-shaped.
53
53
  backend:
54
- kind: CompositeBackend
55
- state:
56
- # Available state backend `kind` options today: `StateBackend`, `LocalShellBackend`, `VfsSandbox`.
57
- kind: VfsSandbox
58
- timeout: 600
59
- routes:
60
- /memories/:
61
- # Available route backend `kind` options today: `StoreBackend`.
62
- kind: StoreBackend
54
+ ref: backend/default
63
55
  # Upstream execution feature: system prompt for the orchestration host.
64
56
  # This becomes the top-level instruction block for the selected execution backend and should hold the
65
57
  # agent's durable role, priorities, and behavioral guardrails rather than bulky project facts.
@@ -0,0 +1,16 @@
1
+ # agent-harness feature: schema version for reusable backend presets.
2
+ apiVersion: agent-harness/v1alpha1
3
+ # agent-harness feature: object type for named DeepAgent backend presets.
4
+ kind: Backends
5
+ spec:
6
+ # upstream deepagents feature: default hybrid backend for workspace execution plus durable /memories storage.
7
+ - kind: Backend
8
+ name: default
9
+ description: Default DeepAgent backend preset with a virtual workspace sandbox and durable /memories storage.
10
+ backendKind: CompositeBackend
11
+ state:
12
+ kind: VfsSandbox
13
+ timeout: 600
14
+ routes:
15
+ /memories/:
16
+ kind: StoreBackend
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.50";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.51";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.50";
1
+ export const AGENT_HARNESS_VERSION = "0.0.51";
@@ -127,14 +127,22 @@ function resolveInterruptOn(agent) {
127
127
  return (agent.deepAgentConfig?.interruptOn ??
128
128
  agent.langchainAgentConfig?.interruptOn);
129
129
  }
130
- function resolveBackendConfig(agent) {
130
+ function resolveBackendConfig(agent, refs) {
131
131
  if (agent.executionMode !== "deepagent") {
132
132
  return undefined;
133
133
  }
134
134
  const backendConfig = typeof agent.deepAgentConfig?.backend === "object" && agent.deepAgentConfig.backend
135
135
  ? agent.deepAgentConfig.backend
136
136
  : undefined;
137
- return backendConfig ? { config: backendConfig } : undefined;
137
+ if (!backendConfig) {
138
+ return undefined;
139
+ }
140
+ if (isRefConfig(backendConfig)) {
141
+ return {
142
+ config: materializeWorkspaceObjectConfig(refs, backendConfig.ref, ["backend"], `Agent ${agent.id} backend`),
143
+ };
144
+ }
145
+ return { config: backendConfig };
138
146
  }
139
147
  function isRefConfig(value) {
140
148
  if (typeof value?.ref !== "string" || value.ref.trim().length === 0) {
@@ -161,6 +169,11 @@ function materializeWorkspaceObjectConfig(refs, ref, allowedKinds, ownerLabel) {
161
169
  const { checkpointerKind: _checkpointerKind, ...rest } = config;
162
170
  return checkpointerKind ? { kind: checkpointerKind, ...rest } : config;
163
171
  }
172
+ if (object.kind === "backend") {
173
+ const backendKind = typeof config.backendKind === "string" ? config.backendKind : undefined;
174
+ const { backendKind: _backendKind, ...rest } = config;
175
+ return backendKind ? { kind: backendKind, ...rest } : config;
176
+ }
164
177
  return config;
165
178
  }
166
179
  function resolveStoreConfig(agent, refs) {
@@ -208,7 +221,7 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
208
221
  const compiledAgentSkills = compileAgentSkills(workspaceRoot, agent);
209
222
  const compiledAgentMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
210
223
  const compiledAgentModel = requireModel(models, agent.modelRef || (internalSubagent ? "model/default" : ""), agent.id);
211
- const backend = resolveBackendConfig(agent);
224
+ const backend = resolveBackendConfig(agent, refs);
212
225
  const store = resolveStoreConfig(agent, refs);
213
226
  const checkpointer = resolveCheckpointerConfig(agent, refs);
214
227
  const runRoot = typeof agent.runRoot === "string" && agent.runRoot.trim().length > 0
@@ -377,11 +377,13 @@ async function objectItemsFromDocument(document, sourcePath) {
377
377
  ? normalizeCatalogSpec(document, { defaultKind: "Model" })
378
378
  : catalogKind === "Stores"
379
379
  ? normalizeCatalogSpec(document)
380
- : catalogKind === "Tools"
381
- ? normalizeCatalogSpec(document, { defaultKind: "Tool" })
382
- : catalogKind === "McpServers"
383
- ? normalizeCatalogSpec(document)
384
- : [];
380
+ : catalogKind === "Backends"
381
+ ? normalizeCatalogSpec(document, { defaultKind: "Backend" })
382
+ : catalogKind === "Tools"
383
+ ? normalizeCatalogSpec(document, { defaultKind: "Tool" })
384
+ : catalogKind === "McpServers"
385
+ ? normalizeCatalogSpec(document)
386
+ : [];
385
387
  if (catalogItems.length > 0) {
386
388
  return catalogItems;
387
389
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",
@@ -50,7 +50,7 @@
50
50
  "scripts": {
51
51
  "build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && cp -R config dist/",
52
52
  "check": "tsc -p tsconfig.json --noEmit",
53
- "test": "vitest run test/public-api.test.ts test/resource-optional-provider.test.ts test/resource-isolation.test.ts test/stock-research-app-load-harness.test.ts test/stock-research-app-run.test.ts test/release-workflow.test.ts test/release-version.test.ts test/gitignore.test.ts test/package-lock.test.ts test/readme.test.ts test/runtime-adapter-regressions.test.ts test/runtime-capabilities.test.ts test/runtime-recovery.test.ts test/tool-extension-gaps.test.ts test/checkpoint-maintenance.test.ts test/llamaindex-dependency-compat.test.ts test/skill-standard.test.ts test/routing-config.test.ts test/workspace-compat-regressions.test.ts test/upstream-compat-regressions.test.ts test/yaml-format.test.ts",
53
+ "test": "vitest run test/public-api.test.ts test/resource-optional-provider.test.ts test/resource-isolation.test.ts test/stock-research-app-load-harness.test.ts test/stock-research-app-run.test.ts test/stock-research-app-config.test.ts test/release-workflow.test.ts test/release-version.test.ts test/gitignore.test.ts test/package-lock.test.ts test/readme.test.ts test/runtime-adapter-regressions.test.ts test/runtime-capabilities.test.ts test/runtime-recovery.test.ts test/tool-extension-gaps.test.ts test/checkpoint-maintenance.test.ts test/llamaindex-dependency-compat.test.ts test/skill-standard.test.ts test/routing-config.test.ts test/workspace-compat-regressions.test.ts test/upstream-compat-regressions.test.ts test/yaml-format.test.ts",
54
54
  "test:real-providers": "vitest run test/real-provider-harness.test.ts",
55
55
  "release:prepare": "npm version patch --no-git-tag-version && node ./scripts/sync-example-version.mjs",
56
56
  "release:pack": "npm pack --dry-run",