@rivus/agent 0.14.2 → 0.14.4
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/README.md +1 -1
- package/dist/acp.js +1 -2
- package/dist/bootstrap/pi-feishu.d.ts +1 -1
- package/dist/bootstrap/pi-feishu.js +4 -4
- package/dist/chunks/agent-loop.d.ts +55 -300
- package/dist/chunks/agent-loop.js +3 -1123
- package/dist/chunks/background-session-authority.js +230 -0
- package/dist/chunks/background-session-control-input.js +51 -0
- package/dist/chunks/background-session-service.d.ts +382 -0
- package/dist/chunks/index.d.ts +1201 -538
- package/dist/chunks/pi-tool-proxy.d.ts +22 -90
- package/dist/chunks/pi.js +5 -2
- package/dist/chunks/rivus-agent-definition-resolver.js +508 -0
- package/dist/chunks/rivus-daemon-cli.js +2776 -3244
- package/dist/chunks/rivus-plugin-testkit.d.ts +175 -2
- package/dist/chunks/rivus-plugin-testkit.js +11 -4
- package/dist/chunks/rivus-skill.d.ts +95 -0
- package/dist/chunks/sha256-digest.js +2 -7
- package/dist/chunks/src.js +11941 -7001
- package/dist/chunks/tool-input-digest.js +158 -0
- package/dist/cli.js +764 -712
- package/dist/index.d.ts +6 -7
- package/dist/index.js +7 -8
- package/dist/mcp.d.ts +48 -9
- package/dist/mcp.js +146 -20
- package/dist/pi.d.ts +3 -4
- package/dist/pi.js +1 -1
- package/package.json +5 -5
- package/dist/chunks/api.d.ts +0 -70
- package/dist/chunks/api.js +0 -471
- package/dist/chunks/api2.d.ts +0 -387
- package/dist/chunks/api2.js +0 -1331
- package/dist/chunks/api3.d.ts +0 -402
- package/dist/chunks/module.js +0 -267
- package/dist/chunks/pi-skill-tool.js +0 -460
- package/dist/chunks/spi.d.ts +0 -1
- package/dist/chunks/spi.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/
|
|
1
|
+
import { Effect, Stream } from "effect";
|
|
2
|
+
//#region src/core/application/agent-execution/loop/agent-loop.ts
|
|
3
3
|
function createAgentLoopTextDelta(delta) {
|
|
4
4
|
return {
|
|
5
5
|
delta,
|
|
@@ -72,1126 +72,6 @@ function createTextAgentLoop$1(options) {
|
|
|
72
72
|
return { run: (input) => Stream.fromEffect(options.generate(input)).pipe(Stream.map((delta) => createAgentLoopTextDelta(delta))) };
|
|
73
73
|
}
|
|
74
74
|
//#endregion
|
|
75
|
-
//#region src/modules/agent-execution/domain/run/agent-events.ts
|
|
76
|
-
function isAssistantTextDeltaEvent(event) {
|
|
77
|
-
return event.type === "assistant_text_delta";
|
|
78
|
-
}
|
|
79
|
-
function isAssistantThinkingDeltaEvent(event) {
|
|
80
|
-
return event.type === "assistant_thinking_delta";
|
|
81
|
-
}
|
|
82
|
-
function isAgentToolExecutionEvent(event) {
|
|
83
|
-
return event.type === "agent_tool_execution_started" || event.type === "agent_tool_execution_updated" || event.type === "agent_tool_execution_ended";
|
|
84
|
-
}
|
|
85
|
-
function isTerminalAgentDomainEvent(event) {
|
|
86
|
-
return event.type === "agent_run_completed" || event.type === "agent_run_failed" || event.type === "agent_run_cancelled";
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/modules/agent-execution/domain/run/agent-run-state.ts
|
|
90
|
-
const initialAgentRunState = {
|
|
91
|
-
finalText: "",
|
|
92
|
-
phase: "idle",
|
|
93
|
-
skillExecutions: {},
|
|
94
|
-
thinkingText: "",
|
|
95
|
-
toolExecutions: {}
|
|
96
|
-
};
|
|
97
|
-
function isTerminalAgentRunPhase(phase) {
|
|
98
|
-
return phase === "completed" || phase === "failed" || phase === "cancelled";
|
|
99
|
-
}
|
|
100
|
-
function evolveAgentRun(state, event) {
|
|
101
|
-
switch (event.type) {
|
|
102
|
-
case "agent_run_accepted": return {
|
|
103
|
-
...state,
|
|
104
|
-
finalText: "",
|
|
105
|
-
phase: "accepted",
|
|
106
|
-
prompt: event.prompt,
|
|
107
|
-
runId: event.runId,
|
|
108
|
-
sessionKey: event.sessionKey,
|
|
109
|
-
thinkingText: "",
|
|
110
|
-
skillExecutions: {},
|
|
111
|
-
toolExecutions: {}
|
|
112
|
-
};
|
|
113
|
-
case "agent_turn_started": return {
|
|
114
|
-
...state,
|
|
115
|
-
finalText: "",
|
|
116
|
-
thinkingText: "",
|
|
117
|
-
phase: "running"
|
|
118
|
-
};
|
|
119
|
-
case "assistant_text_delta": return {
|
|
120
|
-
...state,
|
|
121
|
-
finalText: `${state.finalText}${event.delta}`
|
|
122
|
-
};
|
|
123
|
-
case "assistant_thinking_delta": return {
|
|
124
|
-
...state,
|
|
125
|
-
thinkingText: `${state.thinkingText ?? ""}${event.delta}`
|
|
126
|
-
};
|
|
127
|
-
case "agent_model_execution_started": return {
|
|
128
|
-
...state,
|
|
129
|
-
finalText: ""
|
|
130
|
-
};
|
|
131
|
-
case "agent_model_execution_ended": return state;
|
|
132
|
-
case "agent_skill_execution_started": return {
|
|
133
|
-
...state,
|
|
134
|
-
skillExecutions: {
|
|
135
|
-
...state.skillExecutions,
|
|
136
|
-
[event.skillCallId]: {
|
|
137
|
-
skillCallId: event.skillCallId,
|
|
138
|
-
skillId: event.skillId,
|
|
139
|
-
status: "running"
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
case "agent_skill_execution_ended": return {
|
|
144
|
-
...state,
|
|
145
|
-
skillExecutions: {
|
|
146
|
-
...state.skillExecutions,
|
|
147
|
-
[event.skillCallId]: {
|
|
148
|
-
...state.skillExecutions[event.skillCallId],
|
|
149
|
-
...event.isError ? {} : {
|
|
150
|
-
contentLength: event.contentLength,
|
|
151
|
-
digest: event.digest,
|
|
152
|
-
title: event.title,
|
|
153
|
-
version: event.version
|
|
154
|
-
},
|
|
155
|
-
isError: event.isError,
|
|
156
|
-
skillCallId: event.skillCallId,
|
|
157
|
-
skillId: event.skillId,
|
|
158
|
-
status: "completed"
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
case "agent_tool_execution_started": return {
|
|
163
|
-
...state,
|
|
164
|
-
toolExecutions: {
|
|
165
|
-
...state.toolExecutions,
|
|
166
|
-
[event.toolCallId]: {
|
|
167
|
-
input: event.input,
|
|
168
|
-
status: "running",
|
|
169
|
-
toolCallId: event.toolCallId,
|
|
170
|
-
toolName: event.toolName
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
case "agent_tool_execution_updated": {
|
|
175
|
-
const current = state.toolExecutions[event.toolCallId];
|
|
176
|
-
return {
|
|
177
|
-
...state,
|
|
178
|
-
toolExecutions: {
|
|
179
|
-
...state.toolExecutions,
|
|
180
|
-
[event.toolCallId]: {
|
|
181
|
-
input: event.input,
|
|
182
|
-
status: current?.status ?? "running",
|
|
183
|
-
toolCallId: event.toolCallId,
|
|
184
|
-
toolName: event.toolName,
|
|
185
|
-
partialResult: event.partialResult,
|
|
186
|
-
result: current?.result,
|
|
187
|
-
...current?.isError === void 0 ? {} : { isError: current.isError }
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
case "agent_tool_execution_ended": return {
|
|
193
|
-
...state,
|
|
194
|
-
toolExecutions: {
|
|
195
|
-
...state.toolExecutions,
|
|
196
|
-
[event.toolCallId]: {
|
|
197
|
-
input: state.toolExecutions[event.toolCallId]?.input,
|
|
198
|
-
partialResult: state.toolExecutions[event.toolCallId]?.partialResult,
|
|
199
|
-
result: event.result,
|
|
200
|
-
isError: event.isError,
|
|
201
|
-
status: "completed",
|
|
202
|
-
toolCallId: event.toolCallId,
|
|
203
|
-
toolName: event.toolName
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
case "agent_turn_completed": return {
|
|
208
|
-
...state,
|
|
209
|
-
finalText: event.finalText
|
|
210
|
-
};
|
|
211
|
-
case "agent_run_completed": return {
|
|
212
|
-
...state,
|
|
213
|
-
finalText: event.finalText,
|
|
214
|
-
phase: "completed"
|
|
215
|
-
};
|
|
216
|
-
case "agent_run_failed": return {
|
|
217
|
-
...state,
|
|
218
|
-
errorMessage: event.errorMessage,
|
|
219
|
-
phase: "failed"
|
|
220
|
-
};
|
|
221
|
-
case "agent_run_cancelled": return {
|
|
222
|
-
...state,
|
|
223
|
-
...event.reason ? { cancellationReason: event.reason } : {},
|
|
224
|
-
phase: "cancelled"
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
//#endregion
|
|
229
|
-
//#region src/modules/agent-execution/domain/history/agent-history.ts
|
|
230
|
-
function replayAgentHistory(events) {
|
|
231
|
-
const runs = /* @__PURE__ */ new Map();
|
|
232
|
-
for (const event of events) {
|
|
233
|
-
const current = runs.get(event.runId) ?? createInitialRunSummary(event);
|
|
234
|
-
const next = updateRunSummary(current, event, evolveAgentRun(current.state, event));
|
|
235
|
-
runs.set(event.runId, next);
|
|
236
|
-
}
|
|
237
|
-
const runSummaries = [...runs.values()].map(toRunSummary);
|
|
238
|
-
return {
|
|
239
|
-
runs: runSummaries,
|
|
240
|
-
sessions: buildSessionSummaries(runSummaries),
|
|
241
|
-
totalEvents: events.length
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function createInitialRunSummary(event) {
|
|
245
|
-
return {
|
|
246
|
-
eventCount: 0,
|
|
247
|
-
failedSkillExecutionCount: 0,
|
|
248
|
-
failedToolExecutionCount: 0,
|
|
249
|
-
finalText: "",
|
|
250
|
-
phase: "idle",
|
|
251
|
-
runId: event.runId,
|
|
252
|
-
state: initialAgentRunState,
|
|
253
|
-
thinkingText: "",
|
|
254
|
-
skillExecutionCount: 0,
|
|
255
|
-
toolExecutionCount: 0,
|
|
256
|
-
updatedAt: event.occurredAt
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
function updateRunSummary(current, event, state) {
|
|
260
|
-
const toolExecutions = Object.values(state.toolExecutions);
|
|
261
|
-
const skillExecutions = Object.values(state.skillExecutions);
|
|
262
|
-
const next = {
|
|
263
|
-
...current,
|
|
264
|
-
eventCount: current.eventCount + 1,
|
|
265
|
-
failedToolExecutionCount: toolExecutions.filter((tool) => tool.isError === true).length,
|
|
266
|
-
failedSkillExecutionCount: skillExecutions.filter((skill) => skill.isError === true).length,
|
|
267
|
-
finalText: state.finalText,
|
|
268
|
-
phase: state.phase,
|
|
269
|
-
state,
|
|
270
|
-
thinkingText: state.thinkingText ?? "",
|
|
271
|
-
skillExecutionCount: skillExecutions.length,
|
|
272
|
-
toolExecutionCount: toolExecutions.length,
|
|
273
|
-
updatedAt: event.occurredAt
|
|
274
|
-
};
|
|
275
|
-
switch (event.type) {
|
|
276
|
-
case "agent_run_accepted":
|
|
277
|
-
next.acceptedAt = event.occurredAt;
|
|
278
|
-
next.prompt = event.prompt;
|
|
279
|
-
next.sessionKey = event.sessionKey;
|
|
280
|
-
break;
|
|
281
|
-
case "agent_turn_started":
|
|
282
|
-
next.startedAt = event.occurredAt;
|
|
283
|
-
next.sessionKey ??= event.sessionKey;
|
|
284
|
-
break;
|
|
285
|
-
case "agent_run_completed":
|
|
286
|
-
next.completedAt = event.occurredAt;
|
|
287
|
-
break;
|
|
288
|
-
case "agent_run_failed":
|
|
289
|
-
next.errorMessage = event.errorMessage;
|
|
290
|
-
next.failedAt = event.occurredAt;
|
|
291
|
-
break;
|
|
292
|
-
case "agent_run_cancelled":
|
|
293
|
-
if (event.reason === void 0) delete next.cancellationReason;
|
|
294
|
-
else next.cancellationReason = event.reason;
|
|
295
|
-
next.cancelledAt = event.occurredAt;
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
return next;
|
|
299
|
-
}
|
|
300
|
-
function toRunSummary(summary) {
|
|
301
|
-
return {
|
|
302
|
-
...summary.acceptedAt ? { acceptedAt: summary.acceptedAt } : {},
|
|
303
|
-
...summary.cancellationReason ? { cancellationReason: summary.cancellationReason } : {},
|
|
304
|
-
...summary.cancelledAt ? { cancelledAt: summary.cancelledAt } : {},
|
|
305
|
-
...summary.completedAt ? { completedAt: summary.completedAt } : {},
|
|
306
|
-
...summary.errorMessage ? { errorMessage: summary.errorMessage } : {},
|
|
307
|
-
eventCount: summary.eventCount,
|
|
308
|
-
failedSkillExecutionCount: summary.failedSkillExecutionCount,
|
|
309
|
-
failedToolExecutionCount: summary.failedToolExecutionCount,
|
|
310
|
-
...summary.failedAt ? { failedAt: summary.failedAt } : {},
|
|
311
|
-
finalText: summary.finalText,
|
|
312
|
-
phase: summary.phase,
|
|
313
|
-
...summary.prompt ? { prompt: summary.prompt } : {},
|
|
314
|
-
runId: summary.runId,
|
|
315
|
-
...summary.sessionKey ? { sessionKey: summary.sessionKey } : {},
|
|
316
|
-
...summary.startedAt ? { startedAt: summary.startedAt } : {},
|
|
317
|
-
state: summary.state,
|
|
318
|
-
thinkingText: summary.thinkingText,
|
|
319
|
-
skillExecutionCount: summary.skillExecutionCount,
|
|
320
|
-
toolExecutionCount: summary.toolExecutionCount,
|
|
321
|
-
updatedAt: summary.updatedAt
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
function buildSessionSummaries(runs) {
|
|
325
|
-
const sessions = /* @__PURE__ */ new Map();
|
|
326
|
-
for (const run of runs) {
|
|
327
|
-
if (!run.sessionKey) continue;
|
|
328
|
-
sessions.set(run.sessionKey, [...sessions.get(run.sessionKey) ?? [], run]);
|
|
329
|
-
}
|
|
330
|
-
return [...sessions.entries()].map(([sessionKey, sessionRuns]) => {
|
|
331
|
-
const latest = sessionRuns[sessionRuns.length - 1];
|
|
332
|
-
if (!latest) throw new Error(`session ${sessionKey} has no runs`);
|
|
333
|
-
return {
|
|
334
|
-
failedSkillExecutionCount: latest.failedSkillExecutionCount,
|
|
335
|
-
failedToolExecutionCount: latest.failedToolExecutionCount,
|
|
336
|
-
finalText: latest.finalText,
|
|
337
|
-
latestPhase: latest.phase,
|
|
338
|
-
latestRunId: latest.runId,
|
|
339
|
-
runCount: sessionRuns.length,
|
|
340
|
-
runIds: sessionRuns.map((run) => run.runId),
|
|
341
|
-
sessionKey,
|
|
342
|
-
skillExecutionCount: latest.skillExecutionCount,
|
|
343
|
-
thinkingText: latest.thinkingText,
|
|
344
|
-
toolExecutionCount: latest.toolExecutionCount,
|
|
345
|
-
updatedAt: latest.updatedAt
|
|
346
|
-
};
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
//#endregion
|
|
350
|
-
//#region src/modules/agent-execution/domain/transcript/agent-transcript.ts
|
|
351
|
-
function replayAgentTranscript(events, sessionKey) {
|
|
352
|
-
const turns = replayAgentHistory(events).runs.filter((run) => run.sessionKey === sessionKey).map(createAgentTranscriptTurn);
|
|
353
|
-
const latestTurn = turns.at(-1);
|
|
354
|
-
return {
|
|
355
|
-
...latestTurn ? { latestTurn } : {},
|
|
356
|
-
sessionKey,
|
|
357
|
-
turnCount: turns.length,
|
|
358
|
-
turns
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
function createAgentTranscriptTurn(summary) {
|
|
362
|
-
return {
|
|
363
|
-
...summary.acceptedAt ? { acceptedAt: summary.acceptedAt } : {},
|
|
364
|
-
assistantText: summary.finalText,
|
|
365
|
-
...summary.cancellationReason ? { cancellationReason: summary.cancellationReason } : {},
|
|
366
|
-
...summary.cancelledAt ? { cancelledAt: summary.cancelledAt } : {},
|
|
367
|
-
...summary.completedAt ? { completedAt: summary.completedAt } : {},
|
|
368
|
-
...summary.errorMessage ? { errorMessage: summary.errorMessage } : {},
|
|
369
|
-
...summary.failedAt ? { failedAt: summary.failedAt } : {},
|
|
370
|
-
failedToolExecutionCount: summary.failedToolExecutionCount,
|
|
371
|
-
phase: summary.phase,
|
|
372
|
-
runId: summary.runId,
|
|
373
|
-
sessionKey: summary.sessionKey,
|
|
374
|
-
thinkingText: summary.thinkingText,
|
|
375
|
-
toolExecutionCount: summary.toolExecutionCount,
|
|
376
|
-
updatedAt: summary.updatedAt,
|
|
377
|
-
userText: summary.prompt ?? ""
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
function createAgentTranscriptMessages(transcript) {
|
|
381
|
-
return transcript.turns.flatMap((turn) => {
|
|
382
|
-
const messages = [{
|
|
383
|
-
content: turn.userText,
|
|
384
|
-
role: "user"
|
|
385
|
-
}];
|
|
386
|
-
if (turn.assistantText) messages.push({
|
|
387
|
-
content: turn.assistantText,
|
|
388
|
-
role: "assistant"
|
|
389
|
-
});
|
|
390
|
-
return messages;
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
function createAgentConversationMessages(options) {
|
|
394
|
-
return [...options.transcript ? createAgentTranscriptMessages(options.transcript) : [], {
|
|
395
|
-
content: options.text,
|
|
396
|
-
role: "user"
|
|
397
|
-
}];
|
|
398
|
-
}
|
|
399
|
-
//#endregion
|
|
400
|
-
//#region src/modules/agent-execution/application/contracts/agent-execution-errors.ts
|
|
401
|
-
var AgentHarnessBusy = class {
|
|
402
|
-
activeRun;
|
|
403
|
-
activeState;
|
|
404
|
-
_tag = "AgentHarnessBusy";
|
|
405
|
-
activeRunId;
|
|
406
|
-
activeSessionKey;
|
|
407
|
-
constructor(activeRun, activeState) {
|
|
408
|
-
this.activeRun = activeRun;
|
|
409
|
-
this.activeState = activeState;
|
|
410
|
-
this.activeRunId = activeRun.runId;
|
|
411
|
-
this.activeSessionKey = activeRun.sessionKey;
|
|
412
|
-
}
|
|
413
|
-
};
|
|
414
|
-
var AgentLoopFailed = class {
|
|
415
|
-
runId;
|
|
416
|
-
errorMessage;
|
|
417
|
-
cause;
|
|
418
|
-
state;
|
|
419
|
-
_tag = "AgentLoopFailed";
|
|
420
|
-
constructor(runId, errorMessage, cause, state) {
|
|
421
|
-
this.runId = runId;
|
|
422
|
-
this.errorMessage = errorMessage;
|
|
423
|
-
this.cause = cause;
|
|
424
|
-
this.state = state;
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
var AgentEventSinkFailed = class {
|
|
428
|
-
runId;
|
|
429
|
-
eventType;
|
|
430
|
-
cause;
|
|
431
|
-
_tag = "AgentEventSinkFailed";
|
|
432
|
-
constructor(runId, eventType, cause) {
|
|
433
|
-
this.runId = runId;
|
|
434
|
-
this.eventType = eventType;
|
|
435
|
-
this.cause = cause;
|
|
436
|
-
}
|
|
437
|
-
};
|
|
438
|
-
var AgentEventHandlerFailed = class {
|
|
439
|
-
runId;
|
|
440
|
-
eventType;
|
|
441
|
-
cause;
|
|
442
|
-
state;
|
|
443
|
-
_tag = "AgentEventHandlerFailed";
|
|
444
|
-
constructor(runId, eventType, cause, state) {
|
|
445
|
-
this.runId = runId;
|
|
446
|
-
this.eventType = eventType;
|
|
447
|
-
this.cause = cause;
|
|
448
|
-
this.state = state;
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
var AgentRunCancelled = class {
|
|
452
|
-
runId;
|
|
453
|
-
reason;
|
|
454
|
-
state;
|
|
455
|
-
_tag = "AgentRunCancelled";
|
|
456
|
-
constructor(runId, reason, state) {
|
|
457
|
-
this.runId = runId;
|
|
458
|
-
this.reason = reason;
|
|
459
|
-
this.state = state;
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
//#endregion
|
|
463
|
-
//#region src/modules/agent-execution/application/execution/agent-event-sink.ts
|
|
464
|
-
function createAgentDomainEventSink(append) {
|
|
465
|
-
return { append };
|
|
466
|
-
}
|
|
467
|
-
//#endregion
|
|
468
|
-
//#region src/modules/agent-execution/application/query/agent-event-notifications.ts
|
|
469
|
-
function notifyListeners(listeners, event) {
|
|
470
|
-
for (const listener of listeners) try {
|
|
471
|
-
listener(event);
|
|
472
|
-
} catch {}
|
|
473
|
-
}
|
|
474
|
-
function notifyUpdateListeners(listeners, update) {
|
|
475
|
-
for (const listener of listeners) try {
|
|
476
|
-
listener(update);
|
|
477
|
-
} catch {}
|
|
478
|
-
}
|
|
479
|
-
//#endregion
|
|
480
|
-
//#region src/modules/agent-execution/application/query/agent-run-projection.ts
|
|
481
|
-
function toRunUpdate(event, state, previousState) {
|
|
482
|
-
return {
|
|
483
|
-
event,
|
|
484
|
-
...previousState ? { previousState } : {},
|
|
485
|
-
state
|
|
486
|
-
};
|
|
487
|
-
}
|
|
488
|
-
function replayRunUpdates(events) {
|
|
489
|
-
const updates = [];
|
|
490
|
-
let state = initialAgentRunState;
|
|
491
|
-
for (const event of events) {
|
|
492
|
-
const previousState = updates.length === 0 ? void 0 : state;
|
|
493
|
-
state = evolveAgentRun(state, event);
|
|
494
|
-
updates.push(toRunUpdate(event, state, previousState));
|
|
495
|
-
}
|
|
496
|
-
return updates;
|
|
497
|
-
}
|
|
498
|
-
function buildRunSnapshot(runId, events, updates, state, summary = replayAgentHistory(events).runs[0]) {
|
|
499
|
-
return {
|
|
500
|
-
events: [...events],
|
|
501
|
-
runId,
|
|
502
|
-
...state ? { state } : {},
|
|
503
|
-
summary,
|
|
504
|
-
updates: [...updates]
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
//#endregion
|
|
508
|
-
//#region src/modules/agent-execution/application/query/agent-session-history.ts
|
|
509
|
-
function projectAgentSessionHistory(events, runStates, sessionKey) {
|
|
510
|
-
const history = replayAgentHistory(events.filter((event) => runStates.get(event.runId)?.sessionKey === sessionKey));
|
|
511
|
-
const runs = history.runs;
|
|
512
|
-
const latestRunSummary = runs.at(-1);
|
|
513
|
-
const summary = history.sessions[0];
|
|
514
|
-
return {
|
|
515
|
-
history,
|
|
516
|
-
...latestRunSummary ? { latestRunSummary } : {},
|
|
517
|
-
runs,
|
|
518
|
-
...summary ? { summary } : {},
|
|
519
|
-
transcript: replayAgentTranscript(events, sessionKey)
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
function buildAgentSessionSnapshot(input) {
|
|
523
|
-
return {
|
|
524
|
-
availability: input.availability,
|
|
525
|
-
...input.view.latestRunSummary ? { latestRunSummary: input.view.latestRunSummary } : {},
|
|
526
|
-
runs: input.view.runs,
|
|
527
|
-
sessionKey: input.sessionKey,
|
|
528
|
-
...input.state ? { state: input.state } : {},
|
|
529
|
-
...input.view.summary ? { summary: input.view.summary } : {},
|
|
530
|
-
transcript: input.view.transcript
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
//#endregion
|
|
534
|
-
//#region src/modules/agent-execution/application/query/agent-execution-query-store.ts
|
|
535
|
-
function createAgentExecutionQueryStore(options = {}) {
|
|
536
|
-
const domainEvents = [];
|
|
537
|
-
const runEvents = /* @__PURE__ */ new Map();
|
|
538
|
-
const runStates = /* @__PURE__ */ new Map();
|
|
539
|
-
const sessionStates = /* @__PURE__ */ new Map();
|
|
540
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
541
|
-
const updateListeners = /* @__PURE__ */ new Set();
|
|
542
|
-
let latestState = initialAgentRunState;
|
|
543
|
-
const recordEvent = (event, notify) => {
|
|
544
|
-
const previousEvents = runEvents.get(event.runId);
|
|
545
|
-
const previousState = previousEvents && previousEvents.length > 0 ? runStates.get(event.runId) : void 0;
|
|
546
|
-
domainEvents.push(event);
|
|
547
|
-
if (previousEvents) previousEvents.push(event);
|
|
548
|
-
else runEvents.set(event.runId, [event]);
|
|
549
|
-
const state = evolveAgentRun(previousState ?? initialAgentRunState, event);
|
|
550
|
-
const update = toRunUpdate(event, state, previousState);
|
|
551
|
-
latestState = state;
|
|
552
|
-
if (state.runId) runStates.set(state.runId, state);
|
|
553
|
-
if (state.sessionKey) sessionStates.set(state.sessionKey, state);
|
|
554
|
-
if (notify) {
|
|
555
|
-
notifyListeners(listeners, event);
|
|
556
|
-
notifyUpdateListeners(updateListeners, update);
|
|
557
|
-
}
|
|
558
|
-
return update;
|
|
559
|
-
};
|
|
560
|
-
for (const event of options.initialEvents ?? []) recordEvent(event, false);
|
|
561
|
-
for (const state of options.initialRunStates ?? []) {
|
|
562
|
-
if (state.runId) runStates.set(state.runId, state);
|
|
563
|
-
if (state.sessionKey && isTerminalAgentRunPhase(state.phase)) sessionStates.set(state.sessionKey, state);
|
|
564
|
-
latestState = state;
|
|
565
|
-
}
|
|
566
|
-
const getRunEvents = (runId) => {
|
|
567
|
-
const events = runEvents.get(runId);
|
|
568
|
-
return events ? [...events] : void 0;
|
|
569
|
-
};
|
|
570
|
-
const getRunSummary = (runId) => {
|
|
571
|
-
const events = runEvents.get(runId);
|
|
572
|
-
return events ? replayAgentHistory(events).runs[0] : void 0;
|
|
573
|
-
};
|
|
574
|
-
const getRunUpdates = (runId) => {
|
|
575
|
-
const events = runEvents.get(runId);
|
|
576
|
-
return events ? replayRunUpdates(events) : void 0;
|
|
577
|
-
};
|
|
578
|
-
const getRunSnapshot = (runId) => {
|
|
579
|
-
const events = getRunEvents(runId);
|
|
580
|
-
const summary = getRunSummary(runId);
|
|
581
|
-
return events && summary ? buildRunSnapshot(runId, events, getRunUpdates(runId) ?? [], runStates.get(runId), summary) : void 0;
|
|
582
|
-
};
|
|
583
|
-
const getSessionView = (sessionKey) => projectAgentSessionHistory(domainEvents, runStates, sessionKey);
|
|
584
|
-
const getSessionHistory = (sessionKey) => getSessionView(sessionKey).history;
|
|
585
|
-
const getSessionRuns = (sessionKey) => getSessionView(sessionKey).runs;
|
|
586
|
-
const getSessionLatestRunSummary = (sessionKey) => getSessionView(sessionKey).latestRunSummary;
|
|
587
|
-
const getSessionRunSnapshot = (sessionKey, runId) => runStates.get(runId)?.sessionKey === sessionKey ? getRunSnapshot(runId) : void 0;
|
|
588
|
-
const getSessionLatestRunSnapshot = (sessionKey) => {
|
|
589
|
-
const latestRunId = getSessionLatestRunSummary(sessionKey)?.runId;
|
|
590
|
-
return latestRunId ? getSessionRunSnapshot(sessionKey, latestRunId) : void 0;
|
|
591
|
-
};
|
|
592
|
-
const subscribe = (listener) => {
|
|
593
|
-
listeners.add(listener);
|
|
594
|
-
return () => listeners.delete(listener);
|
|
595
|
-
};
|
|
596
|
-
const subscribeUpdates = (listener) => {
|
|
597
|
-
updateListeners.add(listener);
|
|
598
|
-
return () => updateListeners.delete(listener);
|
|
599
|
-
};
|
|
600
|
-
return {
|
|
601
|
-
project: (event) => recordEvent(event, true),
|
|
602
|
-
getHistory: () => replayAgentHistory(domainEvents),
|
|
603
|
-
getLatestState: () => latestState,
|
|
604
|
-
getRunEvents,
|
|
605
|
-
getRunSnapshot,
|
|
606
|
-
getRunState: (runId) => runStates.get(runId),
|
|
607
|
-
getRunSummary,
|
|
608
|
-
getRunUpdates,
|
|
609
|
-
getSessionHistory,
|
|
610
|
-
getSessionLatestRunSnapshot,
|
|
611
|
-
getSessionLatestRunSummary,
|
|
612
|
-
getSessionRunEvents: (sessionKey, runId) => runStates.get(runId)?.sessionKey === sessionKey ? getRunEvents(runId) : void 0,
|
|
613
|
-
getSessionRunSnapshot,
|
|
614
|
-
getSessionRunState: (sessionKey, runId) => {
|
|
615
|
-
const state = runStates.get(runId);
|
|
616
|
-
return state?.sessionKey === sessionKey ? state : void 0;
|
|
617
|
-
},
|
|
618
|
-
getSessionRunSummary: (sessionKey, runId) => runStates.get(runId)?.sessionKey === sessionKey ? getRunSummary(runId) : void 0,
|
|
619
|
-
getSessionRunUpdates: (sessionKey, runId) => runStates.get(runId)?.sessionKey === sessionKey ? getRunUpdates(runId) : void 0,
|
|
620
|
-
getSessionRuns,
|
|
621
|
-
getSessionSnapshot: (sessionKey, availability) => {
|
|
622
|
-
const state = sessionStates.get(sessionKey);
|
|
623
|
-
return buildAgentSessionSnapshot({
|
|
624
|
-
availability,
|
|
625
|
-
sessionKey,
|
|
626
|
-
...state ? { state } : {},
|
|
627
|
-
view: getSessionView(sessionKey)
|
|
628
|
-
});
|
|
629
|
-
},
|
|
630
|
-
getSessionState: (sessionKey) => sessionStates.get(sessionKey),
|
|
631
|
-
getSessionSummary: (sessionKey) => getSessionView(sessionKey).summary,
|
|
632
|
-
getSessionTranscript: (sessionKey) => getSessionView(sessionKey).transcript,
|
|
633
|
-
subscribe,
|
|
634
|
-
subscribeRun: (runId, listener) => subscribe((event) => {
|
|
635
|
-
if (event.runId === runId) listener(event);
|
|
636
|
-
}),
|
|
637
|
-
subscribeRunUpdates: (runId, listener) => subscribeUpdates((update) => {
|
|
638
|
-
if (update.event.runId === runId) listener(update);
|
|
639
|
-
}),
|
|
640
|
-
subscribeSession: (sessionKey, listener) => subscribe((event) => {
|
|
641
|
-
if (runStates.get(event.runId)?.sessionKey === sessionKey) listener(event);
|
|
642
|
-
}),
|
|
643
|
-
subscribeSessionRun: (sessionKey, runId, listener) => subscribe((event) => {
|
|
644
|
-
if (event.runId === runId && runStates.get(runId)?.sessionKey === sessionKey) listener(event);
|
|
645
|
-
}),
|
|
646
|
-
subscribeSessionRunUpdates: (sessionKey, runId, listener) => subscribeUpdates((update) => {
|
|
647
|
-
if (update.event.runId === runId && update.state.sessionKey === sessionKey) listener(update);
|
|
648
|
-
}),
|
|
649
|
-
subscribeSessionUpdates: (sessionKey, listener) => subscribeUpdates((update) => {
|
|
650
|
-
if (update.state.sessionKey === sessionKey) listener(update);
|
|
651
|
-
}),
|
|
652
|
-
subscribeUpdates
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
//#endregion
|
|
656
|
-
//#region src/modules/agent-execution/application/streaming/agent-run-streams.ts
|
|
657
|
-
function createAgentRunStreams(runPrompt) {
|
|
658
|
-
return {
|
|
659
|
-
events: (command) => createProjectedRunStream(runPrompt, command, (event) => Option.some(event)),
|
|
660
|
-
text: (command) => createProjectedRunStream(runPrompt, command, (event) => event.type === "assistant_text_delta" ? Option.some(event.delta) : Option.none()),
|
|
661
|
-
updates: (command) => createProjectedRunStream(runPrompt, command, (event, state, previousState) => Option.some(toRunUpdate(event, state, previousState)))
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
|
-
function createProjectedRunStream(runPrompt, command, project) {
|
|
665
|
-
return Stream.asyncEffect((emit) => runPrompt(command, (event, state, previousState) => Option.match(project(event, state, previousState), {
|
|
666
|
-
onNone: () => Effect.void,
|
|
667
|
-
onSome: (value) => Effect.promise(() => emit.single(value))
|
|
668
|
-
}), "stream interrupted").pipe(Effect.flatMap(() => Effect.promise(() => emit.end())), Effect.catchAll((error) => Effect.promise(() => emit.fail(error)))));
|
|
669
|
-
}
|
|
670
|
-
//#endregion
|
|
671
|
-
//#region src/modules/agent-execution/application/execution/agent-loop-event-mapper.ts
|
|
672
|
-
function describeLoopError(error) {
|
|
673
|
-
if (error instanceof Error) return error.message;
|
|
674
|
-
if (typeof error === "string") return error;
|
|
675
|
-
try {
|
|
676
|
-
return JSON.stringify(error);
|
|
677
|
-
} catch {
|
|
678
|
-
return String(error);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
function toDomainEvent(runId, sessionKey, event, occurredAt) {
|
|
682
|
-
switch (event.type) {
|
|
683
|
-
case "turn_start": return {
|
|
684
|
-
occurredAt,
|
|
685
|
-
runId,
|
|
686
|
-
sessionKey,
|
|
687
|
-
type: "agent_turn_started"
|
|
688
|
-
};
|
|
689
|
-
case "assistant_text_delta": return {
|
|
690
|
-
delta: event.delta,
|
|
691
|
-
occurredAt,
|
|
692
|
-
runId,
|
|
693
|
-
type: "assistant_text_delta"
|
|
694
|
-
};
|
|
695
|
-
case "assistant_thinking_delta": return {
|
|
696
|
-
delta: event.delta,
|
|
697
|
-
occurredAt,
|
|
698
|
-
runId,
|
|
699
|
-
type: "assistant_thinking_delta"
|
|
700
|
-
};
|
|
701
|
-
case "model_execution_start": return {
|
|
702
|
-
api: event.api,
|
|
703
|
-
model: event.model,
|
|
704
|
-
modelCallId: event.modelCallId,
|
|
705
|
-
occurredAt,
|
|
706
|
-
provider: event.provider,
|
|
707
|
-
runId,
|
|
708
|
-
type: "agent_model_execution_started"
|
|
709
|
-
};
|
|
710
|
-
case "model_execution_end": return {
|
|
711
|
-
api: event.api,
|
|
712
|
-
...event.errorMessage ? { errorMessage: event.errorMessage } : {},
|
|
713
|
-
model: event.model,
|
|
714
|
-
modelCallId: event.modelCallId,
|
|
715
|
-
occurredAt,
|
|
716
|
-
provider: event.provider,
|
|
717
|
-
...event.responseModel ? { responseModel: event.responseModel } : {},
|
|
718
|
-
runId,
|
|
719
|
-
stopReason: event.stopReason,
|
|
720
|
-
type: "agent_model_execution_ended",
|
|
721
|
-
usage: event.usage
|
|
722
|
-
};
|
|
723
|
-
case "skill_execution_start": return {
|
|
724
|
-
occurredAt,
|
|
725
|
-
runId,
|
|
726
|
-
skillCallId: event.skillCallId,
|
|
727
|
-
skillId: event.skillId,
|
|
728
|
-
type: "agent_skill_execution_started"
|
|
729
|
-
};
|
|
730
|
-
case "skill_execution_end": return event.isError ? {
|
|
731
|
-
isError: true,
|
|
732
|
-
occurredAt,
|
|
733
|
-
runId,
|
|
734
|
-
skillCallId: event.skillCallId,
|
|
735
|
-
skillId: event.skillId,
|
|
736
|
-
type: "agent_skill_execution_ended"
|
|
737
|
-
} : {
|
|
738
|
-
contentLength: event.contentLength,
|
|
739
|
-
digest: event.digest,
|
|
740
|
-
isError: false,
|
|
741
|
-
occurredAt,
|
|
742
|
-
runId,
|
|
743
|
-
skillCallId: event.skillCallId,
|
|
744
|
-
skillId: event.skillId,
|
|
745
|
-
title: event.title,
|
|
746
|
-
type: "agent_skill_execution_ended",
|
|
747
|
-
version: event.version
|
|
748
|
-
};
|
|
749
|
-
case "tool_execution_start": return {
|
|
750
|
-
input: event.input,
|
|
751
|
-
occurredAt,
|
|
752
|
-
runId,
|
|
753
|
-
toolCallId: event.toolCallId,
|
|
754
|
-
toolName: event.toolName,
|
|
755
|
-
type: "agent_tool_execution_started"
|
|
756
|
-
};
|
|
757
|
-
case "tool_execution_update": return {
|
|
758
|
-
input: event.input,
|
|
759
|
-
occurredAt,
|
|
760
|
-
partialResult: event.partialResult,
|
|
761
|
-
runId,
|
|
762
|
-
toolCallId: event.toolCallId,
|
|
763
|
-
toolName: event.toolName,
|
|
764
|
-
type: "agent_tool_execution_updated"
|
|
765
|
-
};
|
|
766
|
-
case "tool_execution_end": return {
|
|
767
|
-
isError: event.isError,
|
|
768
|
-
occurredAt,
|
|
769
|
-
result: event.result,
|
|
770
|
-
runId,
|
|
771
|
-
toolCallId: event.toolCallId,
|
|
772
|
-
toolName: event.toolName,
|
|
773
|
-
type: "agent_tool_execution_ended"
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
//#endregion
|
|
778
|
-
//#region src/modules/agent-execution/application/execution/agent-harness.ts
|
|
779
|
-
function createSteeringChannel() {
|
|
780
|
-
return Queue.unbounded().pipe(Effect.map((queue) => ({
|
|
781
|
-
next: () => Queue.take(queue),
|
|
782
|
-
push: (text) => Queue.offer(queue, text).pipe(Effect.asVoid)
|
|
783
|
-
})));
|
|
784
|
-
}
|
|
785
|
-
function createAgentHarness(options) {
|
|
786
|
-
if (options.runTimeoutMs !== void 0 && (!Number.isSafeInteger(options.runTimeoutMs) || options.runTimeoutMs < 1)) throw new Error("Agent run timeout must be a positive integer");
|
|
787
|
-
let activeRun;
|
|
788
|
-
let activeCancellation;
|
|
789
|
-
let activeRunState;
|
|
790
|
-
const queryStore = createAgentExecutionQueryStore({
|
|
791
|
-
...options.initialEvents ? { initialEvents: options.initialEvents } : {},
|
|
792
|
-
...options.initialRunStates ? { initialRunStates: options.initialRunStates } : {}
|
|
793
|
-
});
|
|
794
|
-
const getAvailability = () => {
|
|
795
|
-
if (!activeRun) return { busy: false };
|
|
796
|
-
return {
|
|
797
|
-
activeRun,
|
|
798
|
-
activeRunId: activeRun.runId,
|
|
799
|
-
activeSessionKey: activeRun.sessionKey,
|
|
800
|
-
...activeRunState ? { activeState: activeRunState } : {},
|
|
801
|
-
busy: true
|
|
802
|
-
};
|
|
803
|
-
};
|
|
804
|
-
const getSessionAvailability = (sessionKey) => {
|
|
805
|
-
if (!activeRun) return { busy: false };
|
|
806
|
-
if (activeRun.sessionKey !== sessionKey) return {
|
|
807
|
-
activeInSession: false,
|
|
808
|
-
busy: true
|
|
809
|
-
};
|
|
810
|
-
return {
|
|
811
|
-
activeInSession: true,
|
|
812
|
-
activeRun,
|
|
813
|
-
activeRunId: activeRun.runId,
|
|
814
|
-
...activeRunState ? { activeState: activeRunState } : {},
|
|
815
|
-
busy: true
|
|
816
|
-
};
|
|
817
|
-
};
|
|
818
|
-
const runPrompt = (command, emit, interruptionReason = "run interrupted") => Effect.gen(function* () {
|
|
819
|
-
if (activeRun !== void 0) return yield* Effect.fail(new AgentHarnessBusy(activeRun, activeRunState));
|
|
820
|
-
const runId = yield* options.runIds.next;
|
|
821
|
-
activeRun = {
|
|
822
|
-
runId,
|
|
823
|
-
sessionKey: command.sessionKey
|
|
824
|
-
};
|
|
825
|
-
const previousSessionState = queryStore.getSessionState(command.sessionKey);
|
|
826
|
-
const previousSessionTranscript = queryStore.getSessionTranscript(command.sessionKey);
|
|
827
|
-
const cancellation = {
|
|
828
|
-
abortController: new AbortController(),
|
|
829
|
-
deferred: yield* Deferred.make(),
|
|
830
|
-
steering: yield* createSteeringChannel()
|
|
831
|
-
};
|
|
832
|
-
activeCancellation = cancellation;
|
|
833
|
-
const events = [];
|
|
834
|
-
const updates = [];
|
|
835
|
-
let settled = false;
|
|
836
|
-
let state = initialAgentRunState;
|
|
837
|
-
const project = (event) => Effect.gen(function* () {
|
|
838
|
-
for (const sink of options.eventSinks ?? []) yield* Effect.try({
|
|
839
|
-
try: () => sink.append(event),
|
|
840
|
-
catch: (error) => error
|
|
841
|
-
}).pipe(Effect.flatMap((appendEffect) => appendEffect), Effect.catchAll((error) => Effect.fail(new AgentEventSinkFailed(event.runId, event.type, error))));
|
|
842
|
-
events.push(event);
|
|
843
|
-
const update = queryStore.project(event);
|
|
844
|
-
state = update.state;
|
|
845
|
-
updates.push(update);
|
|
846
|
-
if (activeRun?.runId === state.runId) activeRunState = state;
|
|
847
|
-
return update;
|
|
848
|
-
});
|
|
849
|
-
const record = (event) => Effect.gen(function* () {
|
|
850
|
-
const update = yield* project(event);
|
|
851
|
-
yield* emit(update.event, update.state, update.previousState).pipe(Effect.catchAll((error) => Effect.fail(new AgentEventHandlerFailed(event.runId, event.type, error, state))));
|
|
852
|
-
});
|
|
853
|
-
const recordWithoutEmit = (event) => project(event).pipe(Effect.asVoid);
|
|
854
|
-
const recordInterruptedRun = Effect.gen(function* () {
|
|
855
|
-
if (settled) return;
|
|
856
|
-
if (!cancellation.abortController.signal.aborted) cancellation.abortController.abort({
|
|
857
|
-
reason: interruptionReason,
|
|
858
|
-
runId,
|
|
859
|
-
sessionKey: command.sessionKey
|
|
860
|
-
});
|
|
861
|
-
const interruptedAt = yield* options.clock.now;
|
|
862
|
-
yield* recordWithoutEmit({
|
|
863
|
-
reason: cancellation.requested?.reason ?? interruptionReason,
|
|
864
|
-
occurredAt: interruptedAt,
|
|
865
|
-
runId,
|
|
866
|
-
type: "agent_run_cancelled"
|
|
867
|
-
}).pipe(Effect.catchAll(() => Effect.void));
|
|
868
|
-
settled = true;
|
|
869
|
-
});
|
|
870
|
-
return yield* Effect.gen(function* () {
|
|
871
|
-
const acceptedAt = yield* options.clock.now;
|
|
872
|
-
yield* record({
|
|
873
|
-
occurredAt: acceptedAt,
|
|
874
|
-
prompt: command.text,
|
|
875
|
-
runId,
|
|
876
|
-
sessionKey: command.sessionKey,
|
|
877
|
-
type: "agent_run_accepted"
|
|
878
|
-
});
|
|
879
|
-
const startedAt = yield* options.clock.now;
|
|
880
|
-
yield* record({
|
|
881
|
-
occurredAt: startedAt,
|
|
882
|
-
runId,
|
|
883
|
-
sessionKey: command.sessionKey,
|
|
884
|
-
type: "agent_turn_started"
|
|
885
|
-
});
|
|
886
|
-
const loopInput = {
|
|
887
|
-
abortSignal: cancellation.abortController.signal,
|
|
888
|
-
...command.invocation ? { invocation: command.invocation } : {},
|
|
889
|
-
messages: createAgentConversationMessages({
|
|
890
|
-
text: command.text,
|
|
891
|
-
transcript: previousSessionTranscript
|
|
892
|
-
}),
|
|
893
|
-
...previousSessionState ? { previousSessionState } : {},
|
|
894
|
-
...previousSessionTranscript.turnCount > 0 ? { previousSessionTranscript } : {},
|
|
895
|
-
runId,
|
|
896
|
-
sessionKey: command.sessionKey,
|
|
897
|
-
...options.loop.supportsSteering ? { steering: cancellation.steering } : {},
|
|
898
|
-
text: command.text
|
|
899
|
-
};
|
|
900
|
-
const loop = Effect.try({
|
|
901
|
-
try: () => options.loop.run(loopInput),
|
|
902
|
-
catch: (error) => error
|
|
903
|
-
}).pipe(Effect.flatMap((loopStream) => Stream.runForEach(loopStream.pipe(Stream.interruptWhenDeferred(cancellation.deferred)), (event) => Effect.gen(function* () {
|
|
904
|
-
const occurredAt = yield* options.clock.now;
|
|
905
|
-
yield* record(toDomainEvent(runId, command.sessionKey, event, occurredAt));
|
|
906
|
-
}))), Effect.catchAll((error) => {
|
|
907
|
-
if (error instanceof AgentEventSinkFailed || error instanceof AgentEventHandlerFailed) return Effect.fail(error);
|
|
908
|
-
return Effect.gen(function* () {
|
|
909
|
-
const occurredAt = yield* options.clock.now;
|
|
910
|
-
const errorMessage = describeLoopError(error);
|
|
911
|
-
yield* record({
|
|
912
|
-
errorMessage,
|
|
913
|
-
occurredAt,
|
|
914
|
-
runId,
|
|
915
|
-
type: "agent_run_failed"
|
|
916
|
-
});
|
|
917
|
-
settled = true;
|
|
918
|
-
return yield* Effect.fail(new AgentLoopFailed(runId, errorMessage, error, state));
|
|
919
|
-
});
|
|
920
|
-
}));
|
|
921
|
-
yield* options.runTimeoutMs === void 0 ? loop : Effect.raceFirst(loop, Effect.sleep(options.runTimeoutMs).pipe(Effect.flatMap(() => {
|
|
922
|
-
const request = {
|
|
923
|
-
reason: `run timed out after ${options.runTimeoutMs}ms`,
|
|
924
|
-
runId,
|
|
925
|
-
sessionKey: command.sessionKey
|
|
926
|
-
};
|
|
927
|
-
cancellation.requested = request;
|
|
928
|
-
cancellation.abortController.abort(request);
|
|
929
|
-
return Deferred.succeed(cancellation.deferred, request);
|
|
930
|
-
}), Effect.asVoid));
|
|
931
|
-
if (cancellation.requested) {
|
|
932
|
-
const cancelledAt = yield* options.clock.now;
|
|
933
|
-
yield* record({
|
|
934
|
-
...cancellation.requested.reason ? { reason: cancellation.requested.reason } : {},
|
|
935
|
-
occurredAt: cancelledAt,
|
|
936
|
-
runId,
|
|
937
|
-
type: "agent_run_cancelled"
|
|
938
|
-
});
|
|
939
|
-
settled = true;
|
|
940
|
-
return yield* Effect.fail(new AgentRunCancelled(runId, cancellation.requested.reason, state));
|
|
941
|
-
}
|
|
942
|
-
const turnCompletedAt = yield* options.clock.now;
|
|
943
|
-
yield* record({
|
|
944
|
-
finalText: state.finalText,
|
|
945
|
-
occurredAt: turnCompletedAt,
|
|
946
|
-
runId,
|
|
947
|
-
type: "agent_turn_completed"
|
|
948
|
-
});
|
|
949
|
-
const completedAt = yield* options.clock.now;
|
|
950
|
-
yield* record({
|
|
951
|
-
finalText: state.finalText,
|
|
952
|
-
occurredAt: completedAt,
|
|
953
|
-
runId,
|
|
954
|
-
type: "agent_run_completed"
|
|
955
|
-
});
|
|
956
|
-
settled = true;
|
|
957
|
-
const runSnapshot = buildRunSnapshot(runId, events, updates, state);
|
|
958
|
-
const turn = createAgentTranscriptTurn({
|
|
959
|
-
...runSnapshot.summary,
|
|
960
|
-
sessionKey: command.sessionKey
|
|
961
|
-
});
|
|
962
|
-
return {
|
|
963
|
-
events,
|
|
964
|
-
finalText: state.finalText,
|
|
965
|
-
runId,
|
|
966
|
-
runSnapshot,
|
|
967
|
-
snapshot: queryStore.getSessionSnapshot(command.sessionKey, { busy: false }),
|
|
968
|
-
state,
|
|
969
|
-
turn,
|
|
970
|
-
updates
|
|
971
|
-
};
|
|
972
|
-
}).pipe(Effect.onInterrupt(() => recordInterruptedRun), Effect.ensuring(Effect.sync(() => {
|
|
973
|
-
if (!settled && !cancellation.abortController.signal.aborted) cancellation.abortController.abort({
|
|
974
|
-
reason: interruptionReason,
|
|
975
|
-
runId,
|
|
976
|
-
sessionKey: command.sessionKey
|
|
977
|
-
});
|
|
978
|
-
activeRun = void 0;
|
|
979
|
-
activeCancellation = void 0;
|
|
980
|
-
activeRunState = void 0;
|
|
981
|
-
})));
|
|
982
|
-
});
|
|
983
|
-
const requestCancellation = (runId, reason) => Effect.gen(function* () {
|
|
984
|
-
if (!activeRun || activeRun.runId !== runId || !activeCancellation || activeCancellation.requested) return false;
|
|
985
|
-
const request = {
|
|
986
|
-
...reason ? { reason } : {},
|
|
987
|
-
runId: activeRun.runId,
|
|
988
|
-
sessionKey: activeRun.sessionKey
|
|
989
|
-
};
|
|
990
|
-
const completed = yield* Deferred.succeed(activeCancellation.deferred, request);
|
|
991
|
-
if (completed) {
|
|
992
|
-
activeCancellation.requested = request;
|
|
993
|
-
activeCancellation.abortController.abort(request);
|
|
994
|
-
}
|
|
995
|
-
return completed;
|
|
996
|
-
});
|
|
997
|
-
const requestSteering = (runId, text) => Effect.gen(function* () {
|
|
998
|
-
const normalized = text.trim();
|
|
999
|
-
if (!normalized || !options.loop.supportsSteering || !activeRun || activeRun.runId !== runId || !activeCancellation || activeCancellation.requested) return false;
|
|
1000
|
-
yield* activeCancellation.steering.push(normalized);
|
|
1001
|
-
return true;
|
|
1002
|
-
});
|
|
1003
|
-
const requestSessionCancellation = (sessionKey, runId, reason) => {
|
|
1004
|
-
if (!activeRun || activeRun.sessionKey !== sessionKey) return Effect.succeed(false);
|
|
1005
|
-
return requestCancellation(runId, reason);
|
|
1006
|
-
};
|
|
1007
|
-
const requestSessionSteering = (sessionKey, runId, text) => {
|
|
1008
|
-
if (!activeRun || activeRun.sessionKey !== sessionKey) return Effect.succeed(false);
|
|
1009
|
-
return requestSteering(runId, text);
|
|
1010
|
-
};
|
|
1011
|
-
const requestSessionActiveCancellation = (sessionKey, reason) => {
|
|
1012
|
-
if (!activeRun || activeRun.sessionKey !== sessionKey) return Effect.succeed(false);
|
|
1013
|
-
return requestCancellation(activeRun.runId, reason);
|
|
1014
|
-
};
|
|
1015
|
-
const getSessionActiveRun = (sessionKey) => activeRun?.sessionKey === sessionKey ? activeRun : void 0;
|
|
1016
|
-
const getSessionActiveRunState = (sessionKey) => activeRun?.sessionKey === sessionKey ? activeRunState : void 0;
|
|
1017
|
-
const getSessionSnapshot = (sessionKey) => queryStore.getSessionSnapshot(sessionKey, getSessionAvailability(sessionKey));
|
|
1018
|
-
const streams = createAgentRunStreams(runPrompt);
|
|
1019
|
-
return {
|
|
1020
|
-
cancelActiveRun: (reason) => Effect.gen(function* () {
|
|
1021
|
-
if (!activeRun) return false;
|
|
1022
|
-
return yield* requestCancellation(activeRun.runId, reason);
|
|
1023
|
-
}),
|
|
1024
|
-
cancelRun: requestCancellation,
|
|
1025
|
-
steerRun: requestSteering,
|
|
1026
|
-
forSession: (sessionKey) => ({
|
|
1027
|
-
cancelActiveRun: (reason) => requestSessionActiveCancellation(sessionKey, reason),
|
|
1028
|
-
cancelRun: (runId, reason) => requestSessionCancellation(sessionKey, runId, reason),
|
|
1029
|
-
steerRun: (runId, text) => requestSessionSteering(sessionKey, runId, text),
|
|
1030
|
-
getActiveRun: () => getSessionActiveRun(sessionKey),
|
|
1031
|
-
getActiveRunState: () => getSessionActiveRunState(sessionKey),
|
|
1032
|
-
getAvailability: () => getSessionAvailability(sessionKey),
|
|
1033
|
-
getHistory: () => queryStore.getSessionHistory(sessionKey),
|
|
1034
|
-
getLatestRunSnapshot: () => queryStore.getSessionLatestRunSnapshot(sessionKey),
|
|
1035
|
-
getLatestRunSummary: () => queryStore.getSessionLatestRunSummary(sessionKey),
|
|
1036
|
-
getRunEvents: (runId) => queryStore.getSessionRunEvents(sessionKey, runId),
|
|
1037
|
-
getRunSnapshot: (runId) => queryStore.getSessionRunSnapshot(sessionKey, runId),
|
|
1038
|
-
getRunSummary: (runId) => queryStore.getSessionRunSummary(sessionKey, runId),
|
|
1039
|
-
getRuns: () => queryStore.getSessionRuns(sessionKey),
|
|
1040
|
-
getSnapshot: () => getSessionSnapshot(sessionKey),
|
|
1041
|
-
getSummary: () => queryStore.getSessionSummary(sessionKey),
|
|
1042
|
-
getTranscript: () => queryStore.getSessionTranscript(sessionKey),
|
|
1043
|
-
getRunState: (runId) => queryStore.getSessionRunState(sessionKey, runId),
|
|
1044
|
-
getRunUpdates: (runId) => queryStore.getSessionRunUpdates(sessionKey, runId),
|
|
1045
|
-
getState: () => queryStore.getSessionState(sessionKey),
|
|
1046
|
-
prompt: (text) => runPrompt({
|
|
1047
|
-
sessionKey,
|
|
1048
|
-
text
|
|
1049
|
-
}, () => Effect.void),
|
|
1050
|
-
promptRunSnapshot: (text) => runPrompt({
|
|
1051
|
-
sessionKey,
|
|
1052
|
-
text
|
|
1053
|
-
}, () => Effect.void).pipe(Effect.map((result) => result.runSnapshot)),
|
|
1054
|
-
promptSnapshot: (text) => runPrompt({
|
|
1055
|
-
sessionKey,
|
|
1056
|
-
text
|
|
1057
|
-
}, () => Effect.void).pipe(Effect.map((result) => result.snapshot)),
|
|
1058
|
-
promptText: (text) => runPrompt({
|
|
1059
|
-
sessionKey,
|
|
1060
|
-
text
|
|
1061
|
-
}, () => Effect.void).pipe(Effect.map((result) => result.finalText)),
|
|
1062
|
-
promptTurn: (text) => runPrompt({
|
|
1063
|
-
sessionKey,
|
|
1064
|
-
text
|
|
1065
|
-
}, () => Effect.void).pipe(Effect.map((result) => result.turn)),
|
|
1066
|
-
promptWithEvents: (text, onEvent) => runPrompt({
|
|
1067
|
-
sessionKey,
|
|
1068
|
-
text
|
|
1069
|
-
}, (event) => onEvent(event)),
|
|
1070
|
-
promptWithUpdates: (text, onUpdate) => runPrompt({
|
|
1071
|
-
sessionKey,
|
|
1072
|
-
text
|
|
1073
|
-
}, (event, state, previousState) => onUpdate(toRunUpdate(event, state, previousState))),
|
|
1074
|
-
stream: (text) => streams.events({
|
|
1075
|
-
sessionKey,
|
|
1076
|
-
text
|
|
1077
|
-
}),
|
|
1078
|
-
streamText: (text) => streams.text({
|
|
1079
|
-
sessionKey,
|
|
1080
|
-
text
|
|
1081
|
-
}),
|
|
1082
|
-
streamUpdates: (text) => streams.updates({
|
|
1083
|
-
sessionKey,
|
|
1084
|
-
text
|
|
1085
|
-
}),
|
|
1086
|
-
subscribe: (listener) => queryStore.subscribeSession(sessionKey, listener),
|
|
1087
|
-
subscribeRun: (runId, listener) => queryStore.subscribeSessionRun(sessionKey, runId, listener),
|
|
1088
|
-
subscribeRunUpdates: (runId, listener) => queryStore.subscribeSessionRunUpdates(sessionKey, runId, listener),
|
|
1089
|
-
subscribeUpdates: (listener) => queryStore.subscribeSessionUpdates(sessionKey, listener),
|
|
1090
|
-
sessionKey
|
|
1091
|
-
}),
|
|
1092
|
-
getActiveRun: () => activeRun,
|
|
1093
|
-
getActiveRunId: () => activeRun?.runId,
|
|
1094
|
-
getActiveRunState: () => activeRunState,
|
|
1095
|
-
getAvailability,
|
|
1096
|
-
getHistory: () => queryStore.getHistory(),
|
|
1097
|
-
getRunEvents: (runId) => queryStore.getRunEvents(runId),
|
|
1098
|
-
getRunSnapshot: (runId) => queryStore.getRunSnapshot(runId),
|
|
1099
|
-
getRunSummary: (runId) => queryStore.getRunSummary(runId),
|
|
1100
|
-
getRunState: (runId) => queryStore.getRunState(runId),
|
|
1101
|
-
getRunUpdates: (runId) => queryStore.getRunUpdates(runId),
|
|
1102
|
-
getSessionHistory: (sessionKey) => queryStore.getSessionHistory(sessionKey),
|
|
1103
|
-
getSessionLatestRunSnapshot: (sessionKey) => queryStore.getSessionLatestRunSnapshot(sessionKey),
|
|
1104
|
-
getSessionLatestRunSummary: (sessionKey) => queryStore.getSessionLatestRunSummary(sessionKey),
|
|
1105
|
-
getSessionRuns: (sessionKey) => queryStore.getSessionRuns(sessionKey),
|
|
1106
|
-
getSessionSnapshot,
|
|
1107
|
-
getSessionSummary: (sessionKey) => queryStore.getSessionSummary(sessionKey),
|
|
1108
|
-
getSessionTranscript: (sessionKey) => queryStore.getSessionTranscript(sessionKey),
|
|
1109
|
-
getSessionState: (sessionKey) => queryStore.getSessionState(sessionKey),
|
|
1110
|
-
getState: () => queryStore.getLatestState(),
|
|
1111
|
-
prompt: (command) => runPrompt(command, () => Effect.void),
|
|
1112
|
-
promptRunSnapshot: (command) => runPrompt(command, () => Effect.void).pipe(Effect.map((result) => result.runSnapshot)),
|
|
1113
|
-
promptSnapshot: (command) => runPrompt(command, () => Effect.void).pipe(Effect.map((result) => result.snapshot)),
|
|
1114
|
-
promptText: (command) => runPrompt(command, () => Effect.void).pipe(Effect.map((result) => result.finalText)),
|
|
1115
|
-
promptTurn: (command) => runPrompt(command, () => Effect.void).pipe(Effect.map((result) => result.turn)),
|
|
1116
|
-
promptWithEvents: (command, onEvent) => runPrompt(command, (event) => onEvent(event)),
|
|
1117
|
-
promptWithUpdates: (command, onUpdate) => runPrompt(command, (event, state, previousState) => onUpdate(toRunUpdate(event, state, previousState))),
|
|
1118
|
-
stream: (command) => streams.events(command),
|
|
1119
|
-
streamText: (command) => streams.text(command),
|
|
1120
|
-
streamUpdates: (command) => streams.updates(command),
|
|
1121
|
-
subscribe: (listener) => queryStore.subscribe(listener),
|
|
1122
|
-
subscribeRun: (runId, listener) => queryStore.subscribeRun(runId, listener),
|
|
1123
|
-
subscribeRunUpdates: (runId, listener) => queryStore.subscribeRunUpdates(runId, listener),
|
|
1124
|
-
subscribeUpdates: (listener) => queryStore.subscribeUpdates(listener)
|
|
1125
|
-
};
|
|
1126
|
-
}
|
|
1127
|
-
//#endregion
|
|
1128
|
-
//#region src/modules/agent-execution/application/history/agent-history.ts
|
|
1129
|
-
function restoreAgentHistory(eventLog) {
|
|
1130
|
-
return eventLog.readAll().pipe(Effect.map(replayAgentHistory));
|
|
1131
|
-
}
|
|
1132
|
-
//#endregion
|
|
1133
|
-
//#region src/modules/agent-execution/application/context/agent-context-assembler.ts
|
|
1134
|
-
var AgentContextBudgetExceeded = class extends Error {
|
|
1135
|
-
name = "AgentContextBudgetExceeded";
|
|
1136
|
-
};
|
|
1137
|
-
function assembleAgentContext(input) {
|
|
1138
|
-
const required = [
|
|
1139
|
-
layer("host-safety", input.hostSafety),
|
|
1140
|
-
layer("system-prompt", input.systemPrompt),
|
|
1141
|
-
...input.managedInstructions ? [layer("managed-instructions", input.managedInstructions)] : [],
|
|
1142
|
-
...input.toolSchemas.map((content) => layer("tool-schema", content)),
|
|
1143
|
-
layer("current-input", input.currentInput)
|
|
1144
|
-
];
|
|
1145
|
-
let bytes = size(required);
|
|
1146
|
-
if (bytes > input.maxBytes) throw new AgentContextBudgetExceeded("required context layers exceed byte budget");
|
|
1147
|
-
const selected = [...required];
|
|
1148
|
-
const optional = [
|
|
1149
|
-
...(input.workspaceInstructions ?? []).map((content) => layer("workspace-instructions", content)),
|
|
1150
|
-
...(input.skills ?? []).map((content) => layer("skill", content)),
|
|
1151
|
-
...(input.memory ?? []).map((content) => layer("memory", content)),
|
|
1152
|
-
...input.compaction ? [layer("compaction", input.compaction)] : [],
|
|
1153
|
-
...(input.transcript ?? []).map((content) => layer("transcript", content))
|
|
1154
|
-
];
|
|
1155
|
-
const omitted = /* @__PURE__ */ new Set();
|
|
1156
|
-
for (const candidate of optional) {
|
|
1157
|
-
const candidateBytes = byteLength(candidate.content);
|
|
1158
|
-
if (bytes + candidateBytes <= input.maxBytes) {
|
|
1159
|
-
selected.push(candidate);
|
|
1160
|
-
bytes += candidateBytes;
|
|
1161
|
-
} else omitted.add(candidate.kind);
|
|
1162
|
-
}
|
|
1163
|
-
const order = [
|
|
1164
|
-
"host-safety",
|
|
1165
|
-
"system-prompt",
|
|
1166
|
-
"managed-instructions",
|
|
1167
|
-
"workspace-instructions",
|
|
1168
|
-
"tool-schema",
|
|
1169
|
-
"skill",
|
|
1170
|
-
"memory",
|
|
1171
|
-
"compaction",
|
|
1172
|
-
"transcript",
|
|
1173
|
-
"current-input"
|
|
1174
|
-
];
|
|
1175
|
-
selected.sort((a, b) => order.indexOf(a.kind) - order.indexOf(b.kind));
|
|
1176
|
-
return Object.freeze({
|
|
1177
|
-
bytes,
|
|
1178
|
-
layers: Object.freeze(selected),
|
|
1179
|
-
omittedKinds: Object.freeze(order.filter((kind) => omitted.has(kind)))
|
|
1180
|
-
});
|
|
1181
|
-
}
|
|
1182
|
-
function layer(kind, content) {
|
|
1183
|
-
return Object.freeze({
|
|
1184
|
-
kind,
|
|
1185
|
-
content
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
function size(layers) {
|
|
1189
|
-
return layers.reduce((total, item) => total + byteLength(item.content), 0);
|
|
1190
|
-
}
|
|
1191
|
-
function byteLength(value) {
|
|
1192
|
-
return new TextEncoder().encode(value).byteLength;
|
|
1193
|
-
}
|
|
1194
|
-
//#endregion
|
|
1195
75
|
//#region src/adapters/compatibility/agent-execution/loop/agent-loop.ts
|
|
1196
76
|
function createEventAgentLoop(options) {
|
|
1197
77
|
return { run: (input) => {
|
|
@@ -1269,4 +149,4 @@ function isEffectStream(value) {
|
|
|
1269
149
|
return typeof value === "object" && value !== null && Stream.StreamTypeId in value;
|
|
1270
150
|
}
|
|
1271
151
|
//#endregion
|
|
1272
|
-
export {
|
|
152
|
+
export { createAgentLoopToolExecutionStart as _, createTextAgentLoopFromCallback as a, toEffectAgentLoop as c, createAgentLoopModelExecutionStart as d, createAgentLoopSkillExecutionEnd as f, createAgentLoopToolExecutionEnd as g, createAgentLoopThinkingDelta as h, createTextAgentLoop as i, toEffectAgentLoopInput as l, createAgentLoopTextDelta as m, createAsyncIterableAgentLoop as n, fromEffectAgentLoop as o, createAgentLoopSkillExecutionStart as p, createEventAgentLoop as r, toCompatibilityAgentLoopInput as s, createAgentLoopFromCallback as t, createAgentLoopModelExecutionEnd as u, createAgentLoopToolExecutionUpdate as v, createAgentLoopTurnStart as y };
|