@botbotgo/agent-harness 0.0.100 → 0.0.102
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/persistence/sqlite-run-context-store.d.ts +22 -0
- package/dist/persistence/sqlite-run-context-store.js +64 -0
- package/dist/persistence/sqlite-run-queue-store.d.ts +41 -0
- package/dist/persistence/sqlite-run-queue-store.js +120 -0
- package/dist/persistence/sqlite-store.d.ts +2 -2
- package/dist/persistence/sqlite-store.js +31 -117
- package/dist/resource/mcp-tool-support.d.ts +21 -0
- package/dist/resource/mcp-tool-support.js +173 -0
- package/dist/resource/resource-impl.d.ts +1 -18
- package/dist/resource/resource-impl.js +79 -240
- package/dist/runtime/adapter/invoke-runtime.d.ts +22 -0
- package/dist/runtime/adapter/invoke-runtime.js +18 -0
- package/dist/runtime/adapter/stream-runtime.d.ts +46 -0
- package/dist/runtime/adapter/stream-runtime.js +93 -0
- package/dist/runtime/agent-runtime-adapter.d.ts +1 -12
- package/dist/runtime/agent-runtime-adapter.js +122 -312
- package/dist/runtime/harness/run/recovery.d.ts +42 -0
- package/dist/runtime/harness/run/recovery.js +139 -0
- package/dist/runtime/harness/run/run-operations.d.ts +50 -0
- package/dist/runtime/harness/run/run-operations.js +113 -0
- package/dist/runtime/harness/run/run-slot-acquisition.d.ts +64 -0
- package/dist/runtime/harness/run/run-slot-acquisition.js +157 -0
- package/dist/runtime/harness/run/stream-run.d.ts +53 -0
- package/dist/runtime/harness/run/stream-run.js +304 -0
- package/dist/runtime/harness.d.ts +2 -17
- package/dist/runtime/harness.js +157 -773
- package/dist/runtime/support/runtime-factories.js +2 -2
- package/dist/workspace/object-loader.d.ts +1 -8
- package/dist/workspace/object-loader.js +43 -275
- package/dist/workspace/yaml-object-reader.d.ts +15 -0
- package/dist/workspace/yaml-object-reader.js +202 -0
- 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,304 @@
|
|
|
1
|
+
import { AGENT_INTERRUPT_SENTINEL_PREFIX, RuntimeOperationTimeoutError } from "../../agent-runtime-adapter.js";
|
|
2
|
+
import { normalizeUpstreamRuntimeEvent } from "../../parsing/stream-event-parsing.js";
|
|
3
|
+
import { renderRuntimeFailure, renderToolFailure } from "../../support/harness-support.js";
|
|
4
|
+
import { createContentBlocksItem, createToolResultKey, emitOutputDeltaAndCreateItem, } from "../events/streaming.js";
|
|
5
|
+
function normalizeStreamChunk(chunk) {
|
|
6
|
+
if (typeof chunk === "string") {
|
|
7
|
+
if (chunk.startsWith(AGENT_INTERRUPT_SENTINEL_PREFIX)) {
|
|
8
|
+
return { kind: "interrupt", content: chunk.slice(AGENT_INTERRUPT_SENTINEL_PREFIX.length) };
|
|
9
|
+
}
|
|
10
|
+
return { kind: "content", content: chunk };
|
|
11
|
+
}
|
|
12
|
+
if (chunk.kind === "upstream-event") {
|
|
13
|
+
return { kind: "upstream-event", event: (chunk.event ?? {}) };
|
|
14
|
+
}
|
|
15
|
+
if (chunk.kind === "interrupt") {
|
|
16
|
+
return { kind: "interrupt", content: chunk.content };
|
|
17
|
+
}
|
|
18
|
+
if (chunk.kind === "reasoning") {
|
|
19
|
+
return { kind: "reasoning", content: chunk.content ?? "" };
|
|
20
|
+
}
|
|
21
|
+
if (chunk.kind === "step") {
|
|
22
|
+
return { kind: "step", content: chunk.content ?? "" };
|
|
23
|
+
}
|
|
24
|
+
if (chunk.kind === "tool-result") {
|
|
25
|
+
return {
|
|
26
|
+
kind: "tool-result",
|
|
27
|
+
toolName: chunk.toolName ?? "unknown_tool",
|
|
28
|
+
output: chunk.output,
|
|
29
|
+
isError: chunk.isError,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return { kind: "content", content: chunk.content ?? "" };
|
|
33
|
+
}
|
|
34
|
+
function isUpstreamRuntimeEvent(event) {
|
|
35
|
+
return event.format === "langgraph-v2" && "normalized" in event && "streamPart" in event;
|
|
36
|
+
}
|
|
37
|
+
export async function* streamHarnessRun(options) {
|
|
38
|
+
const priorHistoryPromise = Promise.resolve(options.isNewThread ? [] : undefined).then((historyHint) => historyHint ?? options.loadPriorHistory(options.threadId, options.runId));
|
|
39
|
+
yield { type: "event", event: await options.runCreatedEventPromise };
|
|
40
|
+
let releaseRunSlot = async () => undefined;
|
|
41
|
+
let emitted = false;
|
|
42
|
+
let streamActivityObserved = false;
|
|
43
|
+
const emitOutputDelta = (content) => emitOutputDeltaAndCreateItem(options.emit, options.threadId, options.runId, options.selectedAgentId, content);
|
|
44
|
+
try {
|
|
45
|
+
const [priorHistory, acquiredReleaseRunSlot] = await Promise.all([
|
|
46
|
+
priorHistoryPromise,
|
|
47
|
+
options.releaseRunSlotPromise,
|
|
48
|
+
]).then(([loadedPriorHistory, resolvedReleaseRunSlot]) => [loadedPriorHistory, resolvedReleaseRunSlot]);
|
|
49
|
+
releaseRunSlot = acquiredReleaseRunSlot;
|
|
50
|
+
let assistantOutput = "";
|
|
51
|
+
const toolErrors = [];
|
|
52
|
+
let lastToolResultKey = null;
|
|
53
|
+
for await (const rawChunk of options.stream(options.binding, options.input, options.threadId, priorHistory, {
|
|
54
|
+
context: options.invocation.context,
|
|
55
|
+
state: options.invocation.state,
|
|
56
|
+
files: options.invocation.files,
|
|
57
|
+
runId: options.runId,
|
|
58
|
+
})) {
|
|
59
|
+
if (!rawChunk) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
streamActivityObserved = true;
|
|
63
|
+
const normalizedChunk = normalizeStreamChunk(rawChunk);
|
|
64
|
+
if (normalizedChunk.kind === "upstream-event") {
|
|
65
|
+
const rawEvent = normalizedChunk.event;
|
|
66
|
+
yield {
|
|
67
|
+
type: "upstream-event",
|
|
68
|
+
threadId: options.threadId,
|
|
69
|
+
runId: options.runId,
|
|
70
|
+
agentId: options.selectedAgentId,
|
|
71
|
+
event: isUpstreamRuntimeEvent(rawEvent)
|
|
72
|
+
? rawEvent
|
|
73
|
+
: normalizeUpstreamRuntimeEvent(rawEvent.raw ?? rawEvent),
|
|
74
|
+
};
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (normalizedChunk.kind === "interrupt") {
|
|
78
|
+
const checkpointRef = `checkpoints/${options.threadId}/${options.runId}/cp-1`;
|
|
79
|
+
const waitingEvent = await options.setRunStateAndEmit(options.threadId, options.runId, 6, "waiting_for_approval", {
|
|
80
|
+
previousState: "running",
|
|
81
|
+
checkpointRef,
|
|
82
|
+
});
|
|
83
|
+
const approvalRequest = await options.requestApprovalAndEmit(options.threadId, options.runId, options.input, normalizedChunk.content, checkpointRef, 7);
|
|
84
|
+
yield { type: "event", event: waitingEvent };
|
|
85
|
+
yield { type: "event", event: approvalRequest.event };
|
|
86
|
+
yield {
|
|
87
|
+
type: "result",
|
|
88
|
+
result: {
|
|
89
|
+
threadId: options.threadId,
|
|
90
|
+
runId: options.runId,
|
|
91
|
+
agentId: options.selectedAgentId,
|
|
92
|
+
state: "waiting_for_approval",
|
|
93
|
+
output: assistantOutput,
|
|
94
|
+
finalMessageText: assistantOutput,
|
|
95
|
+
interruptContent: normalizedChunk.content,
|
|
96
|
+
approvalId: approvalRequest.approval.approvalId,
|
|
97
|
+
pendingActionId: approvalRequest.approval.pendingActionId,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (normalizedChunk.kind === "reasoning") {
|
|
103
|
+
await options.emit(options.threadId, options.runId, 3, "reasoning.delta", {
|
|
104
|
+
content: normalizedChunk.content,
|
|
105
|
+
});
|
|
106
|
+
yield {
|
|
107
|
+
type: "reasoning",
|
|
108
|
+
threadId: options.threadId,
|
|
109
|
+
runId: options.runId,
|
|
110
|
+
agentId: options.selectedAgentId,
|
|
111
|
+
content: normalizedChunk.content,
|
|
112
|
+
};
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (normalizedChunk.kind === "step") {
|
|
116
|
+
yield {
|
|
117
|
+
type: "step",
|
|
118
|
+
threadId: options.threadId,
|
|
119
|
+
runId: options.runId,
|
|
120
|
+
agentId: options.selectedAgentId,
|
|
121
|
+
content: normalizedChunk.content,
|
|
122
|
+
};
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (normalizedChunk.kind === "tool-result") {
|
|
126
|
+
const toolResultKey = createToolResultKey(normalizedChunk.toolName, normalizedChunk.output, normalizedChunk.isError);
|
|
127
|
+
if (toolResultKey === lastToolResultKey) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
lastToolResultKey = toolResultKey;
|
|
131
|
+
if (normalizedChunk.isError) {
|
|
132
|
+
toolErrors.push(renderToolFailure(normalizedChunk.toolName, normalizedChunk.output));
|
|
133
|
+
}
|
|
134
|
+
yield {
|
|
135
|
+
type: "tool-result",
|
|
136
|
+
threadId: options.threadId,
|
|
137
|
+
runId: options.runId,
|
|
138
|
+
agentId: options.selectedAgentId,
|
|
139
|
+
toolName: normalizedChunk.toolName,
|
|
140
|
+
output: normalizedChunk.output,
|
|
141
|
+
isError: normalizedChunk.isError,
|
|
142
|
+
};
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
emitted = true;
|
|
146
|
+
assistantOutput += normalizedChunk.content;
|
|
147
|
+
yield await emitOutputDelta(normalizedChunk.content);
|
|
148
|
+
}
|
|
149
|
+
if (!assistantOutput && toolErrors.length > 0) {
|
|
150
|
+
assistantOutput = toolErrors.join("\n\n");
|
|
151
|
+
emitted = true;
|
|
152
|
+
yield await emitOutputDelta(assistantOutput);
|
|
153
|
+
}
|
|
154
|
+
if (!assistantOutput) {
|
|
155
|
+
const actual = await options.invokeWithHistory(options.binding, options.input, options.threadId, options.runId);
|
|
156
|
+
if (Array.isArray(actual.contentBlocks) && actual.contentBlocks.length > 0) {
|
|
157
|
+
yield createContentBlocksItem(options.threadId, options.runId, options.selectedAgentId, actual.contentBlocks);
|
|
158
|
+
}
|
|
159
|
+
if (actual.output) {
|
|
160
|
+
assistantOutput = actual.output;
|
|
161
|
+
emitted = true;
|
|
162
|
+
yield await emitOutputDelta(actual.output);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
await options.appendAssistantMessage(options.threadId, options.runId, assistantOutput);
|
|
166
|
+
yield {
|
|
167
|
+
type: "result",
|
|
168
|
+
result: {
|
|
169
|
+
threadId: options.threadId,
|
|
170
|
+
runId: options.runId,
|
|
171
|
+
agentId: options.selectedAgentId,
|
|
172
|
+
state: "completed",
|
|
173
|
+
output: assistantOutput,
|
|
174
|
+
finalMessageText: assistantOutput,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
yield {
|
|
178
|
+
type: "event",
|
|
179
|
+
event: await options.setRunStateAndEmit(options.threadId, options.runId, 6, "completed", {
|
|
180
|
+
previousState: "running",
|
|
181
|
+
}),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
if (emitted || streamActivityObserved) {
|
|
186
|
+
const runtimeFailure = renderRuntimeFailure(error);
|
|
187
|
+
yield {
|
|
188
|
+
type: "event",
|
|
189
|
+
event: await options.setRunStateAndEmit(options.threadId, options.runId, 6, "failed", {
|
|
190
|
+
previousState: "running",
|
|
191
|
+
error: error instanceof Error ? error.message : String(error),
|
|
192
|
+
}),
|
|
193
|
+
};
|
|
194
|
+
yield {
|
|
195
|
+
type: "content",
|
|
196
|
+
threadId: options.threadId,
|
|
197
|
+
runId: options.runId,
|
|
198
|
+
agentId: options.selectedAgentId,
|
|
199
|
+
content: runtimeFailure,
|
|
200
|
+
};
|
|
201
|
+
yield {
|
|
202
|
+
type: "result",
|
|
203
|
+
result: {
|
|
204
|
+
threadId: options.threadId,
|
|
205
|
+
runId: options.runId,
|
|
206
|
+
agentId: options.selectedAgentId,
|
|
207
|
+
state: "failed",
|
|
208
|
+
output: runtimeFailure,
|
|
209
|
+
finalMessageText: runtimeFailure,
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (error instanceof RuntimeOperationTimeoutError && error.stage === "invoke") {
|
|
215
|
+
const runtimeFailure = renderRuntimeFailure(error);
|
|
216
|
+
yield {
|
|
217
|
+
type: "event",
|
|
218
|
+
event: await options.setRunStateAndEmit(options.threadId, options.runId, 6, "failed", {
|
|
219
|
+
previousState: "running",
|
|
220
|
+
error: error.message,
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
yield {
|
|
224
|
+
type: "content",
|
|
225
|
+
threadId: options.threadId,
|
|
226
|
+
runId: options.runId,
|
|
227
|
+
agentId: options.selectedAgentId,
|
|
228
|
+
content: runtimeFailure,
|
|
229
|
+
};
|
|
230
|
+
yield {
|
|
231
|
+
type: "result",
|
|
232
|
+
result: {
|
|
233
|
+
threadId: options.threadId,
|
|
234
|
+
runId: options.runId,
|
|
235
|
+
agentId: options.selectedAgentId,
|
|
236
|
+
state: "failed",
|
|
237
|
+
output: runtimeFailure,
|
|
238
|
+
finalMessageText: runtimeFailure,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const actual = await options.invokeWithHistory(options.binding, options.input, options.threadId, options.runId);
|
|
245
|
+
await options.appendAssistantMessage(options.threadId, options.runId, actual.output);
|
|
246
|
+
if (Array.isArray(actual.contentBlocks) && actual.contentBlocks.length > 0) {
|
|
247
|
+
yield createContentBlocksItem(options.threadId, options.runId, options.selectedAgentId, actual.contentBlocks);
|
|
248
|
+
}
|
|
249
|
+
if (actual.output) {
|
|
250
|
+
yield await emitOutputDelta(actual.output);
|
|
251
|
+
}
|
|
252
|
+
yield {
|
|
253
|
+
type: "result",
|
|
254
|
+
result: {
|
|
255
|
+
...actual,
|
|
256
|
+
threadId: options.threadId,
|
|
257
|
+
runId: options.runId,
|
|
258
|
+
agentId: options.selectedAgentId,
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
yield {
|
|
262
|
+
type: "event",
|
|
263
|
+
event: await options.setRunStateAndEmit(options.threadId, options.runId, 6, actual.state, {
|
|
264
|
+
previousState: "running",
|
|
265
|
+
}),
|
|
266
|
+
};
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
catch (invokeError) {
|
|
270
|
+
await options.emitSyntheticFallback(options.threadId, options.runId, options.selectedAgentId, invokeError);
|
|
271
|
+
const runtimeFailure = renderRuntimeFailure(invokeError);
|
|
272
|
+
yield {
|
|
273
|
+
type: "event",
|
|
274
|
+
event: await options.setRunStateAndEmit(options.threadId, options.runId, 6, "failed", {
|
|
275
|
+
previousState: "running",
|
|
276
|
+
error: invokeError instanceof Error ? invokeError.message : String(invokeError),
|
|
277
|
+
}),
|
|
278
|
+
};
|
|
279
|
+
yield {
|
|
280
|
+
type: "content",
|
|
281
|
+
threadId: options.threadId,
|
|
282
|
+
runId: options.runId,
|
|
283
|
+
agentId: options.selectedAgentId,
|
|
284
|
+
content: runtimeFailure,
|
|
285
|
+
};
|
|
286
|
+
yield {
|
|
287
|
+
type: "result",
|
|
288
|
+
result: {
|
|
289
|
+
threadId: options.threadId,
|
|
290
|
+
runId: options.runId,
|
|
291
|
+
agentId: options.selectedAgentId,
|
|
292
|
+
state: "failed",
|
|
293
|
+
output: runtimeFailure,
|
|
294
|
+
finalMessageText: runtimeFailure,
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
await options.clearRunRequest(options.threadId, options.runId);
|
|
302
|
+
await releaseRunSlot();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
@@ -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
|
}>;
|