@botbotgo/agent-harness 0.0.40 → 0.0.42

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.
@@ -1,3 +1,3 @@
1
1
  import { type StoreLike } from "../store.js";
2
2
  export declare function createStoreForConfig(storeConfig: Record<string, unknown>, runRoot: string): StoreLike;
3
- export declare function createCheckpointerForConfig(checkpointerConfig: Record<string, unknown>, runRoot: string): unknown;
3
+ export declare function createCheckpointerForConfig(checkpointerConfig: Record<string, unknown> | boolean, runRoot: string): unknown;
@@ -22,6 +22,9 @@ export function createStoreForConfig(storeConfig, runRoot) {
22
22
  }
23
23
  }
24
24
  export function createCheckpointerForConfig(checkpointerConfig, runRoot) {
25
+ if (typeof checkpointerConfig === "boolean") {
26
+ return checkpointerConfig;
27
+ }
25
28
  const kind = typeof checkpointerConfig.kind === "string" ? checkpointerConfig.kind : "FileCheckpointer";
26
29
  switch (kind) {
27
30
  case "MemorySaver":
@@ -43,6 +43,22 @@ function compileMiddlewareConfigs(middleware, models, ownerId) {
43
43
  compiled.model = requireModel(models, compiled.modelRef, ownerId);
44
44
  delete compiled.modelRef;
45
45
  }
46
+ if (compiled.kind === "llmToolSelector" && typeof compiled.modelRef === "string") {
47
+ compiled.model = requireModel(models, compiled.modelRef, ownerId);
48
+ delete compiled.modelRef;
49
+ }
50
+ if (compiled.kind === "modelFallback") {
51
+ const fallbackModelRefs = Array.isArray(compiled.fallbackModelRefs)
52
+ ? compiled.fallbackModelRefs
53
+ : Array.isArray(compiled.modelRefs)
54
+ ? compiled.modelRefs
55
+ : [];
56
+ if (fallbackModelRefs.length > 0) {
57
+ compiled.fallbackModels = fallbackModelRefs.map((modelRef) => requireModel(models, String(modelRef), ownerId));
58
+ delete compiled.fallbackModelRefs;
59
+ delete compiled.modelRefs;
60
+ }
61
+ }
46
62
  return compiled;
47
63
  });
48
64
  }
@@ -117,21 +133,24 @@ function resolveBackendConfig(agent) {
117
133
  return backendConfig ? { config: backendConfig } : undefined;
118
134
  }
119
135
  function resolveStoreConfig(agent) {
120
- if (agent.executionMode !== "deepagent") {
121
- return undefined;
122
- }
123
136
  const inlineStore = typeof agent.deepAgentConfig?.store === "object" && agent.deepAgentConfig.store
124
137
  ? agent.deepAgentConfig.store
125
- : undefined;
138
+ : typeof agent.langchainAgentConfig?.store === "object" && agent.langchainAgentConfig.store
139
+ ? agent.langchainAgentConfig.store
140
+ : undefined;
126
141
  return inlineStore ? { config: inlineStore } : undefined;
127
142
  }
128
143
  function resolveCheckpointerConfig(agent) {
129
144
  const inlineAgentCheckpointer = typeof agent.deepAgentConfig?.checkpointer === "object" && agent.deepAgentConfig.checkpointer
130
145
  ? agent.deepAgentConfig.checkpointer
131
- : typeof agent.langchainAgentConfig?.checkpointer === "object" && agent.langchainAgentConfig.checkpointer
132
- ? agent.langchainAgentConfig.checkpointer
133
- : undefined;
134
- return inlineAgentCheckpointer ? { config: inlineAgentCheckpointer } : undefined;
146
+ : typeof agent.deepAgentConfig?.checkpointer === "boolean"
147
+ ? agent.deepAgentConfig.checkpointer
148
+ : typeof agent.langchainAgentConfig?.checkpointer === "object" && agent.langchainAgentConfig.checkpointer
149
+ ? agent.langchainAgentConfig.checkpointer
150
+ : typeof agent.langchainAgentConfig?.checkpointer === "boolean"
151
+ ? agent.langchainAgentConfig.checkpointer
152
+ : undefined;
153
+ return inlineAgentCheckpointer !== undefined ? { config: inlineAgentCheckpointer } : undefined;
135
154
  }
