@botbotgo/agent-harness 0.0.98 → 0.0.100

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 (64) hide show
  1. package/README.md +5 -4
  2. package/README.zh.md +4 -0
  3. package/dist/benchmark/upstream-runtime-ab-benchmark.d.ts +1 -1
  4. package/dist/benchmark/upstream-runtime-ab-benchmark.js +1 -2
  5. package/dist/contracts/core.d.ts +2 -2
  6. package/dist/contracts/runtime.d.ts +1 -5
  7. package/dist/package-version.d.ts +1 -1
  8. package/dist/package-version.js +1 -1
  9. package/dist/runtime/adapter/deepagent-runnable-config.d.ts +30 -0
  10. package/dist/runtime/adapter/deepagent-runnable-config.js +22 -0
  11. package/dist/runtime/adapter/index.d.ts +0 -2
  12. package/dist/runtime/adapter/index.js +0 -2
  13. package/dist/runtime/adapter/invocation-result.d.ts +13 -0
  14. package/dist/runtime/adapter/invocation-result.js +40 -0
  15. package/dist/runtime/adapter/langchain-runnable-config.d.ts +25 -0
  16. package/dist/runtime/adapter/langchain-runnable-config.js +19 -0
  17. package/dist/runtime/adapter/local-tool-invocation.d.ts +23 -0
  18. package/dist/runtime/adapter/local-tool-invocation.js +64 -0
  19. package/dist/runtime/adapter/runtime-adapter-support.d.ts +18 -0
  20. package/dist/runtime/adapter/runtime-adapter-support.js +54 -0
  21. package/dist/runtime/adapter/stream-event-projection.d.ts +19 -0
  22. package/dist/runtime/adapter/stream-event-projection.js +79 -0
  23. package/dist/runtime/adapter/stream-text-consumption.d.ts +4 -0
  24. package/dist/runtime/adapter/stream-text-consumption.js +18 -0
  25. package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +64 -0
  26. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +144 -0
  27. package/dist/runtime/adapter/tool/tool-replay.d.ts +18 -0
  28. package/dist/runtime/adapter/tool/tool-replay.js +26 -0
  29. package/dist/runtime/agent-runtime-adapter.d.ts +1 -42
  30. package/dist/runtime/agent-runtime-adapter.js +94 -1425
  31. package/dist/runtime/harness/run/helpers.js +2 -8
  32. package/dist/runtime/harness/run/routing.d.ts +1 -3
  33. package/dist/runtime/harness/run/routing.js +2 -25
  34. package/dist/runtime/harness/run/run-lifecycle.d.ts +0 -11
  35. package/dist/runtime/harness/run/run-lifecycle.js +7 -50
  36. package/dist/runtime/harness/runtime-defaults.d.ts +4 -0
  37. package/dist/runtime/harness/runtime-defaults.js +39 -0
  38. package/dist/runtime/harness/system/inventory.js +2 -1
  39. package/dist/runtime/harness/system/skill-requirements.d.ts +1 -0
  40. package/dist/runtime/harness.d.ts +3 -7
  41. package/dist/runtime/harness.js +56 -69
  42. package/dist/runtime/index.d.ts +1 -12
  43. package/dist/runtime/index.js +1 -12
  44. package/dist/runtime/support/compiled-binding.d.ts +0 -2
  45. package/dist/runtime/support/compiled-binding.js +3 -22
  46. package/dist/runtime/support/harness-support.d.ts +0 -11
  47. package/dist/runtime/support/harness-support.js +1 -44
  48. package/dist/runtime/support/index.d.ts +1 -1
  49. package/dist/runtime/support/index.js +1 -1
  50. package/dist/workspace/agent-binding-compiler.js +9 -93
  51. package/dist/workspace/index.d.ts +0 -5
  52. package/dist/workspace/index.js +0 -5
  53. package/dist/workspace/object-loader.js +4 -21
  54. package/dist/workspace/support/agent-capabilities.js +2 -2
  55. package/dist/workspace/support/workspace-ref-utils.d.ts +0 -2
  56. package/dist/workspace/support/workspace-ref-utils.js +0 -17
  57. package/dist/workspace/validate.js +1 -1
  58. package/package.json +1 -1
  59. package/dist/config/workflows/langgraph-workflows.yaml +0 -570
  60. package/dist/config/workflows/runtime-profiles.yaml +0 -94
  61. package/dist/runtime/adapter/langgraph/presets.d.ts +0 -25
  62. package/dist/runtime/adapter/langgraph/presets.js +0 -165
  63. package/dist/runtime/adapter/langgraph/profiles.d.ts +0 -6
  64. package/dist/runtime/adapter/langgraph/profiles.js +0 -206
@@ -42,17 +42,11 @@ export function normalizeRunPriority(priority) {
42
42
  return Math.trunc(priority);
43
43
  }
