agentenkit 0.3.0 → 0.4.0
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 +34 -14
- package/dist/adapters/inline.d.ts +19 -5
- package/dist/adapters/inline.d.ts.map +1 -1
- package/dist/adapters/inline.js +87 -14
- package/dist/adapters/inline.js.map +1 -1
- package/dist/adapters/memory.d.ts +65 -3
- package/dist/adapters/memory.d.ts.map +1 -1
- package/dist/adapters/memory.js +267 -3
- package/dist/adapters/memory.js.map +1 -1
- package/dist/adapters/prisma.d.ts +125 -18
- package/dist/adapters/prisma.d.ts.map +1 -1
- package/dist/adapters/prisma.js +308 -67
- package/dist/adapters/prisma.js.map +1 -1
- package/dist/adapters/qstash.d.ts +15 -2
- package/dist/adapters/qstash.d.ts.map +1 -1
- package/dist/adapters/qstash.js +31 -14
- package/dist/adapters/qstash.js.map +1 -1
- package/dist/adapters/redis.d.ts +40 -4
- package/dist/adapters/redis.d.ts.map +1 -1
- package/dist/adapters/redis.js +265 -20
- package/dist/adapters/redis.js.map +1 -1
- package/dist/adapters/sqlite.d.ts +52 -2
- package/dist/adapters/sqlite.d.ts.map +1 -1
- package/dist/adapters/sqlite.js +342 -35
- package/dist/adapters/sqlite.js.map +1 -1
- package/dist/adapters/stream-scripts.d.ts +49 -0
- package/dist/adapters/stream-scripts.d.ts.map +1 -0
- package/dist/adapters/stream-scripts.js +150 -0
- package/dist/adapters/stream-scripts.js.map +1 -0
- package/dist/adapters/upstash.d.ts +20 -0
- package/dist/adapters/upstash.d.ts.map +1 -1
- package/dist/adapters/upstash.js +29 -0
- package/dist/adapters/upstash.js.map +1 -1
- package/dist/admin/memory.d.ts +11 -1
- package/dist/admin/memory.d.ts.map +1 -1
- package/dist/admin/memory.js +83 -14
- package/dist/admin/memory.js.map +1 -1
- package/dist/admin/migrations/postgres/0002-run-settled-at.d.ts +5 -0
- package/dist/admin/migrations/postgres/0002-run-settled-at.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0002-run-settled-at.js +11 -0
- package/dist/admin/migrations/postgres/0002-run-settled-at.js.map +1 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.d.ts +5 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.js +15 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.js.map +1 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.d.ts +5 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.js +15 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.js.map +1 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.d.ts +5 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.js +12 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.js.map +1 -0
- package/dist/admin/migrations/postgres/index.d.ts.map +1 -1
- package/dist/admin/migrations/postgres/index.js +16 -1
- package/dist/admin/migrations/postgres/index.js.map +1 -1
- package/dist/admin/migrations/runner.d.ts +21 -1
- package/dist/admin/migrations/runner.d.ts.map +1 -1
- package/dist/admin/migrations/runner.js +41 -4
- package/dist/admin/migrations/runner.js.map +1 -1
- package/dist/admin/migrations/sqlite/0002-run-settled-at.d.ts +5 -0
- package/dist/admin/migrations/sqlite/0002-run-settled-at.d.ts.map +1 -0
- package/dist/admin/migrations/sqlite/0002-run-settled-at.js +11 -0
- package/dist/admin/migrations/sqlite/0002-run-settled-at.js.map +1 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.d.ts +5 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.d.ts.map +1 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.js +15 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.js.map +1 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.d.ts +5 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.d.ts.map +1 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.js +15 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.js.map +1 -0
- package/dist/admin/migrations/sqlite/index.d.ts +2 -2
- package/dist/admin/migrations/sqlite/index.d.ts.map +1 -1
- package/dist/admin/migrations/sqlite/index.js +17 -3
- package/dist/admin/migrations/sqlite/index.js.map +1 -1
- package/dist/admin/postgres.d.ts +14 -4
- package/dist/admin/postgres.d.ts.map +1 -1
- package/dist/admin/postgres.js +131 -36
- package/dist/admin/postgres.js.map +1 -1
- package/dist/admin/shared.d.ts +19 -0
- package/dist/admin/shared.d.ts.map +1 -0
- package/dist/admin/shared.js +28 -0
- package/dist/admin/shared.js.map +1 -0
- package/dist/admin/sqlite.d.ts +9 -1
- package/dist/admin/sqlite.d.ts.map +1 -1
- package/dist/admin/sqlite.js +112 -29
- package/dist/admin/sqlite.js.map +1 -1
- package/dist/core/admin.d.ts +28 -6
- package/dist/core/admin.d.ts.map +1 -1
- package/dist/core/admin.js +92 -23
- package/dist/core/admin.js.map +1 -1
- package/dist/core/agent.d.ts +7 -4
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +15 -11
- package/dist/core/agent.js.map +1 -1
- package/dist/core/agui.d.ts +17 -0
- package/dist/core/agui.d.ts.map +1 -0
- package/dist/core/agui.js +69 -0
- package/dist/core/agui.js.map +1 -0
- package/dist/core/context.d.ts +13 -1
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +70 -19
- package/dist/core/context.js.map +1 -1
- package/dist/core/deleteThread.d.ts.map +1 -1
- package/dist/core/deleteThread.js +33 -4
- package/dist/core/deleteThread.js.map +1 -1
- package/dist/core/engine.d.ts +41 -11
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +855 -352
- package/dist/core/engine.js.map +1 -1
- package/dist/core/follow.d.ts +63 -1
- package/dist/core/follow.d.ts.map +1 -1
- package/dist/core/follow.js +293 -16
- package/dist/core/follow.js.map +1 -1
- package/dist/core/hitl.d.ts +43 -0
- package/dist/core/hitl.d.ts.map +1 -1
- package/dist/core/hitl.js +163 -35
- package/dist/core/hitl.js.map +1 -1
- package/dist/core/keys.d.ts +22 -4
- package/dist/core/keys.d.ts.map +1 -1
- package/dist/core/keys.js +23 -5
- package/dist/core/keys.js.map +1 -1
- package/dist/core/lease.d.ts +46 -0
- package/dist/core/lease.d.ts.map +1 -0
- package/dist/core/lease.js +142 -0
- package/dist/core/lease.js.map +1 -0
- package/dist/core/loop.d.ts +27 -7
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +140 -55
- package/dist/core/loop.js.map +1 -1
- package/dist/core/messages.d.ts +21 -2
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +61 -2
- package/dist/core/messages.js.map +1 -1
- package/dist/core/prune.d.ts +24 -0
- package/dist/core/prune.d.ts.map +1 -0
- package/dist/core/prune.js +43 -0
- package/dist/core/prune.js.map +1 -0
- package/dist/core/publish.d.ts +38 -10
- package/dist/core/publish.d.ts.map +1 -1
- package/dist/core/publish.js +126 -12
- package/dist/core/publish.js.map +1 -1
- package/dist/core/reclaim.d.ts +8 -1
- package/dist/core/reclaim.d.ts.map +1 -1
- package/dist/core/reclaim.js +149 -18
- package/dist/core/reclaim.js.map +1 -1
- package/dist/core/run.d.ts +7 -3
- package/dist/core/run.d.ts.map +1 -1
- package/dist/core/run.js +95 -35
- package/dist/core/run.js.map +1 -1
- package/dist/core/segment.d.ts +62 -0
- package/dist/core/segment.d.ts.map +1 -0
- package/dist/core/segment.js +318 -0
- package/dist/core/segment.js.map +1 -0
- package/dist/core/settle.d.ts +57 -0
- package/dist/core/settle.d.ts.map +1 -0
- package/dist/core/settle.js +181 -0
- package/dist/core/settle.js.map +1 -0
- package/dist/core/snapshot.d.ts +36 -0
- package/dist/core/snapshot.d.ts.map +1 -0
- package/dist/core/snapshot.js +87 -0
- package/dist/core/snapshot.js.map +1 -0
- package/dist/core/stop.d.ts +16 -1
- package/dist/core/stop.d.ts.map +1 -1
- package/dist/core/stop.js +69 -15
- package/dist/core/stop.js.map +1 -1
- package/dist/core/stream-events.d.ts +184 -0
- package/dist/core/stream-events.d.ts.map +1 -0
- package/dist/core/stream-events.js +26 -0
- package/dist/core/stream-events.js.map +1 -0
- package/dist/core/stream.d.ts +29 -0
- package/dist/core/stream.d.ts.map +1 -1
- package/dist/core/stream.js +79 -0
- package/dist/core/stream.js.map +1 -1
- package/dist/core/subagent.d.ts +36 -5
- package/dist/core/subagent.d.ts.map +1 -1
- package/dist/core/subagent.js +117 -22
- package/dist/core/subagent.js.map +1 -1
- package/dist/core/types.d.ts +195 -12
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +26 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/usage.d.ts +53 -5
- package/dist/core/usage.d.ts.map +1 -1
- package/dist/core/usage.js +170 -47
- package/dist/core/usage.js.map +1 -1
- package/dist/index.d.ts +16 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -7
- package/dist/index.js.map +1 -1
- package/dist/ports/admin.d.ts +59 -0
- package/dist/ports/admin.d.ts.map +1 -1
- package/dist/ports/kv.d.ts +17 -0
- package/dist/ports/kv.d.ts.map +1 -1
- package/dist/ports/queue.d.ts +87 -7
- package/dist/ports/queue.d.ts.map +1 -1
- package/dist/ports/queue.js +36 -1
- package/dist/ports/queue.js.map +1 -1
- package/dist/ports/runtime.d.ts +171 -20
- package/dist/ports/runtime.d.ts.map +1 -1
- package/dist/ports/storage.d.ts +26 -5
- package/dist/ports/storage.d.ts.map +1 -1
- package/dist/ports/streams.d.ts +60 -0
- package/dist/ports/streams.d.ts.map +1 -0
- package/dist/ports/streams.js +20 -0
- package/dist/ports/streams.js.map +1 -0
- package/dist/pricing.d.ts +5 -0
- package/dist/pricing.d.ts.map +1 -1
- package/dist/pricing.js +35 -10
- package/dist/pricing.js.map +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +144 -46
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { currentRunId } from './keys.js';
|
|
2
|
+
import { ACTIVE_STATES } from './publish.js';
|
|
3
|
+
/** How long after its end a stream still rides on the snapshot. */
|
|
4
|
+
export const RECENT_END_MS = 60_000;
|
|
5
|
+
/** Events that are part of a step's content, and so of its saved messages. */
|
|
6
|
+
const CONTENT = new Set([
|
|
7
|
+
'TEXT_MESSAGE_START', 'TEXT_MESSAGE_CONTENT', 'TEXT_MESSAGE_END',
|
|
8
|
+
'REASONING_START', 'REASONING_CONTENT', 'REASONING_END',
|
|
9
|
+
'TOOL_CALL_START', 'TOOL_CALL_ARGS', 'TOOL_CALL_END', 'TOOL_CALL_RESULT', 'SOURCE',
|
|
10
|
+
]);
|
|
11
|
+
/** Whose step an item belongs to ('' the main agent), and whether it is
|
|
12
|
+
* content. */
|
|
13
|
+
function ownerOf(item) {
|
|
14
|
+
if (item.type === 'SUBAGENT_EVENT')
|
|
15
|
+
return { agent: item.subagentId, content: CONTENT.has(item.event.type) };
|
|
16
|
+
return { agent: '', content: CONTENT.has(item.type) };
|
|
17
|
+
}
|
|
18
|
+
/** Drop each agent's content up to its last finished step (see
|
|
19
|
+
* SnapshotStream.items). */
|
|
20
|
+
export function cutCommitted(items) {
|
|
21
|
+
const lastStep = new Map();
|
|
22
|
+
items.forEach((item, index) => {
|
|
23
|
+
if (item.type === 'STEP_FINISHED')
|
|
24
|
+
lastStep.set(item.agentId ?? '', index);
|
|
25
|
+
});
|
|
26
|
+
return items.filter((item, index) => {
|
|
27
|
+
const { agent, content } = ownerOf(item);
|
|
28
|
+
return !content || index > (lastStep.get(agent) ?? -1);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** The thread's current run stream, from the thread record: the latest
|
|
32
|
+
* segment that started, while it is open or only just ended. Null when
|
|
33
|
+
* there is none, or it is gone. */
|
|
34
|
+
export async function snapshotStream(deps, threadId) {
|
|
35
|
+
if (!deps.streams)
|
|
36
|
+
return null;
|
|
37
|
+
const started = await deps.storage.events.latest(threadId, 'RUN_STARTED');
|
|
38
|
+
if (!started)
|
|
39
|
+
return null;
|
|
40
|
+
const { streamId, runId } = started.payload;
|
|
41
|
+
const ended = await deps.storage.events.latest(threadId, 'RUN_ENDED');
|
|
42
|
+
if (ended && ended.seq > started.seq &&
|
|
43
|
+
ended.payload.streamId === streamId &&
|
|
44
|
+
Date.now() - new Date(ended.createdAt).getTime() > RECENT_END_MS) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const snap = await deps.streams.snapshot(streamId);
|
|
48
|
+
if (!snap)
|
|
49
|
+
return null;
|
|
50
|
+
return {
|
|
51
|
+
streamId,
|
|
52
|
+
runId,
|
|
53
|
+
items: cutCommitted(snap.items),
|
|
54
|
+
end: snap.end,
|
|
55
|
+
offset: snap.items.at(-1)?.offset ?? null,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** One read for a UI: the thread, its messages, its runs, the unfinished
|
|
59
|
+
* run's record entries and its run stream. Null when the thread is gone.
|
|
60
|
+
* `afterMessageId` keeps only the messages after that one: what a tab that
|
|
61
|
+
* already has it is missing (a SNAPSHOT frame). An id the thread does not
|
|
62
|
+
* have keeps them all. */
|
|
63
|
+
export async function threadSnapshot(deps, threadId, opts = {}) {
|
|
64
|
+
const thread = await deps.storage.threads.get(threadId);
|
|
65
|
+
if (!thread)
|
|
66
|
+
return null;
|
|
67
|
+
let messages = await deps.storage.messages.list(threadId, undefined);
|
|
68
|
+
if (opts.afterMessageId) {
|
|
69
|
+
const at = messages.findIndex((m) => m.id === opts.afterMessageId);
|
|
70
|
+
if (at >= 0)
|
|
71
|
+
messages = messages.slice(at + 1);
|
|
72
|
+
}
|
|
73
|
+
const runs = await deps.admin.runs.listByThread(threadId);
|
|
74
|
+
// The record is small (parks, refusals, each segment's start and end),
|
|
75
|
+
// and the run's live events come from its stream, not from here.
|
|
76
|
+
const events = await deps.storage.events.listSince(threadId, -1);
|
|
77
|
+
const lastEventSeq = events.at(-1)?.seq ?? -1;
|
|
78
|
+
// The unfinished run's record entries: its open park, a refusal.
|
|
79
|
+
let activeEvents = [];
|
|
80
|
+
if (ACTIVE_STATES.includes(thread.state)) {
|
|
81
|
+
const runId = await currentRunId(deps, threadId);
|
|
82
|
+
activeEvents = runId ? events.filter((e) => e.runId === runId) : [];
|
|
83
|
+
}
|
|
84
|
+
const stream = await snapshotStream(deps, threadId);
|
|
85
|
+
return { thread, messages, runs, lastEventSeq, activeEvents, stream };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/core/snapshot.ts"],"names":[],"mappings":"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"}
|
package/dist/core/stop.d.ts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import type { RuntimePorts } from '../ports/runtime.js';
|
|
2
2
|
import type { StopResult } from '../ports/runtime.js';
|
|
3
|
+
import type { RegisteredAgent } from './agent.js';
|
|
4
|
+
export interface StopOptions {
|
|
5
|
+
/** Resolves the registered agent a run belongs to, by the name on its
|
|
6
|
+
* record. A stop that ends a run no worker holds (queued, or parked on an
|
|
7
|
+
* approval) runs that agent's `onSettle` itself (§5.6); with no resolver
|
|
8
|
+
* the run is left unsettled for the sweep. */
|
|
9
|
+
agent?: (name: string) => RegisteredAgent | null;
|
|
10
|
+
}
|
|
3
11
|
/** The whole stop mechanism (§2.1): one button, one behavior — everything
|
|
4
12
|
* stops immediately. The engine's poller sees CANCELLED on the hot cache and
|
|
5
13
|
* fires the abort; the durable state is the recovery truth (§3.4). */
|
|
6
|
-
export declare function stop(deps: RuntimePorts, threadId: string): Promise<StopResult>;
|
|
14
|
+
export declare function stop(deps: RuntimePorts, threadId: string, opts?: StopOptions): Promise<StopResult>;
|
|
7
15
|
export declare function recordStoppedRun(deps: RuntimePorts, runId: string, endedAt: Date): Promise<void>;
|
|
16
|
+
/** Answer every open approval with a cancellation, so the history the next
|
|
17
|
+
* run sends is well-formed (§2.5). A park persists the assistant's tool call
|
|
18
|
+
* and defers its result to the resume; a stop means that resume never comes,
|
|
19
|
+
* and a dangling call is a prompt no strict provider accepts. Nested parks
|
|
20
|
+
* close their whole chain: the child's call and every spawnSubagent call
|
|
21
|
+
* waiting on it (§2.7), whose run records end CANCELLED too. */
|
|
22
|
+
export declare function closeOpenParks(deps: RuntimePorts, threadId: string): Promise<void>;
|
|
8
23
|
//# sourceMappingURL=stop.d.ts.map
|
package/dist/core/stop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/core/stop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/core/stop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,WAAW,WAAW;IAC1B;;;mDAG+C;IAC/C,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,GAAG,IAAI,CAAC;CAClD;AAED;;uEAEuE;AACvE,wBAAsB,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmC5G;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAWtG;AAkCD;;;;;iEAKiE;AACjE,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCxF"}
|
package/dist/core/stop.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { publish,
|
|
1
|
+
import { ACTIVE_STATES, publish, transition } from './publish.js';
|
|
2
2
|
import { loadOpenHitls } from './hitl.js';
|
|
3
3
|
import { currentRunId } from './keys.js';
|
|
4
|
+
import { Lease } from './lease.js';
|
|
5
|
+
import { settleEndedRun } from './settle.js';
|
|
4
6
|
/** The whole stop mechanism (§2.1): one button, one behavior — everything
|
|
5
7
|
* stops immediately. The engine's poller sees CANCELLED on the hot cache and
|
|
6
8
|
* fires the abort; the durable state is the recovery truth (§3.4). */
|
|
7
|
-
export async function stop(deps, threadId) {
|
|
9
|
+
export async function stop(deps, threadId, opts = {}) {
|
|
8
10
|
const thread = await deps.storage.threads.get(threadId);
|
|
9
|
-
if (thread
|
|
11
|
+
if (!thread || !ACTIVE_STATES.includes(thread.state)) {
|
|
10
12
|
return { accepted: false, error: `Cannot stop thread in state ${thread?.state ?? 'unknown'}` };
|
|
11
13
|
}
|
|
12
14
|
// Read before the write: an adapter may hand back the very object the
|
|
@@ -14,12 +16,23 @@ export async function stop(deps, threadId) {
|
|
|
14
16
|
const wasParked = thread.state === 'WAITING_FOR_INPUT';
|
|
15
17
|
const runId = await currentRunId(deps, threadId);
|
|
16
18
|
const endedAt = new Date();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
// A compare-and-set on the state and the run (§3.4): a finish, a failure or
|
|
20
|
+
// a newer run that got there first keeps its own ending, and this stop is
|
|
21
|
+
// refused with the state it found.
|
|
22
|
+
const won = await transition(deps, threadId, {
|
|
23
|
+
from: ACTIVE_STATES, to: 'CANCELLED', runId, model: thread.model,
|
|
24
|
+
});
|
|
25
|
+
if (!won) {
|
|
26
|
+
const now = await deps.storage.threads.get(threadId);
|
|
27
|
+
return { accepted: false, error: `Cannot stop thread in state ${now?.state ?? 'unknown'}` };
|
|
28
|
+
}
|
|
19
29
|
// A queued or parked run may never execute again. Close its record here,
|
|
20
30
|
// without touching usage that a running worker can still be accruing.
|
|
21
|
-
if (runId)
|
|
31
|
+
if (runId) {
|
|
22
32
|
await recordStoppedRun(deps, runId, endedAt);
|
|
33
|
+
if (opts.agent)
|
|
34
|
+
await settleAfterStop(deps, opts.agent, threadId, runId);
|
|
35
|
+
}
|
|
23
36
|
await publish(deps, threadId, 'STATE_CHANGE', {
|
|
24
37
|
state: 'CANCELLED', stopReason: 'cancelled', runId, endedAt,
|
|
25
38
|
});
|
|
@@ -41,27 +54,68 @@ export async function recordStoppedRun(deps, runId, endedAt) {
|
|
|
41
54
|
// Operational history must not prevent cancellation.
|
|
42
55
|
}
|
|
43
56
|
}
|
|
57
|
+
/** Settle a stopped run when no worker is there to (§5.6). A queued run never
|
|
58
|
+
* reached a worker; a parked run's worker is long gone. Their steps were
|
|
59
|
+
* priced as they happened, so the bill is real, and the spec's `onSettle` is
|
|
60
|
+
* where it gets charged.
|
|
61
|
+
*
|
|
62
|
+
* It takes the run lock and settles under it, exactly as a worker would. A
|
|
63
|
+
* held lock means a worker owns the run right now (the lock is renewed while
|
|
64
|
+
* a worker runs, §3.4), and that worker settles it: from its own cancel
|
|
65
|
+
* path, or when it finds the thread cancelled at its segment start. Either
|
|
66
|
+
* way the settle claim makes the second arrival a no-op. */
|
|
67
|
+
async function settleAfterStop(deps, lookup, threadId, runId) {
|
|
68
|
+
const rec = await deps.admin.runs.get(runId).catch(() => null);
|
|
69
|
+
if (!rec || rec.settledAt)
|
|
70
|
+
return;
|
|
71
|
+
const agent = lookup(rec.agent);
|
|
72
|
+
if (!agent)
|
|
73
|
+
return;
|
|
74
|
+
const lease = await Lease.acquire(deps, threadId, runId, undefined);
|
|
75
|
+
if (!lease)
|
|
76
|
+
return; // a worker holds the run; it settles the run itself
|
|
77
|
+
// Renewed while the hook runs: a slow settle must not let a queued job take
|
|
78
|
+
// the lock and settle the same run beside it.
|
|
79
|
+
lease.keep();
|
|
80
|
+
try {
|
|
81
|
+
await settleEndedRun(deps, agent, threadId, runId);
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
await lease.release();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
44
87
|
/** Answer every open approval with a cancellation, so the history the next
|
|
45
88
|
* run sends is well-formed (§2.5). A park persists the assistant's tool call
|
|
46
89
|
* and defers its result to the resume; a stop means that resume never comes,
|
|
47
90
|
* and a dangling call is a prompt no strict provider accepts. Nested parks
|
|
48
91
|
* close their whole chain: the child's call and every spawnSubagent call
|
|
49
92
|
* waiting on it (§2.7), whose run records end CANCELLED too. */
|
|
50
|
-
async function closeOpenParks(deps, threadId) {
|
|
93
|
+
export async function closeOpenParks(deps, threadId) {
|
|
51
94
|
const result = { cancelled: true, reason: 'stopped' };
|
|
52
95
|
const toolResult = (toolCallId, toolName) => [
|
|
53
96
|
{ type: 'tool-result', toolCallId, toolName, result },
|
|
54
97
|
];
|
|
98
|
+
const closed = new Set(); // two parks in one child share its frames
|
|
55
99
|
for (const pending of await loadOpenHitls(deps, threadId)) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
await
|
|
100
|
+
let frames = pending.frames;
|
|
101
|
+
if (pending.landed) {
|
|
102
|
+
// Its own call has its result already; only the levels above wait.
|
|
103
|
+
frames = frames.slice(pending.resumeFrame ?? 0);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
await deps.storage.messages.append(threadId, {
|
|
107
|
+
role: 'tool',
|
|
108
|
+
agentId: pending.agentId,
|
|
109
|
+
content: toolResult(pending.toolCallId, pending.toolName),
|
|
110
|
+
});
|
|
111
|
+
if (pending.nested) {
|
|
112
|
+
await recordStoppedRun(deps, pending.nested.agentId, new Date());
|
|
113
|
+
}
|
|
63
114
|
}
|
|
64
|
-
for (const frame of
|
|
115
|
+
for (const frame of frames) {
|
|
116
|
+
if (closed.has(frame.toolCallId))
|
|
117
|
+
continue;
|
|
118
|
+
closed.add(frame.toolCallId);
|
|
65
119
|
await deps.storage.messages.append(threadId, {
|
|
66
120
|
role: 'tool',
|
|
67
121
|
agentId: frame.agentId,
|
package/dist/core/stop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/core/stop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/core/stop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAU7C;;uEAEuE;AACvE,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAkB,EAAE,QAAgB,EAAE,OAAoB,EAAE;IACrF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,MAAM,EAAE,KAAK,IAAI,SAAS,EAAE,EAAE,CAAC;IACjG,CAAC;IAED,sEAAsE;IACtE,uBAAuB;IACvB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,KAAK,mBAAmB,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;IAE3B,4EAA4E;IAC5E,0EAA0E;IAC1E,mCAAmC;IACnC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE;QAC3C,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK;KACjE,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACrD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,GAAG,EAAE,KAAK,IAAI,SAAS,EAAE,EAAE,CAAC;IAC9F,CAAC;IACD,yEAAyE;IACzE,sEAAsE;IACtE,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE;QAC5C,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO;KAC5D,CAAC,CAAC;IAEH,IAAI,SAAS;QAAE,MAAM,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAEpD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAkB,EAAE,KAAa,EAAE,OAAa;IACrF,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO;QAClD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YACjC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO;YACpD,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;SACpE,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;AACH,CAAC;AAED;;;;;;;;;6DAS6D;AAC7D,KAAK,UAAU,eAAe,CAC5B,IAAkB,EAClB,MAAgD,EAChD,QAAgB,EAChB,KAAa;IAEb,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS;QAAE,OAAO;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACpE,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,oDAAoD;IACxE,4EAA4E;IAC5E,8CAA8C;IAC9C,KAAK,CAAC,IAAI,EAAE,CAAC;IACb,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;YAAS,CAAC;QACT,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;;iEAKiE;AACjE,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAkB,EAAE,QAAgB;IACvE,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAAC;QAC3D,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE;KACtD,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC,CAAC,0CAA0C;IAC5E,KAAK,MAAM,OAAO,IAAI,MAAM,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC1D,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,mEAAmE;YACnE,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAC3C,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC;aAC1D,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;gBAAE,SAAS;YAC3C,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC7B,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAC3C,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC;aACvD,CAAC,CAAC;YACH,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,MAAM,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/** The events a run stream carries (see RunStreams). One typed union: a
|
|
2
|
+
* reader checks `type` and the compiler knows the fields. The shapes follow
|
|
3
|
+
* AG-UI, so an AG-UI encoder only renames a few fields. The Go runtime has
|
|
4
|
+
* the same events, with the same names and the same JSON. */
|
|
5
|
+
/** Tokens a step or a run used. */
|
|
6
|
+
export interface StreamUsage {
|
|
7
|
+
inputTokens: number;
|
|
8
|
+
cachedInputTokens: number;
|
|
9
|
+
outputTokens: number;
|
|
10
|
+
totalTokens: number;
|
|
11
|
+
}
|
|
12
|
+
/** Money spent in one currency, in millionths of a unit. */
|
|
13
|
+
export interface StreamCost {
|
|
14
|
+
currency: string;
|
|
15
|
+
micros: number;
|
|
16
|
+
}
|
|
17
|
+
export interface RunStartedEvent {
|
|
18
|
+
type: 'RUN_STARTED';
|
|
19
|
+
threadId: string;
|
|
20
|
+
runId: string;
|
|
21
|
+
streamId: string;
|
|
22
|
+
/** 1 for the first pickup, 2 for the resume after a park, and so on. */
|
|
23
|
+
segment: number;
|
|
24
|
+
}
|
|
25
|
+
export interface TextMessageStartEvent {
|
|
26
|
+
type: 'TEXT_MESSAGE_START';
|
|
27
|
+
messageId: string;
|
|
28
|
+
role: 'assistant';
|
|
29
|
+
}
|
|
30
|
+
export interface TextMessageContentEvent {
|
|
31
|
+
type: 'TEXT_MESSAGE_CONTENT';
|
|
32
|
+
messageId: string;
|
|
33
|
+
delta: string;
|
|
34
|
+
}
|
|
35
|
+
export interface TextMessageEndEvent {
|
|
36
|
+
type: 'TEXT_MESSAGE_END';
|
|
37
|
+
messageId: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ReasoningStartEvent {
|
|
40
|
+
type: 'REASONING_START';
|
|
41
|
+
messageId: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ReasoningContentEvent {
|
|
44
|
+
type: 'REASONING_CONTENT';
|
|
45
|
+
messageId: string;
|
|
46
|
+
delta: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ReasoningEndEvent {
|
|
49
|
+
type: 'REASONING_END';
|
|
50
|
+
messageId: string;
|
|
51
|
+
}
|
|
52
|
+
export interface ToolCallStartEvent {
|
|
53
|
+
type: 'TOOL_CALL_START';
|
|
54
|
+
toolCallId: string;
|
|
55
|
+
toolName: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ToolCallArgsEvent {
|
|
58
|
+
type: 'TOOL_CALL_ARGS';
|
|
59
|
+
toolCallId: string;
|
|
60
|
+
delta: string;
|
|
61
|
+
}
|
|
62
|
+
/** The call is complete. `args` is the whole, parsed argument object, so a
|
|
63
|
+
* reader that missed the ARGS deltas still has it. */
|
|
64
|
+
export interface ToolCallEndEvent {
|
|
65
|
+
type: 'TOOL_CALL_END';
|
|
66
|
+
toolCallId: string;
|
|
67
|
+
toolName: string;
|
|
68
|
+
args: unknown;
|
|
69
|
+
}
|
|
70
|
+
export interface ToolCallResultEvent {
|
|
71
|
+
type: 'TOOL_CALL_RESULT';
|
|
72
|
+
toolCallId: string;
|
|
73
|
+
toolName: string;
|
|
74
|
+
result: unknown;
|
|
75
|
+
}
|
|
76
|
+
/** A source the model cited (a web page, a document). Not in AG-UI: the
|
|
77
|
+
* encoder sends it as CUSTOM. */
|
|
78
|
+
export interface SourceEvent {
|
|
79
|
+
type: 'SOURCE';
|
|
80
|
+
source: unknown;
|
|
81
|
+
}
|
|
82
|
+
/** One model call is done and its messages are saved. */
|
|
83
|
+
export interface StepFinishedEvent {
|
|
84
|
+
type: 'STEP_FINISHED';
|
|
85
|
+
/** 1-based, per agent. */
|
|
86
|
+
step: number;
|
|
87
|
+
/** null for the main agent, the nested run's id otherwise. */
|
|
88
|
+
agentId: string | null;
|
|
89
|
+
finishReason: string;
|
|
90
|
+
usage: StreamUsage;
|
|
91
|
+
}
|
|
92
|
+
export interface MessageAppendedEvent {
|
|
93
|
+
type: 'MESSAGE_APPENDED';
|
|
94
|
+
message: {
|
|
95
|
+
id: string;
|
|
96
|
+
role: string;
|
|
97
|
+
content: unknown;
|
|
98
|
+
agentId: string | null;
|
|
99
|
+
createdAt: string;
|
|
100
|
+
};
|
|
101
|
+
/** The sender's own name for the message, echoed back. */
|
|
102
|
+
clientMessageId?: string;
|
|
103
|
+
}
|
|
104
|
+
/** A tool is waiting for a person. Also kept in the thread record. */
|
|
105
|
+
export interface InputRequiredEvent {
|
|
106
|
+
type: 'INPUT_REQUIRED';
|
|
107
|
+
toolCallId: string;
|
|
108
|
+
toolName: string;
|
|
109
|
+
agentId: string | null;
|
|
110
|
+
arguments: unknown;
|
|
111
|
+
inputSchema: unknown;
|
|
112
|
+
/** The unwind chain for a nested park; empty for the main agent. */
|
|
113
|
+
frames: unknown[];
|
|
114
|
+
nested?: unknown;
|
|
115
|
+
/** The dispatch ticket the answer resumes with. */
|
|
116
|
+
resume?: unknown;
|
|
117
|
+
reason: string;
|
|
118
|
+
expiresAt?: string;
|
|
119
|
+
}
|
|
120
|
+
export interface SubagentStartedEvent {
|
|
121
|
+
type: 'SUBAGENT_STARTED';
|
|
122
|
+
subagentId: string;
|
|
123
|
+
name: string;
|
|
124
|
+
depth: number;
|
|
125
|
+
}
|
|
126
|
+
/** One event from a nested run, wrapped. */
|
|
127
|
+
export interface SubagentEventEvent {
|
|
128
|
+
type: 'SUBAGENT_EVENT';
|
|
129
|
+
subagentId: string;
|
|
130
|
+
event: StreamEvent;
|
|
131
|
+
}
|
|
132
|
+
export interface SubagentFinishedEvent {
|
|
133
|
+
type: 'SUBAGENT_FINISHED';
|
|
134
|
+
subagentId: string;
|
|
135
|
+
/** `cancelled`: a user stop reached the child. */
|
|
136
|
+
status: 'completed' | 'failed' | 'cancelled';
|
|
137
|
+
error?: string;
|
|
138
|
+
}
|
|
139
|
+
/** An app's own event, sent with publishEvent. */
|
|
140
|
+
export interface CustomStreamEvent {
|
|
141
|
+
type: 'CUSTOM';
|
|
142
|
+
name: string;
|
|
143
|
+
value: unknown;
|
|
144
|
+
}
|
|
145
|
+
/** The run's segment ended normally. Always the last item of a stream. */
|
|
146
|
+
export interface RunFinishedEvent {
|
|
147
|
+
type: 'RUN_FINISHED';
|
|
148
|
+
status: 'finished' | 'parked' | 'stopped';
|
|
149
|
+
usage?: StreamUsage;
|
|
150
|
+
costs?: StreamCost[];
|
|
151
|
+
finishReason?: string;
|
|
152
|
+
/** The final text of a one-shot agent. */
|
|
153
|
+
text?: string;
|
|
154
|
+
}
|
|
155
|
+
/** The run's segment ended badly. Always the last item of a stream. */
|
|
156
|
+
export interface RunErrorEvent {
|
|
157
|
+
type: 'RUN_ERROR';
|
|
158
|
+
/** `lost`: the worker died and the sweep closed its stream. */
|
|
159
|
+
status: 'error' | 'lost';
|
|
160
|
+
error: string;
|
|
161
|
+
}
|
|
162
|
+
export type StreamEvent = RunStartedEvent | TextMessageStartEvent | TextMessageContentEvent | TextMessageEndEvent | ReasoningStartEvent | ReasoningContentEvent | ReasoningEndEvent | ToolCallStartEvent | ToolCallArgsEvent | ToolCallEndEvent | ToolCallResultEvent | SourceEvent | StepFinishedEvent | MessageAppendedEvent | InputRequiredEvent | SubagentStartedEvent | SubagentEventEvent | SubagentFinishedEvent | CustomStreamEvent | RunFinishedEvent | RunErrorEvent;
|
|
163
|
+
export type StreamEventType = StreamEvent['type'];
|
|
164
|
+
/** How a stream ends: the last item it will ever hold. */
|
|
165
|
+
export type StreamEnd = RunFinishedEvent | RunErrorEvent;
|
|
166
|
+
/** An event as a stream holds it: with the offset the store gave it. */
|
|
167
|
+
export type StreamItem = StreamEvent & {
|
|
168
|
+
offset: string;
|
|
169
|
+
};
|
|
170
|
+
/** True for the event that ends a stream. */
|
|
171
|
+
export declare function isStreamEnd(e: {
|
|
172
|
+
type: string;
|
|
173
|
+
}): e is StreamEnd;
|
|
174
|
+
/** A run segment's stream id: `<runId>:<segment>`. A park closes a
|
|
175
|
+
* segment's stream and the resume opens the next, so a closed stream never
|
|
176
|
+
* opens again. */
|
|
177
|
+
export declare function streamIdOf(runId: string, segment: number): string;
|
|
178
|
+
/** The run id and segment in a stream id, or null for one not made by
|
|
179
|
+
* streamIdOf. */
|
|
180
|
+
export declare function parseStreamId(streamId: string): {
|
|
181
|
+
runId: string;
|
|
182
|
+
segment: number;
|
|
183
|
+
} | null;
|
|
184
|
+
//# sourceMappingURL=stream-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-events.d.ts","sourceRoot":"","sources":["../../src/core/stream-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The events a run stream carries (see RunStreams). One typed union: a
|
|
2
|
+
* reader checks `type` and the compiler knows the fields. The shapes follow
|
|
3
|
+
* AG-UI, so an AG-UI encoder only renames a few fields. The Go runtime has
|
|
4
|
+
* the same events, with the same names and the same JSON. */
|
|
5
|
+
/** True for the event that ends a stream. */
|
|
6
|
+
export function isStreamEnd(e) {
|
|
7
|
+
return e.type === 'RUN_FINISHED' || e.type === 'RUN_ERROR';
|
|
8
|
+
}
|
|
9
|
+
/** A run segment's stream id: `<runId>:<segment>`. A park closes a
|
|
10
|
+
* segment's stream and the resume opens the next, so a closed stream never
|
|
11
|
+
* opens again. */
|
|
12
|
+
export function streamIdOf(runId, segment) {
|
|
13
|
+
return `${runId}:${segment}`;
|
|
14
|
+
}
|
|
15
|
+
/** The run id and segment in a stream id, or null for one not made by
|
|
16
|
+
* streamIdOf. */
|
|
17
|
+
export function parseStreamId(streamId) {
|
|
18
|
+
const at = streamId.lastIndexOf(':');
|
|
19
|
+
if (at <= 0)
|
|
20
|
+
return null;
|
|
21
|
+
const segment = Number(streamId.slice(at + 1));
|
|
22
|
+
if (!Number.isInteger(segment) || segment < 1)
|
|
23
|
+
return null;
|
|
24
|
+
return { runId: streamId.slice(0, at), segment };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=stream-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-events.js","sourceRoot":"","sources":["../../src/core/stream-events.ts"],"names":[],"mappings":"AAAA;;;8DAG8D;AA4M9D,6CAA6C;AAC7C,MAAM,UAAU,WAAW,CAAC,CAAmB;IAC7C,OAAO,CAAC,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC;AAC7D,CAAC;AAED;;mBAEmB;AACnB,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,OAAe;IACvD,OAAO,GAAG,KAAK,IAAI,OAAO,EAAE,CAAC;AAC/B,CAAC;AAED;kBACkB;AAClB,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC"}
|
package/dist/core/stream.d.ts
CHANGED
|
@@ -9,4 +9,33 @@
|
|
|
9
9
|
* Draining fully first also means `onChunk` fires for every part that did
|
|
10
10
|
* arrive before the failure. */
|
|
11
11
|
export declare function drainOrThrow(fullStream: AsyncIterable<unknown>): Promise<void>;
|
|
12
|
+
/** Merges token deltas before they go out as events (§2.2). Every published
|
|
13
|
+
* event costs a seq, a stored row and a bus send; one per token is thousands
|
|
14
|
+
* a reply. Consecutive text (or reasoning) deltas are joined into one delta
|
|
15
|
+
* of the same shape, so a client reads them exactly as before. A held delta
|
|
16
|
+
* goes out after `windowMs`, or at once when any other kind of chunk comes,
|
|
17
|
+
* or on `flush`: the loop flushes before a step is committed, so its text is
|
|
18
|
+
* never published after the step that produced it. Sends go out in order. */
|
|
19
|
+
export declare class ChunkBatcher {
|
|
20
|
+
private readonly send;
|
|
21
|
+
private readonly windowMs;
|
|
22
|
+
private held;
|
|
23
|
+
private timer?;
|
|
24
|
+
private chain;
|
|
25
|
+
constructor(send: (chunk: unknown) => Promise<void>, windowMs?: number);
|
|
26
|
+
/** Take one chunk. A delta is held; anything else is sent, after what is
|
|
27
|
+
* held, and the promise resolves once it is out, so the step does not move
|
|
28
|
+
* on (a tool starting, say) before what it streamed is stored. */
|
|
29
|
+
push(chunk: unknown): Promise<void>;
|
|
30
|
+
/** Send what is held, and resolve once everything pushed so far is out. */
|
|
31
|
+
flush(): Promise<void>;
|
|
32
|
+
private enqueue;
|
|
33
|
+
}
|
|
34
|
+
/** A chunk as it is published: the SDK part, except that a tool result goes
|
|
35
|
+
* out in the shape the Go runtime sends, `{type, toolCallId, toolName,
|
|
36
|
+
* result}`, with `{error}` as the result of a call whose tool failed (the
|
|
37
|
+
* model got `error: <message>`, but a client marks the call failed from
|
|
38
|
+
* this), and a parked call's placeholder is not sent at all (its verdict
|
|
39
|
+
* arrives with the resume). Null means "do not publish". */
|
|
40
|
+
export declare function chunkPayload(chunk: unknown, toolErrors?: Map<string, string>): unknown | null;
|
|
12
41
|
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/core/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;iCASiC;AACjC,wBAAsB,YAAY,CAAC,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF"}
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/core/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;iCASiC;AACjC,wBAAsB,YAAY,CAAC,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF;AAED;;;;;;8EAM8E;AAC9E,qBAAa,YAAY;IAMrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAN3B,OAAO,CAAC,IAAI,CAAoD;IAChE,OAAO,CAAC,KAAK,CAAC,CAAgC;IAC9C,OAAO,CAAC,KAAK,CAAoC;gBAG9B,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EACvC,QAAQ,SAAK;IAGhC;;uEAEmE;IACnE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnC,2EAA2E;IAC3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,OAAO,CAAC,OAAO;CAOhB;AAED;;;;;6DAK6D;AAC7D,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,GAAG,IAAI,CAa7F"}
|
package/dist/core/stream.js
CHANGED
|
@@ -18,4 +18,83 @@ export async function drainOrThrow(fullStream) {
|
|
|
18
18
|
if (streamError !== undefined)
|
|
19
19
|
throw streamError;
|
|
20
20
|
}
|
|
21
|
+
/** Merges token deltas before they go out as events (§2.2). Every published
|
|
22
|
+
* event costs a seq, a stored row and a bus send; one per token is thousands
|
|
23
|
+
* a reply. Consecutive text (or reasoning) deltas are joined into one delta
|
|
24
|
+
* of the same shape, so a client reads them exactly as before. A held delta
|
|
25
|
+
* goes out after `windowMs`, or at once when any other kind of chunk comes,
|
|
26
|
+
* or on `flush`: the loop flushes before a step is committed, so its text is
|
|
27
|
+
* never published after the step that produced it. Sends go out in order. */
|
|
28
|
+
export class ChunkBatcher {
|
|
29
|
+
send;
|
|
30
|
+
windowMs;
|
|
31
|
+
held = null;
|
|
32
|
+
timer;
|
|
33
|
+
chain = Promise.resolve();
|
|
34
|
+
constructor(send, windowMs = 50) {
|
|
35
|
+
this.send = send;
|
|
36
|
+
this.windowMs = windowMs;
|
|
37
|
+
}
|
|
38
|
+
/** Take one chunk. A delta is held; anything else is sent, after what is
|
|
39
|
+
* held, and the promise resolves once it is out, so the step does not move
|
|
40
|
+
* on (a tool starting, say) before what it streamed is stored. */
|
|
41
|
+
push(chunk) {
|
|
42
|
+
const c = chunk;
|
|
43
|
+
const isDelta = (c?.type === 'text-delta' || c?.type === 'reasoning') && typeof c.textDelta === 'string';
|
|
44
|
+
if (isDelta && this.held && this.held.type === c.type) {
|
|
45
|
+
this.held.textDelta += c.textDelta;
|
|
46
|
+
return Promise.resolve();
|
|
47
|
+
}
|
|
48
|
+
void this.flush();
|
|
49
|
+
if (isDelta) {
|
|
50
|
+
this.held = { ...c, type: c.type, textDelta: c.textDelta };
|
|
51
|
+
this.timer = setTimeout(() => void this.flush(), this.windowMs);
|
|
52
|
+
this.timer.unref?.();
|
|
53
|
+
return Promise.resolve();
|
|
54
|
+
}
|
|
55
|
+
this.enqueue(chunk);
|
|
56
|
+
return this.chain;
|
|
57
|
+
}
|
|
58
|
+
/** Send what is held, and resolve once everything pushed so far is out. */
|
|
59
|
+
flush() {
|
|
60
|
+
if (this.timer)
|
|
61
|
+
clearTimeout(this.timer);
|
|
62
|
+
this.timer = undefined;
|
|
63
|
+
const held = this.held;
|
|
64
|
+
this.held = null;
|
|
65
|
+
if (held)
|
|
66
|
+
this.enqueue(held);
|
|
67
|
+
return this.chain;
|
|
68
|
+
}
|
|
69
|
+
enqueue(chunk) {
|
|
70
|
+
this.chain = this.chain.then(() => this.send(chunk)).catch((err) => {
|
|
71
|
+
// A lost live chunk is not a lost step: the step's messages are stored
|
|
72
|
+
// at commit. It must not stop the chunks after it either.
|
|
73
|
+
console.error('chunk not published', err);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** A chunk as it is published: the SDK part, except that a tool result goes
|
|
78
|
+
* out in the shape the Go runtime sends, `{type, toolCallId, toolName,
|
|
79
|
+
* result}`, with `{error}` as the result of a call whose tool failed (the
|
|
80
|
+
* model got `error: <message>`, but a client marks the call failed from
|
|
81
|
+
* this), and a parked call's placeholder is not sent at all (its verdict
|
|
82
|
+
* arrives with the resume). Null means "do not publish". */
|
|
83
|
+
export function chunkPayload(chunk, toolErrors) {
|
|
84
|
+
const c = chunk;
|
|
85
|
+
if (c?.type !== 'tool-result')
|
|
86
|
+
return chunk;
|
|
87
|
+
const r = c.result;
|
|
88
|
+
if (r && typeof r === 'object' && '__hitl_parked__' in r)
|
|
89
|
+
return null;
|
|
90
|
+
const failed = c.toolCallId ? toolErrors?.get(c.toolCallId) : undefined;
|
|
91
|
+
if (failed !== undefined)
|
|
92
|
+
toolErrors.delete(c.toolCallId);
|
|
93
|
+
return {
|
|
94
|
+
type: 'tool-result',
|
|
95
|
+
toolCallId: c.toolCallId,
|
|
96
|
+
toolName: c.toolName,
|
|
97
|
+
result: failed !== undefined ? { error: failed } : c.result,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
21
100
|
//# sourceMappingURL=stream.js.map
|
package/dist/core/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/core/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;iCASiC;AACjC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkC;IACnE,IAAI,WAAoB,CAAC;IACzB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QACpC,IAAK,IAAiC,EAAE,IAAI,KAAK,OAAO,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACtF,WAAW,GAAI,IAA4B,CAAC,KAAK,CAAC;QACpD,CAAC;IACH,CAAC;IACD,IAAI,WAAW,KAAK,SAAS;QAAE,MAAM,WAAW,CAAC;AACnD,CAAC"}
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/core/stream.ts"],"names":[],"mappings":"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"}
|