@botbotgo/agent-harness 0.0.106 → 0.0.107

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 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.105";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.106";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.105";
1
+ export const AGENT_HARNESS_VERSION = "0.0.106";
@@ -15,6 +15,7 @@ export declare class AgentRuntimeAdapter {
15
15
  private readonly options;
16
16
  private readonly modelCache;
17
17
  private readonly runnableCache;
18
+ private readonly toolNameMappingCache;
18
19
  constructor(options?: RuntimeAdapterOptions);
19
20
  private getModelCacheKey;
20
21
  private invokeWithProviderRetry;
@@ -25,6 +26,7 @@ export declare class AgentRuntimeAdapter {
25
26
  private applyStrictToolJsonInstruction;
26
27
  private resolveModel;
27
28
  private resolveTools;
29
+ private getToolNameMapping;
28
30
  private resolveFilesystemBackend;
29
31
  private resolveBuiltinMiddlewareBackend;
30
32
  private createDeclaredMiddlewareResolverOptions;
@@ -39,6 +39,7 @@ export class AgentRuntimeAdapter {
39
39
  options;
40
40
  modelCache = new Map();
41
41
  runnableCache = new WeakMap();
42
+ toolNameMappingCache = new WeakMap();
42
43
  constructor(options = {}) {
43
44
  this.options = options;
44
45
  }
@@ -93,6 +94,15 @@ export class AgentRuntimeAdapter {
93
94
  resolveToolValues: this.options.toolResolver,
94
95
  });
95
96
  }
97
+ getToolNameMapping(binding) {
98
+ const cached = this.toolNameMappingCache.get(binding);
99
+ if (cached) {
100
+ return cached;
101
+ }
102
+ const resolved = buildToolNameMapping(getBindingPrimaryTools(binding));
103
+ this.toolNameMappingCache.set(binding, resolved);
104
+ return resolved;
105
+ }
96
106
  resolveFilesystemBackend(binding) {
97
107
  const filesystemConfig = getBindingLangChainParams(binding)?.filesystem;
98
108
  const configuredRootDir = typeof filesystemConfig?.rootDir === "string" && filesystemConfig.rootDir.trim().length > 0
@@ -274,7 +284,7 @@ export class AgentRuntimeAdapter {
274
284
  };
275
285
  const primaryTools = getBindingPrimaryTools(binding);
276
286
  const resolvedTools = this.resolveTools(primaryTools, binding);
277
- const toolNameMapping = buildToolNameMapping(primaryTools);
287
+ const toolNameMapping = this.getToolNameMapping(binding);
278
288
  const executableTools = buildExecutableToolMap({
279
289
  primaryTools,
280
290
  resolvedTools,
@@ -311,7 +321,7 @@ export class AgentRuntimeAdapter {
311
321
  const streamIdleTimeoutMs = resolveStreamIdleTimeout(binding);
312
322
  const streamDeadlineAt = invokeTimeoutMs ? Date.now() + invokeTimeoutMs : undefined;
313
323
  const primaryTools = getBindingPrimaryTools(binding);
314
- const toolNameMapping = buildToolNameMapping(primaryTools);
324
+ const toolNameMapping = this.getToolNameMapping(binding);
315
325
  const primaryModel = getBindingPrimaryModel(binding);
316
326
  const forceInvokeFallback = isLangChainBinding(binding) &&
317
327
  primaryTools.length > 0 &&
@@ -2,7 +2,7 @@ import { createCheckpointerForConfig, createStoreForConfig } from "../../support
2
2
  import { resolveCompiledEmbeddingModel, resolveCompiledEmbeddingModelRef } from "../../support/embedding-models.js";
3
3
  import { resolveCompiledVectorStore, resolveCompiledVectorStoreRef } from "../../support/vector-stores.js";
4
4
  export function resolveStoreFromConfig(stores, storeConfig, runRoot) {
5
- const cacheKey = storeConfig ? JSON.stringify(storeConfig) : undefined;
5
+ const cacheKey = storeConfig ? `${runRoot}:${JSON.stringify(storeConfig)}` : undefined;
6
6
  if (!storeConfig || !cacheKey) {
7
7
  return undefined;
8
8
  }
@@ -14,6 +14,9 @@ export declare class AgentHarnessRuntime {
14
14
  private readonly stores;
15
15
  private readonly embeddingModels;
16
16
  private readonly vectorStores;
17
+ private readonly hostBindings;
18
+ private readonly defaultHostBinding?;
19
+ private readonly defaultRunRootValue;
17
20
  private readonly defaultStore;
18
21
  private readonly runtimeMemoryStore;
19
22
  private readonly routingRules;
@@ -30,7 +33,6 @@ export declare class AgentHarnessRuntime {
30
33
  private pendingRunInsertionOrder;
31
34
  private readonly pendingRunSlots;
32
35
  private runtimeEventSequence;
33
- private listHostBindings;
34
36
  private defaultRunRoot;
35
37
  private getDefaultHostAgentId;
36
38
  private resolveSelectedAgentId;
@@ -46,6 +46,9 @@ export class AgentHarnessRuntime {
46
46
  stores = new Map();
47
47
  embeddingModels = new Map();
48
48
  vectorStores = new Map();
49
+ hostBindings;
50
+ defaultHostBinding;
51
+ defaultRunRootValue;
49
52
  defaultStore;
50
53
  runtimeMemoryStore;
51
54
  routingRules;
@@ -62,12 +65,8 @@ export class AgentHarnessRuntime {
62
65
  pendingRunInsertionOrder = 0;
63
66
  pendingRunSlots = [];
64
67
  runtimeEventSequence = 0;
65
- listHostBindings() {
66
- return inferRoutingBindings(this.workspace).hostBindings;
67
- }
68
68
  defaultRunRoot() {
69
- return (this.listHostBindings()[0]?.harnessRuntime.runRoot ??
70
- `${this.workspace.workspaceRoot}/run-data`);
69
+ return this.defaultRunRootValue;
71
70
  }
72
71
  getDefaultHostAgentId() {
73
72
  return getDefaultHostAgentId(this.workspace, this.routingDefaultAgentId);
@@ -85,13 +84,16 @@ export class AgentHarnessRuntime {
85
84
  constructor(workspace, runtimeAdapterOptions = {}) {
86
85
  this.workspace = workspace;
87
86
  this.runtimeAdapterOptions = runtimeAdapterOptions;
87
+ this.hostBindings = inferRoutingBindings(this.workspace).hostBindings;
88
+ this.defaultHostBinding = this.hostBindings[0];
89
+ this.defaultRunRootValue = this.defaultHostBinding?.harnessRuntime.runRoot ?? `${this.workspace.workspaceRoot}/run-data`;
88
90
  const runRoot = this.defaultRunRoot();
89
91
  this.persistence = new SqlitePersistence(runRoot);
90
- const defaultStoreConfig = this.listHostBindings()[0]?.harnessRuntime.store;
92
+ const defaultStoreConfig = this.defaultHostBinding?.harnessRuntime.store;
91
93
  this.defaultStore = resolveStoreFromConfig(this.stores, defaultStoreConfig, runRoot) ?? new FileBackedStore(`${runRoot}/store.json`);
92
- const runtimeMemoryStoreConfig = typeof this.listHostBindings()[0]?.harnessRuntime.runtimeMemory?.store === "object" &&
93
- this.listHostBindings()[0]?.harnessRuntime.runtimeMemory?.store
94
- ? this.listHostBindings()[0]?.harnessRuntime.runtimeMemory?.store
94
+ const runtimeMemoryStoreConfig = typeof this.defaultHostBinding?.harnessRuntime.runtimeMemory?.store === "object" &&
95
+ this.defaultHostBinding?.harnessRuntime.runtimeMemory?.store
96
+ ? this.defaultHostBinding.harnessRuntime.runtimeMemory.store
95
97
  : undefined;
96
98
  this.runtimeMemoryStore = resolveStoreFromConfig(this.stores, runtimeMemoryStoreConfig, runRoot) ?? this.defaultStore;
97
99
  this.resolvedRuntimeAdapterOptions = {
@@ -3,25 +3,49 @@ function asRecord(value) {
3
3
  ? value
4
4
  : undefined;
5
5
  }
6
+ const bindingExecutionViewCache = new WeakMap();
7
+ function deriveBindingExecutionView(binding) {
8
+ const cached = bindingExecutionViewCache.get(binding);
9
+ if (cached) {
10
+ return cached;
11
+ }
12
+ const adapterKind = binding.adapter?.kind ?? binding.agent.executionMode;
13
+ const adapterConfig = binding.adapter?.config ?? {};
14
+ const adapterParams = asRecord(adapterConfig.params);
15
+ const langchainParams = adapterKind === "langchain-v1" && adapterParams
16
+ ? adapterParams
17
+ : binding.langchainAgentParams;
18
+ const deepAgentParams = adapterKind === "deepagent" && adapterParams
19
+ ? adapterParams
20
+ : binding.deepAgentParams;
21
+ const primaryTools = langchainParams?.tools ?? deepAgentParams?.tools ?? [];
22
+ const view = {
23
+ adapterKind,
24
+ adapterConfig,
25
+ langchainParams,
26
+ deepAgentParams,
27
+ primaryTools,
28
+ primaryModel: langchainParams?.model ?? deepAgentParams?.model,
29
+ systemPrompt: langchainParams?.systemPrompt ?? deepAgentParams?.systemPrompt,
30
+ middlewareConfigs: langchainParams?.middleware ?? deepAgentParams?.middleware,
31
+ interruptCompatibilityRules: deepAgentParams?.interruptOn ??
32
+ binding.agent.langchainAgentConfig?.interruptOn,
33
+ storeConfig: deepAgentParams?.store ?? binding.harnessRuntime?.store,
34
+ };
35
+ bindingExecutionViewCache.set(binding, view);
36
+ return view;
37
+ }
6
38
  export function getBindingAdapterKind(binding) {
7
- return binding.adapter?.kind ?? binding.agent.executionMode;
39
+ return deriveBindingExecutionView(binding).adapterKind;
8
40
  }
9
41
  export function getBindingAdapterConfig(binding) {
10
- return binding.adapter?.config ?? {};
42
+ return deriveBindingExecutionView(binding).adapterConfig;
11
43
  }
12
44
  export function getBindingLangChainParams(binding) {
13
- const adapterParams = getBindingAdapterConfig(binding).params;
14
- if (getBindingAdapterKind(binding) === "langchain-v1" && typeof adapterParams === "object" && adapterParams && !Array.isArray(adapterParams)) {
15
- return adapterParams;
16
- }
17
- return binding.langchainAgentParams;
45
+ return deriveBindingExecutionView(binding).langchainParams;
18
46
  }
19
47
  export function getBindingDeepAgentParams(binding) {
20
- const adapterParams = asRecord(getBindingAdapterConfig(binding).params);
21
- if (getBindingAdapterKind(binding) === "deepagent" && adapterParams) {
22
- return adapterParams;
23
- }
24
- return binding.deepAgentParams;
48
+ return deriveBindingExecutionView(binding).deepAgentParams;
25
49
  }
26
50
  export function isLangChainBinding(binding) {
27
51
  return getBindingAdapterKind(binding) === "langchain-v1" || Boolean(binding.langchainAgentParams);
@@ -30,30 +54,29 @@ export function isDeepAgentBinding(binding) {
30
54
  return getBindingAdapterKind(binding) === "deepagent" || Boolean(binding.deepAgentParams);
31
55
  }
32
56
  export function getBindingPrimaryTools(binding) {
33
- return binding.langchainAgentParams?.tools ?? binding.deepAgentParams?.tools ?? [];
57
+ return deriveBindingExecutionView(binding).primaryTools;
34
58
  }
35
59
  export function getBindingPrimaryModel(binding) {
36
- return binding.langchainAgentParams?.model ?? binding.deepAgentParams?.model;
60
+ return deriveBindingExecutionView(binding).primaryModel;
37
61
  }
38
62
  export function getBindingRuntimeModel(binding, slot) {
39
63
  return binding.harnessRuntime.models?.[slot];
40
64
  }
41
65
  export function getBindingSystemPrompt(binding) {
42
- return binding.langchainAgentParams?.systemPrompt ?? binding.deepAgentParams?.systemPrompt;
66
+ return deriveBindingExecutionView(binding).systemPrompt;
43
67
  }
44
68
  export function getBindingMiddlewareConfigs(binding) {
45
- return binding.langchainAgentParams?.middleware ?? binding.deepAgentParams?.middleware;
69
+ return deriveBindingExecutionView(binding).middlewareConfigs;
46
70
  }
47
71
  export function getBindingInterruptCompatibilityRules(binding) {
48
- return binding.deepAgentParams?.interruptOn ??
49
- binding.agent.langchainAgentConfig?.interruptOn;
72
+ return deriveBindingExecutionView(binding).interruptCompatibilityRules;
50
73
  }
51
74
  export function getBindingModelInit(binding) {
52
75
  return getBindingPrimaryModel(binding)?.init;
53
76
  }
54
77
  export function getBindingStoreConfig(binding) {
55
- return binding.deepAgentParams?.store ?? binding.harnessRuntime.store;
78
+ return deriveBindingExecutionView(binding).storeConfig;
56
79
  }
57
80
  export function bindingHasSubagents(binding) {
58
- return (binding.deepAgentParams?.subagents.length ?? 0) > 0;
81
+ return (getBindingDeepAgentParams(binding)?.subagents.length ?? 0) > 0;
59
82
  }
@@ -90,21 +90,20 @@ export function requireTools(tools, refs, ownerId) {
90
90
  }
91
91
  function buildSubagent(agent, workspaceRoot, models, tools, parentSkills, parentModel, parentMemory) {
92
92
  const ownMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
93
+ const execution = compileExecutionCore(agent, models, tools);
93
94
  return {
94
95
  name: resolveAgentRuntimeName(agent),
95
96
  description: agent.description,
96
- systemPrompt: [resolvePromptValue(agent.deepAgentConfig?.systemPrompt), WORKSPACE_BOUNDARY_GUIDANCE].filter(Boolean).join("\n\n"),
97
- tools: requireTools(tools, agent.toolRefs, agent.id),
98
- model: agent.modelRef ? requireModel(models, agent.modelRef, agent.id) : parentModel,
99
- interruptOn: agent.deepAgentConfig?.interruptOn,
97
+ systemPrompt: execution.systemPrompt ?? WORKSPACE_BOUNDARY_GUIDANCE,
98
+ tools: execution.tools,
99
+ model: agent.modelRef ? execution.model : parentModel,
100
+ interruptOn: resolveInterruptOn(agent),
100
101
  skills: compileAgentSkills(workspaceRoot, agent, parentSkills),
101
102
  memory: ownMemory.length > 0 ? ownMemory : parentMemory,
102
- responseFormat: agent.deepAgentConfig?.responseFormat,
103
- contextSchema: agent.deepAgentConfig?.contextSchema,
104
- middleware: compileMiddlewareConfigs(agent.deepAgentConfig?.middleware, models, agent.id),
105
- passthrough: typeof agent.deepAgentConfig?.passthrough === "object" && agent.deepAgentConfig.passthrough
106
- ? { ...agent.deepAgentConfig.passthrough }
107
- : undefined,
103
+ responseFormat: execution.responseFormat,
104
+ contextSchema: execution.contextSchema,
105
+ middleware: execution.middleware,
106
+ passthrough: execution.passthrough,
108
107
  };
109
108
  }
110
109
  function resolveDirectPrompt(agent) {
@@ -124,6 +123,45 @@ function resolveInterruptOn(agent) {
124
123
  return (agent.deepAgentConfig?.interruptOn ??
125
124
  agent.langchainAgentConfig?.interruptOn);
126
125
  }
126
+ function resolveResponseFormat(agent) {
127
+ return agent.deepAgentConfig?.responseFormat ?? agent.langchainAgentConfig?.responseFormat;
128
+ }
129
+ function resolveContextSchema(agent) {
130
+ return agent.deepAgentConfig?.contextSchema ?? agent.langchainAgentConfig?.contextSchema;
131
+ }
132
+ function resolveCompiledMiddleware(agent, models) {
133
+ const middleware = agent.deepAgentConfig?.middleware ??
134
+ agent.langchainAgentConfig?.middleware;
135
+ return compileMiddlewareConfigs(middleware, models, agent.id);
136
+ }
137
+ function resolvePassthrough(agent) {
138
+ const passthrough = typeof agent.deepAgentConfig?.passthrough === "object" && agent.deepAgentConfig.passthrough
139
+ ? agent.deepAgentConfig.passthrough
140
+ : typeof agent.langchainAgentConfig?.passthrough === "object" && agent.langchainAgentConfig.passthrough
141
+ ? agent.langchainAgentConfig.passthrough
142
+ : undefined;
143
+ return passthrough ? { ...passthrough } : undefined;
144
+ }
145
+ function compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory) {
146
+ return agent.subagentRefs.map((ref) => {
147
+ const subagent = agents.get(resolveRefId(ref));
148
+ if (!subagent) {
149
+ throw new Error(`Missing subagent ${ref} for agent ${agent.id}`);
150
+ }
151
+ return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory);
152
+ });
153
+ }
154
+ function compileExecutionCore(agent, models, tools) {
155
+ return {
156
+ model: requireModel(models, agent.modelRef, agent.id),
157
+ tools: requireTools(tools, agent.toolRefs, agent.id),
158
+ systemPrompt: resolveSystemPrompt(agent),
159
+ responseFormat: resolveResponseFormat(agent),
160
+ contextSchema: resolveContextSchema(agent),
161
+ middleware: resolveCompiledMiddleware(agent, models),
162
+ passthrough: resolvePassthrough(agent),
163
+ };
164
+ }
127
165
  function resolveBackendConfig(agent, refs) {
128
166
  if (agent.executionMode !== "deepagent") {
129
167
  return undefined;
@@ -286,7 +324,11 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
286
324
  const resilience = getResilienceConfig(refs);
287
325
  const compiledAgentSkills = compileAgentSkills(workspaceRoot, agent);
288
326
  const compiledAgentMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
289
- const compiledAgentModel = requireModel(models, agent.modelRef || (internalSubagent ? "model/default" : ""), agent.id);
327
+ const execution = compileExecutionCore({
328
+ ...agent,
329
+ modelRef: agent.modelRef || (internalSubagent ? "model/default" : ""),
330
+ }, models, tools);
331
+ const compiledAgentModel = execution.model;
290
332
  const backend = resolveBackendConfig(agent, refs);
291
333
  const store = resolveStoreConfig(agent, refs);
292
334
  const checkpointer = resolveCheckpointerConfig(agent, refs);
@@ -323,28 +365,19 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
323
365
  },
324
366
  };
325
367
  if (agent.executionMode !== "deepagent") {
326
- const basePassthrough = typeof agent.langchainAgentConfig?.passthrough === "object" && agent.langchainAgentConfig.passthrough
327
- ? { ...agent.langchainAgentConfig.passthrough }
328
- : undefined;
329
368
  const langchainAgentParams = {
330
- model: compiledAgentModel,
331
- tools: requireTools(tools, agent.toolRefs, agent.id),
332
- systemPrompt: resolveSystemPrompt(agent),
369
+ model: execution.model,
370
+ tools: execution.tools,
371
+ systemPrompt: execution.systemPrompt,
333
372
  stateSchema: agent.langchainAgentConfig?.stateSchema,
334
- responseFormat: agent.langchainAgentConfig?.responseFormat,
335
- contextSchema: agent.langchainAgentConfig?.contextSchema,
373
+ responseFormat: execution.responseFormat,
374
+ contextSchema: execution.contextSchema,
336
375
  filesystem: typeof agent.langchainAgentConfig?.filesystem === "object" && agent.langchainAgentConfig.filesystem
337
376
  ? { ...agent.langchainAgentConfig.filesystem }
338
377
  : undefined,
339
- middleware: compileMiddlewareConfigs(agent.langchainAgentConfig?.middleware, models, agent.id),
340
- passthrough: basePassthrough,
341
- subagents: agent.subagentRefs.map((ref) => {
342
- const subagent = agents.get(resolveRefId(ref));
343
- if (!subagent) {
344
- throw new Error(`Missing subagent ${ref} for agent ${agent.id}`);
345
- }
346
- return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory);
347
- }),
378
+ middleware: execution.middleware,
379
+ passthrough: execution.passthrough,
380
+ subagents: compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory),
348
381
  memory: compiledAgentMemory,
349
382
  skills: compiledAgentSkills,
350
383
  generalPurposeAgent: typeof agent.langchainAgentConfig?.generalPurposeAgent === "boolean" ? agent.langchainAgentConfig.generalPurposeAgent : undefined,
@@ -370,23 +403,15 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
370
403
  };
371
404
  }
372
405
  const deepAgentParams = {
373
- model: compiledAgentModel,
374
- tools: requireTools(tools, agent.toolRefs, agent.id),
375
- systemPrompt: resolveSystemPrompt(agent),
376
- responseFormat: agent.deepAgentConfig?.responseFormat,
377
- contextSchema: agent.deepAgentConfig?.contextSchema,
378
- middleware: compileMiddlewareConfigs(agent.deepAgentConfig?.middleware, models, agent.id),
379
- passthrough: typeof agent.deepAgentConfig?.passthrough === "object" && agent.deepAgentConfig.passthrough
380
- ? { ...agent.deepAgentConfig.passthrough }
381
- : undefined,
406
+ model: execution.model,
407
+ tools: execution.tools,
408
+ systemPrompt: execution.systemPrompt,
409
+ responseFormat: execution.responseFormat,
410
+ contextSchema: execution.contextSchema,
411
+ middleware: execution.middleware,
412
+ passthrough: execution.passthrough,
382
413
  description: agent.description,
383
- subagents: agent.subagentRefs.map((ref) => {
384
- const subagent = agents.get(resolveRefId(ref));
385
- if (!subagent) {
386
- throw new Error(`Missing subagent ${ref} for agent ${agent.id}`);
387
- }
388
- return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory);
389
- }),
414
+ subagents: compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory),
390
415
  interruptOn: resolveInterruptOn(agent),
391
416
  ...(backend ? { backend: backend.config } : {}),
392
417
  ...(store ? { store: store.config } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.106",
3
+ "version": "0.0.107",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",