44
44
  export function resolveRunListeners(options) {
45
- const runtimeListeners = "runtimeListeners" in options ? options.runtimeListeners : undefined;
46
- const frontendListeners = "frontendListeners" in options ? options.frontendListeners : undefined;
47
45
  const listeners = options.listeners;
48
- if (!listeners && !runtimeListeners && !frontendListeners) {
46
+ if (!listeners) {
49
47
  return undefined;
50
48
  }
51
- return {
52
- ...(runtimeListeners ?? {}),
53
- ...(frontendListeners ?? {}),
54
- ...(listeners ?? {}),
55
- };
49
+ return listeners;
56
50
  }
57
51
  export function mergeRunResultOutput(result, streamedOutput) {
58
52
  return {
@@ -1,7 +1,5 @@
1
- import { type MessageContent, type ThreadSummary, type TranscriptMessage, type WorkspaceBundle } from "../../../contracts/types.js";
2
- export declare function heuristicHostRoute(workspace: WorkspaceBundle, input: MessageContent): string;
1
+ import { type MessageContent, type ThreadSummary, type WorkspaceBundle } from "../../../contracts/types.js";
3
2
  export declare function getDefaultHostAgentId(workspace: WorkspaceBundle, preferredHostAgentId: string): string;
4
- export declare function buildRoutingInput(input: MessageContent, history?: TranscriptMessage[]): string;
5
3
  export declare function resolveSelectedAgentId(options: {
6
4
  workspace: WorkspaceBundle;
7
5
  input: MessageContent;
@@ -1,35 +1,12 @@
1
1
  import { AUTO_AGENT_ID } from "../../../contracts/types.js";
2
- import { extractMessageText } from "../../../utils/message-content.js";
3
- import { heuristicRoute, inferRoutingBindings } from "../../support/harness-support.js";
2
+ import { inferRoutingBindings } from "../../support/harness-support.js";
4
3
  import { isRuntimeEntryBinding } from "../../support/runtime-entry.js";
5
- export function heuristicHostRoute(workspace, input) {
6
- const { primaryBinding, secondaryBinding } = inferRoutingBindings(workspace);
7
- return heuristicRoute(extractMessageText(input), primaryBinding, secondaryBinding);
8
- }
9
4
  export function getDefaultHostAgentId(workspace, preferredHostAgentId) {
10
5
  const preferredBinding = workspace.bindings.get(preferredHostAgentId);
11
6
  if (preferredBinding && isRuntimeEntryBinding(preferredBinding)) {
12
7
  return preferredBinding.agent.id;
13
8
  }
14
- return heuristicHostRoute(workspace, "");
15
- }
16
- export function buildRoutingInput(input, history = []) {
17
- const inputText = extractMessageText(input);
18
- const priorHistory = history.filter((message) => extractMessageText(message.content).trim());
19
- if (priorHistory.length === 0) {
20
- return inputText;
21
- }
22
- const recentTurns = priorHistory.slice(-6).map((message) => {
23
- const role = message.role === "assistant" ? "assistant" : "user";
24
- const compact = extractMessageText(message.content).replace(/\s+/g, " ").trim();
25
- return `${role}: ${compact.slice(0, 240)}`;
26
- });
27
- return [
28
- "Recent conversation context:",
29
- ...recentTurns,
30
- "",
31
- `Current user request: ${inputText}`,
32
- ].join("\n");
9
+ return inferRoutingBindings(workspace).primaryBinding?.agent.id ?? "agent";
33
10
  }
34
11
  export async function resolveSelectedAgentId(options) {
35
12
  const { workspace, input, requestedAgentId, threadId, preferredHostAgentId, getThreadSummary } = options;
@@ -13,22 +13,11 @@ type LifecycleRuntime<TBinding> = {
13
13
  approval: InternalApprovalRecord;
14
14
  event: HarnessEvent;
15
15
  }>;
16
- synthesizeFinalResult: (binding: TBinding, input: MessageContent, actual: RunResult) => Promise<{
17
- output: string;
18
- finalMessageText?: string;
19
- modelId: string;
20
- } | null | undefined>;
21
- reviewRunResult: (binding: TBinding, input: MessageContent, actual: RunResult) => Promise<{
22
- modelId: string;
23
- assessment: string;
24
- } | null | undefined>;
25
16
  };
26
17
  export declare function appendAssistantMessage(persistence: Pick<RuntimePersistence, "appendThreadMessage">, threadId: string, runId: string, content?: string): Promise<void>;
27
18
  export declare function checkpointRefForState(threadId: string, runId: string, state: RunResult["state"]): string | null;
28
19
  export declare function expirePendingApprovals(runtime: Pick<LifecycleRuntime<never>, "persistence" | "emit">, threadId: string, runId: string): Promise<void>;
29
20
  export declare function finalizeCancelledRun(runtime: Pick<LifecycleRuntime<never>, "persistence" | "emit" | "setRunStateAndEmit">, threadId: string, runId: string, previousState: RunResult["state"] | null, reason?: string): Promise<RunResult>;
30
- export declare function synthesizeCompletedRun<TBinding>(runtime: Pick<LifecycleRuntime<TBinding>, "synthesizeFinalResult">, binding: TBinding, input: MessageContent, actual: RunResult): Promise<RunResult>;
31
- export declare function reviewCompletedRun<TBinding>(runtime: Pick<LifecycleRuntime<TBinding>, "reviewRunResult" | "emit">, binding: TBinding, threadId: string, runId: string, input: MessageContent, actual: RunResult): Promise<void>;
32
21
  export declare function finalizeContinuedRun<TBinding>(runtime: LifecycleRuntime<TBinding>, binding: TBinding, threadId: string, runId: string, input: MessageContent, actual: RunResult, options: {
33
22
  previousState: RunResult["state"] | null;
34
23
  stateSequence: number;
@@ -45,65 +45,22 @@ export async function finalizeCancelledRun(runtime, threadId, runId, previousSta
45
45
  output: reason ? `cancelled: ${reason}` : "cancelled",
46
46
  };
47
47
  }
48
- export async function synthesizeCompletedRun(runtime, binding, input, actual) {
49
- try {
50
- const synthesized = await runtime.synthesizeFinalResult(binding, input, actual);
51
- if (!synthesized) {
52
- return actual;
53
- }
54
- return {
55
- ...actual,
56
- output: synthesized.output,
57
- finalMessageText: synthesized.finalMessageText,
58
- metadata: {
59
- ...(typeof actual.metadata === "object" && actual.metadata ? actual.metadata : {}),
60
- finalSynthesis: {
61
- modelId: synthesized.modelId,
62
- },
63
- },
64
- };
65
- }
66
- catch {
67
- return actual;
68
- }
69
- }
70
- export async function reviewCompletedRun(runtime, binding, threadId, runId, input, actual) {
71
- try {
72
- const review = await runtime.reviewRunResult(binding, input, actual);
73
- if (!review) {
74
- return;
75
- }
76
- await runtime.emit(threadId, runId, 7, "run.reviewed", {
77
- modelId: review.modelId,
78
- assessment: review.assessment,
79
- });
80
- }
81
- catch {
82
- // Review is advisory; do not fail the completed run if the review pass fails.
83
- }
84
- }
85
48
  export async function finalizeContinuedRun(runtime, binding, threadId, runId, input, actual, options) {
86
49
  let approval;
87
- const finalizedActual = actual.state === "completed"
88
- ? await synthesizeCompletedRun(runtime, binding, input, actual)
89
- : actual;
90
- await appendAssistantMessage(runtime.persistence, threadId, runId, finalizedActual.output);
50
+ await appendAssistantMessage(runtime.persistence, threadId, runId, actual.output);
91
51
  const checkpointRef = checkpointRefForState(threadId, runId, actual.state);
92
- await runtime.setRunStateAndEmit(threadId, runId, options.stateSequence, finalizedActual.state, {
52
+ await runtime.setRunStateAndEmit(threadId, runId, options.stateSequence, actual.state, {
93
53
  previousState: options.previousState,
94
54
  checkpointRef,
95
55
  });
96
- if (finalizedActual.state === "waiting_for_approval" && options.approvalSequence) {
97
- approval = (await runtime.requestApprovalAndEmit(threadId, runId, input, finalizedActual.interruptContent, checkpointRef, options.approvalSequence)).approval;
98
- }
99
- if (finalizedActual.state === "completed") {
100
- await reviewCompletedRun(runtime, binding, threadId, runId, input, finalizedActual);
56
+ if (actual.state === "waiting_for_approval" && options.approvalSequence) {
57
+ approval = (await runtime.requestApprovalAndEmit(threadId, runId, input, actual.interruptContent, checkpointRef, options.approvalSequence)).approval;
101
58
  }
102
59
  return {
103
- ...finalizedActual,
60
+ ...actual,
104
61
  threadId,
105
62
  runId,
106
- approvalId: approval?.approvalId ?? finalizedActual.approvalId,
107
- pendingActionId: approval?.pendingActionId ?? finalizedActual.pendingActionId,
63
+ approvalId: approval?.approvalId ?? actual.approvalId,
64
+ pendingActionId: approval?.pendingActionId ?? actual.pendingActionId,
108
65
  };
109
66
  }
@@ -0,0 +1,4 @@
1
+ import type { RuntimeHealthSnapshot, WorkspaceBundle } from "../../contracts/types.js";
2
+ export declare function isThreadMemorySyncEnabled(workspace: WorkspaceBundle): boolean;
3
+ export declare function isInventoryEnabled(workspace: WorkspaceBundle): boolean;
4
+ export declare function createDefaultHealthSnapshot(activeRunSlots: number, pendingRunSlots: number): RuntimeHealthSnapshot;
@@ -0,0 +1,39 @@
1
+ export function isThreadMemorySyncEnabled(workspace) {
2
+ const runtimeMemory = workspace.bindings.values().next().value?.harnessRuntime.runtimeMemory;
3
+ const syncConfig = typeof runtimeMemory?.threadMemorySync === "object" && runtimeMemory.threadMemorySync
4
+ ? runtimeMemory.threadMemorySync
5
+ : undefined;
6
+ return runtimeMemory?.enabled === true && syncConfig?.enabled === true;
7
+ }
8
+ export function isInventoryEnabled(workspace) {
9
+ const runtime = workspace.refs.get("runtime/default");
10
+ const value = runtime && "value" in runtime && typeof runtime.value === "object" && runtime.value
11
+ ? runtime.value
12
+ : undefined;
13
+ const inventory = typeof value?.inventory === "object" && value.inventory
14
+ ? value.inventory
15
+ : undefined;
16
+ return inventory?.enabled === true;
17
+ }
18
+ export function createDefaultHealthSnapshot(activeRunSlots, pendingRunSlots) {
19
+ const updatedAt = new Date().toISOString();
20
+ const healthy = { status: "healthy", updatedAt, reason: "health monitor disabled" };
21
+ return {
22
+ status: "healthy",
23
+ updatedAt,
24
+ checks: {
25
+ runtime: healthy,
26
+ llm: healthy,
27
+ persistence: healthy,
28
+ capacity: healthy,
29
+ workload: healthy,
30
+ },
31
+ symptoms: [],
32
+ stats: {
33
+ activeRunSlots,
34
+ pendingRunSlots,
35
+ pendingApprovals: 0,
36
+ stuckRuns: 0,
37
+ },
38
+ };
39
+ }
@@ -41,6 +41,7 @@ function mergeRequirementOptions(binding, options = {}) {
41
41
  return {
42
42
  ...fromBackend,
43
43
  ...options,
44
+ assessRequirements: options.assessRequirements ?? true,
44
45
  env: options.env ? { ...(fromBackend.env ?? {}), ...options.env } : fromBackend.env,
45
46
  path: options.path ?? fromBackend.path,
46
47
  };
@@ -58,7 +59,7 @@ function toSkillRecords(skillPaths, options = {}) {
58
59
  allowedTools: metadata.allowedTools,
59
60
  userInvocable: metadata.userInvocable,
60
61
  openclaw: metadata.openclaw,
61
- requirements: assessSkillRequirements(metadata, options),
62
+ ...(options.assessRequirements === false ? {} : { requirements: assessSkillRequirements(metadata, options) }),
62
63
  };
63
64
  });
64
65
  }
@@ -18,6 +18,7 @@ export type SkillRequirementAssessment = {
18
18
  openclaw?: OpenClawRequirementAssessment;
19
19
  };
20
20
  export type RequirementAssessmentOptions = {
21
+ assessRequirements?: boolean;
21
22
  env?: Record<string, string | undefined>;
22
23
  path?: string;
23
24
  availableBins?: string[];
@@ -17,10 +17,8 @@ export declare class AgentHarnessRuntime {
17
17
  private readonly vectorStores;
18
18
  private readonly defaultStore;
19
19
  private readonly runtimeMemoryStore;
20
- private readonly routingSystemPrompt?;
21
20
  private readonly routingRules;
22
21
  private readonly routingDefaultAgentId?;
23
- private readonly modelRoutingEnabled;
24
22
  private readonly threadMemorySync;
25
23
  private readonly unregisterThreadMemorySync;
26
24
  private readonly resolvedRuntimeAdapterOptions;
@@ -37,15 +35,16 @@ export declare class AgentHarnessRuntime {
37
35
  private runtimeEventSequence;
38
36
  private listHostBindings;
39
37
  private defaultRunRoot;
40
- private heuristicRoute;
41
38
  private getDefaultHostAgentId;
42
- private buildRoutingInput;
43
39
  private resolveSelectedAgentId;
44
40
  private resolveStore;
45
41
  private resolveStoreFromConfig;
46
42
  private resolveEmbeddingModel;
47
43
  private resolveVectorStore;
48
44
  constructor(workspace: WorkspaceBundle, runtimeAdapterOptions?: RuntimeAdapterOptions);
45
+ private createHealthMonitor;
46
+ private recordLlmSuccess;
47
+ private recordLlmFailure;
49
48
  initialize(): Promise<void>;
50
49
  subscribe(listener: (event: HarnessEvent) => void): () => void;
51
50
  getHealth(): Promise<RuntimeHealthSnapshot>;
@@ -97,8 +96,6 @@ export declare class AgentHarnessRuntime {
97
96
  private executeQueuedRun;
98
97
  private checkpointRefForState;
99
98
  private finalizeContinuedRun;
100
- private synthesizeCompletedRun;
101
- private reviewCompletedRun;
102
99
  private emitOutputDeltaAndCreateItem;
103
100
  private createContentBlocksItem;
104
101
  private createToolResultKey;
@@ -127,4 +124,3 @@ export declare class AgentHarnessRuntime {
127
124
  private reclaimExpiredClaimedRuns;
128
125
  private isStaleRunningRun;
129
126
  }
130
- export { AgentHarnessRuntime as AgentHarness };
@@ -6,26 +6,28 @@ import { normalizeUpstreamRuntimeEvent } from "./parsing/stream-event-parsing.js
6
6
  import { createResourceBackendResolver, createResourceToolResolver } from "../resource/resource.js";
7
7
  import { EventBus } from "./harness/events/event-bus.js";
8
8
  import { PolicyEngine } from "./harness/system/policy-engine.js";
9
- import { getConcurrencyConfig, getRecoveryConfig, getRoutingDefaultAgentId, getRoutingRules, getRoutingSystemPrompt, isModelRoutingEnabled, matchRoutingRule, } from "../workspace/support/workspace-ref-utils.js";
9
+ import { getConcurrencyConfig, getRecoveryConfig, getRoutingDefaultAgentId, getRoutingRules, matchRoutingRule, } from "../workspace/support/workspace-ref-utils.js";
10
10
  import { createHarnessEvent, inferRoutingBindings, renderRuntimeFailure, renderToolFailure, } from "./support/harness-support.js";
11
11
  import { ThreadMemorySync } from "./harness/system/thread-memory-sync.js";
12
12
  import { FileBackedStore } from "./harness/system/store.js";
13
13
  import { CheckpointMaintenanceLoop, discoverCheckpointMaintenanceTargets, readCheckpointMaintenanceConfig, } from "./checkpoint-maintenance.js";
14
14
  import { RuntimeRecordMaintenanceLoop, discoverRuntimeRecordMaintenanceTargets, readRuntimeRecordMaintenanceConfig, } from "./maintenance/runtime-record-maintenance.js";
15
15
  import { HealthMonitor } from "./harness/system/health-monitor.js";
16
+ import { readHealthMonitorConfig } from "./harness/system/health-monitor.js";
16
17
  import { extractMessageText, normalizeMessageContent } from "../utils/message-content.js";
17
18
  import { buildPersistedRunRequest, isTerminalRunState, normalizeInvocationEnvelope, normalizeRunPriority, resolveRunListeners, toPublicApprovalRecord, } from "./harness/run/helpers.js";
18
19
  import { emitHarnessEvent, emitRunCreatedEvent, emitSyntheticFallbackEvent, persistApproval, requestApprovalAndEmitEvent, setRunStateAndEmitEvent, } from "./harness/events/events.js";
19
- import { appendAssistantMessage as appendLifecycleAssistantMessage, checkpointRefForState as getCheckpointRefForRunState, expirePendingApprovals as expireLifecyclePendingApprovals, finalizeCancelledRun as finalizeLifecycleCancelledRun, finalizeContinuedRun as finalizeLifecycleContinuedRun, reviewCompletedRun as reviewLifecycleCompletedRun, synthesizeCompletedRun as synthesizeLifecycleCompletedRun, } from "./harness/run/run-lifecycle.js";
20
+ import { appendAssistantMessage as appendLifecycleAssistantMessage, checkpointRefForState as getCheckpointRefForRunState, expirePendingApprovals as expireLifecyclePendingApprovals, finalizeCancelledRun as finalizeLifecycleCancelledRun, finalizeContinuedRun as finalizeLifecycleContinuedRun, } from "./harness/run/run-lifecycle.js";
20
21
  import { createContentBlocksItem as createStreamingContentBlocksItem, createToolResultKey as createStreamingToolResultKey, dispatchRunListeners as dispatchStreamingRunListeners, emitOutputDeltaAndCreateItem as emitStreamingOutputDeltaAndCreateItem, } from "./harness/events/streaming.js";
21
22
  import { buildResumePayload as buildHarnessResumePayload, resolveApprovalRecord as resolveHarnessApprovalRecord, } from "./harness/run/resume.js";
22
23
  import { dropPendingRunSlot, enqueuePendingRunSlot, shiftNextPendingRunSlot } from "./harness/run/run-queue.js";
23
- import { buildRoutingInput, getDefaultHostAgentId, heuristicHostRoute, resolveSelectedAgentId } from "./harness/run/routing.js";
24
+ import { getDefaultHostAgentId, resolveSelectedAgentId } from "./harness/run/routing.js";
24
25
  import { resolveCheckpointer, resolveEmbeddingModel, resolveStore, resolveStoreFromConfig, resolveVectorStore, } from "./harness/run/resources.js";
25
26
  import { createToolMcpServerFromTools, serveToolsOverStdioFromHarness } from "../mcp.js";
26
27
  import { getBindingAdapterKind, getBindingPrimaryTools, getBindingStoreConfig } from "./support/compiled-binding.js";
27
28
  import { isRuntimeEntryBinding } from "./support/runtime-entry.js";
28
29
  import { describeWorkspaceInventory, listAgentSkills as listWorkspaceAgentSkills, } from "./harness/system/inventory.js";
30
+ import { createDefaultHealthSnapshot, isInventoryEnabled, isThreadMemorySyncEnabled, } from "./harness/runtime-defaults.js";
29
31
  export class AgentHarnessRuntime {
30
32
  workspace;
31
33
  runtimeAdapterOptions;
@@ -47,10 +49,8 @@ export class AgentHarnessRuntime {
47
49
  vectorStores = new Map();
48
50
  defaultStore;
49
51
  runtimeMemoryStore;
50
- routingSystemPrompt;
51
52
  routingRules;
52
53
  routingDefaultAgentId;
53
- modelRoutingEnabled;
54
54
  threadMemorySync;
55
55
  unregisterThreadMemorySync;
56
56
  resolvedRuntimeAdapterOptions;
@@ -72,15 +72,8 @@ export class AgentHarnessRuntime {
72
72
  return (this.listHostBindings()[0]?.harnessRuntime.runRoot ??
73
73
  `${this.workspace.workspaceRoot}/run-data`);
74
74
  }
75
- heuristicRoute(input) {
76
- return heuristicHostRoute(this.workspace, input);
77
- }
78
75
  getDefaultHostAgentId() {
79
- return getDefaultHostAgentId(this.workspace, AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID);
80
- }
81
- async buildRoutingInput(input, threadId) {
82
- const history = threadId ? await this.persistence.listThreadMessages(threadId) : [];
83
- return buildRoutingInput(input, history);
76
+ return getDefaultHostAgentId(this.workspace, this.routingDefaultAgentId ?? AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID);
84
77
  }
85
78
  async resolveSelectedAgentId(input, requestedAgentId, threadId) {
86
79
  return resolveSelectedAgentId({
@@ -88,7 +81,7 @@ export class AgentHarnessRuntime {
88
81
  input,
89
82
  requestedAgentId,
90
83
  threadId,
91
- preferredHostAgentId: AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
84
+ preferredHostAgentId: this.routingDefaultAgentId ?? AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
92
85
  getThreadSummary: (currentThreadId) => this.getSession(currentThreadId),
93
86
  });
94
87
  }
@@ -132,12 +125,16 @@ export class AgentHarnessRuntime {
132
125
  ((binding) => createResourceBackendResolver(workspace)(binding)),
133
126
  };
134
127
  this.runtimeAdapter = new AgentRuntimeAdapter(this.resolvedRuntimeAdapterOptions);
135
- this.routingSystemPrompt = getRoutingSystemPrompt(workspace.refs);
136
128
  this.routingRules = getRoutingRules(workspace.refs);
137
129
  this.routingDefaultAgentId = getRoutingDefaultAgentId(workspace.refs);
138
- this.modelRoutingEnabled = isModelRoutingEnabled(workspace.refs);
139
- this.threadMemorySync = new ThreadMemorySync(this.persistence, this.runtimeMemoryStore);
140
- this.unregisterThreadMemorySync = this.eventBus.registerProjection(this.threadMemorySync);
130
+ if (isThreadMemorySyncEnabled(workspace)) {
131
+ this.threadMemorySync = new ThreadMemorySync(this.persistence, this.runtimeMemoryStore);
132
+ this.unregisterThreadMemorySync = this.eventBus.registerProjection(this.threadMemorySync);
133
+ }
134
+ else {
135
+ this.threadMemorySync = null;
136
+ this.unregisterThreadMemorySync = () => { };
137
+ }
141
138
  const checkpointMaintenanceConfig = readCheckpointMaintenanceConfig(workspace);
142
139
  this.checkpointMaintenance = checkpointMaintenanceConfig
143
140
  ? new CheckpointMaintenanceLoop(discoverCheckpointMaintenanceTargets(workspace), checkpointMaintenanceConfig)
@@ -148,8 +145,12 @@ export class AgentHarnessRuntime {
148
145
  : null;
149
146
  this.recoveryConfig = getRecoveryConfig(workspace.refs);
150
147
  this.concurrencyConfig = getConcurrencyConfig(workspace.refs);
151
- this.healthMonitor = new HealthMonitor({
152
- workspace,
148
+ const healthConfig = readHealthMonitorConfig(workspace);
149
+ this.healthMonitor = healthConfig.enabled ? this.createHealthMonitor() : null;
150
+ }
151
+ createHealthMonitor() {
152
+ return new HealthMonitor({
153
+ workspace: this.workspace,
153
154
  persistence: this.persistence,
154
155
  getActiveRunSlots: () => this.activeRunSlots,
155
156
  getPendingRunSlots: () => this.pendingRunSlots.length,
@@ -160,18 +161,27 @@ export class AgentHarnessRuntime {
160
161
  },
161
162
  });
162
163
  }
164
+ recordLlmSuccess(startedAt) {
165
+ this.healthMonitor?.recordLlmSuccess(Date.now() - startedAt);
166
+ }
167
+ recordLlmFailure(startedAt) {
168
+ this.healthMonitor?.recordLlmFailure(Date.now() - startedAt);
169
+ }
163
170
  async initialize() {
164
171
  await this.persistence.initialize();
165
172
  await this.checkpointMaintenance?.start();
166
173
  await this.runtimeRecordMaintenance?.start();
167
- await this.healthMonitor.start();
174
+ await this.healthMonitor?.start();
168
175
  await this.recoverStartupRuns();
169
176
  }
170
177
  subscribe(listener) {
171
178
  return this.eventBus.subscribe(listener);
172
179
  }
173
180
  async getHealth() {
174
- return this.healthMonitor.getSnapshot();
181
+ if (this.healthMonitor) {
182
+ return this.healthMonitor.getSnapshot();
183
+ }
184
+ return createDefaultHealthSnapshot(this.activeRunSlots, this.pendingRunSlots.length);
175
185
  }
176
186
  getBinding(agentId) {
177
187
  return this.workspace.bindings.get(agentId);
@@ -256,10 +266,16 @@ export class AgentHarnessRuntime {
256
266
  return approval ? toPublicApprovalRecord(approval) : null;
257
267
  }
258
268
  listAgentSkills(agentId, options = {}) {
259
- return listWorkspaceAgentSkills(this.workspace, agentId, options);
269
+ return listWorkspaceAgentSkills(this.workspace, agentId, {
270
+ assessRequirements: isInventoryEnabled(this.workspace),
271
+ ...options,
272
+ });
260
273
  }
261
274
  describeWorkspaceInventory(options = {}) {
262
- return describeWorkspaceInventory(this.workspace, options);
275
+ return describeWorkspaceInventory(this.workspace, {
276
+ assessRequirements: isInventoryEnabled(this.workspace),
277
+ ...options,
278
+ });
263
279
  }
264
280
  async deleteThreadCheckpoints(threadId) {
265
281
  const resolver = this.resolvedRuntimeAdapterOptions.checkpointerResolver;
@@ -311,10 +327,7 @@ export class AgentHarnessRuntime {
311
327
  return serveToolsOverStdioFromHarness(tools, options);
312
328
  }
313
329
  async routeAgent(input, options = {}) {
314
- const routingHistory = options.threadId ? await this.persistence.listThreadMessages(options.threadId) : [];
315
- const routingInput = buildRoutingInput(input, routingHistory);
316
330
  const rawInput = extractMessageText(input);
317
- const { primaryBinding, secondaryBinding } = inferRoutingBindings(this.workspace);
318
331
  const configuredRule = this.routingRules.find((rule) => matchRoutingRule(rawInput, rule, options));
319
332
  if (configuredRule) {
320
333
  const configuredBinding = this.workspace.bindings.get(configuredRule.agentId);
@@ -322,25 +335,13 @@ export class AgentHarnessRuntime {
322
335
  return configuredBinding.agent.id;
323
336
  }
324
337
  }
325
- if (!this.modelRoutingEnabled) {
326
- const defaultBinding = this.routingDefaultAgentId
327
- ? this.workspace.bindings.get(this.routingDefaultAgentId)
328
- : primaryBinding;
329
- if (defaultBinding && isRuntimeEntryBinding(defaultBinding)) {
330
- return defaultBinding.agent.id;
331
- }
332
- }
333
- if (!primaryBinding || !secondaryBinding) {
334
- return heuristicHostRoute(this.workspace, rawInput);
335
- }
336
- try {
337
- return await this.runtimeAdapter.route(routingInput, primaryBinding, secondaryBinding, {
338
- systemPrompt: this.routingSystemPrompt,
339
- });
340
- }
341
- catch {
342
- return heuristicHostRoute(this.workspace, rawInput);
338
+ const defaultBinding = this.routingDefaultAgentId
339
+ ? this.workspace.bindings.get(this.routingDefaultAgentId)
340
+ : undefined;
341
+ if (defaultBinding && isRuntimeEntryBinding(defaultBinding)) {
342
+ return defaultBinding.agent.id;
343
343
  }
344
+ return this.getDefaultHostAgentId();
344
345
  }
345
346
  async emit(threadId, runId, sequence, eventType, payload, source = "runtime") {
346
347
  return emitHarnessEvent({
@@ -443,11 +444,11 @@ export class AgentHarnessRuntime {
443
444
  const startedAt = Date.now();
444
445
  try {
445
446
  const result = await this.runtimeAdapter.invoke(binding, input, threadId, runId, resumePayload, history, options);
446
- this.healthMonitor.recordLlmSuccess(Date.now() - startedAt);
447
+ this.recordLlmSuccess(startedAt);
447
448
  return result;
448
449
  }
449
450
  catch (error) {
450
- this.healthMonitor.recordLlmFailure(Date.now() - startedAt);
451
+ this.recordLlmFailure(startedAt);
451
452
  throw error;
452
453
  }
453
454
  }
@@ -532,21 +533,8 @@ export class AgentHarnessRuntime {
532
533
  emit: (currentThreadId, currentRunId, sequence, eventType, payload, source) => this.emit(currentThreadId, currentRunId, sequence, eventType, payload, source),
533
534
  setRunStateAndEmit: (currentThreadId, currentRunId, sequence, state, lifecycleOptions) => this.setRunStateAndEmit(currentThreadId, currentRunId, sequence, state, lifecycleOptions),
534
535
  requestApprovalAndEmit: (currentThreadId, currentRunId, lifecycleInput, interruptContent, checkpointRef, sequence) => this.requestApprovalAndEmit(currentThreadId, currentRunId, lifecycleInput, interruptContent, checkpointRef, sequence),
535
- synthesizeFinalResult: (currentBinding, lifecycleInput, lifecycleActual) => this.runtimeAdapter.synthesizeFinalResult(currentBinding, lifecycleInput, lifecycleActual),
536
- reviewRunResult: (currentBinding, lifecycleInput, lifecycleActual) => this.runtimeAdapter.reviewRunResult(currentBinding, lifecycleInput, lifecycleActual),
537
536
  }, binding, threadId, runId, input, actual, options);
538
537
  }
539
- async synthesizeCompletedRun(binding, input, actual) {
540
- return synthesizeLifecycleCompletedRun({
541
- synthesizeFinalResult: (currentBinding, lifecycleInput, lifecycleActual) => this.runtimeAdapter.synthesizeFinalResult(currentBinding, lifecycleInput, lifecycleActual),
542
- }, binding, input, actual);
543
- }
544
- async reviewCompletedRun(binding, threadId, runId, input, actual) {
545
- return reviewLifecycleCompletedRun({
546
- reviewRunResult: (currentBinding, lifecycleInput, lifecycleActual) => this.runtimeAdapter.reviewRunResult(currentBinding, lifecycleInput, lifecycleActual),
547
- emit: (currentThreadId, currentRunId, sequence, eventType, payload, source) => this.emit(currentThreadId, currentRunId, sequence, eventType, payload, source),
548
- }, binding, threadId, runId, input, actual);
549
- }
550
538
  async emitOutputDeltaAndCreateItem(threadId, runId, agentId, content) {
551
539
  return emitStreamingOutputDeltaAndCreateItem((currentThreadId, currentRunId, sequence, eventType, payload) => this.emit(currentThreadId, currentRunId, sequence, eventType, payload), threadId, runId, agentId, content);
552
540
  }
@@ -793,7 +781,7 @@ export class AgentHarnessRuntime {
793
781
  input: options.input,
794
782
  requestedAgentId: options.agentId,
795
783
  threadId: options.threadId,
796
- preferredHostAgentId: AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
784
+ preferredHostAgentId: this.routingDefaultAgentId ?? AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
797
785
  getThreadSummary: (threadId) => this.getSession(threadId),
798
786
  });
799
787
  const binding = this.workspace.bindings.get(selectedAgentId);
@@ -838,7 +826,7 @@ export class AgentHarnessRuntime {
838
826
  input: options.input,
839
827
  requestedAgentId: options.agentId,
840
828
  threadId: options.threadId,
841
- preferredHostAgentId: AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
829
+ preferredHostAgentId: this.routingDefaultAgentId ?? AgentHarnessRuntime.DEFAULT_HOST_AGENT_ID,
842
830
  getThreadSummary: (threadId) => this.getSession(threadId),
843
831
  });
844
832
  const binding = this.workspace.bindings.get(selectedAgentId);
@@ -1178,7 +1166,7 @@ export class AgentHarnessRuntime {
1178
1166
  const startedAt = Date.now();
1179
1167
  try {
1180
1168
  const actual = await this.runtimeAdapter.invoke(binding, "", threadId, runId, resumePayload, priorHistory);
1181
- this.healthMonitor.recordLlmSuccess(Date.now() - startedAt);
1169
+ this.recordLlmSuccess(startedAt);
1182
1170
  const cancelledAfterInvoke = await this.getRunCancellation(runId);
1183
1171
  if (cancelledAfterInvoke.requested) {
1184
1172
  return this.finalizeCancelledRun(threadId, runId, "resuming", cancelledAfterInvoke.reason);
@@ -1196,7 +1184,7 @@ export class AgentHarnessRuntime {
1196
1184
  };
1197
1185
  }
1198
1186
  catch (error) {
1199
- this.healthMonitor.recordLlmFailure(Date.now() - startedAt);
1187
+ this.recordLlmFailure(startedAt);
1200
1188
  throw error;
1201
1189
  }
1202
1190
  }
@@ -1233,12 +1221,12 @@ export class AgentHarnessRuntime {
1233
1221
  };
1234
1222
  }
1235
1223
  async close() {
1236
- await this.healthMonitor.stop();
1224
+ await this.healthMonitor?.stop();
1237
1225
  await this.checkpointMaintenance?.stop();
1238
1226
  await this.runtimeRecordMaintenance?.stop();
1239
1227
  this.unregisterThreadMemorySync();
1240
1228
  await Promise.allSettled(Array.from(this.backgroundTasks));
1241
- await this.threadMemorySync.close();
1229
+ await this.threadMemorySync?.close();
1242
1230
  }
1243
1231
  async stop() {
1244
1232
  await this.close();
@@ -1391,7 +1379,7 @@ export class AgentHarnessRuntime {
1391
1379
  const startedAt = Date.now();
1392
1380
  try {
1393
1381
  const actual = await this.runtimeAdapter.invoke(binding, "", thread.threadId, thread.latestRunId, recoveryIntent.resumePayload, priorHistory);
1394
- this.healthMonitor.recordLlmSuccess(Date.now() - startedAt);
1382
+ this.recordLlmSuccess(startedAt);
1395
1383
  await this.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
1396
1384
  await this.finalizeContinuedRun(binding, thread.threadId, thread.latestRunId, runInput, actual, {
1397
1385
  previousState: "resuming",
@@ -1400,7 +1388,7 @@ export class AgentHarnessRuntime {
1400
1388
  });
1401
1389
  }
1402
1390
  catch (error) {
1403
- this.healthMonitor.recordLlmFailure(Date.now() - startedAt);
1391
+ this.recordLlmFailure(startedAt);
1404
1392
  if (recoveryIntent.attempts + 1 >= this.recoveryConfig.maxRecoveryAttempts) {
1405
1393
  await this.persistence.setRunState(thread.threadId, thread.latestRunId, "failed", recoveryIntent.checkpointRef);
1406
1394
  await this.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
@@ -1459,4 +1447,3 @@ export class AgentHarnessRuntime {
1459
1447
  return nowMs - heartbeatAtMs >= this.concurrencyConfig.heartbeatTimeoutMs;
1460
1448
  }
1461
1449
  }
1462
- export { AgentHarnessRuntime as AgentHarness };
@@ -1,15 +1,4 @@
1
- export { AgentRuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX } from "./agent-runtime-adapter.js";
2
1
  export { EventBus } from "./harness/events/event-bus.js";
3
2
  export { createRuntimeEventSink, RuntimeEventSinkImpl } from "./harness/events/event-sink.js";
4
- export { FileCheckpointSaver } from "./file-checkpoint-saver.js";
5
- export { CheckpointMaintenanceLoop, discoverCheckpointMaintenanceTargets, maintainSqliteCheckpoints, readCheckpointMaintenanceConfig, } from "./checkpoint-maintenance.js";
6
- export { ManagedSqliteSaver } from "./sqlite-maintained-checkpoint-saver.js";
7
- export { AgentHarnessRuntime, AgentHarness } from "./harness.js";
8
- export { describeWorkspaceInventory, findAgentBinding, listAgentSkills, listAgentTools, listAvailableAgents, listSpecialists, } from "./harness/system/inventory.js";
9
- export { assessOpenClawRequirements, assessSkillRequirements, } from "./harness/system/skill-requirements.js";
10
- export * from "./parsing/index.js";
11
- export { PolicyEngine } from "./harness/system/policy-engine.js";
12
- export { createInMemoryStore, FileBackedStore } from "./harness/system/store.js";
13
- export * from "./support/index.js";
14
- export { ThreadMemorySync } from "./harness/system/thread-memory-sync.js";
3
+ export { AgentHarnessRuntime } from "./harness.js";
15
4
  export type { HarnessEventListener, HarnessEventProjection, RuntimeEventSink } from "../contracts/types.js";
@@ -1,14 +1,3 @@
1
- export { AgentRuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX } from "./agent-runtime-adapter.js";
2
1
  export { EventBus } from "./harness/events/event-bus.js";
3
2
  export { createRuntimeEventSink, RuntimeEventSinkImpl } from "./harness/events/event-sink.js";
4
- export { FileCheckpointSaver } from "./file-checkpoint-saver.js";
5
- export { CheckpointMaintenanceLoop, discoverCheckpointMaintenanceTargets, maintainSqliteCheckpoints, readCheckpointMaintenanceConfig, } from "./checkpoint-maintenance.js";
6
- export { ManagedSqliteSaver } from "./sqlite-maintained-checkpoint-saver.js";
7
- export { AgentHarnessRuntime, AgentHarness } from "./harness.js";
8
- export { describeWorkspaceInventory, findAgentBinding, listAgentSkills, listAgentTools, listAvailableAgents, listSpecialists, } from "./harness/system/inventory.js";
9
- export { assessOpenClawRequirements, assessSkillRequirements, } from "./harness/system/skill-requirements.js";
10
- export * from "./parsing/index.js";
11
- export { PolicyEngine } from "./harness/system/policy-engine.js";
12
- export { createInMemoryStore, FileBackedStore } from "./harness/system/store.js";
13
- export * from "./support/index.js";
14
- export { ThreadMemorySync } from "./harness/system/thread-memory-sync.js";
3
+ export { AgentHarnessRuntime } from "./harness.js";
@@ -1,8 +1,6 @@
1
1
  import type { CompiledAgentBinding, CompiledModel, CompiledTool, DeepAgentParams, LangChainAgentParams, RuntimeModelSlot } from "../../contracts/types.js";
2
2
  export declare function getBindingAdapterKind(binding: CompiledAgentBinding): string;
3
3
  export declare function getBindingAdapterConfig(binding: CompiledAgentBinding): Record<string, unknown>;
4
- export declare function getBindingLangGraphWorkflow(binding: CompiledAgentBinding): Record<string, unknown> | undefined;
5
- export declare function getBindingLangGraphPreset(binding: CompiledAgentBinding): string | undefined;
6
4
  export declare function getBindingLangChainParams(binding: CompiledAgentBinding): LangChainAgentParams | undefined;
7
5
  export declare function getBindingDeepAgentParams(binding: CompiledAgentBinding): DeepAgentParams | undefined;
8
6
  export declare function isLangChainBinding(binding: CompiledAgentBinding): boolean;