@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.
@@ -215,6 +215,21 @@ function readExecutionConfig(value) {
215
215
  ? { ...value }
216
216
  : undefined;
217
217
  }
218
+ function cloneConfigValue(value) {
219
+ if (Array.isArray(value)) {
220
+ return value.map((item) => cloneConfigValue(item));
221
+ }
222
+ if (typeof value === "object" && value !== null) {
223
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, cloneConfigValue(entry)]));
224
+ }
225
+ return value;
226
+ }
227
+ function readPassthroughConfig(item, consumedKeys) {
228
+ const passthrough = Object.fromEntries(Object.entries(item)
229
+ .filter(([key]) => !consumedKeys.includes(key))
230
+ .map(([key, value]) => [key, cloneConfigValue(value)]));
231
+ return Object.keys(passthrough).length > 0 ? passthrough : undefined;
232
+ }
218
233
  function resolveExecutionBackend(item, current) {
219
234
  const execution = readExecutionConfig(item.execution) ?? readExecutionConfig(current?.execution);
220
235
  const backend = typeof execution?.backend === "string"
@@ -222,16 +237,43 @@ function resolveExecutionBackend(item, current) {
222
237
  : typeof execution?.mode === "string"
223
238
  ? execution.mode.trim().toLowerCase()
224
239
  : undefined;
225
- if (backend === "langchain-v1" || backend === "langchain" || backend === "langchain-agent") {
240
+ if (backend === "langchain-v1") {
226
241
  return "langchain-v1";
227
242
  }
228
- if (backend === "deepagent" || backend === "deepagents") {
243
+ if (backend === "deepagent") {
229
244
  return "deepagent";
230
245
  }
231
246
  return undefined;
232
247
  }
233
248
  function readSharedAgentConfig(item) {
234
249
  const middleware = readMiddlewareArray(item.middleware);
250
+ const passthrough = readPassthroughConfig(item, [
251
+ "id",
252
+ "kind",
253
+ "description",
254
+ "modelRef",
255
+ "runRoot",
256
+ "tools",
257
+ "mcpServers",
258
+ "skills",
259
+ "memory",
260
+ "subagents",
261
+ "execution",
262
+ "capabilities",
263
+ "systemPrompt",
264
+ "checkpointer",
265
+ "interruptOn",
266
+ "stateSchema",
267
+ "responseFormat",
268
+ "contextSchema",
269
+ "includeAgentName",
270
+ "version",
271
+ "middleware",
272
+ "backend",
273
+ "store",
274
+ "taskDescription",
275
+ "generalPurposeAgent",
276
+ ]);
235
277
  return {
236
278
  ...(typeof item.systemPrompt === "string" ? { systemPrompt: item.systemPrompt } : {}),
237
279
  ...((typeof item.checkpointer === "object" && item.checkpointer) || typeof item.checkpointer === "boolean"
@@ -244,12 +286,15 @@ function readSharedAgentConfig(item) {
244
286
  ...(item.includeAgentName === "inline" ? { includeAgentName: "inline" } : {}),
245
287
  ...(item.version === "v1" || item.version === "v2" ? { version: item.version } : {}),
246
288
  ...(middleware ? { middleware } : {}),
289
+ ...(passthrough ? { passthrough } : {}),
247
290
  };
248
291
  }
249
292
  function readLangchainAgentConfig(item) {
250
293
  return {
251
294
  ...readSharedAgentConfig(item),
252
295
  ...(typeof item.store === "object" && item.store ? { store: item.store } : {}),
296
+ ...(typeof item.taskDescription === "string" && item.taskDescription.trim() ? { taskDescription: item.taskDescription } : {}),
297
+ ...(typeof item.generalPurposeAgent === "boolean" ? { generalPurposeAgent: item.generalPurposeAgent } : {}),
253
298
  };
254
299
  }
255
300
  function readDeepAgentConfig(item) {
@@ -264,17 +309,13 @@ function readDeepAgentConfig(item) {
264
309
  export function parseAgentItem(item, sourcePath) {
265
310
  const subagentRefs = readRefArray(item.subagents);
266
311
  const subagentPathRefs = readPathArray(item.subagents);
267
- const kind = typeof item.kind === "string" ? item.kind : "agent";
268
- const executionMode = String(resolveExecutionBackend(item) ??
269
- (kind === "langchain-agent" ? "langchain-v1" : undefined) ??
270
- (kind === "deepagent" ? "deepagent" : undefined) ??
271
- "deepagent");
312
+ const executionMode = String(resolveExecutionBackend(item) ?? "deepagent");
272
313
  return {
273
314
  id: String(item.id),
274
315
  executionMode: executionMode,
275
316
  capabilities: readCapabilities(item.capabilities) ?? (executionMode === "deepagent"
276
317
  ? { delegation: true, memory: true }
277
- : { delegation: false, memory: false }),
318
+ : { delegation: true, memory: true }),
278
319
  description: String(item.description ?? ""),
279
320
  modelRef: readSingleRef(item.modelRef) ?? "",
280
321
  runRoot: typeof item.runRoot === "string" ? item.runRoot : undefined,
@@ -487,7 +528,7 @@ async function readNamedModelItems(root) {
487
528
  return records;
488
529
  }
489
530
  function isAgentKind(kind) {
490
- return kind === "deepagent" || kind === "langchain-agent" || kind === "agent";
531
+ return kind === "agent";
491
532
  }
492
533
  async function readConfigAgentItems(configRoot) {
493
534
  const records = await readYamlItems(configRoot, "agents", { recursive: true });
@@ -536,18 +577,7 @@ export async function readToolModuleItems(root) {
536
577
  return records;
537
578
  }
538
579
  function inferExecutionMode(item, current) {
539
- const explicitExecution = resolveExecutionBackend(item, current);
540
- if (explicitExecution) {
541
- return explicitExecution;
542
- }
543
- const kind = typeof item.kind === "string" ? item.kind : typeof current?.kind === "string" ? current.kind : undefined;
544
- if (kind === "langchain-agent") {
545
- return "langchain-v1";
546
- }
547
- if (kind === "deepagent") {
548
- return "deepagent";
549
- }
550
- return undefined;
580
+ return resolveExecutionBackend(item, current);
551
581
  }
552
582
  export async function loadWorkspaceObjects(workspaceRoot, options = {}) {
553
583
  const refs = new Map();
@@ -207,6 +207,7 @@ export function parseToolObject(object) {
207
207
  const value = object.value;
208
208
  const backend = asObject(value.backend);
209
209
  const mcp = asObject(value.mcp);
210
+ const providerTool = asObject(value.providerTool) ?? asObject(value.provider);
210
211
  const mcpReferenceConfig = mcp
211
212
  ? {
212
213
  ...(typeof mcp.serverRef === "string"
@@ -226,16 +227,22 @@ export function parseToolObject(object) {
226
227
  ? "bundle"
227
228
  : mcp
228
229
  ? "mcp"
229
- : backend
230
- ? "backend"
231
- : "function";
230
+ : providerTool
231
+ ? "provider"
232
+ : backend
233
+ ? "backend"
234
+ : "function";
232
235
  return {
233
236
  id: object.id,
234
237
  type: String(inferredType),
235
238
  name: String(value.name ?? "").trim(),
236
239
  description: String(value.description ?? "").trim(),
237
240
  implementationName: typeof value.implementationName === "string" ? value.implementationName : undefined,
238
- config: mergeObjects(asObject(value.config), (mcpReferenceConfig && Object.keys(mcpReferenceConfig).length > 0) || (mcpServerConfig && Object.keys(mcpServerConfig).length > 0)
241
+ config: mergeObjects(mergeObjects(asObject(value.config), providerTool
242
+ ? {
243
+ providerTool,
244
+ }
245
+ : undefined), (mcpReferenceConfig && Object.keys(mcpReferenceConfig).length > 0) || (mcpServerConfig && Object.keys(mcpServerConfig).length > 0)
239
246
  ? {
240
247
  mcp: mcpReferenceConfig,
241
248
  ...(mcpServerConfig && Object.keys(mcpServerConfig).length > 0 ? { mcpServer: mcpServerConfig } : {}),
@@ -9,8 +9,8 @@ export function inferAgentCapabilities(agent) {
9
9
  return normalizeCapabilities(agent.capabilities);
10
10
  }
11
11
  return {
12
- delegation: agent.executionMode === "deepagent",
13
- memory: agent.executionMode === "deepagent",
12
+ delegation: agent.executionMode === "deepagent" || agent.executionMode === "langchain-v1",
13
+ memory: agent.executionMode === "deepagent" || agent.executionMode === "langchain-v1",
14
14
  };
15
15
  }
16
16
  export function inferBindingCapabilities(binding) {
@@ -12,10 +12,6 @@ export type RoutingRule = {
12
12
  hasThreadId?: boolean;
13
13
  caseSensitive?: boolean;
14
14
  };
15
- export type RuntimeRecoveryConfig = {
16
- enabled: boolean;
17
- resumeOnStartup: boolean;
18
- };
19
15
  export type RecoveryConfig = {
20
16
  enabled: boolean;
21
17
  resumeResumingRunsOnStartup: boolean;
@@ -26,7 +22,6 @@ export type ConcurrencyConfig = {
26
22
  };
27
23
  export declare function getWorkspaceObject(refs: Map<string, WorkspaceObject | ParsedAgentObject>, ref: string | undefined): WorkspaceObject | undefined;
28
24
  export declare function getRuntimeDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): Record<string, unknown> | undefined;
29
- export declare function getRuntimeRecoveryConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): RuntimeRecoveryConfig;
30
25
  export declare function getRecoveryConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): RecoveryConfig;
31
26
  export declare function getConcurrencyConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): ConcurrencyConfig;
32
27
  export declare function getRoutingSystemPrompt(refs: Map<string, WorkspaceObject | ParsedAgentObject>): string | undefined;
@@ -25,16 +25,6 @@ export function getRuntimeDefaults(refs) {
25
25
  }
26
26
  return runtimes[0].value;
27
27
  }
28
- export function getRuntimeRecoveryConfig(refs) {
29
- const runtimeDefaults = getRuntimeDefaults(refs);
30
- const recovery = typeof runtimeDefaults?.recovery === "object" && runtimeDefaults.recovery
31
- ? runtimeDefaults.recovery
32
- : undefined;
33
- return {
34
- enabled: recovery?.enabled !== false,
35
- resumeOnStartup: recovery?.resumeOnStartup !== false,
36
- };
37
- }
38
28
  export function getRecoveryConfig(refs) {
39
29
  const runtimeDefaults = getRuntimeDefaults(refs);
40
30
  const recovery = typeof runtimeDefaults?.recovery === "object" && runtimeDefaults.recovery
@@ -49,7 +39,7 @@ export function getRecoveryConfig(refs) {
49
39
  enabled: recovery.enabled !== false,
50
40
  resumeResumingRunsOnStartup: typeof recovery.resumeResumingRunsOnStartup === "boolean"
51
41
  ? recovery.resumeResumingRunsOnStartup
52
- : recovery.resumeOnStartup !== false,
42
+ : true,
53
43
  maxRecoveryAttempts,
54
44
  };
55
45
  }
@@ -38,6 +38,12 @@ function validateMiddlewareConfig(agent) {
38
38
  if (kind === "modelFallback" && !Array.isArray(typed.fallbackModels) && !Array.isArray(typed.models)) {
39
39
  throw new Error(`Agent ${agent.id} modelFallback middleware requires fallbackModels or models`);
40
40
  }
41
+ if (kind === "humanInTheLoop" && typeof typed.interruptOn !== "object") {
42
+ throw new Error(`Agent ${agent.id} humanInTheLoop middleware requires interruptOn`);
43
+ }
44
+ if (kind === "pii" && typeof typed.piiType !== "string") {
45
+ throw new Error(`Agent ${agent.id} pii middleware requires piiType`);
46
+ }
41
47
  }
42
48
  }
43
49
  export function validateAgent(agent) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",
@@ -26,11 +26,6 @@
26
26
  "types": "./dist/tools.d.ts",
27
27
  "import": "./dist/tools.js",
28
28
  "default": "./dist/tools.js"
29
- },
30
- "./presentation": {
31
- "types": "./dist/presentation.d.ts",
32
- "import": "./dist/presentation.js",
33
- "default": "./dist/presentation.js"
34
29
  }
35
30
  },
36
31
  "dependencies": {
@@ -38,7 +33,7 @@
38
33
  "@langchain/community": "^1.1.24",
39
34
  "@langchain/core": "^1.1.33",
40
35
  "@langchain/google": "^0.1.7",
41
- "@langchain/langgraph": "^1.2.3",
36
+ "@langchain/langgraph": "^1.2.5",
42
37
  "@langchain/langgraph-checkpoint-sqlite": "^1.0.1",
43
38
  "@langchain/ollama": "^1.2.6",
44
39
  "@langchain/openai": "^1.1.0",
@@ -46,7 +41,7 @@
46
41
  "@llamaindex/ollama": "^0.1.23",
47
42
  "@modelcontextprotocol/sdk": "^1.12.0",
48
43
  "deepagents": "1.8.4",
49
- "langchain": "1.2.34",
44
+ "langchain": "^1.2.36",
50
45
  "llamaindex": "^0.12.1",
51
46
  "mustache": "^4.2.0",
52
47
  "yaml": "^2.8.1",
@@ -55,9 +50,8 @@
55
50
  "scripts": {
56
51
  "build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && cp -R config dist/",
57
52
  "check": "tsc -p tsconfig.json --noEmit",
58
- "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-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/embedded-browser-bookmarks.test.ts test/presentation-wallee.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/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",
59
54
  "test:real-providers": "vitest run test/real-provider-harness.test.ts",
60
- "test:integration": "npm run build && node scripts/integration-wallee-browser.mjs",
61
55
  "release:prepare": "npm version patch --no-git-tag-version && node ./scripts/sync-example-version.mjs",
62
56
  "release:pack": "npm pack --dry-run",
63
57
  "release:publish": "npm publish --access public --registry https://registry.npmjs.org/"