@botbotgo/agent-harness 0.0.102 → 0.0.104
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/middleware-assembly.d.ts +75 -0
- package/dist/runtime/adapter/middleware-assembly.js +175 -0
- package/dist/runtime/adapter/runtime-shell.d.ts +27 -0
- package/dist/runtime/adapter/runtime-shell.js +168 -0
- package/dist/runtime/adapter/tool-resolution.d.ts +14 -0
- package/dist/runtime/adapter/tool-resolution.js +57 -0
- package/dist/runtime/agent-runtime-adapter.d.ts +1 -6
- package/dist/runtime/agent-runtime-adapter.js +76 -356
- package/dist/runtime/harness/run/startup-runtime.d.ts +32 -0
- package/dist/runtime/harness/run/startup-runtime.js +23 -0
- package/dist/runtime/harness/run/thread-records.d.ts +21 -0
- package/dist/runtime/harness/run/thread-records.js +59 -0
- package/dist/runtime/harness.d.ts +0 -2
- package/dist/runtime/harness.js +32 -130
- package/package.json +1 -1
|
@@ -22,8 +22,6 @@ export declare class AgentHarnessRuntime {
|
|
|
22
22
|
private readonly threadMemorySync;
|
|
23
23
|
private readonly unregisterThreadMemorySync;
|
|
24
24
|
private readonly resolvedRuntimeAdapterOptions;
|
|
25
|
-
private readonly checkpointMaintenance;
|
|
26
|
-
private readonly runtimeRecordMaintenance;
|
|
27
25
|
private readonly healthMonitor;
|
|
28
26
|
private readonly recoveryConfig;
|
|
29
27
|
private readonly concurrencyConfig;
|
package/dist/runtime/harness.js
CHANGED
|
@@ -9,12 +9,9 @@ import { getConcurrencyConfig, getRecoveryConfig, getRoutingDefaultAgentId, getR
|
|
|
9
9
|
import { createHarnessEvent, inferRoutingBindings, renderRuntimeFailure, } from "./support/harness-support.js";
|
|
10
10
|
import { ThreadMemorySync } from "./harness/system/thread-memory-sync.js";
|
|
11
11
|
import { FileBackedStore } from "./harness/system/store.js";
|
|
12
|
-
import {
|
|
13
|
-
import { RuntimeRecordMaintenanceLoop, discoverRuntimeRecordMaintenanceTargets, readRuntimeRecordMaintenanceConfig, } from "./maintenance/runtime-record-maintenance.js";
|
|
14
|
-
import { HealthMonitor } from "./harness/system/health-monitor.js";
|
|
15
|
-
import { readHealthMonitorConfig } from "./harness/system/health-monitor.js";
|
|
12
|
+
import { HealthMonitor, readHealthMonitorConfig, } from "./harness/system/health-monitor.js";
|
|
16
13
|
import { extractMessageText, normalizeMessageContent } from "../utils/message-content.js";
|
|
17
|
-
import { buildPersistedRunRequest,
|
|
14
|
+
import { buildPersistedRunRequest, normalizeInvocationEnvelope, normalizeRunPriority, resolveRunListeners, } from "./harness/run/helpers.js";
|
|
18
15
|
import { emitHarnessEvent, emitRunCreatedEvent, emitSyntheticFallbackEvent, requestApprovalAndEmitEvent, setRunStateAndEmitEvent, } from "./harness/events/events.js";
|
|
19
16
|
import { appendAssistantMessage as appendLifecycleAssistantMessage, finalizeCancelledRun as finalizeLifecycleCancelledRun, finalizeContinuedRun as finalizeLifecycleContinuedRun, } from "./harness/run/run-lifecycle.js";
|
|
20
17
|
import { dispatchRunListeners as dispatchStreamingRunListeners, } from "./harness/events/streaming.js";
|
|
@@ -29,8 +26,9 @@ import { getBindingAdapterKind, getBindingPrimaryTools, getBindingStoreConfig }
|
|
|
29
26
|
import { isRuntimeEntryBinding } from "./support/runtime-entry.js";
|
|
30
27
|
import { describeWorkspaceInventory, listAgentSkills as listWorkspaceAgentSkills, } from "./harness/system/inventory.js";
|
|
31
28
|
import { createDefaultHealthSnapshot, isInventoryEnabled, isThreadMemorySyncEnabled, } from "./harness/runtime-defaults.js";
|
|
32
|
-
import {
|
|
29
|
+
import { initializeHarnessRuntime, isStaleRunningRun as isHarnessStaleRunningRun, } from "./harness/run/startup-runtime.js";
|
|
33
30
|
import { streamHarnessRun } from "./harness/run/stream-run.js";
|
|
31
|
+
import { deleteThreadRecord, getPublicApproval, getThreadRecord, listPublicApprovals, } from "./harness/run/thread-records.js";
|
|
34
32
|
export class AgentHarnessRuntime {
|
|
35
33
|
workspace;
|
|
36
34
|
runtimeAdapterOptions;
|
|
@@ -57,8 +55,6 @@ export class AgentHarnessRuntime {
|
|
|
57
55
|
threadMemorySync;
|
|
58
56
|
unregisterThreadMemorySync;
|
|
59
57
|
resolvedRuntimeAdapterOptions;
|
|
60
|
-
checkpointMaintenance;
|
|
61
|
-
runtimeRecordMaintenance;
|
|
62
58
|
healthMonitor;
|
|
63
59
|
recoveryConfig;
|
|
64
60
|
concurrencyConfig;
|
|
@@ -126,14 +122,6 @@ export class AgentHarnessRuntime {
|
|
|
126
122
|
this.threadMemorySync = null;
|
|
127
123
|
this.unregisterThreadMemorySync = () => { };
|
|
128
124
|
}
|
|
129
|
-
const checkpointMaintenanceConfig = readCheckpointMaintenanceConfig(workspace);
|
|
130
|
-
this.checkpointMaintenance = checkpointMaintenanceConfig
|
|
131
|
-
? new CheckpointMaintenanceLoop(discoverCheckpointMaintenanceTargets(workspace), checkpointMaintenanceConfig)
|
|
132
|
-
: null;
|
|
133
|
-
const runtimeRecordMaintenanceConfig = readRuntimeRecordMaintenanceConfig(workspace);
|
|
134
|
-
this.runtimeRecordMaintenance = runtimeRecordMaintenanceConfig
|
|
135
|
-
? new RuntimeRecordMaintenanceLoop(discoverRuntimeRecordMaintenanceTargets(workspace), runtimeRecordMaintenanceConfig)
|
|
136
|
-
: null;
|
|
137
125
|
this.recoveryConfig = getRecoveryConfig(workspace.refs);
|
|
138
126
|
this.concurrencyConfig = getConcurrencyConfig(workspace.refs);
|
|
139
127
|
const healthConfig = readHealthMonitorConfig(workspace);
|
|
@@ -145,8 +133,8 @@ export class AgentHarnessRuntime {
|
|
|
145
133
|
persistence: this.persistence,
|
|
146
134
|
getActiveRunSlots: () => this.activeRunSlots,
|
|
147
135
|
getPendingRunSlots: () => this.pendingRunSlots.length,
|
|
148
|
-
getCheckpointMaintenanceStatus: () =>
|
|
149
|
-
getRuntimeRecordMaintenanceStatus: () =>
|
|
136
|
+
getCheckpointMaintenanceStatus: () => null,
|
|
137
|
+
getRuntimeRecordMaintenanceStatus: () => null,
|
|
150
138
|
publishEvent: async (payload) => {
|
|
151
139
|
this.eventBus.publish(createHarnessEvent("__runtime__", "__runtime__", ++this.runtimeEventSequence, "runtime.health.changed", payload));
|
|
152
140
|
},
|
|
@@ -159,11 +147,10 @@ export class AgentHarnessRuntime {
|
|
|
159
147
|
this.healthMonitor?.recordLlmFailure(Date.now() - startedAt);
|
|
160
148
|
}
|
|
161
149
|
async initialize() {
|
|
162
|
-
await
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
await this.recoverStartupRuns();
|
|
150
|
+
await initializeHarnessRuntime({
|
|
151
|
+
persistence: this.persistence,
|
|
152
|
+
healthMonitor: this.healthMonitor,
|
|
153
|
+
});
|
|
167
154
|
}
|
|
168
155
|
subscribe(listener) {
|
|
169
156
|
return this.eventBus.subscribe(listener);
|
|
@@ -204,47 +191,20 @@ export class AgentHarnessRuntime {
|
|
|
204
191
|
return this.persistence.getSession(threadId);
|
|
205
192
|
}
|
|
206
193
|
async getThread(threadId) {
|
|
207
|
-
|
|
208
|
-
this.
|
|
209
|
-
this.
|
|
210
|
-
|
|
211
|
-
this.persistence.listThreadRuns(threadId),
|
|
212
|
-
]);
|
|
213
|
-
if (!threadSummary || !meta) {
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
const latestRunId = threadSummary.latestRunId;
|
|
217
|
-
const latestApprovals = await this.persistence.getRunApprovals(threadId, latestRunId);
|
|
218
|
-
const pendingApproval = latestApprovals
|
|
219
|
-
.filter((approval) => approval.status === "pending")
|
|
220
|
-
.sort((left, right) => right.requestedAt.localeCompare(left.requestedAt))[0];
|
|
221
|
-
return {
|
|
222
|
-
threadId,
|
|
223
|
-
entryAgentId: meta.entryAgentId,
|
|
224
|
-
currentState: threadSummary.status,
|
|
225
|
-
latestRunId,
|
|
226
|
-
createdAt: meta.createdAt,
|
|
227
|
-
updatedAt: threadSummary.updatedAt,
|
|
228
|
-
messages,
|
|
229
|
-
runs,
|
|
230
|
-
pendingDecision: pendingApproval
|
|
231
|
-
? {
|
|
232
|
-
approvalId: pendingApproval.approvalId,
|
|
233
|
-
pendingActionId: pendingApproval.pendingActionId,
|
|
234
|
-
toolName: pendingApproval.toolName,
|
|
235
|
-
allowedDecisions: pendingApproval.allowedDecisions,
|
|
236
|
-
requestedAt: pendingApproval.requestedAt,
|
|
237
|
-
}
|
|
238
|
-
: undefined,
|
|
239
|
-
};
|
|
194
|
+
return getThreadRecord({
|
|
195
|
+
persistence: this.persistence,
|
|
196
|
+
getSession: (currentThreadId) => this.getSession(currentThreadId),
|
|
197
|
+
}, threadId);
|
|
240
198
|
}
|
|
241
199
|
async listApprovals(filter) {
|
|
242
|
-
|
|
243
|
-
|
|
200
|
+
return listPublicApprovals({
|
|
201
|
+
persistence: this.persistence,
|
|
202
|
+
}, filter);
|
|
244
203
|
}
|
|
245
204
|
async getApproval(approvalId) {
|
|
246
|
-
|
|
247
|
-
|
|
205
|
+
return getPublicApproval({
|
|
206
|
+
persistence: this.persistence,
|
|
207
|
+
}, approvalId);
|
|
248
208
|
}
|
|
249
209
|
listAgentSkills(agentId, options = {}) {
|
|
250
210
|
return listWorkspaceAgentSkills(this.workspace, agentId, {
|
|
@@ -277,19 +237,11 @@ export class AgentHarnessRuntime {
|
|
|
277
237
|
}
|
|
278
238
|
}
|
|
279
239
|
async deleteThread(threadId) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (activeRun) {
|
|
286
|
-
throw new Error(`Cannot delete thread ${threadId} while run ${activeRun.runId} is ${activeRun.state}`);
|
|
287
|
-
}
|
|
288
|
-
const deleted = await this.persistence.deleteThread(threadId);
|
|
289
|
-
if (deleted) {
|
|
290
|
-
await this.deleteThreadCheckpoints(threadId);
|
|
291
|
-
}
|
|
292
|
-
return deleted;
|
|
240
|
+
return deleteThreadRecord({
|
|
241
|
+
getThread: (currentThreadId) => this.getThread(currentThreadId),
|
|
242
|
+
deleteThread: (currentThreadId) => this.persistence.deleteThread(currentThreadId),
|
|
243
|
+
deleteThreadCheckpoints: (currentThreadId) => this.deleteThreadCheckpoints(currentThreadId),
|
|
244
|
+
}, threadId);
|
|
293
245
|
}
|
|
294
246
|
async createToolMcpServer(options) {
|
|
295
247
|
const tools = this.resolveAgentTools(options.agentId).map(({ compiledTool, resolvedTool }) => ({
|
|
@@ -752,8 +704,6 @@ export class AgentHarnessRuntime {
|
|
|
752
704
|
}
|
|
753
705
|
async close() {
|
|
754
706
|
await this.healthMonitor?.stop();
|
|
755
|
-
await this.checkpointMaintenance?.stop();
|
|
756
|
-
await this.runtimeRecordMaintenance?.stop();
|
|
757
707
|
this.unregisterThreadMemorySync();
|
|
758
708
|
await Promise.allSettled(Array.from(this.backgroundTasks));
|
|
759
709
|
await this.threadMemorySync?.close();
|
|
@@ -771,63 +721,15 @@ export class AgentHarnessRuntime {
|
|
|
771
721
|
}, options);
|
|
772
722
|
}
|
|
773
723
|
async recoverStartupRuns() {
|
|
774
|
-
|
|
775
|
-
return;
|
|
776
|
-
}
|
|
777
|
-
await this.reclaimExpiredClaimedRuns();
|
|
778
|
-
const threads = await this.persistence.listSessions();
|
|
779
|
-
const recoveryContext = this.createStartupRecoveryContext();
|
|
780
|
-
for (const thread of threads) {
|
|
781
|
-
const handled = await recoverQueuedStartupRun(recoveryContext, thread) ||
|
|
782
|
-
await recoverRunningStartupRun(recoveryContext, thread) ||
|
|
783
|
-
await recoverResumingStartupRun(recoveryContext, thread);
|
|
784
|
-
if (handled) {
|
|
785
|
-
continue;
|
|
786
|
-
}
|
|
787
|
-
}
|
|
724
|
+
return;
|
|
788
725
|
}
|
|
789
|
-
async reclaimExpiredClaimedRuns(
|
|
790
|
-
|
|
791
|
-
for (const claim of expiredClaims) {
|
|
792
|
-
const thread = await this.persistence.getSession(claim.threadId);
|
|
793
|
-
if (!thread) {
|
|
794
|
-
await this.persistence.releaseRunClaim(claim.runId);
|
|
795
|
-
continue;
|
|
796
|
-
}
|
|
797
|
-
const lifecycle = await this.persistence.getRunLifecycle(claim.threadId, claim.runId);
|
|
798
|
-
if (lifecycle.state === "claimed") {
|
|
799
|
-
await this.persistence.enqueueRun({
|
|
800
|
-
threadId: claim.threadId,
|
|
801
|
-
runId: claim.runId,
|
|
802
|
-
priority: claim.priority,
|
|
803
|
-
queueKey: claim.queueKey,
|
|
804
|
-
availableAt: nowIso,
|
|
805
|
-
});
|
|
806
|
-
await this.setRunStateAndEmit(claim.threadId, claim.runId, 99, "queued", {
|
|
807
|
-
previousState: "claimed",
|
|
808
|
-
});
|
|
809
|
-
await this.emit(claim.threadId, claim.runId, 100, "run.queued", {
|
|
810
|
-
queuePosition: 0,
|
|
811
|
-
activeRunCount: this.activeRunSlots,
|
|
812
|
-
maxConcurrentRuns: this.concurrencyConfig.maxConcurrentRuns,
|
|
813
|
-
recoveredOnStartup: true,
|
|
814
|
-
reclaimReason: "expired-lease",
|
|
815
|
-
});
|
|
816
|
-
continue;
|
|
817
|
-
}
|
|
818
|
-
await this.persistence.releaseRunClaim(claim.runId);
|
|
819
|
-
}
|
|
726
|
+
async reclaimExpiredClaimedRuns(_nowIso = new Date().toISOString()) {
|
|
727
|
+
return;
|
|
820
728
|
}
|
|
821
729
|
async isStaleRunningRun(thread, nowMs = Date.now()) {
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
}
|
|
827
|
-
const heartbeatAtMs = Date.parse(heartbeatAt);
|
|
828
|
-
if (!Number.isFinite(heartbeatAtMs)) {
|
|
829
|
-
return true;
|
|
830
|
-
}
|
|
831
|
-
return nowMs - heartbeatAtMs >= this.concurrencyConfig.heartbeatTimeoutMs;
|
|
730
|
+
return isHarnessStaleRunningRun({
|
|
731
|
+
persistence: this.persistence,
|
|
732
|
+
concurrencyConfig: this.concurrencyConfig,
|
|
733
|
+
}, thread, nowMs);
|
|
832
734
|
}
|
|
833
735
|
}
|