@botbotgo/agent-harness 0.0.111 → 0.0.112

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.
Files changed (45) hide show
  1. package/README.md +0 -2
  2. package/README.zh.md +0 -2
  3. package/dist/config/agents/direct.yaml +58 -59
  4. package/dist/config/agents/orchestra.yaml +68 -70
  5. package/dist/contracts/core.d.ts +0 -2
  6. package/dist/contracts/runtime.d.ts +0 -17
  7. package/dist/contracts/workspace.d.ts +2 -7
  8. package/dist/init-project.js +10 -8
  9. package/dist/package-version.d.ts +1 -1
  10. package/dist/package-version.js +1 -1
  11. package/dist/persistence/file-store.d.ts +1 -5
  12. package/dist/persistence/file-store.js +1 -34
  13. package/dist/runtime/adapter/compat/deepagent-compat.d.ts +6 -0
  14. package/dist/runtime/adapter/compat/deepagent-compat.js +3 -0
  15. package/dist/runtime/adapter/{execution-context.d.ts → flow/execution-context.d.ts} +17 -3
  16. package/dist/runtime/adapter/{execution-context.js → flow/execution-context.js} +20 -2
  17. package/dist/runtime/adapter/flow/invocation-flow.d.ts +24 -0
  18. package/dist/runtime/adapter/flow/invocation-flow.js +42 -0
  19. package/dist/runtime/adapter/{invoke-runtime.d.ts → flow/invoke-runtime.d.ts} +3 -3
  20. package/dist/runtime/adapter/{invoke-runtime.js → flow/invoke-runtime.js} +1 -1
  21. package/dist/runtime/adapter/flow/runnable-assembly.d.ts +51 -0
  22. package/dist/runtime/adapter/flow/runnable-assembly.js +52 -0
  23. package/dist/runtime/adapter/{stream-runtime.d.ts → flow/stream-runtime.d.ts} +3 -3
  24. package/dist/runtime/adapter/{stream-runtime.js → flow/stream-runtime.js} +6 -6
  25. package/dist/runtime/adapter/middleware-assembly.d.ts +1 -1
  26. package/dist/runtime/adapter/middleware-assembly.js +5 -8
  27. package/dist/runtime/adapter/runnable-config.d.ts +0 -2
  28. package/dist/runtime/adapter/runnable-config.js +0 -2
  29. package/dist/runtime/adapter/runtime-adapter-support.d.ts +0 -7
  30. package/dist/runtime/adapter/runtime-adapter-support.js +1 -20
  31. package/dist/runtime/adapter/runtime-shell.js +1 -1
  32. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +10 -9
  33. package/dist/runtime/adapter/tool-resolution.d.ts +1 -1
  34. package/dist/runtime/agent-runtime-adapter.d.ts +1 -1
  35. package/dist/runtime/agent-runtime-adapter.js +52 -81
  36. package/dist/runtime/harness/system/inventory.d.ts +2 -2
  37. package/dist/runtime/harness/system/inventory.js +5 -6
  38. package/dist/runtime/parsing/stream-event-parsing.js +2 -2
  39. package/dist/runtime/support/compiled-binding.d.ts +1 -2
  40. package/dist/runtime/support/compiled-binding.js +0 -3
  41. package/dist/workspace/agent-binding-compiler.js +2 -22
  42. package/dist/workspace/object-loader.js +94 -23
  43. package/dist/workspace/support/workspace-ref-utils.d.ts +1 -2
  44. package/dist/workspace/support/workspace-ref-utils.js +0 -12
  45. package/package.json +1 -1
@@ -1,28 +1,23 @@
1
1
  import path from "node:path";
2
- import { Command, MemorySaver } from "@langchain/langgraph";
3
2
  import { createDeepAgent, FilesystemBackend, } from "deepagents";
4
3
  import { createAgent } from "langchain";
5
4
  import { wrapResolvedModel, } from "./parsing/output-parsing.js";
6
- import { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, } from "./adapter/compat/deepagent-compat.js";
5
+ import { assembleDeepAgentRunnable, assembleLangChainRunnable, } from "./adapter/flow/runnable-assembly.js";
7
6
  import { buildToolNameMapping, } from "./adapter/tool/tool-name-mapping.js";
8
- import { finalizeInvocationResult } from "./adapter/invocation-result.js";
9
- import { invokeRuntimeWithLocalTools } from "./adapter/invoke-runtime.js";
10
- import { streamRuntimeExecution } from "./adapter/stream-runtime.js";
7
+ import { executeRuntimeInvocation } from "./adapter/flow/invocation-flow.js";
8
+ import { streamRuntimeExecution } from "./adapter/flow/stream-runtime.js";
11
9
  import { buildDeepAgentRunnableConfig, buildLangChainRunnableConfig } from "./adapter/runnable-config.js";
12
10
  import { applyStrictToolJsonInstruction as applyStrictToolJsonInstructionHelper, callRuntimeWithToolParseRecovery as callRuntimeWithToolParseRecoveryHelper, createModelFallbackRunnable as createModelFallbackRunnableHelper, invokeWithProviderRetry as invokeWithProviderRetryHelper, iterateWithTimeout as iterateWithTimeoutHelper, materializeModelStream as materializeModelStreamHelper, RuntimeOperationTimeoutError, withRuntimeTimeout, } from "./adapter/runtime-shell.js";