136
155
  export function compileBinding(workspaceRoot, agent, agents, referencedSubagentIds, refs, models, tools) {
137
156
  const internalSubagent = referencedSubagentIds.has(agent.id);
@@ -162,9 +181,15 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
162
181
  model: compiledAgentModel,
163
182
  tools: requireTools(tools, agent.toolRefs, agent.id),
164
183
  systemPrompt: resolveSystemPrompt(agent),
184
+ stateSchema: agent.langchainAgentConfig?.stateSchema,
165
185
  responseFormat: agent.langchainAgentConfig?.responseFormat,
166
186
  contextSchema: agent.langchainAgentConfig?.contextSchema,
167
187
  middleware: compileMiddlewareConfigs(agent.langchainAgentConfig?.middleware, models, agent.id),
188
+ includeAgentName: agent.langchainAgentConfig?.includeAgentName === "inline" ? "inline" : undefined,
189
+ version: agent.langchainAgentConfig?.version === "v1" || agent.langchainAgentConfig?.version === "v2"
190
+ ? agent.langchainAgentConfig.version
191
+ : undefined,
192
+ name: resolveAgentRuntimeName(agent),
168
193
  description: agent.description,
169
194
  };
170
195
  return {
@@ -196,6 +221,10 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
196
221
  name: resolveAgentRuntimeName(agent),
197
222
  memory: compiledAgentMemory,
198
223
  skills: compiledAgentSkills,
224
+ generalPurposeAgent: typeof agent.deepAgentConfig?.generalPurposeAgent === "boolean" ? agent.deepAgentConfig.generalPurposeAgent : undefined,
225
+ taskDescription: typeof agent.deepAgentConfig?.taskDescription === "string" && agent.deepAgentConfig.taskDescription.trim()
226
+ ? agent.deepAgentConfig.taskDescription
227
+ : undefined,
199
228
  },
200
229
  };
201
230
  }
@@ -213,21 +213,31 @@ function readSharedAgentConfig(item) {
213
213
  const middleware = readMiddlewareArray(item.middleware);
214
214
  return {
215
215
  ...(typeof item.systemPrompt === "string" ? { systemPrompt: item.systemPrompt } : {}),
216
- ...(typeof item.checkpointer === "object" && item.checkpointer ? { checkpointer: item.checkpointer } : {}),
216
+ ...((typeof item.checkpointer === "object" && item.checkpointer) || typeof item.checkpointer === "boolean"
217
+ ? { checkpointer: item.checkpointer }
218
+ : {}),
217
219
  ...(typeof item.interruptOn === "object" && item.interruptOn ? { interruptOn: item.interruptOn } : {}),
220
+ ...(item.stateSchema !== undefined ? { stateSchema: item.stateSchema } : {}),
218
221
  ...(item.responseFormat !== undefined ? { responseFormat: item.responseFormat } : {}),
219
222
  ...(item.contextSchema !== undefined ? { contextSchema: item.contextSchema } : {}),
223
+ ...(item.includeAgentName === "inline" ? { includeAgentName: "inline" } : {}),
224
+ ...(item.version === "v1" || item.version === "v2" ? { version: item.version } : {}),
220
225
  ...(middleware ? { middleware } : {}),
221
226
  };
222
227
  }
223
228
  function readLangchainAgentConfig(item) {
224
- return readSharedAgentConfig(item);
229
+ return {
230
+ ...readSharedAgentConfig(item),
231
+ ...(typeof item.store === "object" && item.store ? { store: item.store } : {}),
232
+ };
225
233
  }
226
234
  function readDeepAgentConfig(item) {
227
235
  return {
228
236
  ...readSharedAgentConfig(item),
229
237
  ...(typeof item.backend === "object" && item.backend ? { backend: item.backend } : {}),
230
238
  ...(typeof item.store === "object" && item.store ? { store: item.store } : {}),
239
+ ...(typeof item.taskDescription === "string" && item.taskDescription.trim() ? { taskDescription: item.taskDescription } : {}),
240
+ ...(typeof item.generalPurposeAgent === "boolean" ? { generalPurposeAgent: item.generalPurposeAgent } : {}),
231
241
  };
232
242
  }
233
243
  export function parseAgentItem(item, sourcePath) {
@@ -12,8 +12,23 @@ 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
+ export type RecoveryConfig = {
20
+ enabled: boolean;
21
+ resumeResumingRunsOnStartup: boolean;
22
+ maxRecoveryAttempts: number;
23
+ };
24
+ export type ConcurrencyConfig = {
25
+ maxConcurrentRuns?: number;
26
+ };
15
27
  export declare function getWorkspaceObject(refs: Map<string, WorkspaceObject | ParsedAgentObject>, ref: string | undefined): WorkspaceObject | undefined;
16
28
  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
+ export declare function getRecoveryConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): RecoveryConfig;
31
+ export declare function getConcurrencyConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): ConcurrencyConfig;
17
32
  export declare function getRoutingSystemPrompt(refs: Map<string, WorkspaceObject | ParsedAgentObject>): string | undefined;
18
33
  export declare function getRoutingDefaultAgentId(refs: Map<string, WorkspaceObject | ParsedAgentObject>): string | undefined;
