@botbotgo/agent-harness 0.0.107 → 0.0.109

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 (42) hide show
  1. package/dist/package-version.d.ts +1 -1
  2. package/dist/package-version.js +1 -1
  3. package/dist/runtime/adapter/execution-context.d.ts +34 -0
  4. package/dist/runtime/adapter/execution-context.js +52 -0
  5. package/dist/runtime/adapter/middleware-assembly.js +29 -14
  6. package/dist/runtime/adapter/runnable-config.d.ts +57 -0
  7. package/dist/runtime/adapter/runnable-config.js +64 -0
  8. package/dist/runtime/adapter/runtime-adapter-support.d.ts +0 -1
  9. package/dist/runtime/adapter/runtime-adapter-support.js +5 -8
  10. package/dist/runtime/agent-runtime-adapter.js +28 -34
  11. package/dist/runtime/harness/background-runtime.d.ts +13 -0
  12. package/dist/runtime/harness/background-runtime.js +8 -0
  13. package/dist/runtime/harness/bindings.d.ts +14 -0
  14. package/dist/runtime/harness/bindings.js +23 -0
  15. package/dist/runtime/harness/events/listener-runtime.d.ts +18 -0
  16. package/dist/runtime/harness/events/listener-runtime.js +9 -0
  17. package/dist/runtime/harness/events/runtime-event-operations.d.ts +17 -0
  18. package/dist/runtime/harness/events/runtime-event-operations.js +9 -0
  19. package/dist/runtime/harness/run/recovery.d.ts +1 -1
  20. package/dist/runtime/harness/run/resume-runtime.d.ts +55 -0
  21. package/dist/runtime/harness/run/resume-runtime.js +26 -0
  22. package/dist/runtime/harness/run/routing.d.ts +8 -0
  23. package/dist/runtime/harness/run/routing.js +21 -0
  24. package/dist/runtime/harness/run/run-operations.d.ts +47 -0
  25. package/dist/runtime/harness/run/run-operations.js +67 -0
  26. package/dist/runtime/harness/run/start-run.d.ts +82 -0
  27. package/dist/runtime/harness/run/start-run.js +88 -0
  28. package/dist/runtime/harness/run/startup-runtime.d.ts +2 -1
  29. package/dist/runtime/harness/run/startup-runtime.js +38 -3
  30. package/dist/runtime/harness/run/stream-runtime.d.ts +48 -0
  31. package/dist/runtime/harness/run/stream-runtime.js +14 -0
  32. package/dist/runtime/harness.d.ts +5 -6
  33. package/dist/runtime/harness.js +186 -299
  34. package/dist/runtime/support/compiled-binding.d.ts +14 -0
  35. package/dist/runtime/support/compiled-binding.js +14 -10
  36. package/dist/runtime/support/runtime-adapter-options.d.ts +17 -0
  37. package/dist/runtime/support/runtime-adapter-options.js +29 -0
  38. package/package.json +1 -1
  39. package/dist/runtime/adapter/deepagent-runnable-config.d.ts +0 -30
  40. package/dist/runtime/adapter/deepagent-runnable-config.js +0 -22
  41. package/dist/runtime/adapter/langchain-runnable-config.d.ts +0 -25
  42. package/dist/runtime/adapter/langchain-runnable-config.js +0 -19
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.106";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.108";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.106";
1
+ export const AGENT_HARNESS_VERSION = "0.0.108";
@@ -0,0 +1,34 @@
1
+ import type { CompiledAgentBinding, CompiledTool } from "../../contracts/types.js";
2
+ import type { ToolNameMapping } from "./tool/tool-name-mapping.js";
3
+ import { getBindingPrimaryModel } from "../support/compiled-binding.js";
4
+ export declare function buildBindingToolCatalog(input: {
5
+ binding: CompiledAgentBinding;
6
+ getToolNameMapping: (binding: CompiledAgentBinding) => ToolNameMapping;
7
+ }): {
8
+ primaryTools: CompiledTool[];
9
+ toolNameMapping: ToolNameMapping;
10
+ };
11
+ export declare function buildBindingToolExecutionContext(input: {
12
+ binding: CompiledAgentBinding;
13
+ resolveTools: (tools: CompiledTool[], binding?: CompiledAgentBinding) => unknown[];
14
+ getToolNameMapping: (binding: CompiledAgentBinding) => ToolNameMapping;
15
+ context?: Record<string, unknown>;
16
+ }): {
17
+ primaryTools: CompiledTool[];
18
+ resolvedTools: unknown[];
19
+ toolNameMapping: ToolNameMapping;
20
+ executableTools: Map<string, import("./invoke-runtime.js").ExecutableTool>;
21
+ defersToUpstreamHitlExecution: boolean;
22
+ };
23
+ export declare function resolveLangChainStreamContext(input: {
24
+ binding: CompiledAgentBinding;
25
+ resolveModel: (model: NonNullable<ReturnType<typeof getBindingPrimaryModel>>) => Promise<unknown>;
26
+ resolveTools: (tools: CompiledTool[], binding?: CompiledAgentBinding) => unknown[];
27
+ }): Promise<{
28
+ primaryTools: CompiledTool[];
29
+ forceInvokeFallback: boolean;
30
+ canUseDirectModelStream: boolean;
31
+ langChainStreamModel: {
32
+ stream?: (input: unknown) => Promise<AsyncIterable<unknown>>;
33
+ } | undefined;
34
+ }>;
@@ -0,0 +1,52 @@
1
+ import { buildExecutableToolMap } from "./tool-resolution.js";
2
+ import { getBindingLangChainParams, getBindingPrimaryModel, getBindingPrimaryTools, isLangChainBinding } from "../support/compiled-binding.js";
3
+ export function buildBindingToolCatalog(input) {
4
+ const primaryTools = getBindingPrimaryTools(input.binding);
5
+ const toolNameMapping = input.getToolNameMapping(input.binding);
6
+ return {
7
+ primaryTools,
8
+ toolNameMapping,
9
+ };
10
+ }
11
+ export function buildBindingToolExecutionContext(input) {
12
+ const { primaryTools, toolNameMapping } = buildBindingToolCatalog(input);
13
+ const resolvedTools = input.resolveTools(primaryTools, input.binding);
14
+ const executableTools = buildExecutableToolMap({
15
+ primaryTools,
16
+ resolvedTools,
17
+ toolNameMapping,
18
+ context: input.context,
19
+ });
20
+ return {
21
+ primaryTools,
22
+ resolvedTools,
23
+ toolNameMapping,
24
+ executableTools,
25
+ defersToUpstreamHitlExecution: primaryTools.some((tool) => tool.hitl?.enabled === true),
26
+ };
27
+ }
28
+ export async function resolveLangChainStreamContext(input) {
29
+ const primaryTools = getBindingPrimaryTools(input.binding);
30
+ const primaryModel = getBindingPrimaryModel(input.binding);
31
+ const forceInvokeFallback = isLangChainBinding(input.binding) &&
32
+ primaryTools.length > 0 &&
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))
37
+ : undefined;
38
+ const resolvedLangChainTools = langchainParams ? input.resolveTools(langchainParams.tools, input.binding) : [];
39
+ const canUseDirectModelStream = !!resolvedLangChainModel &&
40
+ (resolvedLangChainTools.length === 0 || typeof resolvedLangChainModel.bindTools !== "function");
41
+ const langChainStreamModel = resolvedLangChainModel && canUseDirectModelStream
42
+ ? resolvedLangChainModel
43
+ : resolvedLangChainModel && typeof resolvedLangChainModel.bindTools === "function" && resolvedLangChainTools.length > 0
44
+ ? resolvedLangChainModel.bindTools(resolvedLangChainTools)
45
+ : undefined;
46
+ return {
47
+ primaryTools,
48
+ forceInvokeFallback,
49
+ canUseDirectModelStream,
50
+ langChainStreamModel,
51
+ };
52
+ }
@@ -4,10 +4,32 @@ import { createAgent, humanInTheLoopMiddleware } from "langchain";
4
4
  import { createBuiltinMiddlewareTools } from "./tool/builtin-middleware-tools.js";