13
11
  import { invokeBuiltinTaskTool as invokeBuiltinTaskToolHelper, resolveAutomaticSummarizationMiddleware as resolveAutomaticSummarizationMiddlewareHelper, resolveBuiltinMiddlewareBackend as resolveBuiltinMiddlewareBackendHelper, resolveBuiltinMiddlewareTools as resolveBuiltinMiddlewareToolsHelper, resolveLangChainAutomaticMiddleware as resolveLangChainAutomaticMiddlewareHelper, resolveMiddleware as resolveMiddlewareHelper, resolveSubagents as resolveSubagentsHelper, } from "./adapter/middleware-assembly.js";
14
12
  import { computeRemainingTimeoutMs, resolveBindingTimeout, resolveStreamIdleTimeout, } from "./adapter/resilience.js";
15
13
  import { createResolvedModel } from "./adapter/model/model-providers.js";
16
- import { buildInvocationRequest, } from "./adapter/model/invocation-request.js";
17
- import { compileInterruptOn } from "./adapter/tool/interrupt-policy.js";
18
- import { countConfiguredTools, } from "./adapter/runtime-adapter-support.js";
19
14
  import { resolveAdapterTools } from "./adapter/tool-resolution.js";
20
- import { buildBindingToolCatalog, buildBindingToolExecutionContext, resolveLangChainStreamContext, } from "./adapter/execution-context.js";
21
- export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, shouldRelaxDeepAgentDelegationPrompt, } from "./adapter/compat/deepagent-compat.js";
15
+ import { resolveRuntimeStreamExecutionContext, } from "./adapter/flow/execution-context.js";
16
+ export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, resolveDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, shouldRelaxDeepAgentDelegationPrompt, } from "./adapter/compat/deepagent-compat.js";
22
17
  export { buildAuthOmittingFetch, normalizeOpenAICompatibleInit } from "./adapter/compat/openai-compatible.js";
23
18
  export { buildToolNameMapping, createModelFacingToolNameCandidates, createModelFacingToolNameLookupCandidates, resolveModelFacingToolName, sanitizeToolNameForModel, } from "./adapter/tool/tool-name-mapping.js";
24
19
  export { computeRemainingTimeoutMs, isRetryableProviderError, resolveBindingTimeout, resolveProviderRetryPolicy, resolveStreamIdleTimeout, resolveTimeoutMs, } from "./adapter/resilience.js";