19
34
  export declare function isModelRoutingEnabled(refs: Map<string, WorkspaceObject | ParsedAgentObject>): boolean;
@@ -25,6 +25,46 @@ 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
+ export function getRecoveryConfig(refs) {
39
+ const runtimeDefaults = getRuntimeDefaults(refs);
40
+ const recovery = typeof runtimeDefaults?.recovery === "object" && runtimeDefaults.recovery
41
+ ? runtimeDefaults.recovery
42
+ : {};
43
+ const maxRecoveryAttempts = typeof recovery.maxRecoveryAttempts === "number" &&
44
+ Number.isFinite(recovery.maxRecoveryAttempts) &&
45
+ recovery.maxRecoveryAttempts > 0
46
+ ? Math.floor(recovery.maxRecoveryAttempts)
47
+ : 3;
48
+ return {
49
+ enabled: recovery.enabled !== false,
50
+ resumeResumingRunsOnStartup: typeof recovery.resumeResumingRunsOnStartup === "boolean"
51
+ ? recovery.resumeResumingRunsOnStartup
52
+ : recovery.resumeOnStartup !== false,
53
+ maxRecoveryAttempts,
54
+ };
55
+ }
56
+ export function getConcurrencyConfig(refs) {
57
+ const runtimeDefaults = getRuntimeDefaults(refs);
58
+ const concurrency = typeof runtimeDefaults?.concurrency === "object" && runtimeDefaults.concurrency
59
+ ? runtimeDefaults.concurrency
60
+ : {};
61
+ const maxConcurrentRuns = typeof concurrency.maxConcurrentRuns === "number" &&
62
+ Number.isFinite(concurrency.maxConcurrentRuns) &&
63
+ concurrency.maxConcurrentRuns > 0
64
+ ? Math.floor(concurrency.maxConcurrentRuns)
65
+ : undefined;
66
+ return { maxConcurrentRuns };
67
+ }
28
68
  export function getRoutingSystemPrompt(refs) {
29
69
  const routing = getRoutingObject(refs);
30
70
  return typeof routing?.systemPrompt === "string" && routing.systemPrompt.trim() ? routing.systemPrompt : undefined;
@@ -1,18 +1,15 @@
1
1
  const allowedExecutionModes = new Set(["deepagent", "langchain-v1"]);
2
- const allowedMiddlewareKinds = new Set([
3
- "summarization",
4
- "modelRetry",
5
- "toolRetry",
6
- "toolCallLimit",
7
- "modelCallLimit",
8
- "todoList",
9
- ]);
10
2
  function hasPromptContent(value) {
11
3
  return typeof value === "string" && value.trim().length > 0;
12
4
  }
13
5
  function validateCheckpointerConfig(agent) {
14
6
  const checkpointer = (typeof agent.deepAgentConfig?.checkpointer === "object" && agent.deepAgentConfig.checkpointer) ||
7
+ (typeof agent.deepAgentConfig?.checkpointer === "boolean" ? agent.deepAgentConfig.checkpointer : undefined) ||
8
+ (typeof agent.langchainAgentConfig?.checkpointer === "boolean" ? agent.langchainAgentConfig.checkpointer : undefined) ||
15
9
  (typeof agent.langchainAgentConfig?.checkpointer === "object" && agent.langchainAgentConfig.checkpointer);
10
+ if (typeof checkpointer === "boolean") {
11
+ return;
12
+ }
16
13
  if (!checkpointer) {
17
14
  return;
18
15
  }
@@ -33,13 +30,16 @@ function validateMiddlewareConfig(agent) {
33
30
  throw new Error(`Agent ${agent.id} middleware entries must be objects`);
34
31
  }
35
32
  const typed = config;
36
- const kind = typeof typed.kind === "string" ? typed.kind : "";
37
- if (!allowedMiddlewareKinds.has(kind)) {
38
- throw new Error(`Agent ${agent.id} middleware kind ${kind || "(missing)"} is not supported`);
33
+ const kind = typeof typed.kind === "string" ? typed.kind.trim() : "";
34
+ if (!kind) {
35
+ throw new Error(`Agent ${agent.id} middleware kind is required`);
39
36
  }
40
37
  if (kind === "summarization" && typed.model === undefined && typeof typed.modelRef !== "string") {
41
38
  throw new Error(`Agent ${agent.id} summarization middleware requires model or modelRef`);
42
39
  }
40
+ if (kind === "modelFallback" && !Array.isArray(typed.fallbackModels) && !Array.isArray(typed.models)) {
41
+ throw new Error(`Agent ${agent.id} modelFallback middleware requires fallbackModels or models`);
42
+ }
43
43
  }
44
44
  }
45
45
  export function validateAgent(agent) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
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/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",
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-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",
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",