@botbotgo/agent-harness 0.0.100 → 0.0.101
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/resource/resource-impl.js +78 -76
- package/dist/runtime/agent-runtime-adapter.d.ts +1 -12
- package/dist/runtime/agent-runtime-adapter.js +33 -148
- package/dist/runtime/harness/run/recovery.d.ts +42 -0
- package/dist/runtime/harness/run/recovery.js +139 -0
- package/dist/runtime/harness.d.ts +2 -17
- package/dist/runtime/harness.js +306 -473
- package/dist/runtime/support/runtime-factories.js +2 -2
- package/dist/workspace/object-loader.js +40 -78
- package/package.json +1 -1
- package/dist/runtime/checkpoint-maintenance.d.ts +0 -1
- package/dist/runtime/checkpoint-maintenance.js +0 -1
- package/dist/runtime/file-checkpoint-saver.d.ts +0 -1
- package/dist/runtime/file-checkpoint-saver.js +0 -1
- package/dist/runtime/sqlite-maintained-checkpoint-saver.d.ts +0 -1
- package/dist/runtime/sqlite-maintained-checkpoint-saver.js +0 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { normalizeRunPriority } from "./helpers.js";
|
|
2
|
+
export async function recoverQueuedStartupRun(context, thread) {
|
|
3
|
+
if (thread.status !== "queued") {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
const runMeta = await context.persistence.getRunMeta(thread.threadId, thread.latestRunId);
|
|
7
|
+
const binding = context.getBinding(runMeta.agentId);
|
|
8
|
+
if (!binding) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
const request = await context.persistence.getRunRequest(thread.threadId, thread.latestRunId);
|
|
12
|
+
if (!request) {
|
|
13
|
+
await context.setRunStateAndEmit(thread.threadId, thread.latestRunId, 100, "failed", {
|
|
14
|
+
previousState: "queued",
|
|
15
|
+
error: "missing persisted run request for queued run recovery",
|
|
16
|
+
});
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
const releaseRunSlot = await context.acquireRunSlot(thread.threadId, thread.latestRunId, "running", normalizeRunPriority(request.priority));
|
|
20
|
+
try {
|
|
21
|
+
await context.executeQueuedRun(binding, request.input, thread.threadId, thread.latestRunId, runMeta.agentId, {
|
|
22
|
+
context: request.invocation?.context,
|
|
23
|
+
state: request.invocation?.inputs,
|
|
24
|
+
files: request.invocation?.attachments,
|
|
25
|
+
previousState: "queued",
|
|
26
|
+
stateSequence: 103,
|
|
27
|
+
approvalSequence: 104,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
await releaseRunSlot();
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
export async function recoverRunningStartupRun(context, thread) {
|
|
36
|
+
if (thread.status !== "running") {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const isStale = await context.isStaleRunningRun(thread);
|
|
40
|
+
if (!isStale) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const runMeta = await context.persistence.getRunMeta(thread.threadId, thread.latestRunId);
|
|
44
|
+
const binding = context.getBinding(runMeta.agentId);
|
|
45
|
+
if (!binding) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (!context.supportsRunningReplay(binding)) {
|
|
49
|
+
await context.setRunStateAndEmit(thread.threadId, thread.latestRunId, 100, "failed", {
|
|
50
|
+
previousState: "running",
|
|
51
|
+
error: "stale running run cannot be replayed safely",
|
|
52
|
+
});
|
|
53
|
+
await context.persistence.releaseRunClaim(thread.latestRunId);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
const request = await context.persistence.getRunRequest(thread.threadId, thread.latestRunId);
|
|
57
|
+
if (!request) {
|
|
58
|
+
await context.setRunStateAndEmit(thread.threadId, thread.latestRunId, 100, "failed", {
|
|
59
|
+
previousState: "running",
|
|
60
|
+
error: "missing persisted run request for stale running run recovery",
|
|
61
|
+
});
|
|
62
|
+
await context.persistence.releaseRunClaim(thread.latestRunId);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
const releaseRunSlot = await context.acquireRunSlot(thread.threadId, thread.latestRunId, "running", normalizeRunPriority(request.priority));
|
|
66
|
+
try {
|
|
67
|
+
await context.emit(thread.threadId, thread.latestRunId, 100, "run.resumed", {
|
|
68
|
+
resumeKind: "startup-running-recovery",
|
|
69
|
+
state: "running",
|
|
70
|
+
});
|
|
71
|
+
await context.executeQueuedRun(binding, request.input, thread.threadId, thread.latestRunId, runMeta.agentId, {
|
|
72
|
+
context: request.invocation?.context,
|
|
73
|
+
state: request.invocation?.inputs,
|
|
74
|
+
files: request.invocation?.attachments,
|
|
75
|
+
previousState: "running",
|
|
76
|
+
stateSequence: 103,
|
|
77
|
+
approvalSequence: 104,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
await releaseRunSlot();
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
export async function recoverResumingStartupRun(context, thread) {
|
|
86
|
+
if (thread.status !== "resuming" || !context.recoveryConfig.resumeResumingRunsOnStartup) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const binding = context.getBinding(thread.agentId);
|
|
90
|
+
if (!binding) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
const recoveryIntent = await context.persistence.getRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
94
|
+
if (!recoveryIntent || recoveryIntent.kind !== "approval-decision") {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
if (recoveryIntent.attempts >= context.recoveryConfig.maxRecoveryAttempts) {
|
|
98
|
+
await context.persistence.setRunState(thread.threadId, thread.latestRunId, "failed", recoveryIntent.checkpointRef);
|
|
99
|
+
await context.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
await context.persistence.saveRecoveryIntent(thread.threadId, thread.latestRunId, {
|
|
103
|
+
...recoveryIntent,
|
|
104
|
+
attempts: recoveryIntent.attempts + 1,
|
|
105
|
+
});
|
|
106
|
+
await context.emit(thread.threadId, thread.latestRunId, 100, "run.resumed", {
|
|
107
|
+
resumeKind: "startup-recovery",
|
|
108
|
+
checkpointRef: recoveryIntent.checkpointRef,
|
|
109
|
+
state: "resuming",
|
|
110
|
+
});
|
|
111
|
+
const history = await context.persistence.listThreadMessages(thread.threadId);
|
|
112
|
+
const priorHistory = history.filter((message) => message.runId !== thread.latestRunId);
|
|
113
|
+
const runInput = await context.loadRunInput(thread.threadId, thread.latestRunId);
|
|
114
|
+
const startedAt = Date.now();
|
|
115
|
+
try {
|
|
116
|
+
const actual = await context.runtimeAdapter.invoke(binding, "", thread.threadId, thread.latestRunId, recoveryIntent.resumePayload, priorHistory);
|
|
117
|
+
context.recordLlmSuccess(startedAt);
|
|
118
|
+
await context.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
119
|
+
await context.finalizeContinuedRun(binding, thread.threadId, thread.latestRunId, runInput, actual, {
|
|
120
|
+
previousState: "resuming",
|
|
121
|
+
stateSequence: 101,
|
|
122
|
+
approvalSequence: 102,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
context.recordLlmFailure(startedAt);
|
|
127
|
+
if (recoveryIntent.attempts + 1 >= context.recoveryConfig.maxRecoveryAttempts) {
|
|
128
|
+
await context.persistence.setRunState(thread.threadId, thread.latestRunId, "failed", recoveryIntent.checkpointRef);
|
|
129
|
+
await context.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
130
|
+
await context.emit(thread.threadId, thread.latestRunId, 101, "run.state.changed", {
|
|
131
|
+
previousState: "resuming",
|
|
132
|
+
state: "failed",
|
|
133
|
+
checkpointRef: recoveryIntent.checkpointRef,
|
|
134
|
+
error: error instanceof Error ? error.message : String(error),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
@@ -37,10 +37,6 @@ export declare class AgentHarnessRuntime {
|
|
|
37
37
|
private defaultRunRoot;
|
|
38
38
|
private getDefaultHostAgentId;
|
|
39
39
|
private resolveSelectedAgentId;
|
|
40
|
-
private resolveStore;
|
|
41
|
-
private resolveStoreFromConfig;
|
|
42
|
-
private resolveEmbeddingModel;
|
|
43
|
-
private resolveVectorStore;
|
|
44
40
|
constructor(workspace: WorkspaceBundle, runtimeAdapterOptions?: RuntimeAdapterOptions);
|
|
45
41
|
private createHealthMonitor;
|
|
46
42
|
private recordLlmSuccess;
|
|
@@ -48,8 +44,6 @@ export declare class AgentHarnessRuntime {
|
|
|
48
44
|
initialize(): Promise<void>;
|
|
49
45
|
subscribe(listener: (event: HarnessEvent) => void): () => void;
|
|
50
46
|
getHealth(): Promise<RuntimeHealthSnapshot>;
|
|
51
|
-
private getBinding;
|
|
52
|
-
private listAgentTools;
|
|
53
47
|
private resolveAgentTools;
|
|
54
48
|
private supportsRunningReplay;
|
|
55
49
|
listThreads(filter?: {
|
|
@@ -86,34 +80,25 @@ export declare class AgentHarnessRuntime {
|
|
|
86
80
|
private ensureThreadStarted;
|
|
87
81
|
private loadPriorHistory;
|
|
88
82
|
private loadRunInput;
|
|
89
|
-
private appendAssistantMessage;
|
|
90
83
|
private getRunCancellation;
|
|
91
|
-
private expirePendingApprovals;
|
|
92
84
|
private finalizeCancelledRun;
|
|
93
85
|
private invokeWithHistory;
|
|
94
86
|
private resolvePersistedRunPriority;
|
|
95
87
|
private enqueuePendingRunSlot;
|
|
96
88
|
private executeQueuedRun;
|
|
97
|
-
private checkpointRefForState;
|
|
98
89
|
private finalizeContinuedRun;
|
|
99
|
-
private emitOutputDeltaAndCreateItem;
|
|
100
|
-
private createContentBlocksItem;
|
|
101
|
-
private createToolResultKey;
|
|
102
|
-
private emitRunCreated;
|
|
103
90
|
private setRunStateAndEmit;
|
|
104
91
|
private requestApprovalAndEmit;
|
|
105
|
-
private emitSyntheticFallback;
|
|
106
|
-
private persistApproval;
|
|
107
|
-
private resolveApprovalRecord;
|
|
108
92
|
private isDecisionRun;
|
|
109
93
|
private notifyListener;
|
|
94
|
+
private prepareRunStart;
|
|
95
|
+
private createStartupRecoveryContext;
|
|
110
96
|
private acquireRunSlot;
|
|
111
97
|
private dropPendingRunSlot;
|
|
112
98
|
private dispatchRunListeners;
|
|
113
99
|
run(options: RunOptions): Promise<RunResult>;
|
|
114
100
|
streamEvents(options: RunStartOptions): AsyncGenerator<HarnessStreamItem>;
|
|
115
101
|
resume(options: ResumeOptions): Promise<RunResult>;
|
|
116
|
-
private buildResumePayload;
|
|
117
102
|
restartConversation(options: RestartConversationOptions): Promise<RunResult & {
|
|
118
103
|
restart: Record<string, string>;
|
|
119
104
|
}>;
|