@botbotgo/agent-harness 0.0.105 → 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.104";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.106";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.104";
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
  }
@@ -1,10 +1,10 @@
1
1
  import { type MessageContent, type ThreadSummary, type WorkspaceBundle } from "../../../contracts/types.js";
2
- export declare function getDefaultHostAgentId(workspace: WorkspaceBundle, preferredHostAgentId: string): string;
2
+ export declare function getDefaultHostAgentId(workspace: WorkspaceBundle, preferredHostAgentId?: string): string;
3
3
  export declare function resolveSelectedAgentId(options: {
4
4
  workspace: WorkspaceBundle;
5
5
  input: MessageContent;
6
6
  requestedAgentId?: string;
7
7
  threadId?: string;
8
- preferredHostAgentId: string;
8
+ preferredHostAgentId?: string;
9
9
  getThreadSummary: (threadId: string) => Promise<ThreadSummary | null>;
10
10
  }): Promise<string>;
@@ -1,9 +1,8 @@
1
1
  import { AUTO_AGENT_ID } from "../../../contracts/types.js";
2
2
  import { inferRoutingBindings } from "../../support/harness-support.js";
3
- import { isRuntimeEntryBinding } from "../../support/runtime-entry.js";
4
3
  export function getDefaultHostAgentId(workspace, preferredHostAgentId) {
5
- const preferredBinding = workspace.bindings.get(preferredHostAgentId);
6
- if (preferredBinding && isRuntimeEntryBinding(preferredBinding)) {
4
+ const preferredBinding = preferredHostAgentId ? workspace.bindings.get(preferredHostAgentId) : undefined;
5
+ if (preferredBinding) {
7
6
  return preferredBinding.agent.id;
8
7
  }
9
8
  return inferRoutingBindings(workspace).primaryBinding?.agent.id ?? "agent";
@@ -14,7 +13,7 @@ export async function resolveSelectedAgentId(options) {
14
13
  if (threadId) {
15
14
  const thread = await getThreadSummary(threadId);
16
15
  const threadBinding = thread ? workspace.bindings.get(thread.agentId) : undefined;
17
- if (thread?.agentId && threadBinding && isRuntimeEntryBinding(threadBinding)) {
16
+ if (thread?.agentId && threadBinding) {
18
17
  return thread.agentId;
19
18
  }
20
19
  }
@@ -2,9 +2,8 @@ import { readSkillMetadata } from "../../support/skill-metadata.js";
2
2
  import { getBindingPrimaryTools } from "../../support/compiled-binding.js";
3
3
  import { assessSkillRequirements, } from "./skill-requirements.js";
4
4
  import { createRuntimeEnv } from "../../support/runtime-env.js";
5
- import { isRuntimeEntryBinding } from "../../support/runtime-entry.js";
6
5
  function listHostBindings(workspace) {
7
- return Array.from(workspace.bindings.values()).filter((binding) => isRuntimeEntryBinding(binding));
6
+ return Array.from(workspace.bindings.values());
8
7
  }
9
8
  export function findAgentBinding(workspace, agentId) {
10
9
  return workspace.bindings.get(agentId);
@@ -5,7 +5,6 @@ import type { RequirementAssessmentOptions } from "./harness/system/skill-requir
5
5
  export declare class AgentHarnessRuntime {
6
6
  private readonly workspace;
7
7
  private readonly runtimeAdapterOptions;
8
- private static readonly DEFAULT_HOST_AGENT_ID;
9
8
  private static readonly BACKGROUND_EVENT_TYPES;
10
9
  private readonly eventBus;
11
10
  private readonly persistence;
@@ -15,6 +14,9 @@ export declare class AgentHarnessRuntime {
15
14
  private readonly stores;
16
15
  private readonly embeddingModels;
17
16
  private readonly vectorStores;
17
+ private readonly hostBindings;
18
+ private readonly defaultHostBinding?;
19
+ private readonly defaultRunRootValue;
18
20
  private readonly defaultStore;
19
21
  private readonly runtimeMemoryStore;
20
22
  private readonly routingRules;
@@ -31,7 +33,6 @@ export declare class AgentHarnessRuntime {
31
33
  private pendingRunInsertionOrder;
32
34
  private readonly pendingRunSlots;
33
35
  private runtimeEventSequence;
34
- private listHostBindings;
35
36
  private defaultRunRoot;
36
37
  private getDefaultHostAgentId;
37
38
  private resolveSelectedAgentId;
@@ -23,7 +23,6 @@ import { getDefaultHostAgentId, resolveSelectedAgentId } from "./harness/run/rou
23
23
  import { resolveCheckpointer, resolveEmbeddingModel, resolveStore, resolveStoreFromConfig, resolveVectorStore, } from "./harness/run/resources.js";
24
24
  import { createToolMcpServerFromTools, serveToolsOverStdioFromHarness } from "../mcp.js";
25
25
  import { getBindingAdapterKind, getBindingPrimaryTools, getBindingStoreConfig } from "./support/compiled-binding.js";
26
- import { isRuntimeEntryBinding } from "./support/runtime-entry.js";
27
26
  import { describeWorkspaceInventory, listAgentSkills as listWorkspaceAgentSkills, } from "./harness/system/inventory.js";
28
27
  import { createDefaultHealthSnapshot, isInventoryEnabled, isThreadMemorySyncEnabled, } from "./harness/runtime-defaults.js";
29
28
  import { initializeHarnessRuntime, isStaleRunningRun as isHarnessStaleRunningRun, } from "./harness/run/startup-runtime.js";
@@ -32,7 +31,6 @@ import { deleteThreadRecord, getPublicApproval, getThreadRecord, listPublicAppro
32
31
  export class AgentHarnessRuntime {
33
32
  workspace;
34
33
  runtimeAdapterOptions;
35
- static DEFAULT_HOST_AGENT_ID = "orchestra";
36
34
  static BACKGROUND_EVENT_TYPES = new Set([
37
35
  "run.created",
38
36
  "run.queued",
@@ -48,6 +46,9 @@ export class AgentHarnessRuntime {
48
46
  stores = new Map();
49
47
  embeddingModels = new Map();
50
48
  vectorStores = new Map();
49
+ hostBindings;
50
+ defaultHostBinding;
51
+ defaultRunRootValue;
51
52
  defaultStore;
52
53
  runtimeMemoryStore;
53
54
  routingRules;
@@ -64,15 +65,11 @@ export class AgentHarnessRuntime {
64
65
  pendingRunInsertionOrder = 0;
65
66
  pendingRunSlots = [];
66
67
  runtimeEventSequence = 0;
67
- listHostBindings() {
68
- return inferRoutingBindings(this.workspace).hostBindings;
69
- }
70
68
  defaultRunRoot() {
71
- return (this.listHostBindings()[0]?.harnessRuntime.runRoot ??
72
- `${this.workspace.workspaceRoot}/run-data`);
69
+ return this.defaultRunRootValue;
73
70
  }
74
71
  getDefaultHostAgentId() {
75
- return getDefaultHostAgentId(this.workspace, this.routingDefaultAgentId ?? AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID);
72
+ return getDefaultHostAgentId(this.workspace, this.routingDefaultAgentId);
76
73
  }
77
74
  async resolveSelectedAgentId(input, requestedAgentId, threadId) {
78
75
  return resolveSelectedAgentId({
@@ -80,20 +77,23 @@ export class AgentHarnessRuntime {
80
77
  input,
81
78
  requestedAgentId,
82
79
  threadId,
83
- preferredHostAgentId: this.routingDefaultAgentId ?? AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
80
+ preferredHostAgentId: this.routingDefaultAgentId,
84
81
  getThreadSummary: (currentThreadId) => this.getSession(currentThreadId),
85
82
  });
86
83
  }
87
84
  constructor(workspace, runtimeAdapterOptions = {}) {
88
85
  this.workspace = workspace;
89
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`;
90
90
  const runRoot = this.defaultRunRoot();
91
91
  this.persistence = new SqlitePersistence(runRoot);
92
- const defaultStoreConfig = this.listHostBindings()[0]?.harnessRuntime.store;
92
+ const defaultStoreConfig = this.defaultHostBinding?.harnessRuntime.store;
93
93
  this.defaultStore = resolveStoreFromConfig(this.stores, defaultStoreConfig, runRoot) ?? new FileBackedStore(`${runRoot}/store.json`);
94
- const runtimeMemoryStoreConfig = typeof this.listHostBindings()[0]?.harnessRuntime.runtimeMemory?.store === "object" &&
95
- this.listHostBindings()[0]?.harnessRuntime.runtimeMemory?.store
96
- ? 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
97
97
  : undefined;
98
98
  this.runtimeMemoryStore = resolveStoreFromConfig(this.stores, runtimeMemoryStoreConfig, runRoot) ?? this.defaultStore;
99
99
  this.resolvedRuntimeAdapterOptions = {
@@ -264,14 +264,14 @@ export class AgentHarnessRuntime {
264
264
  const configuredRule = this.routingRules.find((rule) => matchRoutingRule(rawInput, rule, options));
265
265
  if (configuredRule) {
266
266
  const configuredBinding = this.workspace.bindings.get(configuredRule.agentId);
267
- if (configuredBinding && isRuntimeEntryBinding(configuredBinding)) {
267
+ if (configuredBinding) {
268
268
  return configuredBinding.agent.id;
269
269
  }
270
270
  }
271
271
  const defaultBinding = this.routingDefaultAgentId
272
272
  ? this.workspace.bindings.get(this.routingDefaultAgentId)
273
273
  : undefined;
274
- if (defaultBinding && isRuntimeEntryBinding(defaultBinding)) {
274
+ if (defaultBinding) {
275
275
  return defaultBinding.agent.id;
276
276
  }
277
277
  return this.getDefaultHostAgentId();
@@ -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
  }
@@ -11,7 +11,5 @@ export declare function createHarnessEvent(threadId: string, runId: string, sequ
11
11
  export declare function createPendingApproval(threadId: string, runId: string, checkpointRef: string, input: string, interruptContent?: string): InternalApprovalRecord;
12
12
  export declare function inferRoutingBindings(workspace: WorkspaceBundle): {
13
13
  primaryBinding: import("../../contracts/workspace.js").CompiledAgentBinding;
14
- secondaryBinding: import("../../contracts/workspace.js").CompiledAgentBinding | undefined;
15
- researchBinding: import("../../contracts/workspace.js").CompiledAgentBinding | undefined;
16
14
  hostBindings: import("../../contracts/workspace.js").CompiledAgentBinding[];
17
15
  };
@@ -1,6 +1,5 @@
1
1
  import { createPersistentId } from "../../utils/id.js";
2
2
  import { isDelegationCapableBinding } from "../../workspace/support/agent-capabilities.js";
3
- import { isRuntimeEntryBinding } from "./runtime-entry.js";
4
3
  export function renderRuntimeFailure(error) {
5
4
  const message = error instanceof Error ? error.message : String(error);
6
5
  return `runtime_error=${message}`.trim();
@@ -87,38 +86,9 @@ export function createPendingApproval(threadId, runId, checkpointRef, input, int
87
86
  };
88
87
  }
89
88
  export function inferRoutingBindings(workspace) {
90
- const runtimeEntryBindings = Array.from(workspace.bindings.values()).filter((binding) => isRuntimeEntryBinding(binding));
91
- const orchestrationHosts = runtimeEntryBindings.filter((binding) => binding.agent.executionMode === "deepagent" || Boolean(binding.deepAgentParams));
92
- const routingHosts = orchestrationHosts.length > 0 ? orchestrationHosts : runtimeEntryBindings;
93
- const deepAgentHosts = routingHosts.filter((binding) => binding.agent.executionMode === "deepagent" || Boolean(binding.deepAgentParams));
94
- const nonDeepAgentHosts = routingHosts.filter((binding) => !deepAgentHosts.includes(binding));
95
- const researchBinding = routingHosts.find((binding) => binding.agent.id === "research-lite" || binding.agent.id === "research");
96
- const directBinding = routingHosts.find((binding) => binding.agent.id === "direct");
97
- const delegationHosts = routingHosts.filter((binding) => isDelegationCapableBinding(binding));
98
- const deepAgentDelegationHosts = deepAgentHosts.filter((binding) => isDelegationCapableBinding(binding));
99
- const nonDeepAgentDelegationHosts = nonDeepAgentHosts.filter((binding) => isDelegationCapableBinding(binding));
100
- const lightweightHosts = routingHosts.filter((binding) => !isDelegationCapableBinding(binding));
101
- const defaultOrchestratingHost = routingHosts.find((binding) => binding.agent.id === "orchestra") ??
102
- deepAgentDelegationHosts.find((binding) => (binding.deepAgentParams?.subagents.length ?? 0) > 0) ??
103
- deepAgentDelegationHosts[0] ??
104
- deepAgentHosts[0] ??
105
- nonDeepAgentDelegationHosts.find((binding) => (binding.deepAgentParams?.subagents.length ?? 0) > 0) ??
106
- nonDeepAgentDelegationHosts[0] ??
107
- nonDeepAgentHosts[0];
108
- const delegationPreferredSecondary = deepAgentDelegationHosts.find((binding) => (binding.deepAgentParams?.subagents.length ?? 0) > 0) ??
109
- deepAgentDelegationHosts[0] ??
110
- nonDeepAgentDelegationHosts.find((binding) => (binding.deepAgentParams?.subagents.length ?? 0) > 0) ??
111
- nonDeepAgentDelegationHosts[0] ??
112
- delegationHosts[0];
113
- const genericLightweightHost = lightweightHosts.find((binding) => binding.agent.id !== researchBinding?.agent.id);
114
- const primaryBinding = defaultOrchestratingHost ?? directBinding ?? genericLightweightHost ?? routingHosts[0] ?? runtimeEntryBindings[0];
115
- const secondaryBinding = genericLightweightHost && genericLightweightHost.agent.id !== primaryBinding?.agent.id
116
- ? genericLightweightHost
117
- : directBinding && directBinding.agent.id !== primaryBinding?.agent.id
118
- ? directBinding
119
- : delegationPreferredSecondary && delegationPreferredSecondary.agent.id !== primaryBinding?.agent.id
120
- ? delegationPreferredSecondary
121
- : routingHosts.find((binding) => binding.agent.id !== primaryBinding?.agent.id) ??
122
- (orchestrationHosts.length > 0 ? undefined : runtimeEntryBindings.find((binding) => binding.agent.id !== primaryBinding?.agent.id));
123
- return { primaryBinding, secondaryBinding, researchBinding, hostBindings: runtimeEntryBindings };
89
+ const hostBindings = Array.from(workspace.bindings.values());
90
+ const orchestrationHosts = hostBindings.filter((binding) => binding.agent.executionMode === "deepagent" || Boolean(binding.deepAgentParams));
91
+ const routingHosts = orchestrationHosts.length > 0 ? orchestrationHosts : hostBindings;
92
+ const primaryBinding = routingHosts.find((binding) => isDelegationCapableBinding(binding)) ?? routingHosts[0] ?? hostBindings[0];
93
+ return { primaryBinding, hostBindings };
124
94
  }
@@ -72,9 +72,6 @@ function resolveAgentRuntimeName(agent) {
72
72
  if (normalizedSourcePath.includes("/packages/framework/")) {
73
73
  return `core.${baseName}`;
74
74
  }
75
- if (["direct", "orchestra", "research-lite"].includes(baseName)) {
76
- return `core.${baseName}`;
77
- }
78
75
  return baseName;
79
76
  }
80
77
  export function requireTools(tools, refs, ownerId) {
@@ -93,21 +90,20 @@ export function requireTools(tools, refs, ownerId) {
93
90
  }
94
91
  function buildSubagent(agent, workspaceRoot, models, tools, parentSkills, parentModel, parentMemory) {
95
92
  const ownMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
93
+ const execution = compileExecutionCore(agent, models, tools);
96
94
  return {
97
95
  name: resolveAgentRuntimeName(agent),
98
96
  description: agent.description,
99
- systemPrompt: [resolvePromptValue(agent.deepAgentConfig?.systemPrompt), WORKSPACE_BOUNDARY_GUIDANCE].filter(Boolean).join("\n\n"),
100
- tools: requireTools(tools, agent.toolRefs, agent.id),
101
- model: agent.modelRef ? requireModel(models, agent.modelRef, agent.id) : parentModel,
102
- 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),
103
101
  skills: compileAgentSkills(workspaceRoot, agent, parentSkills),
104
102
  memory: ownMemory.length > 0 ? ownMemory : parentMemory,
105
- responseFormat: agent.deepAgentConfig?.responseFormat,
106
- contextSchema: agent.deepAgentConfig?.contextSchema,
107
- middleware: compileMiddlewareConfigs(agent.deepAgentConfig?.middleware, models, agent.id),
108
- passthrough: typeof agent.deepAgentConfig?.passthrough === "object" && agent.deepAgentConfig.passthrough
109
- ? { ...agent.deepAgentConfig.passthrough }
110
- : undefined,
103
+ responseFormat: execution.responseFormat,
104
+ contextSchema: execution.contextSchema,
105
+ middleware: execution.middleware,
106
+ passthrough: execution.passthrough,
111
107
  };
112
108
  }
113
109
  function resolveDirectPrompt(agent) {
@@ -127,6 +123,45 @@ function resolveInterruptOn(agent) {
127
123
  return (agent.deepAgentConfig?.interruptOn ??
128
124
  agent.langchainAgentConfig?.interruptOn);
129
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
+ }
130
165
  function resolveBackendConfig(agent, refs) {
131
166
  if (agent.executionMode !== "deepagent") {
132
167
  return undefined;
@@ -289,7 +324,11 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
289
324
  const resilience = getResilienceConfig(refs);
290
325
  const compiledAgentSkills = compileAgentSkills(workspaceRoot, agent);
291
326
  const compiledAgentMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
292
- 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;
293
332
  const backend = resolveBackendConfig(agent, refs);
294
333
  const store = resolveStoreConfig(agent, refs);
295
334
  const checkpointer = resolveCheckpointerConfig(agent, refs);
@@ -326,28 +365,19 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
326
365
  },
327
366
  };
328
367
  if (agent.executionMode !== "deepagent") {
329
- const basePassthrough = typeof agent.langchainAgentConfig?.passthrough === "object" && agent.langchainAgentConfig.passthrough
330
- ? { ...agent.langchainAgentConfig.passthrough }
331
- : undefined;
332
368
  const langchainAgentParams = {
333
- model: compiledAgentModel,
334
- tools: requireTools(tools, agent.toolRefs, agent.id),
335
- systemPrompt: resolveSystemPrompt(agent),
369
+ model: execution.model,
370
+ tools: execution.tools,
371
+ systemPrompt: execution.systemPrompt,
336
372
  stateSchema: agent.langchainAgentConfig?.stateSchema,
337
- responseFormat: agent.langchainAgentConfig?.responseFormat,
338
- contextSchema: agent.langchainAgentConfig?.contextSchema,
373
+ responseFormat: execution.responseFormat,
374
+ contextSchema: execution.contextSchema,
339
375
  filesystem: typeof agent.langchainAgentConfig?.filesystem === "object" && agent.langchainAgentConfig.filesystem
340
376
  ? { ...agent.langchainAgentConfig.filesystem }
341
377
  : undefined,
342
- middleware: compileMiddlewareConfigs(agent.langchainAgentConfig?.middleware, models, agent.id),
343
- passthrough: basePassthrough,
344
- subagents: agent.subagentRefs.map((ref) => {
345
- const subagent = agents.get(resolveRefId(ref));
346
- if (!subagent) {
347
- throw new Error(`Missing subagent ${ref} for agent ${agent.id}`);
348
- }
349
- return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory);
350
- }),
378
+ middleware: execution.middleware,
379
+ passthrough: execution.passthrough,
380
+ subagents: compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory),
351
381
  memory: compiledAgentMemory,
352
382
  skills: compiledAgentSkills,
353
383
  generalPurposeAgent: typeof agent.langchainAgentConfig?.generalPurposeAgent === "boolean" ? agent.langchainAgentConfig.generalPurposeAgent : undefined,
@@ -373,23 +403,15 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
373
403
  };
374
404
  }
375
405
  const deepAgentParams = {
376
- model: compiledAgentModel,
377
- tools: requireTools(tools, agent.toolRefs, agent.id),
378
- systemPrompt: resolveSystemPrompt(agent),
379
- responseFormat: agent.deepAgentConfig?.responseFormat,
380
- contextSchema: agent.deepAgentConfig?.contextSchema,
381
- middleware: compileMiddlewareConfigs(agent.deepAgentConfig?.middleware, models, agent.id),
382
- passthrough: typeof agent.deepAgentConfig?.passthrough === "object" && agent.deepAgentConfig.passthrough
383
- ? { ...agent.deepAgentConfig.passthrough }
384
- : 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,
385
413
  description: agent.description,
386
- subagents: agent.subagentRefs.map((ref) => {
387
- const subagent = agents.get(resolveRefId(ref));
388
- if (!subagent) {
389
- throw new Error(`Missing subagent ${ref} for agent ${agent.id}`);
390
- }
391
- return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory);
392
- }),
414
+ subagents: compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory),
393
415
  interruptOn: resolveInterruptOn(agent),
394
416
  ...(backend ? { backend: backend.config } : {}),
395
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.105",
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",
@@ -1,2 +0,0 @@
1
- import type { CompiledAgentBinding } from "../../contracts/types.js";
2
- export declare function isRuntimeEntryBinding(binding: CompiledAgentBinding): boolean;
@@ -1,3 +0,0 @@
1
- export function isRuntimeEntryBinding(binding) {
2
- return Boolean(binding);
3
- }