@botbotgo/agent-harness 0.0.108 → 0.0.110
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.
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/adapter/execution-context.d.ts +7 -0
- package/dist/runtime/adapter/execution-context.js +9 -2
- package/dist/runtime/adapter/middleware-assembly.js +2 -2
- package/dist/runtime/adapter/runnable-config.d.ts +44 -0
- package/dist/runtime/adapter/runnable-config.js +51 -0
- package/dist/runtime/adapter/runtime-adapter-support.d.ts +0 -1
- package/dist/runtime/adapter/runtime-adapter-support.js +1 -4
- package/dist/runtime/agent-runtime-adapter.d.ts +1 -0
- package/dist/runtime/agent-runtime-adapter.js +37 -20
- package/dist/runtime/harness/events/listener-runtime.d.ts +18 -0
- package/dist/runtime/harness/events/listener-runtime.js +9 -0
- package/dist/runtime/harness/events/runtime-event-operations.d.ts +17 -0
- package/dist/runtime/harness/events/runtime-event-operations.js +9 -0
- package/dist/runtime/harness/run/recovery.d.ts +1 -1
- package/dist/runtime/harness/run/recovery.js +65 -47
- package/dist/runtime/harness/run/routing.d.ts +8 -0
- package/dist/runtime/harness/run/routing.js +21 -0
- package/dist/runtime/harness/run/run-operations.d.ts +47 -0
- package/dist/runtime/harness/run/run-operations.js +108 -6
- package/dist/runtime/harness/run/start-run.d.ts +82 -0
- package/dist/runtime/harness/run/start-run.js +88 -0
- package/dist/runtime/harness/run/startup-runtime.d.ts +2 -1
- package/dist/runtime/harness/run/startup-runtime.js +38 -3
- package/dist/runtime/harness.d.ts +5 -3
- package/dist/runtime/harness.js +163 -238
- package/dist/runtime/support/runtime-adapter-options.d.ts +17 -0
- package/dist/runtime/support/runtime-adapter-options.js +29 -0
- package/dist/workspace/agent-binding-compiler.js +24 -88
- package/dist/workspace/support/agent-capabilities.js +2 -6
- package/dist/workspace/support/agent-execution-config.d.ts +18 -0
- package/dist/workspace/support/agent-execution-config.js +35 -0
- package/dist/workspace/validate.js +6 -11
- package/package.json +1 -1
- package/dist/runtime/adapter/deepagent-runnable-config.d.ts +0 -13
- package/dist/runtime/adapter/deepagent-runnable-config.js +0 -29
- package/dist/runtime/adapter/langchain-runnable-config.d.ts +0 -11
- package/dist/runtime/adapter/langchain-runnable-config.js +0 -24
package/dist/runtime/harness.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { AUTO_AGENT_ID } from "../contracts/types.js";
|
|
2
1
|
import { SqlitePersistence } from "../persistence/sqlite-store.js";
|
|
3
2
|
import { createPersistentId } from "../utils/id.js";
|
|
4
3
|
import { AgentRuntimeAdapter } from "./agent-runtime-adapter.js";
|
|
5
|
-
import { createResourceBackendResolver, createResourceToolResolver } from "../resource/resource.js";
|
|
6
4
|
import { EventBus } from "./harness/events/event-bus.js";
|
|
7
5
|
import { createBackgroundEventRuntime } from "./harness/background-runtime.js";
|
|
8
6
|
import { PolicyEngine } from "./harness/system/policy-engine.js";
|
|
9
|
-
import { getConcurrencyConfig, getRecoveryConfig, getRoutingDefaultAgentId, getRoutingRules,
|
|
7
|
+
import { getConcurrencyConfig, getRecoveryConfig, getRoutingDefaultAgentId, getRoutingRules, } from "../workspace/support/workspace-ref-utils.js";
|
|
10
8
|
import { createHarnessEvent, inferRoutingBindings, renderRuntimeFailure, } from "./support/harness-support.js";
|
|
11
9
|
import { ThreadMemorySync } from "./harness/system/thread-memory-sync.js";
|
|
12
10
|
import { FileBackedStore } from "./harness/system/store.js";
|
|
13
11
|
import { HealthMonitor, readHealthMonitorConfig, } from "./harness/system/health-monitor.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
12
|
+
import { normalizeInvocationEnvelope, normalizeRunPriority, resolveRunListeners, } from "./harness/run/helpers.js";
|
|
13
|
+
import { emitHarnessEvent, } from "./harness/events/events.js";
|
|
14
|
+
import { createRuntimeEventOperations } from "./harness/events/runtime-event-operations.js";
|
|
17
15
|
import { appendAssistantMessage as appendLifecycleAssistantMessage, finalizeCancelledRun as finalizeLifecycleCancelledRun, finalizeContinuedRun as finalizeLifecycleContinuedRun, } from "./harness/run/run-lifecycle.js";
|
|
18
|
-
import {
|
|
16
|
+
import { createListenerDispatchRuntime } from "./harness/events/listener-runtime.js";
|
|
19
17
|
import { buildResumePayload as buildHarnessResumePayload, resolveApprovalRecord as resolveHarnessApprovalRecord, } from "./harness/run/resume.js";
|
|
20
|
-
import { cancelRunOperation, resumeRun } from "./harness/run/run-operations.js";
|
|
18
|
+
import { cancelRunOperation, executeQueuedRunOperation, resumeRun } from "./harness/run/run-operations.js";
|
|
21
19
|
import { acquireRunSlot as acquireHarnessRunSlot } from "./harness/run/run-slot-acquisition.js";
|
|
22
20
|
import { dropPendingRunSlot, enqueuePendingRunSlot } from "./harness/run/run-queue.js";
|
|
23
|
-
import { getDefaultHostAgentId, resolveSelectedAgentId } from "./harness/run/routing.js";
|
|
24
|
-
import {
|
|
21
|
+
import { getDefaultHostAgentId, resolveSelectedAgentId, routeAgentId } from "./harness/run/routing.js";
|
|
22
|
+
import { resolveStoreFromConfig, } from "./harness/run/resources.js";
|
|
25
23
|
import { createToolMcpServerFromTools, serveToolsOverStdioFromHarness } from "../mcp.js";
|
|
26
|
-
import { getBindingAdapterKind
|
|
27
|
-
import {
|
|
24
|
+
import { getBindingAdapterKind } from "./support/compiled-binding.js";
|
|
25
|
+
import { bindingSupportsRunningReplay, getWorkspaceBinding, resolveWorkspaceAgentTools, } from "./harness/bindings.js";
|
|
28
26
|
import { describeWorkspaceInventory, listAgentSkills as listWorkspaceAgentSkills, } from "./harness/system/inventory.js";
|
|
29
27
|
import { createDefaultHealthSnapshot, isInventoryEnabled, isThreadMemorySyncEnabled, } from "./harness/runtime-defaults.js";
|
|
30
|
-
import {
|
|
28
|
+
import { resolveRuntimeAdapterOptions } from "./support/runtime-adapter-options.js";
|
|
29
|
+
import { initializeHarnessRuntime, reclaimExpiredClaimedRuns as reclaimHarnessExpiredClaimedRuns, recoverStartupRuns as recoverHarnessStartupRuns, isStaleRunningRun as isHarnessStaleRunningRun, } from "./harness/run/startup-runtime.js";
|
|
31
30
|
import { streamHarnessRun } from "./harness/run/stream-run.js";
|
|
31
|
+
import { defaultRequestedAgentId, prepareRunStart } from "./harness/run/start-run.js";
|
|
32
32
|
import { deleteThreadRecord, getPublicApproval, getThreadRecord, listPublicApprovals, } from "./harness/run/thread-records.js";
|
|
33
33
|
export class AgentHarnessRuntime {
|
|
34
34
|
workspace;
|
|
@@ -67,7 +67,10 @@ export class AgentHarnessRuntime {
|
|
|
67
67
|
pendingRunInsertionOrder = 0;
|
|
68
68
|
pendingRunSlots = [];
|
|
69
69
|
runtimeEventSequence = 0;
|
|
70
|
+
initialized = false;
|
|
71
|
+
closed = false;
|
|
70
72
|
backgroundEventRuntime;
|
|
73
|
+
runtimeEventOperations;
|
|
71
74
|
defaultRunRoot() {
|
|
72
75
|
return this.defaultRunRootValue;
|
|
73
76
|
}
|
|
@@ -84,6 +87,16 @@ export class AgentHarnessRuntime {
|
|
|
84
87
|
getThreadSummary: (currentThreadId) => this.getSession(currentThreadId),
|
|
85
88
|
});
|
|
86
89
|
}
|
|
90
|
+
createPrepareRunStartRuntime() {
|
|
91
|
+
return {
|
|
92
|
+
workspace: this.workspace,
|
|
93
|
+
policyEngine: this.policyEngine,
|
|
94
|
+
persistence: this.persistence,
|
|
95
|
+
resolveSelectedAgentId: (input, requestedAgentId, threadId) => this.resolveSelectedAgentId(input, requestedAgentId, threadId),
|
|
96
|
+
emitRunCreated: (threadId, runId, payload) => this.runtimeEventOperations.emitRunCreated(threadId, runId, payload),
|
|
97
|
+
acquireRunSlot: (threadId, runId, activeState, priority) => this.acquireRunSlot(threadId, runId, activeState, priority),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
87
100
|
constructor(workspace, runtimeAdapterOptions = {}) {
|
|
88
101
|
this.workspace = workspace;
|
|
89
102
|
this.runtimeAdapterOptions = runtimeAdapterOptions;
|
|
@@ -99,21 +112,16 @@ export class AgentHarnessRuntime {
|
|
|
99
112
|
? this.defaultHostBinding.harnessRuntime.runtimeMemory.store
|
|
100
113
|
: undefined;
|
|
101
114
|
this.runtimeMemoryStore = resolveStoreFromConfig(this.stores, runtimeMemoryStoreConfig, runRoot) ?? this.defaultStore;
|
|
102
|
-
this.resolvedRuntimeAdapterOptions = {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
storeResolver: runtimeAdapterOptions.storeResolver ??
|
|
113
|
-
((binding) => resolveStore(this.stores, this.defaultStore, this.defaultRunRoot(), (currentBinding) => currentBinding ? getBindingStoreConfig(currentBinding) : undefined, binding)),
|
|
114
|
-
backendResolver: runtimeAdapterOptions.backendResolver ??
|
|
115
|
-
((binding) => createResourceBackendResolver(workspace)(binding)),
|
|
116
|
-
};
|
|
115
|
+
this.resolvedRuntimeAdapterOptions = resolveRuntimeAdapterOptions({
|
|
116
|
+
workspace,
|
|
117
|
+
runtimeAdapterOptions,
|
|
118
|
+
checkpointers: this.checkpointers,
|
|
119
|
+
stores: this.stores,
|
|
120
|
+
defaultStore: this.defaultStore,
|
|
121
|
+
embeddingModels: this.embeddingModels,
|
|
122
|
+
vectorStores: this.vectorStores,
|
|
123
|
+
getDefaultRunRoot: () => this.defaultRunRoot(),
|
|
124
|
+
});
|
|
117
125
|
this.runtimeAdapter = new AgentRuntimeAdapter(this.resolvedRuntimeAdapterOptions);
|
|
118
126
|
this.backgroundEventRuntime = createBackgroundEventRuntime({
|
|
119
127
|
persistence: this.persistence,
|
|
@@ -121,6 +129,7 @@ export class AgentHarnessRuntime {
|
|
|
121
129
|
trackBackgroundTask: (task) => this.trackBackgroundTask(task),
|
|
122
130
|
backgroundEventTypes: AgentHarnessRuntime.BACKGROUND_EVENT_TYPES,
|
|
123
131
|
});
|
|
132
|
+
this.runtimeEventOperations = createRuntimeEventOperations(this.backgroundEventRuntime);
|
|
124
133
|
this.routingRules = getRoutingRules(workspace.refs);
|
|
125
134
|
this.routingDefaultAgentId = getRoutingDefaultAgentId(workspace.refs);
|
|
126
135
|
if (isThreadMemorySyncEnabled(workspace)) {
|
|
@@ -156,10 +165,18 @@ export class AgentHarnessRuntime {
|
|
|
156
165
|
this.healthMonitor?.recordLlmFailure(Date.now() - startedAt);
|
|
157
166
|
}
|
|
158
167
|
async initialize() {
|
|
168
|
+
if (this.closed) {
|
|
169
|
+
throw new Error("AgentHarnessRuntime has been closed and cannot be reinitialized");
|
|
170
|
+
}
|
|
171
|
+
if (this.initialized) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
159
174
|
await initializeHarnessRuntime({
|
|
160
175
|
persistence: this.persistence,
|
|
161
176
|
healthMonitor: this.healthMonitor,
|
|
162
177
|
});
|
|
178
|
+
await this.recoverStartupRuns();
|
|
179
|
+
this.initialized = true;
|
|
163
180
|
}
|
|
164
181
|
subscribe(listener) {
|
|
165
182
|
return this.eventBus.subscribe(listener);
|
|
@@ -236,45 +253,21 @@ export class AgentHarnessRuntime {
|
|
|
236
253
|
}, threadId);
|
|
237
254
|
}
|
|
238
255
|
async createToolMcpServer(options) {
|
|
239
|
-
const tools =
|
|
240
|
-
workspace: this.workspace,
|
|
241
|
-
agentId: options.agentId,
|
|
242
|
-
toolResolver: this.resolvedRuntimeAdapterOptions.toolResolver,
|
|
243
|
-
}).map(({ compiledTool, resolvedTool }) => ({
|
|
244
|
-
compiledTool,
|
|
245
|
-
resolvedTool,
|
|
246
|
-
sourceTool: this.workspace.tools.get(compiledTool.id),
|
|
247
|
-
}));
|
|
256
|
+
const tools = this.resolveToolMcpServerTools(options.agentId);
|
|
248
257
|
return createToolMcpServerFromTools(tools, options);
|
|
249
258
|
}
|
|
250
259
|
async serveToolsOverStdio(options) {
|
|
251
|
-
const tools =
|
|
252
|
-
workspace: this.workspace,
|
|
253
|
-
agentId: options.agentId,
|
|
254
|
-
toolResolver: this.resolvedRuntimeAdapterOptions.toolResolver,
|
|
255
|
-
}).map(({ compiledTool, resolvedTool }) => ({
|
|
256
|
-
compiledTool,
|
|
257
|
-
resolvedTool,
|
|
258
|
-
sourceTool: this.workspace.tools.get(compiledTool.id),
|
|
259
|
-
}));
|
|
260
|
+
const tools = this.resolveToolMcpServerTools(options.agentId);
|
|
260
261
|
return serveToolsOverStdioFromHarness(tools, options);
|
|
261
262
|
}
|
|
262
263
|
async routeAgent(input, options = {}) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
const defaultBinding = this.routingDefaultAgentId
|
|
272
|
-
? getWorkspaceBinding(this.workspace, this.routingDefaultAgentId)
|
|
273
|
-
: undefined;
|
|
274
|
-
if (defaultBinding) {
|
|
275
|
-
return defaultBinding.agent.id;
|
|
276
|
-
}
|
|
277
|
-
return this.getDefaultHostAgentId();
|
|
264
|
+
return routeAgentId({
|
|
265
|
+
workspace: this.workspace,
|
|
266
|
+
input,
|
|
267
|
+
routingRules: this.routingRules,
|
|
268
|
+
routingDefaultAgentId: this.routingDefaultAgentId,
|
|
269
|
+
threadId: options.threadId,
|
|
270
|
+
});
|
|
278
271
|
}
|
|
279
272
|
async emit(threadId, runId, sequence, eventType, payload, source = "runtime") {
|
|
280
273
|
return emitHarnessEvent({
|
|
@@ -290,55 +283,16 @@ export class AgentHarnessRuntime {
|
|
|
290
283
|
this.backgroundTasks.delete(task);
|
|
291
284
|
});
|
|
292
285
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
};
|
|
304
|
-
if (typeof this.persistence.bootstrapRun === "function") {
|
|
305
|
-
await this.persistence.bootstrapRun({
|
|
306
|
-
threadId,
|
|
307
|
-
agentId: binding.agent.id,
|
|
308
|
-
runId,
|
|
309
|
-
status: "running",
|
|
310
|
-
createdAt,
|
|
311
|
-
executionMode: getBindingAdapterKind(binding),
|
|
312
|
-
adapterKind: getBindingAdapterKind(binding),
|
|
313
|
-
userMessage,
|
|
314
|
-
runRequest,
|
|
315
|
-
createThread: isNewThread,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
if (isNewThread) {
|
|
320
|
-
await this.persistence.createThread({
|
|
321
|
-
threadId,
|
|
322
|
-
agentId: selectedAgentId,
|
|
323
|
-
runId,
|
|
324
|
-
status: "running",
|
|
325
|
-
createdAt,
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
await Promise.all([
|
|
329
|
-
this.persistence.appendThreadMessage(threadId, userMessage),
|
|
330
|
-
this.persistence.createRun({
|
|
331
|
-
threadId,
|
|
332
|
-
runId,
|
|
333
|
-
agentId: binding.agent.id,
|
|
334
|
-
executionMode: getBindingAdapterKind(binding),
|
|
335
|
-
adapterKind: getBindingAdapterKind(binding),
|
|
336
|
-
createdAt,
|
|
337
|
-
}),
|
|
338
|
-
this.persistence.saveRunRequest(threadId, runId, runRequest),
|
|
339
|
-
]);
|
|
340
|
-
}
|
|
341
|
-
return { threadId, runId, createdAt, isNewThread };
|
|
286
|
+
resolveToolMcpServerTools(agentId) {
|
|
287
|
+
return resolveWorkspaceAgentTools({
|
|
288
|
+
workspace: this.workspace,
|
|
289
|
+
agentId,
|
|
290
|
+
toolResolver: this.resolvedRuntimeAdapterOptions.toolResolver,
|
|
291
|
+
}).map(({ compiledTool, resolvedTool }) => ({
|
|
292
|
+
compiledTool,
|
|
293
|
+
resolvedTool,
|
|
294
|
+
sourceTool: this.workspace.tools.get(compiledTool.id),
|
|
295
|
+
}));
|
|
342
296
|
}
|
|
343
297
|
async loadPriorHistory(threadId, runId) {
|
|
344
298
|
const history = await this.persistence.listThreadMessages(threadId);
|
|
@@ -384,71 +338,33 @@ export class AgentHarnessRuntime {
|
|
|
384
338
|
return enqueuePendingRunSlot(this.pendingRunSlots, entry, this.pendingRunInsertionOrder++);
|
|
385
339
|
}
|
|
386
340
|
async executeQueuedRun(binding, input, threadId, runId, agentId, options = {}) {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
const actual = await this.invokeWithHistory(binding, input, threadId, runId, undefined, options.priorHistory, {
|
|
415
|
-
context: options.context,
|
|
416
|
-
state: options.state,
|
|
417
|
-
files: options.files,
|
|
418
|
-
});
|
|
419
|
-
const cancelledAfterInvoke = await this.getRunCancellation(runId);
|
|
420
|
-
if (cancelledAfterInvoke.requested) {
|
|
421
|
-
return this.finalizeCancelledRun(threadId, runId, previousState === "queued" ? "running" : previousState, cancelledAfterInvoke.reason);
|
|
422
|
-
}
|
|
423
|
-
const finalized = await this.finalizeContinuedRun(binding, threadId, runId, input, actual, {
|
|
424
|
-
previousState: previousState === "queued" ? "running" : previousState,
|
|
425
|
-
stateSequence: options.stateSequence ?? 103,
|
|
426
|
-
approvalSequence: options.approvalSequence ?? 104,
|
|
427
|
-
});
|
|
428
|
-
return {
|
|
429
|
-
...finalized,
|
|
430
|
-
agentId,
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
catch (error) {
|
|
434
|
-
await emitSyntheticFallbackEvent({
|
|
435
|
-
...this.backgroundEventRuntime,
|
|
436
|
-
}, threadId, runId, agentId, error, 103);
|
|
437
|
-
await this.setRunStateAndEmit(threadId, runId, 104, "failed", {
|
|
438
|
-
previousState: previousState === "queued" ? "running" : previousState,
|
|
439
|
-
error: error instanceof Error ? error.message : String(error),
|
|
440
|
-
});
|
|
441
|
-
return {
|
|
442
|
-
threadId,
|
|
443
|
-
runId,
|
|
444
|
-
agentId,
|
|
445
|
-
state: "failed",
|
|
446
|
-
output: renderRuntimeFailure(error),
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
finally {
|
|
450
|
-
await this.persistence.clearRunRequest(threadId, runId);
|
|
451
|
-
}
|
|
341
|
+
return executeQueuedRunOperation({
|
|
342
|
+
persistence: this.persistence,
|
|
343
|
+
getRunCancellation: (currentRunId) => this.getRunCancellation(currentRunId),
|
|
344
|
+
finalizeCancelledRun: (currentThreadId, currentRunId, previousRunState, reason) => this.finalizeCancelledRun(currentThreadId, currentRunId, previousRunState, reason),
|
|
345
|
+
emit: (currentThreadId, currentRunId, sequence, eventType, payload) => {
|
|
346
|
+
if (eventType === "run.dequeued") {
|
|
347
|
+
return this.emit(currentThreadId, currentRunId, sequence, eventType, {
|
|
348
|
+
...payload,
|
|
349
|
+
activeRunCount: this.activeRunSlots,
|
|
350
|
+
maxConcurrentRuns: this.concurrencyConfig.maxConcurrentRuns,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return this.emit(currentThreadId, currentRunId, sequence, eventType, payload);
|
|
354
|
+
},
|
|
355
|
+
setRunStateAndEmit: (currentThreadId, currentRunId, sequence, state, stateOptions) => this.setRunStateAndEmit(currentThreadId, currentRunId, sequence, state, stateOptions),
|
|
356
|
+
invokeWithHistory: (activeBinding, activeInput, currentThreadId, currentRunId, resumePayload, priorHistory, invokeOptions) => this.invokeWithHistory(activeBinding, activeInput, currentThreadId, currentRunId, resumePayload, priorHistory, invokeOptions),
|
|
357
|
+
finalizeContinuedRun: (activeBinding, currentThreadId, currentRunId, currentInput, actual, finalizeOptions) => this.finalizeContinuedRun(activeBinding, currentThreadId, currentRunId, currentInput, actual, finalizeOptions),
|
|
358
|
+
emitSyntheticFallback: (currentThreadId, currentRunId, currentAgentId, error) => this.runtimeEventOperations.emitSyntheticFallback(currentThreadId, currentRunId, currentAgentId, error, 103),
|
|
359
|
+
renderRuntimeFailure,
|
|
360
|
+
}, {
|
|
361
|
+
binding,
|
|
362
|
+
message: input,
|
|
363
|
+
threadId,
|
|
364
|
+
runId,
|
|
365
|
+
agentId,
|
|
366
|
+
options,
|
|
367
|
+
});
|
|
452
368
|
}
|
|
453
369
|
async finalizeContinuedRun(binding, threadId, runId, input, actual, options) {
|
|
454
370
|
return finalizeLifecycleContinuedRun({
|
|
@@ -459,14 +375,10 @@ export class AgentHarnessRuntime {
|
|
|
459
375
|
}, binding, threadId, runId, input, actual, options);
|
|
460
376
|
}
|
|
461
377
|
async setRunStateAndEmit(threadId, runId, sequence, state, options) {
|
|
462
|
-
return
|
|
463
|
-
...this.backgroundEventRuntime,
|
|
464
|
-
}, threadId, runId, sequence, state, options);
|
|
378
|
+
return this.runtimeEventOperations.setRunStateAndEmit(threadId, runId, sequence, state, options);
|
|
465
379
|
}
|
|
466
380
|
async requestApprovalAndEmit(threadId, runId, input, interruptContent, checkpointRef, sequence) {
|
|
467
|
-
return
|
|
468
|
-
...this.backgroundEventRuntime,
|
|
469
|
-
}, threadId, runId, input, interruptContent, checkpointRef, sequence);
|
|
381
|
+
return this.runtimeEventOperations.requestApprovalAndEmit(threadId, runId, input, interruptContent, checkpointRef, sequence);
|
|
470
382
|
}
|
|
471
383
|
isDecisionRun(options) {
|
|
472
384
|
return "decision" in options;
|
|
@@ -477,29 +389,6 @@ export class AgentHarnessRuntime {
|
|
|
477
389
|
}
|
|
478
390
|
await listener(value);
|
|
479
391
|
}
|
|
480
|
-
async prepareRunStart(options, invocation, runCreatedPayload) {
|
|
481
|
-
const selectedAgentId = await this.resolveSelectedAgentId(options.input, options.agentId, options.threadId);
|
|
482
|
-
const binding = getRequiredWorkspaceBinding(this.workspace, selectedAgentId);
|
|
483
|
-
const policyDecision = this.policyEngine.evaluate(binding);
|
|
484
|
-
if (!policyDecision.allowed) {
|
|
485
|
-
throw new Error(`Policy evaluation blocked agent ${selectedAgentId}: ${policyDecision.reasons.join(", ")}`);
|
|
486
|
-
}
|
|
487
|
-
const priority = normalizeRunPriority(options.priority);
|
|
488
|
-
const runRequest = buildPersistedRunRequest(options.input, invocation, priority);
|
|
489
|
-
const { threadId, runId, isNewThread } = await this.ensureThreadStarted(selectedAgentId, binding, options.input, runRequest, options.threadId);
|
|
490
|
-
return {
|
|
491
|
-
binding,
|
|
492
|
-
selectedAgentId,
|
|
493
|
-
priority,
|
|
494
|
-
threadId,
|
|
495
|
-
runId,
|
|
496
|
-
isNewThread,
|
|
497
|
-
runCreatedEventPromise: emitRunCreatedEvent({
|
|
498
|
-
...this.backgroundEventRuntime,
|
|
499
|
-
}, threadId, runId, runCreatedPayload(binding, selectedAgentId)),
|
|
500
|
-
releaseRunSlotPromise: this.acquireRunSlot(threadId, runId, "running", priority),
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
392
|
async acquireRunSlot(threadId, runId, activeState = "running", priority = 0) {
|
|
504
393
|
return acquireHarnessRunSlot({
|
|
505
394
|
persistence: this.persistence,
|
|
@@ -523,12 +412,6 @@ export class AgentHarnessRuntime {
|
|
|
523
412
|
dropPendingRunSlot(runId) {
|
|
524
413
|
return dropPendingRunSlot(this.pendingRunSlots, runId);
|
|
525
414
|
}
|
|
526
|
-
async dispatchRunListeners(stream, listeners) {
|
|
527
|
-
return dispatchStreamingRunListeners(stream, listeners, {
|
|
528
|
-
notifyListener: (listener, value) => this.notifyListener(listener, value),
|
|
529
|
-
getThread: (threadId) => this.getThread(threadId),
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
415
|
async run(options) {
|
|
533
416
|
if (this.isDecisionRun(options)) {
|
|
534
417
|
const resumeOptions = {
|
|
@@ -542,15 +425,22 @@ export class AgentHarnessRuntime {
|
|
|
542
425
|
}
|
|
543
426
|
const resolvedListeners = resolveRunListeners(options);
|
|
544
427
|
if (resolvedListeners) {
|
|
545
|
-
return
|
|
428
|
+
return createListenerDispatchRuntime({
|
|
429
|
+
notifyListener: (listener, value) => this.notifyListener(listener, value),
|
|
430
|
+
getThread: (threadId) => this.getThread(threadId),
|
|
431
|
+
}).dispatchRunListeners(this.streamEvents(options), resolvedListeners);
|
|
546
432
|
}
|
|
547
433
|
const invocation = normalizeInvocationEnvelope(options);
|
|
548
|
-
const { binding, selectedAgentId, threadId, runId, isNewThread, runCreatedEventPromise, releaseRunSlotPromise, } = await this.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
434
|
+
const { binding, selectedAgentId, threadId, runId, isNewThread, runCreatedEventPromise, releaseRunSlotPromise, } = await prepareRunStart(this.createPrepareRunStartRuntime(), {
|
|
435
|
+
options,
|
|
436
|
+
invocation,
|
|
437
|
+
runCreatedPayload: (activeBinding, activeSelectedAgentId) => ({
|
|
438
|
+
agentId: activeBinding.agent.id,
|
|
439
|
+
requestedAgentId: defaultRequestedAgentId(options.agentId),
|
|
440
|
+
selectedAgentId: activeSelectedAgentId,
|
|
441
|
+
executionMode: getBindingAdapterKind(activeBinding),
|
|
442
|
+
}),
|
|
443
|
+
});
|
|
554
444
|
await runCreatedEventPromise;
|
|
555
445
|
const releaseRunSlot = await releaseRunSlotPromise;
|
|
556
446
|
try {
|
|
@@ -585,13 +475,17 @@ export class AgentHarnessRuntime {
|
|
|
585
475
|
}
|
|
586
476
|
return;
|
|
587
477
|
}
|
|
588
|
-
const { threadId, runId, isNewThread, runCreatedEventPromise, releaseRunSlotPromise, } = await this.
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
478
|
+
const { threadId, runId, isNewThread, runCreatedEventPromise, releaseRunSlotPromise, } = await prepareRunStart(this.createPrepareRunStartRuntime(), {
|
|
479
|
+
options,
|
|
480
|
+
invocation,
|
|
481
|
+
runCreatedPayload: (_binding, activeSelectedAgentId) => ({
|
|
482
|
+
agentId: activeSelectedAgentId,
|
|
483
|
+
requestedAgentId: defaultRequestedAgentId(options.agentId),
|
|
484
|
+
selectedAgentId: activeSelectedAgentId,
|
|
485
|
+
input: options.input,
|
|
486
|
+
state: "running",
|
|
487
|
+
}),
|
|
488
|
+
});
|
|
595
489
|
yield* streamHarnessRun({
|
|
596
490
|
binding,
|
|
597
491
|
input: options.input,
|
|
@@ -602,17 +496,15 @@ export class AgentHarnessRuntime {
|
|
|
602
496
|
isNewThread,
|
|
603
497
|
runCreatedEventPromise,
|
|
604
498
|
releaseRunSlotPromise,
|
|
605
|
-
loadPriorHistory: (
|
|
606
|
-
stream: (
|
|
607
|
-
invokeWithHistory: (
|
|
608
|
-
emit: (
|
|
609
|
-
setRunStateAndEmit: (
|
|
610
|
-
requestApprovalAndEmit: (
|
|
611
|
-
appendAssistantMessage: (
|
|
612
|
-
clearRunRequest: (
|
|
613
|
-
emitSyntheticFallback: (
|
|
614
|
-
...this.backgroundEventRuntime,
|
|
615
|
-
}, currentThreadId, currentRunId, currentSelectedAgentId, error),
|
|
499
|
+
loadPriorHistory: (threadId, runId) => this.loadPriorHistory(threadId, runId),
|
|
500
|
+
stream: (binding, message, threadId, priorHistory, streamOptions) => this.runtimeAdapter.stream(binding, message, threadId, priorHistory, streamOptions),
|
|
501
|
+
invokeWithHistory: (binding, input, threadId, runId) => this.invokeWithHistory(binding, input, threadId, runId),
|
|
502
|
+
emit: (threadId, runId, sequence, eventType, payload) => this.emit(threadId, runId, sequence, eventType, payload),
|
|
503
|
+
setRunStateAndEmit: (threadId, runId, sequence, state, stateOptions) => this.setRunStateAndEmit(threadId, runId, sequence, state, stateOptions),
|
|
504
|
+
requestApprovalAndEmit: (threadId, runId, input, interruptContent, checkpointRef, sequence) => this.requestApprovalAndEmit(threadId, runId, input, interruptContent, checkpointRef, sequence),
|
|
505
|
+
appendAssistantMessage: (threadId, runId, content) => appendLifecycleAssistantMessage(this.persistence, threadId, runId, content),
|
|
506
|
+
clearRunRequest: (threadId, runId) => this.persistence.clearRunRequest(threadId, runId),
|
|
507
|
+
emitSyntheticFallback: (threadId, runId, selectedAgentId, error) => this.runtimeEventOperations.emitSyntheticFallback(threadId, runId, selectedAgentId, error),
|
|
616
508
|
});
|
|
617
509
|
}
|
|
618
510
|
async resume(options) {
|
|
@@ -665,10 +557,15 @@ export class AgentHarnessRuntime {
|
|
|
665
557
|
};
|
|
666
558
|
}
|
|
667
559
|
async close() {
|
|
560
|
+
if (this.closed) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
this.closed = true;
|
|
668
564
|
await this.healthMonitor?.stop();
|
|
669
565
|
this.unregisterThreadMemorySync();
|
|
670
566
|
await Promise.allSettled(Array.from(this.backgroundTasks));
|
|
671
567
|
await this.threadMemorySync?.close();
|
|
568
|
+
this.initialized = false;
|
|
672
569
|
}
|
|
673
570
|
async stop() {
|
|
674
571
|
await this.close();
|
|
@@ -683,10 +580,38 @@ export class AgentHarnessRuntime {
|
|
|
683
580
|
}, options);
|
|
684
581
|
}
|
|
685
582
|
async recoverStartupRuns() {
|
|
686
|
-
|
|
583
|
+
await recoverHarnessStartupRuns({
|
|
584
|
+
recoveryConfig: this.recoveryConfig,
|
|
585
|
+
persistence: this.persistence,
|
|
586
|
+
createStartupRecoveryContext: () => ({
|
|
587
|
+
persistence: this.persistence,
|
|
588
|
+
workspace: this.workspace,
|
|
589
|
+
runtimeAdapter: this.runtimeAdapter,
|
|
590
|
+
recoveryConfig: this.recoveryConfig,
|
|
591
|
+
concurrencyConfig: this.concurrencyConfig,
|
|
592
|
+
getBinding: (agentId) => getWorkspaceBinding(this.workspace, agentId),
|
|
593
|
+
acquireRunSlot: (threadId, runId, activeState, priority) => this.acquireRunSlot(threadId, runId, activeState, priority),
|
|
594
|
+
executeQueuedRun: (binding, input, threadId, runId, agentId, options) => this.executeQueuedRun(binding, input, threadId, runId, agentId, options),
|
|
595
|
+
setRunStateAndEmit: (threadId, runId, sequence, state, options) => this.setRunStateAndEmit(threadId, runId, sequence, state, options),
|
|
596
|
+
emit: (threadId, runId, sequence, eventType, payload) => this.emit(threadId, runId, sequence, eventType, payload),
|
|
597
|
+
loadRunInput: (threadId, runId) => this.loadRunInput(threadId, runId),
|
|
598
|
+
finalizeContinuedRun: (binding, threadId, runId, input, actual, options) => this.finalizeContinuedRun(binding, threadId, runId, input, actual, options),
|
|
599
|
+
supportsRunningReplay: (binding) => bindingSupportsRunningReplay(binding),
|
|
600
|
+
isStaleRunningRun: (thread, nowMs) => this.isStaleRunningRun(thread, nowMs),
|
|
601
|
+
recordLlmSuccess: (startedAt) => this.recordLlmSuccess(startedAt),
|
|
602
|
+
recordLlmFailure: (startedAt) => this.recordLlmFailure(startedAt),
|
|
603
|
+
}),
|
|
604
|
+
reclaimExpiredClaimedRuns: (nowIso) => this.reclaimExpiredClaimedRuns(nowIso),
|
|
605
|
+
});
|
|
687
606
|
}
|
|
688
|
-
async reclaimExpiredClaimedRuns(
|
|
689
|
-
|
|
607
|
+
async reclaimExpiredClaimedRuns(nowIso = new Date().toISOString()) {
|
|
608
|
+
await reclaimHarnessExpiredClaimedRuns({
|
|
609
|
+
persistence: this.persistence,
|
|
610
|
+
setRunStateAndEmit: (threadId, runId, sequence, state, options) => this.setRunStateAndEmit(threadId, runId, sequence, state, options),
|
|
611
|
+
emit: (threadId, runId, sequence, eventType, payload) => this.emit(threadId, runId, sequence, eventType, payload),
|
|
612
|
+
concurrencyConfig: this.concurrencyConfig,
|
|
613
|
+
getActiveRunSlots: () => this.activeRunSlots,
|
|
614
|
+
}, nowIso);
|
|
690
615
|
}
|
|
691
616
|
async isStaleRunningRun(thread, nowMs = Date.now()) {
|
|
692
617
|
return isHarnessStaleRunningRun({
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CompiledAgentBinding, RuntimeAdapterOptions, WorkspaceBundle } from "../../contracts/types.js";
|
|
2
|
+
import type { StoreLike } from "../harness/system/store.js";
|
|
3
|
+
export declare function createBindingStoreResolver(input: {
|
|
4
|
+
stores: Map<string, StoreLike>;
|
|
5
|
+
defaultStore: StoreLike;
|
|
6
|
+
getDefaultRunRoot: () => string;
|
|
7
|
+
}): (binding?: CompiledAgentBinding) => StoreLike;
|
|
8
|
+
export declare function resolveRuntimeAdapterOptions(input: {
|
|
9
|
+
workspace: WorkspaceBundle;
|
|
10
|
+
runtimeAdapterOptions: RuntimeAdapterOptions;
|
|
11
|
+
checkpointers: Map<string, unknown>;
|
|
12
|
+
stores: Map<string, StoreLike>;
|
|
13
|
+
defaultStore: StoreLike;
|
|
14
|
+
embeddingModels: Map<string, unknown>;
|
|
15
|
+
vectorStores: Map<string, unknown>;
|
|
16
|
+
getDefaultRunRoot: () => string;
|
|
17
|
+
}): RuntimeAdapterOptions;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createResourceBackendResolver, createResourceToolResolver } from "../../resource/resource.js";
|
|
2
|
+
import { resolveCheckpointer, resolveEmbeddingModel, resolveStore, resolveVectorStore, } from "../harness/run/resources.js";
|
|
3
|
+
import { getBindingStoreConfig } from "./compiled-binding.js";
|
|
4
|
+
export function createBindingStoreResolver(input) {
|
|
5
|
+
return (binding) => resolveStore(input.stores, input.defaultStore, input.getDefaultRunRoot(), (currentBinding) => currentBinding ? getBindingStoreConfig(currentBinding) : undefined, binding);
|
|
6
|
+
}
|
|
7
|
+
export function resolveRuntimeAdapterOptions(input) {
|
|
8
|
+
const { workspace, runtimeAdapterOptions, checkpointers, stores, defaultStore, embeddingModels, vectorStores, getDefaultRunRoot, } = input;
|
|
9
|
+
const storeResolver = runtimeAdapterOptions.storeResolver ??
|
|
10
|
+
createBindingStoreResolver({
|
|
11
|
+
stores,
|
|
12
|
+
defaultStore,
|
|
13
|
+
getDefaultRunRoot,
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
...runtimeAdapterOptions,
|
|
17
|
+
toolResolver: runtimeAdapterOptions.toolResolver ??
|
|
18
|
+
createResourceToolResolver(workspace, {
|
|
19
|
+
getStore: (binding) => binding ? storeResolver(binding) : defaultStore,
|
|
20
|
+
getEmbeddingModel: (embeddingModelRef) => resolveEmbeddingModel(workspace, embeddingModels, embeddingModelRef, runtimeAdapterOptions),
|
|
21
|
+
getVectorStore: (vectorStoreRef) => resolveVectorStore(workspace, vectorStores, vectorStoreRef, runtimeAdapterOptions),
|
|
22
|
+
}),
|
|
23
|
+
checkpointerResolver: runtimeAdapterOptions.checkpointerResolver ??
|
|
24
|
+
((binding) => resolveCheckpointer(checkpointers, binding)),
|
|
25
|
+
storeResolver,
|
|
26
|
+
backendResolver: runtimeAdapterOptions.backendResolver ??
|
|
27
|
+
((binding) => createResourceBackendResolver(workspace)(binding)),
|
|
28
|
+
};
|
|
29
|
+
}
|