25
- import { getBindingAdapterKind, getBindingDeepAgentParams, getBindingInterruptCompatibilityRules, getBindingLangChainParams, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
20
+ import { getBindingAdapterKind, getBindingLangChainParams, getBindingToolCount, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
26
21
  const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
27
22
  const UPSTREAM_BUILTIN_MIDDLEWARE_TOOL_NAMES = Object.freeze([
28
23
  "write_todos",
@@ -35,12 +30,6 @@ const UPSTREAM_BUILTIN_MIDDLEWARE_TOOL_NAMES = Object.freeze([
35
30
  "execute",
36
31
  "task",
37
32
  ]);
38
- function resolveBindingCheckpointer(options, binding) {
39
- return options.checkpointerResolver ? options.checkpointerResolver(binding) : new MemorySaver();
40
- }
41
- function resolveBindingInterruptOn(binding) {
42
- return compileInterruptOn(getBindingPrimaryTools(binding), getBindingInterruptCompatibilityRules(binding));
43
- }
44
33
  export class AgentRuntimeAdapter {
45
34
  options;
46
35
  modelCache = new Map();
@@ -222,22 +211,29 @@ export class AgentRuntimeAdapter {
222
211
  });
223
212
  }
224
213
  async createLangChainRunnable(binding, options = {}) {
225
- const params = getBindingLangChainParams(binding);
226
- const interruptOn = resolveBindingInterruptOn(binding);
227
- const model = (await this.resolveModel(params.model));
228
- const tools = this.resolveTools(params.tools, binding);
214
+ const assembly = await assembleLangChainRunnable({
215
+ binding,
216
+ runtimeAdapterOptions: this.options,
217
+ resolveModel: (model) => this.resolveModel(model),
218
+ resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
219
+ resolveMiddleware: (currentBinding, interruptOn) => this.resolveMiddleware(currentBinding, interruptOn),
220
+ passthroughOverride: options.passthroughOverride,
221
+ systemPromptOverride: options.systemPromptOverride,
222
+ });
223
+ const model = assembly.resolvedModel;
224
+ const tools = assembly.resolvedTools;
229
225
  if (tools.length > 0 && typeof model.bindTools !== "function") {
230
- throw new Error(`Agent ${binding.agent.id} configures ${tools.length} tool(s), but resolved model ${params.model.id} does not support tool binding.`);
226
+ throw new Error(`Agent ${binding.agent.id} configures ${tools.length} tool(s), but resolved model ${assembly.langchainParams.model.id} does not support tool binding.`);
231
227
  }
232
228
  return createAgent(buildLangChainRunnableConfig({
233
- langchainParams: params,
229
+ langchainParams: assembly.langchainParams,
234
230
  resolvedModel: model,
235
231
  resolvedTools: tools,
236
- resolvedMiddleware: await this.resolveMiddleware(binding, interruptOn),
237
- resolvedCheckpointer: resolveBindingCheckpointer(this.options, binding),
238
- resolvedStore: this.options.storeResolver?.(binding),
239
- passthroughOverride: options.passthroughOverride,
240
- systemPromptOverride: options.systemPromptOverride,
232
+ resolvedMiddleware: assembly.resolvedMiddleware,
233
+ resolvedCheckpointer: assembly.resolvedCheckpointer,
234
+ resolvedStore: assembly.resolvedStore,
235
+ passthroughOverride: assembly.passthroughOverride,
236
+ systemPromptOverride: assembly.systemPromptOverride,
241
237
  }));
242
238
  }
243
239
  async createRunnable(binding) {
@@ -250,27 +246,25 @@ export class AgentRuntimeAdapter {
250
246
  return this.createDeepAgentRunnable(binding);
251
247
  }
252
248
  async createDeepAgentRunnable(binding) {
253
- const params = getBindingDeepAgentParams(binding);
254
- if (!params) {
255
- throw new Error(`Agent ${binding.agent.id} has no runnable params`);
256
- }
257
- const compatibleParams = applyDeepAgentDelegationPromptCompatibility(params.model, params);
249
+ const assembly = await assembleDeepAgentRunnable({
250
+ binding,
251
+ runtimeAdapterOptions: this.options,
252
+ resolveModel: (model) => this.resolveModel(model),
253
+ resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
254
+ resolveMiddleware: (currentBinding, interruptOn) => this.resolveMiddleware(currentBinding, interruptOn),
255
+ resolveSubagents: (subagents, currentBinding) => this.resolveSubagents(subagents, currentBinding),
256
+ });
258
257
  const deepAgentConfig = buildDeepAgentRunnableConfig({
259
- compatibleParams,
260
- resolvedModel: await this.resolveModel(compatibleParams.model),
261
- resolvedTools: this.resolveTools(compatibleParams.tools, binding),
262
- resolvedMiddleware: await this.resolveMiddleware(binding),
263
- resolvedSubagents: await this.resolveSubagents(compatibleParams.subagents, binding),
264
- resolvedCheckpointer: resolveBindingCheckpointer(this.options, binding),
265
- resolvedStore: this.options.storeResolver?.(binding),
266
- resolvedBackend: this.options.backendResolver?.(binding),
267
- resolvedInterruptOn: resolveBindingInterruptOn(binding),
268
- resolvedSkills: (await materializeDeepAgentSkillSourcePaths({
269
- workspaceRoot: binding.harnessRuntime.workspaceRoot,
270
- runRoot: binding.harnessRuntime.runRoot,
271
- ownerId: binding.agent.id,
272
- skillPaths: compatibleParams.skills,
273
- })) ?? [],
258
+ compatibleParams: assembly.compatibleParams,
259
+ resolvedModel: assembly.resolvedModel,
260
+ resolvedTools: assembly.resolvedTools,
261
+ resolvedMiddleware: assembly.resolvedMiddleware,
262
+ resolvedSubagents: assembly.resolvedSubagents,
263
+ resolvedCheckpointer: assembly.resolvedCheckpointer,
264
+ resolvedStore: assembly.resolvedStore,
265
+ resolvedBackend: assembly.resolvedBackend,
266
+ resolvedInterruptOn: assembly.resolvedInterruptOn,
267
+ resolvedSkills: assembly.resolvedSkills,
274
268
  });
275
269
  return createDeepAgent(deepAgentConfig);
276
270
  }
@@ -290,9 +284,6 @@ export class AgentRuntimeAdapter {
290
284
  }
291
285
  }
292
286
  async invoke(binding, input, threadId, runId, resumePayload, history = [], options = {}) {
293
- const request = resumePayload === undefined
294
- ? buildInvocationRequest(binding, history, input, options)
295
- : new Command({ resume: resumePayload });
296
287
  const callRuntime = async (activeBinding, activeRequest) => {
297
288
  return this.invokeWithProviderRetry(activeBinding, async () => {
298
289
  const runnable = await this.create(activeBinding);
@@ -307,47 +298,27 @@ export class AgentRuntimeAdapter {
307
298
  callRuntime,
308
299
  });
309
300
  };
310
- const { primaryTools, toolNameMapping, executableTools, defersToUpstreamHitlExecution, } = buildBindingToolExecutionContext({
301
+ return executeRuntimeInvocation({
311
302
  binding,
303
+ input,
304
+ threadId,
305
+ runId,
306
+ resumePayload,
307
+ history,
308
+ invokeOptions: options,
312
309
  resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
313
310
  getToolNameMapping: (currentBinding) => this.getToolNameMapping(currentBinding),
314
- context: options.context,
315
- });
316
- const builtinExecutableTools = await this.resolveBuiltinMiddlewareTools(binding, options);
317
- const localOrUpstreamInvocation = await invokeRuntimeWithLocalTools({
318
- binding,
319
- request,
320
- resumePayload,
321
- primaryTools,
322
- defersToUpstreamHitlExecution,
323
- toolNameMapping,
324
- executableTools,
325
- builtinExecutableTools: builtinExecutableTools,
311
+ resolveBuiltinMiddlewareTools: (currentBinding, currentOptions) => this.resolveBuiltinMiddlewareTools(currentBinding, currentOptions),
326
312
  callRuntimeWithToolParseRecovery,
327
313
  });
328
- const result = localOrUpstreamInvocation.result;
329
- const executedToolResults = [...localOrUpstreamInvocation.executedToolResults];
330
- if (!result) {
331
- throw new Error("Agent invocation returned no result");
332
- }
333
- return finalizeInvocationResult({
334
- bindingAgentId: binding.agent.id,
335
- threadId,
336
- runId,
337
- result,
338
- executedToolResults,
339
- });
340
314
  }
341
315
  async *stream(binding, input, threadId, history = [], options = {}) {
342
316
  const invokeTimeoutMs = resolveBindingTimeout(binding);
343
317
  const streamIdleTimeoutMs = resolveStreamIdleTimeout(binding);
344
318
  const streamDeadlineAt = invokeTimeoutMs ? Date.now() + invokeTimeoutMs : undefined;
345
- const { primaryTools, toolNameMapping } = buildBindingToolCatalog({
319
+ const { primaryTools, toolNameMapping, forceInvokeFallback, canUseDirectModelStream, langChainStreamModel, } = await resolveRuntimeStreamExecutionContext({
346
320
  binding,
347
321
  getToolNameMapping: (currentBinding) => this.getToolNameMapping(currentBinding),
348
- });
349
- const { forceInvokeFallback, canUseDirectModelStream, langChainStreamModel, } = await resolveLangChainStreamContext({
350
- binding,
351
322
  resolveModel: (model) => this.resolveModel(model),
352
323
  resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
353
324
  });
@@ -373,7 +344,7 @@ export class AgentRuntimeAdapter {
373
344
  getSystemPrompt: (activeBinding) => getBindingSystemPrompt(activeBinding),
374
345
  isLangChainBinding,
375
346
  isDeepAgentBinding,
376
- countConfiguredTools,
347
+ countConfiguredTools: getBindingToolCount,
377
348
  });
378
349
  }
379
350
  }
@@ -20,14 +20,14 @@ export type InventorySkillRecord = {
20
20
  export type InventoryAgentRecord = {
21
21
  id: string;
22
22
  description: string;
23
- role: "agent" | "specialist";
23
+ parentAgentId?: string;
24
24
  tools: InventoryToolRecord[];
25
25
  skills: InventorySkillRecord[];
26
26
  };
27
27
  export declare function findAgentBinding(workspace: WorkspaceBundle, agentId: string): CompiledAgentBinding | undefined;
28
28
  export declare function listAgentTools(workspace: WorkspaceBundle, agentId: string): InventoryToolRecord[];
29
29
  export declare function listAgentSkills(workspace: WorkspaceBundle, agentId: string, options?: RequirementAssessmentOptions): InventorySkillRecord[];
30
- export declare function listSpecialists(workspace: WorkspaceBundle, options?: RequirementAssessmentOptions): InventoryAgentRecord[];
30
+ export declare function listSubagents(workspace: WorkspaceBundle, options?: RequirementAssessmentOptions): InventoryAgentRecord[];
31
31
  export declare function listAvailableAgents(workspace: WorkspaceBundle, options?: RequirementAssessmentOptions): InventoryAgentRecord[];
32
32
  export declare function describeWorkspaceInventory(workspace: WorkspaceBundle, options?: RequirementAssessmentOptions): {
33
33
  workspaceRoot: string;
@@ -77,30 +77,29 @@ export function listAgentSkills(workspace, agentId, options = {}) {
77
77
  const resolvedOptions = mergeRequirementOptions(binding, options);
78
78
  return toSkillRecords(binding.deepAgentParams?.skills ?? binding.langchainAgentParams?.skills ?? [], resolvedOptions);
79
79
  }
80
- function describeSubagent(subagent, options = {}) {
80
+ function describeSubagent(subagent, parentAgentId, options = {}) {
81
81
  return {
82
82
  id: subagent.name,
83
83
  description: subagent.description,
84
- role: "specialist",
84
+ parentAgentId,
85
85
  tools: dedupeTools(subagent.tools ?? []),
86
86
  skills: toSkillRecords(subagent.skills ?? [], options),
87
87
  };
88
88
  }
89
- export function listSpecialists(workspace, options = {}) {
89
+ export function listSubagents(workspace, options = {}) {
90
90
  return listHostBindings(workspace).flatMap((binding) => {
91
91
  const resolvedOptions = mergeRequirementOptions(binding, options);
92
- return (binding.deepAgentParams?.subagents ?? []).map((subagent) => describeSubagent(subagent, resolvedOptions));
92
+ return (binding.deepAgentParams?.subagents ?? []).map((subagent) => describeSubagent(subagent, binding.agent.id, resolvedOptions));
93
93
  });
94
94
  }
95
95
  export function listAvailableAgents(workspace, options = {}) {
96
96
  const topLevel = listHostBindings(workspace).map((binding) => ({
97
97
  id: binding.agent.id,
98
98
  description: binding.agent.description,
99
- role: "agent",
100
99
  tools: listAgentTools(workspace, binding.agent.id),
101
100
  skills: listAgentSkills(workspace, binding.agent.id, options),
102
101
  }));
103
- return [...topLevel, ...listSpecialists(workspace, options)];
102
+ return [...topLevel, ...listSubagents(workspace, options)];
104
103
  }
105
104
  export function describeWorkspaceInventory(workspace, options = {}) {
106
105
  return {
@@ -390,13 +390,13 @@ export function extractAgentStep(event) {
390
390
  return "preparing model request…";
391
391
  if (/RunnableLambda/i.test(name) || /^__start__$/.test(name))
392
392
  return null;
393
- if (/specialist/i.test(name))
393
+ if (/(subagent|specialist)/i.test(name))
394
394
  return `starting ${humanizeEventName(name)}…`;
395
395
  if (/agent$/i.test(name))
396
396
  return `running ${humanizeEventName(name)}…`;
397
397
  }
398
398
  if (typed.event === "on_chain_end") {
399
- if (/specialist/i.test(name))
399
+ if (/(subagent|specialist)/i.test(name))
400
400
  return `${humanizeEventName(name)} done`;
401
401
  if (/agent$/i.test(name) && !/^__start__$/.test(name))
402
402
  return `${humanizeEventName(name)} done`;
@@ -1,4 +1,4 @@
1
- import type { CompiledAgentBinding, CompiledModel, CompiledTool, DeepAgentParams, LangChainAgentParams, RuntimeModelSlot } from "../../contracts/types.js";
1
+ import type { CompiledAgentBinding, CompiledModel, CompiledTool, DeepAgentParams, LangChainAgentParams } from "../../contracts/types.js";
2
2
  export type BindingExecutionView = {
3
3
  adapterKind: string;
4
4
  adapterConfig: Record<string, unknown>;
@@ -25,7 +25,6 @@ export declare function isLangChainBinding(binding: CompiledAgentBinding): boole
25
25
  export declare function isDeepAgentBinding(binding: CompiledAgentBinding): boolean;
26
26
  export declare function getBindingPrimaryTools(binding: CompiledAgentBinding): CompiledTool[];
27
27
  export declare function getBindingPrimaryModel(binding: CompiledAgentBinding): CompiledModel | undefined;
28
- export declare function getBindingRuntimeModel(binding: CompiledAgentBinding, slot: RuntimeModelSlot): CompiledModel | undefined;
29
28
  export declare function getBindingSystemPrompt(binding: CompiledAgentBinding): string | undefined;
30
29
  export declare function getBindingMiddlewareConfigs(binding: CompiledAgentBinding): Array<Record<string, unknown>> | undefined;
31
30
  export declare function getBindingToolCount(binding: CompiledAgentBinding): number;
@@ -69,9 +69,6 @@ export function getBindingPrimaryTools(binding) {
69
69
  export function getBindingPrimaryModel(binding) {
70
70
  return getBindingExecutionView(binding).primaryModel;
71
71
  }
72
- export function getBindingRuntimeModel(binding, slot) {
73
- return binding.harnessRuntime.models?.[slot];
74
- }
75
72
  export function getBindingSystemPrompt(binding) {
76
73
  return getBindingExecutionView(binding).systemPrompt;
77
74
  }
@@ -4,7 +4,7 @@ import { compileModel, compileTool } from "./resource-compilers.js";
4
4
  import { inferAgentCapabilities } from "./support/agent-capabilities.js";
5
5
  import { getAgentExecutionConfigValue, getAgentExecutionObject, getAgentExecutionString } from "./support/agent-execution-config.js";
6
6
  import { discoverSkillPaths } from "./support/discovery.js";
7
- import { compileAgentMemories, getResilienceConfig, getRuntimeDefaults, getRuntimeMemoryDefaults, getRuntimeModelDefaults, getWorkspaceObject, resolvePromptValue, resolveRefId } from "./support/workspace-ref-utils.js";
7
+ import { compileAgentMemories, getResilienceConfig, getRuntimeDefaults, getRuntimeMemoryDefaults, getWorkspaceObject, resolvePromptValue, resolveRefId } from "./support/workspace-ref-utils.js";
8
8
  const WORKSPACE_BOUNDARY_GUIDANCE = "Keep repository and file exploration bounded to the current workspace root unless the user explicitly asks for broader host or filesystem access. " +
9
9
  "Do not inspect absolute paths outside the workspace, system directories, or unrelated repos by default. " +
10
10
  "Prefer workspace-local tools, relative paths, and the current repository checkout when analyzing code.";
@@ -233,7 +233,7 @@ function resolveCheckpointerConfig(agent, refs) {
233
233
  return { config: inlineAgentCheckpointer };
234
234
  }
235
235
  function resolveRuntimeMemoryConfig(agent, refs) {
236
- const inlineRuntimeMemory = getAgentExecutionObject(agent, "runtimeMemory");
236
+ const inlineRuntimeMemory = agent.runtimeMemory ?? getAgentExecutionObject(agent, "runtimeMemory");
237
237
  if (inlineRuntimeMemory) {
238
238
  if (isRefConfig(inlineRuntimeMemory)) {
239
239
  return {
@@ -245,20 +245,6 @@ function resolveRuntimeMemoryConfig(agent, refs) {
245
245
  const runtimeMemoryDefaults = getRuntimeMemoryDefaults(refs);
246
246
  return runtimeMemoryDefaults ? { config: runtimeMemoryDefaults } : undefined;
247
247
  }
248
- function resolveRuntimeModelRefs(agent, refs) {
249
- const merged = {
250
- ...(getRuntimeModelDefaults(refs) ?? {}),
251
- ...(agent.runtimeModelRefs ?? {}),
252
- };
253
- return Object.keys(merged).length > 0 ? merged : undefined;
254
- }
255
- function compileRuntimeModels(modelRefs, models, ownerId) {
256
- if (!modelRefs) {
257
- return undefined;
258
- }
259
- const compiled = Object.fromEntries(Object.entries(modelRefs).map(([slot, modelRef]) => [slot, requireModel(models, modelRef, ownerId)]));
260
- return Object.keys(compiled).length > 0 ? compiled : undefined;
261
- }
262
248
  export function compileBinding(workspaceRoot, agent, agents, referencedSubagentIds, refs, models, tools) {
263
249
  const internalSubagent = referencedSubagentIds.has(agent.id);
264
250
  const runtimeDefaults = getRuntimeDefaults(refs);
@@ -274,8 +260,6 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
274
260
  const store = resolveStoreConfig(agent, refs);
275
261
  const checkpointer = resolveCheckpointerConfig(agent, refs);
276
262
  const runtimeMemory = resolveRuntimeMemoryConfig(agent, refs);
277
- const runtimeModelRefs = resolveRuntimeModelRefs(agent, refs);
278
- const runtimeModels = compileRuntimeModels(runtimeModelRefs, models, agent.id);
279
263
  const runRoot = typeof agent.runRoot === "string" && agent.runRoot.trim().length > 0
280
264
  ? path.resolve(workspaceRoot, agent.runRoot)
281
265
  : typeof runtimeDefaults?.runRoot === "string" && runtimeDefaults.runRoot.trim().length > 0
@@ -296,8 +280,6 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
296
280
  harnessRuntime: {
297
281
  runRoot,
298
282
  workspaceRoot,
299
- ...(runtimeModelRefs ? { modelRefs: runtimeModelRefs } : {}),
300
- ...(runtimeModels ? { models: runtimeModels } : {}),
301
283
  capabilities: inferAgentCapabilities(agent),
302
284
  resilience,
303
285
  ...(checkpointer ? { checkpointer: checkpointer.config } : {}),
@@ -356,8 +338,6 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
356
338
  name: resolveAgentRuntimeName(agent),
357
339
  memory: compiledAgentMemory,
358
340
  skills: compiledAgentSkills,
359
- generalPurposeAgent: getAgentExecutionConfigValue(agent, "generalPurposeAgent", { executionMode: "deepagent" }),
360
- taskDescription: getAgentExecutionString(agent, "taskDescription", { executionMode: "deepagent" }),
361
341
  };
362
342
  return {
363
343
  ...base,
@@ -151,9 +151,75 @@ const CONSUMED_AGENT_CONFIG_KEYS = [
151
151
  "generalPurposeAgent",
152
152
  "filesystem",
153
153
  ];
154
+ const RESERVED_EXECUTION_KEYS = [
155
+ "backend",
156
+ "modelRef",
157
+ "tools",
158
+ "skills",
159
+ "memory",
160
+ "subagents",
161
+ "mcpServers",
162
+ "config",
163
+ ];
164
+ const MIGRATED_EXECUTION_CONFIG_KEYS = [
165
+ "systemPrompt",
166
+ "checkpointer",
167
+ "interruptOn",
168
+ "stateSchema",
169
+ "responseFormat",
170
+ "contextSchema",
171
+ "includeAgentName",
172
+ "version",
173
+ "middleware",
174
+ "store",
175
+ "taskDescription",
176
+ "generalPurposeAgent",
177
+ "filesystem",
178
+ ];
154
179
  function readExecutionConfig(value) {
155
180
  return asMutableObject(value);
156
181
  }
182
+ function normalizeAgentItemForMerge(item) {
183
+ const normalized = { ...item };
184
+ const execution = readExecutionConfig(normalized.execution);
185
+ if (!execution) {
186
+ return normalized;
187
+ }
188
+ const config = asMutableObject(execution.config);
189
+ const runtime = readRuntimeConfig(normalized);
190
+ if (config) {
191
+ for (const key of MIGRATED_EXECUTION_CONFIG_KEYS) {
192
+ if (!(key in config) || execution[key] !== undefined) {
193
+ continue;
194
+ }
195
+ execution[key] = cloneConfigValue(config[key]);
196
+ delete config[key];
197
+ }
198
+ if (config.runtimeMemory !== undefined && runtime?.runtimeMemory === undefined) {
199
+ const nextRuntime = runtime ?? {};
200
+ nextRuntime.runtimeMemory = cloneConfigValue(config.runtimeMemory);
201
+ normalized.runtime = nextRuntime;
202
+ delete config.runtimeMemory;
203
+ }
204
+ }
205
+ if (config && Object.keys(config).length > 0) {
206
+ execution.config = config;
207
+ }
208
+ else {
209
+ delete execution.config;
210
+ }
211
+ normalized.execution = execution;
212
+ return normalized;
213
+ }
214
+ function readExecutionAgentConfig(item) {
215
+ const execution = readExecutionConfig(item.execution) ?? {};
216
+ const config = asMutableObject(execution.config) ?? {};
217
+ const directExecutionConfig = Object.fromEntries(Object.entries(execution).filter(([key]) => !RESERVED_EXECUTION_KEYS.includes(key)));
218
+ return {
219
+ ...config,
220
+ ...directExecutionConfig,
221
+ };
222
+ }
157
223
  function readExecutionValue(item, key, reader) {
158
224
  const execution = readExecutionConfig(item.execution);
159
225
  return reader(execution?.[key]);
@@ -161,19 +227,17 @@ function readExecutionValue(item, key, reader) {
161
227
  function readRuntimeConfig(item) {
162
228
  return asMutableObject(item.runtime);
163
229
  }
164
- function readRuntimeModelRefs(runtime) {
165
- if (!runtime) {
166
- return undefined;
230
+ function readRuntimeMemoryConfig(item, runtime) {
231
+ if (typeof runtime?.runtimeMemory === "object" && runtime.runtimeMemory && !Array.isArray(runtime.runtimeMemory)) {
232
+ return cloneConfigValue(runtime.runtimeMemory);
167
233
  }
168
- const modelRefs = {
169
- ...(typeof runtime.planningModelRef === "string" && runtime.planningModelRef.trim()
170
- ? { planning: runtime.planningModelRef.trim() }
171
- : {}),
172
- ...(typeof runtime.executionModelRef === "string" && runtime.executionModelRef.trim()
173
- ? { execution: runtime.executionModelRef.trim() }
174
- : {}),
175
- };
176
- return Object.keys(modelRefs).length > 0 ? modelRefs : undefined;
234
+ const legacyExecutionConfig = readExecutionAgentConfig(item);
235
+ if (typeof legacyExecutionConfig.runtimeMemory === "object" &&
236
+ legacyExecutionConfig.runtimeMemory &&
237
+ !Array.isArray(legacyExecutionConfig.runtimeMemory)) {
238
+ return cloneConfigValue(legacyExecutionConfig.runtimeMemory);
239
+ }
240
+ return undefined;
177
241
  }
178
242
  function cloneConfigValue(value) {
179
243
  if (Array.isArray(value)) {
@@ -239,12 +303,15 @@ function resolveExecutionBackend(item, current) {
239
303
  }
240
304
  return undefined;
241
305
  }
242
- function readSharedAgentConfigFields(config) {
306
+ function readSharedAgentConfigFields(config, options = {}) {
243
307
  return {
244
308
  ...(typeof config.store === "object" && config.store ? { store: config.store } : {}),
245
- ...(typeof config.runtimeMemory === "object" && config.runtimeMemory ? { runtimeMemory: config.runtimeMemory } : {}),
246
- ...(typeof config.taskDescription === "string" && config.taskDescription.trim() ? { taskDescription: config.taskDescription } : {}),
247
- ...(typeof config.generalPurposeAgent === "boolean" ? { generalPurposeAgent: config.generalPurposeAgent } : {}),
309
+ ...(options.includeDelegationControls && typeof config.taskDescription === "string" && config.taskDescription.trim()
310
+ ? { taskDescription: config.taskDescription }
311
+ : {}),
312
+ ...(options.includeDelegationControls && typeof config.generalPurposeAgent === "boolean"
313
+ ? { generalPurposeAgent: config.generalPurposeAgent }
314
+ : {}),
248
315
  };
249
316
  }
250
317
  function readSharedAgentConfig(config) {
@@ -268,11 +335,11 @@ function readSharedAgentConfig(config) {
268
335
  };
269
336
  }
270
337
  function readAgentConfig(item, options = {}) {
271
- const config = readExecutionValue(item, "config", asMutableObject) ?? {};
338
+ const config = readExecutionAgentConfig(item);
272
339
  const passthrough = readPassthroughConfig(config, [...CONSUMED_AGENT_CONFIG_KEYS]);
273
340
  return {
274
341
  ...readSharedAgentConfig(config),
275
- ...readSharedAgentConfigFields(config),
342
+ ...readSharedAgentConfigFields(config, { includeDelegationControls: options.includeDelegationControls }),
276
343
  ...(options.includeObjectBackend && typeof config.backend === "object" && config.backend ? { backend: config.backend } : {}),
277
344
  ...(passthrough ? { passthrough } : {}),
278
345
  };
@@ -286,7 +353,7 @@ export function parseAgentItem(item, sourcePath) {
286
353
  return {
287
354
  id: String(item.id),
288
355
  executionMode: executionMode,
289
- runtimeModelRefs: readRuntimeModelRefs(runtime),
356
+ runtimeMemory: readRuntimeMemoryConfig(item, runtime),
290
357
  capabilities: readCapabilities(item.capabilities) ?? (executionMode === "deepagent"
291
358
  ? { delegation: true, memory: true }
292
359
  : { delegation: true, memory: true }),
@@ -299,8 +366,11 @@ export function parseAgentItem(item, sourcePath) {
299
366
  memorySources: readExecutionValue(item, "memory", readPathArray).map((entry) => resolveModuleRelativePath(entry, moduleRoot)),
300
367
  subagentRefs,
301
368
  subagentPathRefs,
302
- langchainAgentConfig: normalizeModuleAgentConfig(readAgentConfig(item), moduleRoot),
303
- deepAgentConfig: normalizeModuleAgentConfig(readAgentConfig(item, { includeObjectBackend: true }), moduleRoot),
369
+ langchainAgentConfig: normalizeModuleAgentConfig(readAgentConfig(item, { includeDelegationControls: true }), moduleRoot),
370
+ deepAgentConfig: normalizeModuleAgentConfig(readAgentConfig(item, {
371
+ includeObjectBackend: true,
372
+ includeDelegationControls: false,
373
+ }), moduleRoot),
304
374
  sourcePath,
305
375
  };
306
376
  }
@@ -347,11 +417,12 @@ function mergeRawItemRecord(records, key, item, sourcePath) {
347
417
  return mergedRecord;
348
418
  }
349
419
  function mergeAgentRecord(records, item, sourcePath) {
350
- const id = typeof item.id === "string" ? item.id : undefined;
420
+ const normalizedItem = normalizeAgentItemForMerge(item);
421
+ const id = typeof normalizedItem.id === "string" ? normalizedItem.id : undefined;
351
422
  if (!id) {
352
423
  return null;
353
424
  }
354
- return mergeRawItemRecord(records, id, item, sourcePath);
425
+ return mergeRawItemRecord(records, id, normalizedItem, sourcePath);
355
426
  }
356
427
  function mergeWorkspaceObjectRecord(records, workspaceObject, item, sourcePath) {
357
428
  mergeRawItemRecord(records, `${workspaceObject.kind}/${workspaceObject.id}`, item, sourcePath);
@@ -1,4 +1,4 @@
1
- import type { ParsedAgentObject, RuntimeModelRefMap, WorkspaceObject } from "../../contracts/types.js";
1
+ import type { ParsedAgentObject, WorkspaceObject } from "../../contracts/types.js";
2
2
  export type RoutingRule = {
3
3
  agentId: string;
4
4
  equals?: string[];
@@ -34,7 +34,6 @@ export type ResilienceConfig = {
34
34
  export declare function getWorkspaceObject(refs: Map<string, WorkspaceObject | ParsedAgentObject>, ref: string | undefined): WorkspaceObject | undefined;
35
35
  export declare function getRuntimeDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): Record<string, unknown> | undefined;
36
36
  export declare function getRuntimeMemoryDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): Record<string, unknown> | undefined;
37
- export declare function getRuntimeModelDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): RuntimeModelRefMap | undefined;
38
37
  export declare function getRecoveryConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): RecoveryConfig;
39
38
  export declare function getConcurrencyConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): ConcurrencyConfig;
40
39
  export declare function getResilienceConfig(refs: Map<string, WorkspaceObject | ParsedAgentObject>): ResilienceConfig;
@@ -36,18 +36,6 @@ export function getRuntimeMemoryDefaults(refs) {
36
36
  }
37
37
  return runtimeMemories[0].value;
38
38
  }
39
- export function getRuntimeModelDefaults(refs) {
40
- const runtimeDefaults = getRuntimeDefaults(refs);
41
- const modelRefs = {
42
- ...(typeof runtimeDefaults?.planningModelRef === "string" && runtimeDefaults.planningModelRef.trim()
43
- ? { planning: runtimeDefaults.planningModelRef.trim() }
44
- : {}),
45
- ...(typeof runtimeDefaults?.executionModelRef === "string" && runtimeDefaults.executionModelRef.trim()
46
- ? { execution: runtimeDefaults.executionModelRef.trim() }
47
- : {}),
48
- };
49
- return Object.keys(modelRefs).length > 0 ? modelRefs : undefined;
50
- }
51
39
  export function getRecoveryConfig(refs) {
52
40
  const runtimeDefaults = getRuntimeDefaults(refs);
53
41
  const recovery = typeof runtimeDefaults?.recovery === "object" && runtimeDefaults.recovery
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.111",
3
+ "version": "0.0.112",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",