@botbotgo/agent-harness 0.0.116 → 0.0.118

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.
@@ -170,6 +170,7 @@ export type DeepAgentParams = {
170
170
  responseFormat?: unknown;
171
171
  contextSchema?: unknown;
172
172
  middleware?: Array<Record<string, unknown>>;
173
+ passthrough?: Record<string, unknown>;
173
174
  description: string;
174
175
  subagents: CompiledSubAgent[];
175
176
  interruptOn?: Record<string, boolean | object>;
@@ -179,12 +180,20 @@ export type DeepAgentParams = {
179
180
  memory: string[];
180
181
  skills: string[];
181
182
  };
183
+ export type CompiledExecutionBinding = {
184
+ kind: "langchain-v1";
185
+ params: LangChainAgentParams;
186
+ } | {
187
+ kind: "deepagent";
188
+ params: DeepAgentParams;
189
+ };
182
190
  export type CompiledAgentBinding = {
183
191
  agent: ParsedAgentObject;
184
192
  adapter?: {
185
193
  kind: string;
186
194
  config?: Record<string, unknown>;
187
195
  };
196
+ execution?: CompiledExecutionBinding;
188
197
  langchainAgentParams?: LangChainAgentParams;
189
198
  deepAgentParams?: DeepAgentParams;
190
199
  harnessRuntime: {
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.115";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.117";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.115";
1
+ export const AGENT_HARNESS_VERSION = "0.0.117";
@@ -5,6 +5,7 @@ import { stat } from "node:fs/promises";
5
5
  import { readFile } from "node:fs/promises";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import { CompositeBackend, LocalShellBackend, StateBackend, StoreBackend } from "deepagents";
8
+ import { getBindingBackendConfig } from "../runtime/support/compiled-binding.js";
8
9
  import { createRuntimeEnv } from "../runtime/support/runtime-env.js";
9
10
  import { isSupportedToolModulePath, loadToolModuleDefinition } from "../tool-modules.js";
10
11
  import { createMcpToolResolver, } from "./mcp-tool-support.js";
@@ -175,7 +176,7 @@ function createInlineBackendInstance(workspaceRoot, kind, config, runtimeLike) {
175
176
  }
176
177
  function createInlineBackendResolver(workspace) {
177
178
  return (binding) => {
178
- const backendConfig = binding.deepAgentParams?.backend;
179
+ const backendConfig = getBindingBackendConfig(binding);
179
180
  if (!backendConfig || typeof backendConfig !== "object") {
180
181
  return undefined;
181
182
  }
@@ -1,5 +1,5 @@
1
1
  import { buildExecutableToolMap } from "../tool-resolution.js";
2
- import { getBindingLangChainParams, getBindingPrimaryModel, getBindingPrimaryTools, isLangChainBinding } from "../../support/compiled-binding.js";
2
+ import { getBindingPrimaryModel, getBindingPrimaryTools, isLangChainBinding } from "../../support/compiled-binding.js";
3
3
  export function buildBindingToolCatalog(input) {
4
4
  const primaryTools = getBindingPrimaryTools(input.binding);
5
5
  const toolNameMapping = input.getToolNameMapping(input.binding);
@@ -31,11 +31,10 @@ export async function resolveLangChainStreamContext(input) {
31
31
  const forceInvokeFallback = isLangChainBinding(input.binding) &&
32
32
  primaryTools.length > 0 &&
33
33
  primaryModel?.provider === "openai-compatible";
34
- const langchainParams = isLangChainBinding(input.binding) ? getBindingLangChainParams(input.binding) : undefined;
35
- const resolvedLangChainModel = langchainParams
36
- ? (await input.resolveModel(langchainParams.model))
34
+ const resolvedLangChainModel = primaryModel
35
+ ? (await input.resolveModel(primaryModel))
37
36
  : undefined;
38
- const resolvedLangChainTools = langchainParams ? input.resolveTools(langchainParams.tools, input.binding) : [];
37
+ const resolvedLangChainTools = primaryTools.length > 0 ? input.resolveTools(primaryTools, input.binding) : [];
39
38
  const canUseDirectModelStream = !!resolvedLangChainModel &&
40
39
  (resolvedLangChainTools.length === 0 || typeof resolvedLangChainModel.bindTools !== "function");
41
40
  const langChainStreamModel = resolvedLangChainModel && canUseDirectModelStream
@@ -6,7 +6,7 @@ import { compileInterruptOn } from "./tool/interrupt-policy.js";
6
6
  import { extractToolFallbackContext, extractVisibleOutput } from "../parsing/output-parsing.js";
7
7
  import { isRecord } from "../../utils/object.js";
8
8
  import { resolveDeclaredMiddleware } from "./tool/declared-middleware.js";
9
- import { bindingHasLangChainSubagentSupport, bindingHasMiddlewareKind, getBindingDeepAgentParams, getBindingInterruptCompatibilityRules, getBindingLangChainParams, getBindingMiddlewareConfigs, getBindingPrimaryModel, isDeepAgentBinding, isLangChainBinding, } from "../support/compiled-binding.js";
9
+ import { bindingHasLangChainSubagentSupport, bindingHasMiddlewareKind, getBindingExecutionKind, getBindingGeneralPurposeAgent, getBindingInterruptCompatibilityRules, getBindingMiddlewareConfigs, getBindingMemorySources, getBindingPrimaryModel, getBindingPrimaryTools, getBindingSkills, getBindingSubagents, getBindingTaskDescription, isDeepAgentBinding, isLangChainBinding, } from "../support/compiled-binding.js";
10
10
  import { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths } from "./compat/deepagent-compat.js";
11
11
  export function buildBuiltinTaskSubagentMiddleware(input) {
12
12
  const { selectedSubagent, builtinBackend, summarizationModel } = input;
@@ -105,24 +105,26 @@ export async function resolveSubagents(input) {
105
105
  }));
106
106
  }
107
107
  export async function invokeBuiltinTaskTool(input) {
108
- if (!isDeepAgentBinding(input.binding)) {
108
+ if (!isDeepAgentBinding(input.binding) || getBindingExecutionKind(input.binding) !== "deepagent") {
109
109
  throw new Error("The built-in task tool is only available for deepagent bindings.");
110
110
  }
111
- const params = getBindingDeepAgentParams(input.binding);
112
- if (!params) {
111
+ const primaryModel = getBindingPrimaryModel(input.binding);
112
+ const primaryTools = getBindingPrimaryTools(input.binding);
113
+ const compiledSubagents = getBindingSubagents(input.binding);
114
+ if (!primaryModel) {
113
115
  throw new Error(`Agent ${input.binding.agent.id} has no deepagent params`);
114
116
  }
115
117
  const typedInput = isRecord(input.toolInput) ? input.toolInput : {};
116
118
  const description = typeof typedInput.description === "string" ? typedInput.description : "";
117
119
  const subagentType = typeof typedInput.subagent_type === "string" ? typedInput.subagent_type : "";
118
120
  const builtinBackend = input.resolveBuiltinMiddlewareBackend(input.binding, input.options);
119
- const resolvedSubagents = await input.resolveSubagents(params.subagents, input.binding);
121
+ const resolvedSubagents = await input.resolveSubagents(compiledSubagents, input.binding);
120
122
  const selectedSubagent = resolvedSubagents.find((subagent) => subagent.name === subagentType);
121
123
  if (!selectedSubagent) {
122
124
  const allowed = resolvedSubagents.map((subagent) => subagent.name);
123
125
  throw new Error(`Error: invoked agent of type ${subagentType}, the only allowed types are ${allowed.map((name) => `\`${name}\``).join(", ")}`);
124
126
  }
125
- const resolvedHostModel = selectedSubagent.model ? undefined : await input.resolveModel(params.model);
127
+ const resolvedHostModel = selectedSubagent.model ? undefined : await input.resolveModel(primaryModel);
126
128
  const summarizationModel = selectedSubagent.model ?? resolvedHostModel;
127
129
  const middleware = buildBuiltinTaskSubagentMiddleware({
128
130
  selectedSubagent,
@@ -131,7 +133,7 @@ export async function invokeBuiltinTaskTool(input) {
131
133
  });
132
134
  const runnable = createAgent({
133
135
  model: (selectedSubagent.model ?? resolvedHostModel),
134
- tools: (selectedSubagent.tools ?? input.resolveTools(params.tools, input.binding)),
136
+ tools: (selectedSubagent.tools ?? input.resolveTools(primaryTools, input.binding)),
135
137
  systemPrompt: selectedSubagent.systemPrompt ?? DEFAULT_SUBAGENT_PROMPT,
136
138
  middleware: middleware,
137
139
  responseFormat: selectedSubagent.responseFormat,
@@ -163,29 +165,30 @@ export async function resolveAutomaticSummarizationMiddleware(input) {
163
165
  return resolveDeclaredMiddleware([{ kind: "summarization", model: primaryModel }], input.createDeclaredMiddlewareResolverOptions(input.binding));
164
166
  }
165
167
  export async function resolveLangChainAutomaticMiddleware(input) {
166
- const params = getBindingLangChainParams(input.binding);
167
- if (!params) {
168
+ const primaryModel = getBindingPrimaryModel(input.binding);
169
+ const primaryTools = getBindingPrimaryTools(input.binding);
170
+ if (!isLangChainBinding(input.binding) || !primaryModel) {
168
171
  return [];
169
172
  }
170
173
  const delegationCompatibility = resolveLangChainDelegationCompatibility({
171
- model: params.model,
172
- subagents: params.subagents,
173
- generalPurposeAgent: params.generalPurposeAgent,
174
- taskDescription: params.taskDescription,
174
+ model: primaryModel,
175
+ subagents: getBindingSubagents(input.binding),
176
+ generalPurposeAgent: getBindingGeneralPurposeAgent(input.binding),
177
+ taskDescription: getBindingTaskDescription(input.binding),
175
178
  });
176
179
  const automaticMiddleware = [];
177
180
  automaticMiddleware.push(createPatchToolCallsMiddleware());
178
181
  automaticMiddleware.push(...(await input.resolveAutomaticSummarizationMiddleware(input.binding)));
179
182
  automaticMiddleware.push(...buildLangChainContextMiddleware({
180
183
  binding: input.binding,
181
- skills: params.skills,
182
- memory: params.memory,
184
+ skills: getBindingSkills(input.binding),
185
+ memory: getBindingMemorySources(input.binding),
183
186
  resolveFilesystemBackend: input.resolveFilesystemBackend,
184
187
  }));
185
188
  if (bindingHasLangChainSubagentSupport(input.binding)) {
186
189
  automaticMiddleware.push(createSubAgentMiddleware({
187
- defaultModel: (await input.resolveModel(params.model)),
188
- defaultTools: input.resolveTools(params.tools, input.binding),
190
+ defaultModel: (await input.resolveModel(primaryModel)),
191
+ defaultTools: input.resolveTools(primaryTools, input.binding),
189
192
  defaultInterruptOn: getBindingInterruptCompatibilityRules(input.binding),
190
193
  subagents: (await input.resolveSubagents(delegationCompatibility.subagents ?? [], input.binding)),
191
194
  generalPurposeAgent: delegationCompatibility.generalPurposeAgent,
@@ -1,3 +1,4 @@
1
+ import { getBindingSkills } from "../../support/compiled-binding.js";
1
2
  import { extractMessageText, normalizeMessageContent } from "../../../utils/message-content.js";
2
3
  import { readSkillMetadata } from "../../support/skill-metadata.js";
3
4
  export function buildAgentMessages(history, input) {
@@ -14,7 +15,7 @@ export function buildSlashCommandSkillInstruction(binding, input) {
14
15
  }
15
16
  const invokedName = match[1].toLowerCase();
16
17
  const argumentText = match[2]?.trim() ?? "";
17
- const skillPaths = binding.deepAgentParams?.skills ?? binding.langchainAgentParams?.skills ?? [];
18
+ const skillPaths = getBindingSkills(binding);
18
19
  const matchedSkillPath = skillPaths.find((skillPath) => readSkillMetadata(skillPath).name.toLowerCase() === invokedName);
19
20
  if (!matchedSkillPath) {
20
21
  return undefined;
@@ -2,7 +2,7 @@ import { setTimeout as sleep } from "node:timers/promises";
2
2
  import { extractVisibleOutput, isToolCallParseFailure, STRICT_TOOL_JSON_INSTRUCTION } from "../parsing/output-parsing.js";
3
3
  import { readStreamDelta } from "../parsing/stream-event-parsing.js";
4
4
  import { computeRemainingTimeoutMs, isRetryableProviderError, resolveProviderRetryPolicy } from "./resilience.js";
5
- import { getBindingDeepAgentParams, getBindingLangChainParams, isDeepAgentBinding, isLangChainBinding, } from "../support/compiled-binding.js";
5
+ import { isDeepAgentBinding, isLangChainBinding, withUpdatedBindingExecutionParams, } from "../support/compiled-binding.js";
6
6
  export class RuntimeOperationTimeoutError extends Error {
7
7
  operation;
8
8
  timeoutMs;
@@ -134,24 +134,16 @@ export function createModelFallbackRunnable(model) {
134
134
  }
135
135
  export function applyStrictToolJsonInstruction(binding) {
136
136
  if (isLangChainBinding(binding)) {
137
- const params = getBindingLangChainParams(binding);
138
- return {
139
- ...binding,
140
- langchainAgentParams: {
141
- ...params,
142
- systemPrompt: [params.systemPrompt, STRICT_TOOL_JSON_INSTRUCTION].filter(Boolean).join("\n\n"),
143
- },
144
- };
137
+ return withUpdatedBindingExecutionParams(binding, (params) => ({
138
+ ...params,
139
+ systemPrompt: [params.systemPrompt, STRICT_TOOL_JSON_INSTRUCTION].filter(Boolean).join("\n\n"),
140
+ }));
145
141
  }
146
142
  if (isDeepAgentBinding(binding)) {
147
- const params = getBindingDeepAgentParams(binding);
148
- return {
149
- ...binding,
150
- deepAgentParams: {
151
- ...params,
152
- systemPrompt: [params.systemPrompt, STRICT_TOOL_JSON_INSTRUCTION].filter(Boolean).join("\n\n"),
153
- },
154
- };
143
+ return withUpdatedBindingExecutionParams(binding, (params) => ({
144
+ ...params,
145
+ systemPrompt: [params.systemPrompt, STRICT_TOOL_JSON_INSTRUCTION].filter(Boolean).join("\n\n"),
146
+ }));
155
147
  }
156
148
  return binding;
157
149
  }
@@ -18,7 +18,7 @@ export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillS
18
18
  export { buildAuthOmittingFetch, normalizeOpenAICompatibleInit } from "./adapter/compat/openai-compatible.js";
19
19
  export { buildToolNameMapping, createModelFacingToolNameCandidates, createModelFacingToolNameLookupCandidates, resolveModelFacingToolName, sanitizeToolNameForModel, } from "./adapter/tool/tool-name-mapping.js";
20
20
  export { computeRemainingTimeoutMs, isRetryableProviderError, resolveBindingTimeout, resolveProviderRetryPolicy, resolveStreamIdleTimeout, resolveTimeoutMs, } from "./adapter/resilience.js";
21
- import { getBindingAdapterKind, getBindingDeepAgentParams, getBindingInterruptCompatibilityRules, getBindingLangChainParams, getBindingToolCount, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
21
+ import { getBindingAdapterKind, getBindingExecutionKind, getBindingExecutionParams, getBindingFilesystemConfig, getBindingInterruptCompatibilityRules, getBindingPrimaryModel, getBindingSkills, getBindingSubagents, getBindingToolCount, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
22
22
  const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
23
23
  const UPSTREAM_BUILTIN_MIDDLEWARE_TOOL_NAMES = Object.freeze([
24
24
  "write_todos",
@@ -37,21 +37,43 @@ export function resolveRunnableCheckpointer(options, binding) {
37
37
  export function resolveRunnableInterruptOn(binding) {
38
38
  return compileInterruptOn(getBindingPrimaryTools(binding), getBindingInterruptCompatibilityRules(binding));
39
39
  }
40
+ function buildUpstreamCreateBaseParams(binding, compileOnlyFields) {
41
+ const executionParams = getBindingExecutionParams(binding);
42
+ if (!executionParams) {
43
+ throw new Error(`Agent ${binding.agent.id} has no compiled execution params`);
44
+ }
45
+ const source = executionParams;
46
+ const passthrough = typeof source.passthrough === "object" && source.passthrough
47
+ ? source.passthrough
48
+ : undefined;
49
+ const stripped = Object.fromEntries(Object.entries(source).filter(([key]) => key !== "passthrough" && !compileOnlyFields.includes(key)));
50
+ return {
51
+ ...(passthrough ?? {}),
52
+ ...stripped,
53
+ };
54
+ }
40
55
  export function buildLangChainCreateParams(input) {
41
- const langchainParams = getBindingLangChainParams(input.binding);
42
- if (!langchainParams) {
56
+ const executionKind = getBindingExecutionKind(input.binding);
57
+ const executionParams = getBindingExecutionParams(input.binding);
58
+ if (executionKind !== "langchain-v1" || !executionParams) {
43
59
  throw new Error(`Agent ${input.binding.agent.id} has no langchain params`);
44
60
  }
61
+ const upstreamParams = buildUpstreamCreateBaseParams(input.binding, [
62
+ "model",
63
+ "tools",
64
+ "middleware",
65
+ "interruptOn",
66
+ "filesystem",
67
+ "subagents",
68
+ "memory",
69
+ "skills",
70
+ "generalPurposeAgent",
71
+ "taskDescription",
72
+ ]);
45
73
  return {
46
- ...(input.passthroughOverride ?? langchainParams.passthrough ?? {}),
47
- systemPrompt: input.systemPromptOverride ?? langchainParams.systemPrompt,
48
- stateSchema: langchainParams.stateSchema,
49
- responseFormat: langchainParams.responseFormat,
50
- contextSchema: langchainParams.contextSchema,
51
- includeAgentName: langchainParams.includeAgentName,
52
- version: langchainParams.version,
53
- name: langchainParams.name,
54
- description: langchainParams.description,
74
+ ...upstreamParams,
75
+ ...(input.passthroughOverride ?? {}),
76
+ systemPrompt: input.systemPromptOverride ?? executionParams.systemPrompt,
55
77
  model: input.resolvedModel,
56
78
  tools: input.resolvedTools,
57
79
  middleware: input.resolvedMiddleware,
@@ -60,16 +82,26 @@ export function buildLangChainCreateParams(input) {
60
82
  };
61
83
  }
62
84
  export function buildDeepAgentCreateParams(input) {
63
- const deepAgentParams = getBindingDeepAgentParams(input.binding);
64
- if (!deepAgentParams) {
85
+ const executionKind = getBindingExecutionKind(input.binding);
86
+ if (executionKind !== "deepagent" || !getBindingExecutionParams(input.binding)) {
65
87
  throw new Error(`Agent ${input.binding.agent.id} has no runnable params`);
66
88
  }
89
+ const upstreamParams = buildUpstreamCreateBaseParams(input.binding, [
90
+ "model",
91
+ "tools",
92
+ "middleware",
93
+ "subagents",
94
+ "interruptOn",
95
+ "skills",
96
+ "backend",
97
+ "store",
98
+ // These do not belong to DeepAgents top-level create params even if
99
+ // compatibility fixtures stuff them into compiled deepagent params.
100
+ "generalPurposeAgent",
101
+ "taskDescription",
102
+ ]);
67
103
  return {
68
- systemPrompt: deepAgentParams.systemPrompt,
69
- responseFormat: deepAgentParams.responseFormat,
70
- contextSchema: deepAgentParams.contextSchema,
71
- name: deepAgentParams.name,
72
- memory: deepAgentParams.memory,
104
+ ...upstreamParams,
73
105
  skills: input.resolvedSkills,
74
106
  model: input.resolvedModel,
75
107
  tools: input.resolvedTools,
@@ -150,7 +182,7 @@ export class AgentRuntimeAdapter {
150
182
  return resolved;
151
183
  }
152
184
  resolveFilesystemBackend(binding) {
153
- const filesystemConfig = getBindingLangChainParams(binding)?.filesystem;
185
+ const filesystemConfig = getBindingFilesystemConfig(binding);
154
186
  const configuredRootDir = typeof filesystemConfig?.rootDir === "string" && filesystemConfig.rootDir.trim().length > 0
155
187
  ? filesystemConfig.rootDir
156
188
  : undefined;
@@ -262,19 +294,21 @@ export class AgentRuntimeAdapter {
262
294
  });
263
295
  }
264
296
  async createLangChainRunnable(binding, options = {}) {
265
- const langchainParams = getBindingLangChainParams(binding);
266
- if (!langchainParams) {
297
+ const executionKind = getBindingExecutionKind(binding);
298
+ const primaryModel = getBindingPrimaryModel(binding);
299
+ const primaryTools = getBindingPrimaryTools(binding);
300
+ if (executionKind !== "langchain-v1" || !primaryModel) {
267
301
  throw new Error(`Agent ${binding.agent.id} has no langchain params`);
268
302
  }
269
303
  const interruptOn = resolveRunnableInterruptOn(binding);
270
- const resolvedModel = await this.resolveModel(langchainParams.model);
271
- const resolvedTools = this.resolveTools(langchainParams.tools, binding);
304
+ const resolvedModel = await this.resolveModel(primaryModel);
305
+ const resolvedTools = this.resolveTools(primaryTools, binding);
272
306
  const resolvedMiddleware = await this.resolveMiddleware(binding, interruptOn);
273
307
  const resolvedCheckpointer = resolveRunnableCheckpointer(this.options, binding);
274
308
  const resolvedStore = this.options.storeResolver?.(binding);
275
309
  const model = resolvedModel;
276
310
  if (resolvedTools.length > 0 && typeof model.bindTools !== "function") {
277
- throw new Error(`Agent ${binding.agent.id} configures ${resolvedTools.length} tool(s), but resolved model ${langchainParams.model.id} does not support tool binding.`);
311
+ throw new Error(`Agent ${binding.agent.id} configures ${resolvedTools.length} tool(s), but resolved model ${primaryModel.id} does not support tool binding.`);
278
312
  }
279
313
  return createAgent(buildLangChainCreateParams({
280
314
  binding,
@@ -297,14 +331,16 @@ export class AgentRuntimeAdapter {
297
331
  return this.createDeepAgentRunnable(binding);
298
332
  }
299
333
  async createDeepAgentRunnable(binding) {
300
- const deepAgentParams = getBindingDeepAgentParams(binding);
301
- if (!deepAgentParams) {
334
+ const executionKind = getBindingExecutionKind(binding);
335
+ const primaryModel = getBindingPrimaryModel(binding);
336
+ const primaryTools = getBindingPrimaryTools(binding);
337
+ if (executionKind !== "deepagent" || !primaryModel) {
302
338
  throw new Error(`Agent ${binding.agent.id} has no runnable params`);
303
339
  }
304
- const resolvedModel = await this.resolveModel(deepAgentParams.model);
305
- const resolvedTools = this.resolveTools(deepAgentParams.tools, binding);
340
+ const resolvedModel = await this.resolveModel(primaryModel);
341
+ const resolvedTools = this.resolveTools(primaryTools, binding);
306
342
  const resolvedMiddleware = await this.resolveMiddleware(binding);
307
- const resolvedSubagents = await this.resolveSubagents(deepAgentParams.subagents, binding);
343
+ const resolvedSubagents = await this.resolveSubagents(getBindingSubagents(binding), binding);
308
344
  const resolvedCheckpointer = resolveRunnableCheckpointer(this.options, binding);
309
345
  const resolvedStore = this.options.storeResolver?.(binding);
310
346
  const resolvedBackend = this.options.backendResolver?.(binding);
@@ -313,7 +349,7 @@ export class AgentRuntimeAdapter {
313
349
  workspaceRoot: binding.harnessRuntime.workspaceRoot,
314
350
  runRoot: binding.harnessRuntime.runRoot,
315
351
  ownerId: binding.agent.id,
316
- skillPaths: deepAgentParams.skills,
352
+ skillPaths: getBindingSkills(binding),
317
353
  }) ?? [];
318
354
  const deepAgentConfig = buildDeepAgentCreateParams({
319
355
  binding,
@@ -1,5 +1,5 @@
1
1
  import { readSkillMetadata } from "../../support/skill-metadata.js";
2
- import { getBindingPrimaryTools } from "../../support/compiled-binding.js";
2
+ import { getBindingBackendConfig, getBindingPrimaryTools, getBindingSkills, getBindingSubagents } from "../../support/compiled-binding.js";
3
3
  import { assessSkillRequirements, } from "./skill-requirements.js";
4
4
  import { createRuntimeEnv } from "../../support/runtime-env.js";
5
5
  function listHostBindings(workspace) {
@@ -16,9 +16,7 @@ function dedupeTools(tools) {
16
16
  return Array.from(deduped.values());
17
17
  }
18
18
  function readBackendRequirementOptions(binding) {
19
- const backend = binding.deepAgentParams?.backend && typeof binding.deepAgentParams.backend === "object"
20
- ? binding.deepAgentParams.backend
21
- : undefined;
19
+ const backend = getBindingBackendConfig(binding);
22
20
  if (!backend) {
23
21
  return {};
24
22
  }
@@ -75,7 +73,7 @@ export function listAgentSkills(workspace, agentId, options = {}) {
75
73
  return [];
76
74
  }
77
75
  const resolvedOptions = mergeRequirementOptions(binding, options);
78
- return toSkillRecords(binding.deepAgentParams?.skills ?? binding.langchainAgentParams?.skills ?? [], resolvedOptions);
76
+ return toSkillRecords(getBindingSkills(binding), resolvedOptions);
79
77
  }
80
78
  function describeSubagent(subagent, parentAgentId, options = {}) {
81
79
  return {
@@ -89,7 +87,7 @@ function describeSubagent(subagent, parentAgentId, options = {}) {
89
87
  export function listSubagents(workspace, options = {}) {
90
88
  return listHostBindings(workspace).flatMap((binding) => {
91
89
  const resolvedOptions = mergeRequirementOptions(binding, options);
92
- return (binding.deepAgentParams?.subagents ?? []).map((subagent) => describeSubagent(subagent, binding.agent.id, resolvedOptions));
90
+ return getBindingSubagents(binding).map((subagent) => describeSubagent(subagent, binding.agent.id, resolvedOptions));
93
91
  });
94
92
  }
95
93
  export function listAvailableAgents(workspace, options = {}) {
@@ -1,4 +1,4 @@
1
- import type { CompiledAgentBinding, CompiledModel, CompiledTool, DeepAgentParams, LangChainAgentParams } from "../../contracts/types.js";
1
+ import type { CompiledAgentBinding, CompiledModel, CompiledSubAgent, CompiledTool, DeepAgentParams, LangChainAgentParams } from "../../contracts/types.js";
2
2
  export type BindingExecutionView = {
3
3
  adapterKind: string;
4
4
  langchainParams?: LangChainAgentParams;
@@ -19,6 +19,16 @@ export declare function getBindingExecutionView(binding: CompiledAgentBinding):
19
19
  export declare function getBindingAdapterKind(binding: CompiledAgentBinding): string;
20
20
  export declare function getBindingLangChainParams(binding: CompiledAgentBinding): LangChainAgentParams | undefined;
21
21
  export declare function getBindingDeepAgentParams(binding: CompiledAgentBinding): DeepAgentParams | undefined;
22
+ export declare function getBindingExecutionParams(binding: CompiledAgentBinding): LangChainAgentParams | DeepAgentParams | undefined;
23
+ export declare function getBindingExecutionKind(binding: CompiledAgentBinding): "langchain-v1" | "deepagent" | undefined;
24
+ export declare function withUpdatedBindingExecutionParams(binding: CompiledAgentBinding, updater: (params: LangChainAgentParams | DeepAgentParams) => LangChainAgentParams | DeepAgentParams): CompiledAgentBinding;
25
+ export declare function getBindingSkills(binding: CompiledAgentBinding): string[];
26
+ export declare function getBindingMemorySources(binding: CompiledAgentBinding): string[];
27
+ export declare function getBindingSubagents(binding: CompiledAgentBinding): CompiledSubAgent[];
28
+ export declare function getBindingGeneralPurposeAgent(binding: CompiledAgentBinding): boolean | undefined;
29
+ export declare function getBindingTaskDescription(binding: CompiledAgentBinding): string | undefined;
30
+ export declare function getBindingBackendConfig(binding: CompiledAgentBinding): Record<string, unknown> | undefined;
31
+ export declare function getBindingFilesystemConfig(binding: CompiledAgentBinding): Record<string, unknown> | undefined;
22
32
  export declare function isLangChainBinding(binding: CompiledAgentBinding): boolean;
23
33
  export declare function isDeepAgentBinding(binding: CompiledAgentBinding): boolean;
24
34
  export declare function getBindingPrimaryTools(binding: CompiledAgentBinding): CompiledTool[];
@@ -10,11 +10,14 @@ function deriveBindingExecutionView(binding) {
10
10
  }
11
11
  const adapterKind = binding.adapter?.kind ?? binding.agent.executionMode;
12
12
  const legacyAdapterParams = getLegacyAdapterParams(binding);
13
- const langchainParams = binding.langchainAgentParams ??
13
+ const compiledExecution = binding.execution;
14
+ const langchainParams = (compiledExecution?.kind === "langchain-v1" ? compiledExecution.params : undefined) ??
15
+ binding.langchainAgentParams ??
14
16
  (adapterKind === "langchain-v1" && legacyAdapterParams
15
17
  ? legacyAdapterParams
16
18
  : undefined);
17
- const deepAgentParams = binding.deepAgentParams ??
19
+ const deepAgentParams = (compiledExecution?.kind === "deepagent" ? compiledExecution.params : undefined) ??
20
+ binding.deepAgentParams ??
18
21
  (adapterKind === "deepagent" && legacyAdapterParams
19
22
  ? legacyAdapterParams
20
23
  : undefined);
@@ -57,11 +60,89 @@ export function getBindingLangChainParams(binding) {
57
60
  export function getBindingDeepAgentParams(binding) {
58
61
  return getBindingExecutionView(binding).deepAgentParams;
59
62
  }
63
+ export function getBindingExecutionParams(binding) {
64
+ return getBindingExecutionView(binding).executionParams;
65
+ }
66
+ export function getBindingExecutionKind(binding) {
67
+ const execution = binding.execution;
68
+ if (execution?.kind === "langchain-v1" || execution?.kind === "deepagent") {
69
+ return execution.kind;
70
+ }
71
+ if (getBindingAdapterKind(binding) === "langchain-v1" || binding.langchainAgentParams) {
72
+ return "langchain-v1";
73
+ }
74
+ if (getBindingAdapterKind(binding) === "deepagent" || binding.deepAgentParams) {
75
+ return "deepagent";
76
+ }
77
+ return undefined;
78
+ }
79
+ export function withUpdatedBindingExecutionParams(binding, updater) {
80
+ const kind = getBindingExecutionKind(binding);
81
+ const params = getBindingExecutionParams(binding);
82
+ if (!kind || !params) {
83
+ return binding;
84
+ }
85
+ const updatedParams = updater(params);
86
+ if (kind === "langchain-v1") {
87
+ return {
88
+ ...binding,
89
+ execution: {
90
+ kind,
91
+ params: updatedParams,
92
+ },
93
+ langchainAgentParams: updatedParams,
94
+ };
95
+ }
96
+ return {
97
+ ...binding,
98
+ execution: {
99
+ kind,
100
+ params: updatedParams,
101
+ },
102
+ deepAgentParams: updatedParams,
103
+ };
104
+ }
105
+ export function getBindingSkills(binding) {
106
+ const execution = getBindingExecutionParams(binding);
107
+ return Array.isArray(execution?.skills) ? execution.skills : [];
108
+ }
109
+ export function getBindingMemorySources(binding) {
110
+ const execution = getBindingExecutionParams(binding);
111
+ return Array.isArray(execution?.memory)
112
+ ? (execution.memory)
113
+ : [];
114
+ }
115
+ export function getBindingSubagents(binding) {
116
+ const execution = getBindingExecutionParams(binding);
117
+ return Array.isArray(execution?.subagents)
118
+ ? (execution.subagents)
119
+ : [];
120
+ }
121
+ export function getBindingGeneralPurposeAgent(binding) {
122
+ const execution = getBindingExecutionParams(binding);
123
+ const value = execution?.generalPurposeAgent;
124
+ return typeof value === "boolean" ? value : undefined;
125
+ }
126
+ export function getBindingTaskDescription(binding) {
127
+ const execution = getBindingExecutionParams(binding);
128
+ const value = execution?.taskDescription;
129
+ return typeof value === "string" && value.trim().length > 0 ? value : undefined;
130
+ }
131
+ export function getBindingBackendConfig(binding) {
132
+ const execution = getBindingExecutionParams(binding);
133
+ const backend = execution?.backend;
134
+ return typeof backend === "object" && backend ? backend : undefined;
135
+ }
136
+ export function getBindingFilesystemConfig(binding) {
137
+ const execution = getBindingExecutionParams(binding);
138
+ const filesystem = execution?.filesystem;
139
+ return typeof filesystem === "object" && filesystem ? filesystem : undefined;
140
+ }
60
141
  export function isLangChainBinding(binding) {
61
- return getBindingAdapterKind(binding) === "langchain-v1" || Boolean(binding.langchainAgentParams);
142
+ return getBindingAdapterKind(binding) === "langchain-v1" || binding.execution?.kind === "langchain-v1" || Boolean(binding.langchainAgentParams);
62
143
  }
63
144
  export function isDeepAgentBinding(binding) {
64
- return getBindingAdapterKind(binding) === "deepagent" || Boolean(binding.deepAgentParams);
145
+ return getBindingAdapterKind(binding) === "deepagent" || binding.execution?.kind === "deepagent" || Boolean(binding.deepAgentParams);
65
146
  }
66
147
  export function getBindingPrimaryTools(binding) {
67
148
  return getBindingExecutionView(binding).primaryTools;
@@ -1,5 +1,6 @@
1
1
  import { createPersistentId } from "../../utils/id.js";
2
2
  import { isDelegationCapableBinding } from "../../workspace/support/agent-capabilities.js";
3
+ import { isDeepAgentBinding } from "./compiled-binding.js";
3
4
  export function renderRuntimeFailure(error) {
4
5
  const message = error instanceof Error ? error.message : String(error);
5
6
  return `runtime_error=${message}`.trim();
@@ -87,7 +88,7 @@ export function createPendingApproval(threadId, runId, checkpointRef, input, int
87
88
  }
88
89
  export function inferRoutingBindings(workspace) {
89
90
  const hostBindings = Array.from(workspace.bindings.values());
90
- const orchestrationHosts = hostBindings.filter((binding) => binding.agent.executionMode === "deepagent" || Boolean(binding.deepAgentParams));
91
+ const orchestrationHosts = hostBindings.filter((binding) => isDeepAgentBinding(binding));
91
92
  const routingHosts = orchestrationHosts.length > 0 ? orchestrationHosts : hostBindings;
92
93
  const primaryBinding = routingHosts.find((binding) => isDelegationCapableBinding(binding)) ?? routingHosts[0] ?? hostBindings[0];
93
94
  return { primaryBinding, hostBindings };
@@ -300,6 +300,10 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
300
300
  };
301
301
  return {
302
302
  ...base,
303
+ execution: {
304
+ kind: "langchain-v1",
305
+ params: langchainAgentParams,
306
+ },
303
307
  langchainAgentParams,
304
308
  };
305
309
  }
@@ -310,6 +314,7 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
310
314
  responseFormat: execution.responseFormat,
311
315
  contextSchema: execution.contextSchema,
312
316
  middleware: execution.middleware,
317
+ passthrough: execution.passthrough,
313
318
  description: agent.description,
314
319
  subagents: compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel),
315
320
  interruptOn: resolveInterruptOn(agent),
@@ -321,6 +326,10 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
321
326
  };
322
327
  return {
323
328
  ...base,
329
+ execution: {
330
+ kind: "deepagent",
331
+ params: deepAgentParams,
332
+ },
324
333
  deepAgentParams,
325
334
  };
326
335
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.116",
3
+ "version": "0.0.118",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",