5
5
  import { compileInterruptOn } from "./tool/interrupt-policy.js";
6
6
  import { extractToolFallbackContext, extractVisibleOutput } from "../parsing/output-parsing.js";
7
- import { hasConfiguredMiddlewareKind, hasConfiguredSubagentSupport, isObject, isRecord } from "./runtime-adapter-support.js";
7
+ import { hasConfiguredMiddlewareKind, hasConfiguredSubagentSupport, isRecord } from "./runtime-adapter-support.js";
8
8
  import { resolveDeclaredMiddleware } from "./tool/declared-middleware.js";
9
9
  import { getBindingDeepAgentParams, getBindingInterruptCompatibilityRules, getBindingLangChainParams, getBindingMiddlewareConfigs, getBindingPrimaryModel, isDeepAgentBinding, isLangChainBinding, } from "../support/compiled-binding.js";
10
10
  import { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths } from "./compat/deepagent-compat.js";
11
+ function buildLangChainContextMiddleware(params) {
12
+ const middleware = [];
13
+ const hasSkills = (params.compatibleParams.skills?.length ?? 0) > 0;
14
+ const hasMemory = (params.compatibleParams.memory?.length ?? 0) > 0;
15
+ if (!hasSkills && !hasMemory) {
16
+ return middleware;
17
+ }
18
+ const backend = params.resolveFilesystemBackend(params.binding);
19
+ if (hasSkills) {
20
+ middleware.push(createSkillsMiddleware({
21
+ backend,
22
+ sources: params.compatibleParams.skills,
23
+ }));
24
+ }
25
+ if (hasMemory) {
26
+ middleware.push(createMemoryMiddleware({
27
+ backend,
28
+ sources: params.compatibleParams.memory,
29
+ }));
30
+ }
31
+ return middleware;
32
+ }
11
33
  export function resolveBuiltinMiddlewareBackend(input) {
12
34
  const runtimeState = {
13
35
  ...(input.options?.state ?? {}),
@@ -54,7 +76,7 @@ export async function invokeBuiltinTaskTool(input) {
54
76
  if (!params) {
55
77
  throw new Error(`Agent ${input.binding.agent.id} has no deepagent params`);
56
78
  }
57
- const typedInput = isObject(input.toolInput) ? input.toolInput : {};
79
+ const typedInput = isRecord(input.toolInput) ? input.toolInput : {};
58
80
  const description = typeof typedInput.description === "string" ? typedInput.description : "";
59
81
  const subagentType = typeof typedInput.subagent_type === "string" ? typedInput.subagent_type : "";
60
82
  const builtinBackend = input.resolveBuiltinMiddlewareBackend(input.binding, input.options);
@@ -134,18 +156,11 @@ export async function resolveLangChainAutomaticMiddleware(input) {
134
156
  const automaticMiddleware = [];
135
157
  automaticMiddleware.push(createPatchToolCallsMiddleware());
136
158
  automaticMiddleware.push(...(await input.resolveAutomaticSummarizationMiddleware(input.binding)));
137
- if ((compatibleParams.skills?.length ?? 0) > 0) {
138
- automaticMiddleware.push(createSkillsMiddleware({
139
- backend: input.resolveFilesystemBackend(input.binding),
140
- sources: compatibleParams.skills,
141
- }));
142
- }
143
- if ((compatibleParams.memory?.length ?? 0) > 0) {
144
- automaticMiddleware.push(createMemoryMiddleware({
145
- backend: input.resolveFilesystemBackend(input.binding),
146
- sources: compatibleParams.memory,
147
- }));
148
- }
159
+ automaticMiddleware.push(...buildLangChainContextMiddleware({
160
+ binding: input.binding,
161
+ compatibleParams,
162
+ resolveFilesystemBackend: input.resolveFilesystemBackend,
163
+ }));
149
164
  if (hasConfiguredSubagentSupport(input.binding)) {
150
165
  automaticMiddleware.push(createSubAgentMiddleware({
151
166
  defaultModel: (await input.resolveModel(compatibleParams.model)),
@@ -0,0 +1,57 @@
1
+ export type ResolvedRunnableDependencies = {
2
+ resolvedModel: unknown;
3
+ resolvedTools: unknown[];
4
+ resolvedMiddleware: unknown[];
5
+ resolvedCheckpointer: unknown;
6
+ resolvedStore: unknown;
7
+ };
8
+ type LangChainRunnableConfigParams = {
9
+ langchainParams: {
10
+ passthrough?: Record<string, unknown>;
11
+ systemPrompt?: string;
12
+ stateSchema?: unknown;
13
+ responseFormat?: unknown;
14
+ contextSchema?: unknown;
15
+ includeAgentName?: unknown;
16
+ version?: unknown;
17
+ name?: unknown;
18
+ description?: unknown;
19
+ };
20
+ resolvedModel: unknown;
21
+ resolvedTools: unknown[];
22
+ resolvedMiddleware: unknown[];
23
+ resolvedCheckpointer: unknown;
24
+ resolvedStore: unknown;
25
+ passthroughOverride?: Record<string, unknown>;
26
+ systemPromptOverride?: string;
27
+ };
28
+ type DeepAgentRunnableConfigParams = {
29
+ compatibleParams: {
30
+ passthrough?: Record<string, unknown>;
31
+ systemPrompt?: string;
32
+ responseFormat?: unknown;
33
+ contextSchema?: unknown;
34
+ name?: unknown;
35
+ memory?: unknown;
36
+ generalPurposeAgent?: unknown;
37
+ taskDescription?: unknown;
38
+ };
39
+ resolvedModel: unknown;
40
+ resolvedTools: unknown[];
41
+ resolvedMiddleware: unknown[];
42
+ resolvedSubagents: unknown[];
43
+ resolvedCheckpointer: unknown;
44
+ resolvedStore: unknown;
45
+ resolvedBackend: unknown;
46
+ resolvedInterruptOn: unknown;
47
+ resolvedSkills: string[];
48
+ };
49
+ export declare function buildResolvedRunnableConfig(params: {
50
+ passthrough?: Record<string, unknown>;
51
+ staticConfig?: Record<string, unknown>;
52
+ resolved: ResolvedRunnableDependencies;
53
+ extraConfig?: Record<string, unknown>;
54
+ }): Record<string, unknown>;
55
+ export declare function buildLangChainRunnableConfig(params: LangChainRunnableConfigParams): Record<string, unknown>;
56
+ export declare function buildDeepAgentRunnableConfig(params: DeepAgentRunnableConfigParams): Record<string, unknown>;
57
+ export {};
@@ -0,0 +1,64 @@
1
+ export function buildResolvedRunnableConfig(params) {
2
+ const { passthrough, staticConfig, resolved, extraConfig } = params;
3
+ return {
4
+ ...(passthrough ?? {}),
5
+ ...(staticConfig ?? {}),
6
+ model: resolved.resolvedModel,
7
+ tools: resolved.resolvedTools,
8
+ middleware: resolved.resolvedMiddleware,
9
+ checkpointer: resolved.resolvedCheckpointer,
10
+ store: resolved.resolvedStore,
11
+ ...(extraConfig ?? {}),
12
+ };
13
+ }
14
+ export function buildLangChainRunnableConfig(params) {
15
+ const { langchainParams, resolvedModel, resolvedTools, resolvedMiddleware, resolvedCheckpointer, resolvedStore, passthroughOverride, systemPromptOverride, } = params;
16
+ return buildResolvedRunnableConfig({
17
+ passthrough: passthroughOverride ?? langchainParams.passthrough ?? {},
18
+ staticConfig: {
19
+ systemPrompt: systemPromptOverride ?? langchainParams.systemPrompt,
20
+ stateSchema: langchainParams.stateSchema,
21
+ responseFormat: langchainParams.responseFormat,
22
+ contextSchema: langchainParams.contextSchema,
23
+ includeAgentName: langchainParams.includeAgentName,
24
+ version: langchainParams.version,
25
+ name: langchainParams.name,
26
+ description: langchainParams.description,
27
+ },
28
+ resolved: {
29
+ resolvedModel,
30
+ resolvedTools,
31
+ resolvedMiddleware,
32
+ resolvedCheckpointer,
33
+ resolvedStore,
34
+ },
35
+ });
36
+ }
37
+ export function buildDeepAgentRunnableConfig(params) {
38
+ const { compatibleParams, resolvedModel, resolvedTools, resolvedMiddleware, resolvedSubagents, resolvedCheckpointer, resolvedStore, resolvedBackend, resolvedInterruptOn, resolvedSkills, } = params;
39
+ return buildResolvedRunnableConfig({
40
+ passthrough: compatibleParams.passthrough ?? {},
41
+ staticConfig: {
42
+ systemPrompt: compatibleParams.systemPrompt,
43
+ responseFormat: compatibleParams.responseFormat,
44
+ contextSchema: compatibleParams.contextSchema,
45
+ name: compatibleParams.name,
46
+ memory: compatibleParams.memory,
47
+ skills: resolvedSkills,
48
+ generalPurposeAgent: compatibleParams.generalPurposeAgent,
49
+ taskDescription: compatibleParams.taskDescription,
50
+ },
51
+ resolved: {
52
+ resolvedModel,
53
+ resolvedTools,
54
+ resolvedMiddleware,
55
+ resolvedCheckpointer,
56
+ resolvedStore,
57
+ },
58
+ extraConfig: {
59
+ subagents: resolvedSubagents,
60
+ backend: resolvedBackend,
61
+ interruptOn: resolvedInterruptOn,
62
+ },
63
+ });
64
+ }
@@ -1,6 +1,5 @@
1
1
  import type { CompiledAgentBinding } from "../../contracts/types.js";
2
2
  export declare function countConfiguredTools(binding: CompiledAgentBinding): number;
3
- export declare function asObject(value: unknown): Record<string, unknown> | undefined;
4
3
  export declare function sleep(ms: number): Promise<void>;
5
4
  export declare function hasConfiguredSubagentSupport(binding: CompiledAgentBinding): boolean;
6
5
  export declare function hasConfiguredMiddlewareKind(binding: CompiledAgentBinding, kind: string): boolean;
@@ -1,22 +1,19 @@
1
- import { getBindingLangChainParams, getBindingMiddlewareConfigs, getBindingPrimaryTools } from "../support/compiled-binding.js";
1
+ import { getBindingExecutionView } from "../support/compiled-binding.js";
2
2
  export function countConfiguredTools(binding) {
3
- return getBindingPrimaryTools(binding).length;
4
- }
5
- export function asObject(value) {
6
- return typeof value === "object" && value ? value : undefined;
3
+ return getBindingExecutionView(binding).primaryTools.length;
7
4
  }
8
5
  export function sleep(ms) {
9
6
  return new Promise((resolve) => setTimeout(resolve, ms));
10
7
  }
11
8
  export function hasConfiguredSubagentSupport(binding) {
12
- const params = getBindingLangChainParams(binding);
9
+ const params = getBindingExecutionView(binding).langchainParams;
13
10
  if (!params) {
14
11
  return false;
15
12
  }
16
13
  return (params.subagents?.length ?? 0) > 0 || params.generalPurposeAgent === true || Boolean(params.taskDescription?.trim());
17
14
  }
18
15
  export function hasConfiguredMiddlewareKind(binding, kind) {
19
- return getBindingMiddlewareConfigs(binding)?.some((entry) => entry.kind === kind) ?? false;
16
+ return getBindingExecutionView(binding).middlewareConfigs?.some((entry) => entry.kind === kind) ?? false;
20
17
  }
21
18
  export function isRecord(value) {
22
19
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -34,7 +31,7 @@ export function truncateLines(lines, maxChars = 12_000) {
34
31
  export function summarizeBuiltinWriteTodosArgs(args) {
35
32
  const todos = Array.isArray(args.todos) ? args.todos : [];
36
33
  const items = todos.flatMap((todo) => {
37
- if (!isObject(todo)) {
34
+ if (!isRecord(todo)) {
38
35
  return [];
39
36
  }
40
37
  const content = typeof todo.content === "string" && todo.content.trim().length > 0
@@ -8,8 +8,7 @@ import { buildToolNameMapping, } from "./adapter/tool/tool-name-mapping.js";
8
8
  import { finalizeInvocationResult } from "./adapter/invocation-result.js";
9
9
  import { invokeRuntimeWithLocalTools } from "./adapter/invoke-runtime.js";
10
10
  import { streamRuntimeExecution } from "./adapter/stream-runtime.js";
11
- import { buildDeepAgentRunnableConfig } from "./adapter/deepagent-runnable-config.js";
12
- import { buildLangChainRunnableConfig } from "./adapter/langchain-runnable-config.js";
11
+ import { buildDeepAgentRunnableConfig, buildLangChainRunnableConfig } from "./adapter/runnable-config.js";
13
12
  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";
14
13
  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";
15
14
  import { computeRemainingTimeoutMs, resolveBindingTimeout, resolveStreamIdleTimeout, } from "./adapter/resilience.js";
@@ -17,12 +16,13 @@ import { createResolvedModel } from "./adapter/model/model-providers.js";
17
16
  import { buildInvocationRequest, } from "./adapter/model/invocation-request.js";
18
17
  import { compileInterruptOn } from "./adapter/tool/interrupt-policy.js";
19
18
  import { countConfiguredTools, } from "./adapter/runtime-adapter-support.js";
20
- import { buildExecutableToolMap, resolveAdapterTools } from "./adapter/tool-resolution.js";
19
+ import { resolveAdapterTools } from "./adapter/tool-resolution.js";
20
+ import { buildBindingToolCatalog, buildBindingToolExecutionContext, resolveLangChainStreamContext, } from "./adapter/execution-context.js";
21
21
  export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillSourcePaths, relativizeDeepAgentSkillSourcePaths, shouldRelaxDeepAgentDelegationPrompt, } from "./adapter/compat/deepagent-compat.js";
22
22
  export { buildAuthOmittingFetch, normalizeOpenAICompatibleInit } from "./adapter/compat/openai-compatible.js";
23
23
  export { buildToolNameMapping, createModelFacingToolNameCandidates, createModelFacingToolNameLookupCandidates, resolveModelFacingToolName, sanitizeToolNameForModel, } from "./adapter/tool/tool-name-mapping.js";
24
24
  export { computeRemainingTimeoutMs, isRetryableProviderError, resolveBindingTimeout, resolveProviderRetryPolicy, resolveStreamIdleTimeout, resolveTimeoutMs, } from "./adapter/resilience.js";
25
- import { getBindingAdapterKind, getBindingDeepAgentParams, getBindingInterruptCompatibilityRules, getBindingLangChainParams, getBindingPrimaryModel, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
25
+ import { getBindingAdapterKind, getBindingDeepAgentParams, getBindingInterruptCompatibilityRules, getBindingLangChainParams, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
26
26
  const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
27
27
  const UPSTREAM_BUILTIN_MIDDLEWARE_TOOL_NAMES = Object.freeze([
28
28
  "write_todos",
@@ -35,6 +35,12 @@ const UPSTREAM_BUILTIN_MIDDLEWARE_TOOL_NAMES = Object.freeze([
35
35
  "execute",
36
36
  "task",
37
37
  ]);
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
+ }
38
44
  export class AgentRuntimeAdapter {
39
45
  options;
40
46
  modelCache = new Map();
@@ -198,7 +204,7 @@ export class AgentRuntimeAdapter {
198
204
  }
199
205
  async createLangChainRunnable(binding, options = {}) {
200
206
  const params = getBindingLangChainParams(binding);
201
- const interruptOn = compileInterruptOn(getBindingPrimaryTools(binding), getBindingInterruptCompatibilityRules(binding));
207
+ const interruptOn = resolveBindingInterruptOn(binding);
202
208
  const model = (await this.resolveModel(params.model));
203
209
  const tools = this.resolveTools(params.tools, binding);
204
210
  if (tools.length > 0 && typeof model.bindTools !== "function") {
@@ -209,7 +215,7 @@ export class AgentRuntimeAdapter {
209
215
  resolvedModel: model,
210
216
  resolvedTools: tools,
211
217
  resolvedMiddleware: await this.resolveMiddleware(binding, interruptOn),
212
- resolvedCheckpointer: this.options.checkpointerResolver ? this.options.checkpointerResolver(binding) : new MemorySaver(),
218
+ resolvedCheckpointer: resolveBindingCheckpointer(this.options, binding),
213
219
  resolvedStore: this.options.storeResolver?.(binding),
214
220
  passthroughOverride: options.passthroughOverride,
215
221
  systemPromptOverride: options.systemPromptOverride,
@@ -236,10 +242,10 @@ export class AgentRuntimeAdapter {
236
242
  resolvedTools: this.resolveTools(compatibleParams.tools, binding),
237
243
  resolvedMiddleware: await this.resolveMiddleware(binding),
238
244
  resolvedSubagents: await this.resolveSubagents(compatibleParams.subagents, binding),
239
- resolvedCheckpointer: this.options.checkpointerResolver ? this.options.checkpointerResolver(binding) : new MemorySaver(),
245
+ resolvedCheckpointer: resolveBindingCheckpointer(this.options, binding),
240
246
  resolvedStore: this.options.storeResolver?.(binding),
241
247
  resolvedBackend: this.options.backendResolver?.(binding),
242
- resolvedInterruptOn: compileInterruptOn(getBindingPrimaryTools(binding), getBindingInterruptCompatibilityRules(binding)),
248
+ resolvedInterruptOn: resolveBindingInterruptOn(binding),
243
249
  resolvedSkills: (await materializeDeepAgentSkillSourcePaths({
244
250
  workspaceRoot: binding.harnessRuntime.workspaceRoot,
245
251
  runRoot: binding.harnessRuntime.runRoot,
@@ -282,13 +288,10 @@ export class AgentRuntimeAdapter {
282
288
  callRuntime,
283
289
  });
284
290
  };
285
- const primaryTools = getBindingPrimaryTools(binding);
286
- const resolvedTools = this.resolveTools(primaryTools, binding);
287
- const toolNameMapping = this.getToolNameMapping(binding);
288
- const executableTools = buildExecutableToolMap({
289
- primaryTools,
290
- resolvedTools,
291
- toolNameMapping,
291
+ const { primaryTools, toolNameMapping, executableTools, defersToUpstreamHitlExecution, } = buildBindingToolExecutionContext({
292
+ binding,
293
+ resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
294
+ getToolNameMapping: (currentBinding) => this.getToolNameMapping(currentBinding),
292
295
  context: options.context,
293
296
  });
294
297
  const builtinExecutableTools = await this.resolveBuiltinMiddlewareTools(binding, options);
@@ -297,7 +300,7 @@ export class AgentRuntimeAdapter {
297
300
  request,
298
301
  resumePayload,
299
302
  primaryTools,
300
- defersToUpstreamHitlExecution: primaryTools.some((tool) => tool.hitl?.enabled === true),
303
+ defersToUpstreamHitlExecution,
301
304
  toolNameMapping,
302
305
  executableTools,
303
306
  builtinExecutableTools: builtinExecutableTools,
@@ -320,24 +323,15 @@ export class AgentRuntimeAdapter {
320
323
  const invokeTimeoutMs = resolveBindingTimeout(binding);
321
324
  const streamIdleTimeoutMs = resolveStreamIdleTimeout(binding);
322
325
  const streamDeadlineAt = invokeTimeoutMs ? Date.now() + invokeTimeoutMs : undefined;
323
- const primaryTools = getBindingPrimaryTools(binding);
324
- const toolNameMapping = this.getToolNameMapping(binding);
325
- const primaryModel = getBindingPrimaryModel(binding);
326
- const forceInvokeFallback = isLangChainBinding(binding) &&
327
- primaryTools.length > 0 &&
328
- primaryModel?.provider === "openai-compatible";
329
- const langchainParams = isLangChainBinding(binding) ? getBindingLangChainParams(binding) : undefined;
330
- const resolvedLangChainModel = langchainParams
331
- ? (await this.resolveModel(langchainParams.model))
332
- : undefined;
333
- const resolvedLangChainTools = langchainParams ? this.resolveTools(langchainParams.tools, binding) : [];
334
- const canUseDirectModelStream = !!resolvedLangChainModel &&
335
- (resolvedLangChainTools.length === 0 || typeof resolvedLangChainModel.bindTools !== "function");
336
- const langChainStreamModel = resolvedLangChainModel && canUseDirectModelStream
337
- ? resolvedLangChainModel
338
- : resolvedLangChainModel && typeof resolvedLangChainModel.bindTools === "function" && resolvedLangChainTools.length > 0
339
- ? resolvedLangChainModel.bindTools(resolvedLangChainTools)
340
- : undefined;
326
+ const { primaryTools, toolNameMapping } = buildBindingToolCatalog({
327
+ binding,
328
+ getToolNameMapping: (currentBinding) => this.getToolNameMapping(currentBinding),
329
+ });
330
+ const { forceInvokeFallback, canUseDirectModelStream, langChainStreamModel, } = await resolveLangChainStreamContext({
331
+ binding,
332
+ resolveModel: (model) => this.resolveModel(model),
333
+ resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
334
+ });
341
335
  yield* streamRuntimeExecution({
342
336
  binding,
343
337
  input,
@@ -0,0 +1,13 @@
1
+ import type { HarnessEvent } from "../../contracts/types.js";
2
+ import type { RuntimePersistence } from "../../persistence/types.js";
3
+ export declare function createBackgroundEventRuntime(input: {
4
+ persistence: RuntimePersistence;
5
+ publishEvent: (event: HarnessEvent) => void;
6
+ trackBackgroundTask: (task: Promise<void>) => void;
7
+ backgroundEventTypes: ReadonlySet<HarnessEvent["eventType"]>;
8
+ }): {
9
+ persistence: RuntimePersistence;
10
+ publishEvent: (event: HarnessEvent) => void;
11
+ trackBackgroundTask: (task: Promise<void>) => void;
12
+ backgroundEventTypes: ReadonlySet<import("../../contracts/runtime.js").HarnessEventType>;
13
+ };
@@ -0,0 +1,8 @@
1
+ export function createBackgroundEventRuntime(input) {
2
+ return {
3
+ persistence: input.persistence,
4
+ publishEvent: input.publishEvent,
5
+ trackBackgroundTask: input.trackBackgroundTask,
6
+ backgroundEventTypes: input.backgroundEventTypes,
7
+ };
8
+ }
@@ -0,0 +1,14 @@
1
+ import type { CompiledTool, RuntimeAdapterOptions, WorkspaceBundle } from "../../contracts/types.js";
2
+ type Binding = WorkspaceBundle["bindings"] extends Map<any, infer T> ? T : never;
3
+ export declare function getWorkspaceBinding(workspace: WorkspaceBundle, agentId: string): Binding | undefined;
4
+ export declare function getRequiredWorkspaceBinding(workspace: WorkspaceBundle, agentId: string): Binding;
5
+ export declare function resolveWorkspaceAgentTools(input: {
6
+ workspace: WorkspaceBundle;
7
+ agentId: string;
8
+ toolResolver?: RuntimeAdapterOptions["toolResolver"];
9
+ }): Array<{
10
+ compiledTool: CompiledTool;
11
+ resolvedTool: unknown;
12
+ }>;
13
+ export declare function bindingSupportsRunningReplay(binding: Binding): boolean;
14
+ export {};
@@ -0,0 +1,23 @@
1
+ import { getBindingPrimaryTools } from "../support/compiled-binding.js";
2
+ export function getWorkspaceBinding(workspace, agentId) {
3
+ return workspace.bindings.get(agentId);
4
+ }
5
+ export function getRequiredWorkspaceBinding(workspace, agentId) {
6
+ const binding = getWorkspaceBinding(workspace, agentId);
7
+ if (!binding) {
8
+ throw new Error(`Unknown agent ${agentId}`);
9
+ }
10
+ return binding;
11
+ }
12
+ export function resolveWorkspaceAgentTools(input) {
13
+ const binding = getRequiredWorkspaceBinding(input.workspace, input.agentId);
14
+ const compiledTools = getBindingPrimaryTools(binding);
15
+ const resolvedTools = input.toolResolver ? input.toolResolver(compiledTools.map((tool) => tool.id), binding) : [];
16
+ return compiledTools.map((compiledTool, index) => ({
17
+ compiledTool,
18
+ resolvedTool: resolvedTools[index],
19
+ }));
20
+ }
21
+ export function bindingSupportsRunningReplay(binding) {
22
+ return getBindingPrimaryTools(binding).every((tool) => tool.retryable === true);
23
+ }
@@ -0,0 +1,18 @@
1
+ import type { HarnessStreamItem, RunListeners, RunResult } from "../../../contracts/types.js";
2
+ export declare function createListenerDispatchRuntime(input: {
3
+ notifyListener: <T>(listener: ((value: T) => void | Promise<void>) | undefined, value: T) => Promise<void>;
4
+ getThread: (threadId: string) => Promise<{
5
+ currentState: RunResult["state"];
6
+ latestRunId: string;
7
+ entryAgentId: string;
8
+ runs: Array<{
9
+ agentId: string;
10
+ }>;
11
+ pendingDecision?: {
12
+ approvalId?: string;
13
+ pendingActionId?: string;
14
+ };
15
+ } | null>;
16
+ }): {
17
+ dispatchRunListeners: (stream: AsyncGenerator<HarnessStreamItem>, listeners: RunListeners) => Promise<RunResult>;
18
+ };
@@ -0,0 +1,9 @@
1
+ import { dispatchRunListeners as dispatchStreamingRunListeners } from "./streaming.js";
2
+ export function createListenerDispatchRuntime(input) {
3
+ return {
4
+ dispatchRunListeners: (stream, listeners) => dispatchStreamingRunListeners(stream, listeners, {
5
+ notifyListener: (listener, value) => input.notifyListener(listener, value),
6
+ getThread: (threadId) => input.getThread(threadId),
7
+ }),
8
+ };
9
+ }
@@ -0,0 +1,17 @@
1
+ import type { HarnessEvent, MessageContent, RunResult } from "../../../contracts/types.js";
2
+ import { emitRunCreatedEvent } from "./events.js";
3
+ type EventRuntime = Parameters<typeof emitRunCreatedEvent>[0];
4
+ export declare function createRuntimeEventOperations(runtime: EventRuntime): {
5
+ emitRunCreated: (threadId: string, runId: string, payload: Record<string, unknown>) => Promise<HarnessEvent>;
6
+ setRunStateAndEmit: (threadId: string, runId: string, sequence: number, state: RunResult["state"], options: {
7
+ previousState: string | null;
8
+ checkpointRef?: string | null;
9
+ error?: string;
10
+ }) => Promise<HarnessEvent>;
11
+ requestApprovalAndEmit: (threadId: string, runId: string, input: MessageContent, interruptContent: string | undefined, checkpointRef: string, sequence: number) => Promise<{
12
+ approval: import("../../../contracts/runtime.js").InternalApprovalRecord;
13
+ event: HarnessEvent;
14
+ }>;
15
+ emitSyntheticFallback: (threadId: string, runId: string, selectedAgentId: string, error: unknown, sequence?: number) => Promise<void>;
16
+ };
17
+ export {};
@@ -0,0 +1,9 @@
1
+ import { emitRunCreatedEvent, emitSyntheticFallbackEvent, requestApprovalAndEmitEvent, setRunStateAndEmitEvent } from "./events.js";
2
+ export function createRuntimeEventOperations(runtime) {
3
+ return {
4
+ emitRunCreated: (threadId, runId, payload) => emitRunCreatedEvent(runtime, threadId, runId, payload),
5
+ setRunStateAndEmit: (threadId, runId, sequence, state, options) => setRunStateAndEmitEvent(runtime, threadId, runId, sequence, state, options),
6
+ requestApprovalAndEmit: (threadId, runId, input, interruptContent, checkpointRef, sequence) => requestApprovalAndEmitEvent(runtime, threadId, runId, input, interruptContent, checkpointRef, sequence),
7
+ emitSyntheticFallback: (threadId, runId, selectedAgentId, error, sequence) => emitSyntheticFallbackEvent(runtime, threadId, runId, selectedAgentId, error, sequence),
8
+ };
9
+ }
@@ -3,7 +3,7 @@ import type { RuntimePersistence } from "../../../persistence/types.js";
3
3
  import type { AgentRuntimeAdapter } from "../../agent-runtime-adapter.js";
4
4
  import type { ConcurrencyConfig, RecoveryConfig } from "../../../workspace/support/workspace-ref-utils.js";
5
5
  type RecoveryBinding = WorkspaceBundle["bindings"] extends Map<any, infer T> ? T : never;
6
- type StartupRecoveryContext = {
6
+ export type StartupRecoveryContext = {
7
7
  persistence: RuntimePersistence;
8
8
  workspace: WorkspaceBundle;
9
9
  runtimeAdapter: AgentRuntimeAdapter;