@superdurable/dex-agents 0.1.0 → 0.2.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 +1568 -62
- package/dist/src/agent-built-in-tools.d.ts +81 -0
- package/dist/src/agent-built-in-tools.js +246 -0
- package/dist/src/agent-built-in-tools.js.map +1 -0
- package/dist/src/agent-context-compaction.d.ts +108 -0
- package/dist/src/agent-context-compaction.js +39 -0
- package/dist/src/agent-context-compaction.js.map +1 -0
- package/dist/src/agent-framework-runner.d.ts +456 -16
- package/dist/src/agent-framework-runner.js +4 -3
- package/dist/src/agent-framework-runner.js.map +1 -1
- package/dist/src/agent-plans.d.ts +48 -0
- package/dist/src/agent-plans.js +86 -0
- package/dist/src/agent-plans.js.map +1 -0
- package/dist/src/agent-session-cancellation-steps.d.ts +28 -0
- package/dist/src/agent-session-cancellation-steps.js +154 -0
- package/dist/src/agent-session-cancellation-steps.js.map +1 -0
- package/dist/src/agent-session-codecs.d.ts +65 -4
- package/dist/src/agent-session-codecs.js +342 -8
- package/dist/src/agent-session-codecs.js.map +1 -1
- package/dist/src/agent-session-flow.d.ts +295 -27
- package/dist/src/agent-session-flow.js +368 -21
- package/dist/src/agent-session-flow.js.map +1 -1
- package/dist/src/agent-session-persistence.d.ts +81 -4
- package/dist/src/agent-session-persistence.js +33 -2
- package/dist/src/agent-session-persistence.js.map +1 -1
- package/dist/src/agent-session-settings.d.ts +58 -0
- package/dist/src/agent-session-settings.js +81 -0
- package/dist/src/agent-session-settings.js.map +1 -0
- package/dist/src/agent-session-step-options.d.ts +27 -0
- package/dist/src/agent-session-step-options.js +39 -0
- package/dist/src/agent-session-step-options.js.map +1 -0
- package/dist/src/agent-session-step-types.d.ts +20 -0
- package/dist/src/agent-session-step-types.js +28 -0
- package/dist/src/agent-session-step-types.js.map +1 -0
- package/dist/src/agent-session-steps.d.ts +101 -8
- package/dist/src/agent-session-steps.js +936 -197
- package/dist/src/agent-session-steps.js.map +1 -1
- package/dist/src/agent-session-tracer.d.ts +61 -0
- package/dist/src/agent-session-tracer.js +608 -0
- package/dist/src/agent-session-tracer.js.map +1 -0
- package/dist/src/agent-session-transitions.d.ts +189 -26
- package/dist/src/agent-session-transitions.js +680 -32
- package/dist/src/agent-session-transitions.js.map +1 -1
- package/dist/src/agent-session-values.d.ts +690 -29
- package/dist/src/agent-session-values.js +39 -4
- package/dist/src/agent-session-values.js.map +1 -1
- package/dist/src/agent-session-wait-steps.d.ts +53 -0
- package/dist/src/agent-session-wait-steps.js +389 -0
- package/dist/src/agent-session-wait-steps.js.map +1 -0
- package/dist/src/agent-tracing-options.d.ts +107 -0
- package/dist/src/agent-tracing-options.js +20 -0
- package/dist/src/agent-tracing-options.js.map +1 -0
- package/dist/src/ai-sdk/ai-sdk-model-client.d.ts +40 -0
- package/dist/src/ai-sdk/ai-sdk-model-client.js +235 -0
- package/dist/src/ai-sdk/ai-sdk-model-client.js.map +1 -0
- package/dist/src/ai-sdk/index.d.ts +1 -0
- package/dist/src/ai-sdk/index.js +9 -0
- package/dist/src/ai-sdk/index.js.map +1 -0
- package/dist/src/index.d.ts +9 -3
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/index.d.ts +3 -0
- package/dist/src/mcp/index.js +10 -0
- package/dist/src/mcp/index.js.map +1 -0
- package/dist/src/mcp/mcp-resource-and-prompt-tools.d.ts +29 -0
- package/dist/src/mcp/mcp-resource-and-prompt-tools.js +185 -0
- package/dist/src/mcp/mcp-resource-and-prompt-tools.js.map +1 -0
- package/dist/src/mcp/mcp-server-config.d.ts +86 -0
- package/dist/src/mcp/mcp-server-config.js +38 -0
- package/dist/src/mcp/mcp-server-config.js.map +1 -0
- package/dist/src/mcp/mcp-tool-source.d.ts +470 -0
- package/dist/src/mcp/mcp-tool-source.js +1204 -0
- package/dist/src/mcp/mcp-tool-source.js.map +1 -0
- package/dist/src/stepwise/agent-definition.d.ts +158 -0
- package/dist/src/stepwise/agent-definition.js +9 -0
- package/dist/src/stepwise/agent-definition.js.map +1 -0
- package/dist/src/stepwise/function-tool.d.ts +130 -0
- package/dist/src/stepwise/function-tool.js +75 -0
- package/dist/src/stepwise/function-tool.js.map +1 -0
- package/dist/src/stepwise/index.d.ts +7 -0
- package/dist/src/stepwise/index.js +12 -0
- package/dist/src/stepwise/index.js.map +1 -0
- package/dist/src/stepwise/json-schema-validation.d.ts +9 -0
- package/dist/src/stepwise/json-schema-validation.js +141 -0
- package/dist/src/stepwise/json-schema-validation.js.map +1 -0
- package/dist/src/stepwise/model-client.d.ts +194 -0
- package/dist/src/stepwise/model-client.js +9 -0
- package/dist/src/stepwise/model-client.js.map +1 -0
- package/dist/src/stepwise/scripted-model-client.d.ts +99 -0
- package/dist/src/stepwise/scripted-model-client.js +156 -0
- package/dist/src/stepwise/scripted-model-client.js.map +1 -0
- package/dist/src/stepwise/stepwise-agent-runner.d.ts +189 -0
- package/dist/src/stepwise/stepwise-agent-runner.js +804 -0
- package/dist/src/stepwise/stepwise-agent-runner.js.map +1 -0
- package/dist/src/stepwise/stepwise-agent-session-flow.d.ts +35 -0
- package/dist/src/stepwise/stepwise-agent-session-flow.js +56 -0
- package/dist/src/stepwise/stepwise-agent-session-flow.js.map +1 -0
- package/dist/src/stepwise/stepwise-input-items.d.ts +12 -0
- package/dist/src/stepwise/stepwise-input-items.js +172 -0
- package/dist/src/stepwise/stepwise-input-items.js.map +1 -0
- package/dist/src/stepwise/tool-source.d.ts +103 -0
- package/dist/src/stepwise/tool-source.js +9 -0
- package/dist/src/stepwise/tool-source.js.map +1 -0
- package/dist/src/testing/agent-session-test-client.d.ts +65 -8
- package/dist/src/testing/agent-session-test-client.js +95 -22
- package/dist/src/testing/agent-session-test-client.js.map +1 -1
- package/dist/src/testing/index.d.ts +1 -0
- package/dist/src/testing/index.js +1 -0
- package/dist/src/testing/index.js.map +1 -1
- package/dist/src/testing/private-dex-engine.d.ts +9 -0
- package/dist/src/testing/private-dex-engine.js +9 -1
- package/dist/src/testing/private-dex-engine.js.map +1 -1
- package/dist/src/testing/scripted-model-client.d.ts +1 -0
- package/dist/src/testing/scripted-model-client.js +10 -0
- package/dist/src/testing/scripted-model-client.js.map +1 -0
- package/dist/src/ui-stream/agent-event-json.d.ts +30 -0
- package/dist/src/ui-stream/agent-event-json.js +64 -0
- package/dist/src/ui-stream/agent-event-json.js.map +1 -0
- package/dist/src/ui-stream/agent-event-sse.d.ts +154 -0
- package/dist/src/ui-stream/agent-event-sse.js +159 -0
- package/dist/src/ui-stream/agent-event-sse.js.map +1 -0
- package/dist/src/ui-stream/agent-event-stream-positions.d.ts +42 -0
- package/dist/src/ui-stream/agent-event-stream-positions.js +153 -0
- package/dist/src/ui-stream/agent-event-stream-positions.js.map +1 -0
- package/dist/src/ui-stream/agent-session-record-reader.d.ts +72 -0
- package/dist/src/ui-stream/agent-session-record-reader.js +241 -0
- package/dist/src/ui-stream/agent-session-record-reader.js.map +1 -0
- package/dist/src/ui-stream/agent-ui-message-stream-responses.d.ts +219 -0
- package/dist/src/ui-stream/agent-ui-message-stream-responses.js +440 -0
- package/dist/src/ui-stream/agent-ui-message-stream-responses.js.map +1 -0
- package/dist/src/ui-stream/agent-ui-message-stream.d.ts +138 -0
- package/dist/src/ui-stream/agent-ui-message-stream.js +681 -0
- package/dist/src/ui-stream/agent-ui-message-stream.js.map +1 -0
- package/dist/src/ui-stream/agent-ui-message-types.d.ts +238 -0
- package/dist/src/ui-stream/agent-ui-message-types.js +57 -0
- package/dist/src/ui-stream/agent-ui-message-types.js.map +1 -0
- package/dist/src/ui-stream/agent-ui-messages.d.ts +66 -0
- package/dist/src/ui-stream/agent-ui-messages.js +220 -0
- package/dist/src/ui-stream/agent-ui-messages.js.map +1 -0
- package/dist/src/ui-stream/agent-ui-stream-cursor.d.ts +64 -0
- package/dist/src/ui-stream/agent-ui-stream-cursor.js +186 -0
- package/dist/src/ui-stream/agent-ui-stream-cursor.js.map +1 -0
- package/dist/src/ui-stream/index.d.ts +14 -0
- package/dist/src/ui-stream/index.js +22 -0
- package/dist/src/ui-stream/index.js.map +1 -0
- package/dist/src/ui-stream/server-sent-event-responses.d.ts +6 -0
- package/dist/src/ui-stream/server-sent-event-responses.js +34 -0
- package/dist/src/ui-stream/server-sent-event-responses.js.map +1 -0
- package/package.json +41 -5
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// Copyright (c) 2026 Super Durable, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Sustainable Use License 1.0.
|
|
4
|
+
// You may not use this file except in compliance with the License.
|
|
5
|
+
// See the LICENSE file in the repository root.
|
|
6
|
+
//
|
|
7
|
+
// SPDX-License-Identifier: LicenseRef-Sustainable-Use-1.0
|
|
8
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
9
|
+
import { FlowNotFoundError } from "@superdurable/dex";
|
|
10
|
+
import { messageSequenceKey } from "../agent-session-persistence.js";
|
|
11
|
+
import { findMessageChunkRange } from "../agent-session-transitions.js";
|
|
12
|
+
import { parseTurnNumber } from "./agent-event-stream-positions.js";
|
|
13
|
+
const committedRecordWaitMs = 3_000;
|
|
14
|
+
const committedRecordPollIntervalMs = 25;
|
|
15
|
+
const storedMessagePageSize = 50;
|
|
16
|
+
const recentStoredMessageCount = 200;
|
|
17
|
+
const maximumStoredMessageReadAttempts = 3;
|
|
18
|
+
/** Reads committed session state for the UI streams; Attribute reads need no running Worker. */
|
|
19
|
+
export class AgentSessionRecordReader {
|
|
20
|
+
client;
|
|
21
|
+
flow;
|
|
22
|
+
flowId;
|
|
23
|
+
constructor(client, flow, flowId) {
|
|
24
|
+
this.client = client;
|
|
25
|
+
this.flow = flow;
|
|
26
|
+
this.flowId = flowId;
|
|
27
|
+
}
|
|
28
|
+
async readAgentState() {
|
|
29
|
+
const [state] = await this.client.getAttributes(this.flowId, this.flow.agentState);
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Waits until a turn's end committed, because its end event reaches the Stream before the commit.
|
|
34
|
+
* @returns `true` once the turn is no longer active; `false` after 3 seconds without that commit.
|
|
35
|
+
*/
|
|
36
|
+
async waitForTurnToEnd(turnId) {
|
|
37
|
+
const deadline = Date.now() + committedRecordWaitMs;
|
|
38
|
+
for (;;) {
|
|
39
|
+
const state = await this.readAgentState();
|
|
40
|
+
if (state?.activeTurnId !== turnId) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
if (Date.now() >= deadline) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
await delay(committedRecordPollIntervalMs);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Reads the IDs of the tool calls whose approval `resolve_interrupt` still accepts.
|
|
51
|
+
* @returns The tool call IDs of the pending `tool_approval` interrupts.
|
|
52
|
+
*/
|
|
53
|
+
async readPendingApprovalToolCallIds() {
|
|
54
|
+
const [interrupts] = await this.client.getAttributes(this.flowId, this.flow.pendingInterrupts);
|
|
55
|
+
return new Set((interrupts ?? [])
|
|
56
|
+
.filter((interrupt) => interrupt.kind === "tool_approval")
|
|
57
|
+
.map((interrupt) => interrupt.toolCallId));
|
|
58
|
+
}
|
|
59
|
+
async isFlowRunning() {
|
|
60
|
+
try {
|
|
61
|
+
return (await this.client.describeFlow(this.flowId)).status === "running";
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error instanceof FlowNotFoundError) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Reads what the session holds about one tool call of a turn.
|
|
72
|
+
*
|
|
73
|
+
* Events reach the Stream before their Step commits, so it polls the record until `isReady` holds, for
|
|
74
|
+
* up to 3 seconds. A turn that ended deleted its records; then it reads the turn's stored messages.
|
|
75
|
+
* @returns The record when it exists, plus the tool name, arguments, and stored result text from the
|
|
76
|
+
* record or the stored messages; each is `undefined` when neither holds it.
|
|
77
|
+
*/
|
|
78
|
+
async readToolCallDetails(turnId, toolCallId, isReady) {
|
|
79
|
+
const record = await this.waitForToolCall(turnId, toolCallId, isReady);
|
|
80
|
+
if (record !== undefined) {
|
|
81
|
+
return { record, toolName: record.toolName, toolArguments: record.arguments, storedToolOutput: undefined };
|
|
82
|
+
}
|
|
83
|
+
const storedMessages = await this.readStoredToolMessages(turnId, toolCallId);
|
|
84
|
+
return {
|
|
85
|
+
record: undefined,
|
|
86
|
+
toolName: storedMessages.toolCall?.toolName ?? storedMessages.toolResult?.toolName ?? undefined,
|
|
87
|
+
toolArguments: storedMessages.toolCall?.toolArguments ?? undefined,
|
|
88
|
+
storedToolOutput: storedMessages.toolResult?.toolOutput ?? undefined,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async waitForToolCall(turnId, toolCallId, isReady) {
|
|
92
|
+
const deadline = Date.now() + committedRecordWaitMs;
|
|
93
|
+
for (;;) {
|
|
94
|
+
const [record] = await this.client.getAttributes(this.flowId, this.flow.agentToolCalls.instance(toolCallId));
|
|
95
|
+
const turnRecord = record?.turnId === turnId ? record : undefined;
|
|
96
|
+
if ((turnRecord !== undefined && isReady(turnRecord)) || Date.now() >= deadline) {
|
|
97
|
+
return turnRecord;
|
|
98
|
+
}
|
|
99
|
+
if (turnRecord === undefined && (await this.readAgentState())?.activeTurnId !== turnId) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
await delay(committedRecordPollIntervalMs);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Waits up to 3 seconds for a tool call record to be committed, because events precede their commit.
|
|
107
|
+
* @returns The record, or `undefined` when it never appeared or the turn is no longer active.
|
|
108
|
+
*/
|
|
109
|
+
async readCommittedToolCall(turnId, toolCallId) {
|
|
110
|
+
return this.waitForToolCall(turnId, toolCallId, () => true);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Reads one tool call record once, without waiting for a commit.
|
|
114
|
+
* @returns The record when it exists and belongs to `turnId`, otherwise `undefined`.
|
|
115
|
+
*/
|
|
116
|
+
async readToolCall(turnId, toolCallId) {
|
|
117
|
+
const [record] = await this.client.getAttributes(this.flowId, this.flow.agentToolCalls.instance(toolCallId));
|
|
118
|
+
return record?.turnId === turnId ? record : undefined;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Reads the stored tool results among the last 200 stored messages of any turn.
|
|
122
|
+
* @returns The results in sequence order, each with its turn, tool call ID, and the text the model saw.
|
|
123
|
+
*/
|
|
124
|
+
async readRecentStoredToolResults() {
|
|
125
|
+
const state = await this.readAgentState();
|
|
126
|
+
const endSequence = state?.nextMessageSequence ?? 1;
|
|
127
|
+
const startSequence = Math.max(1, endSequence - recentStoredMessageCount);
|
|
128
|
+
if (startSequence >= endSequence) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
const results = [];
|
|
132
|
+
for (const message of (await this.readStoredMessages(startSequence, endSequence)).messages) {
|
|
133
|
+
const toolOutput = message?.toolOutput ?? message?.text;
|
|
134
|
+
if (message?.role === "tool" && message.toolCallId !== null && toolOutput != null) {
|
|
135
|
+
results.push({ turnId: message.turnId, toolCallId: message.toolCallId, toolOutput });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return results;
|
|
139
|
+
}
|
|
140
|
+
/** Finds a tool call's stored request and result messages, newest pages first, within its turn. */
|
|
141
|
+
async readStoredToolMessages(turnId, toolCallId) {
|
|
142
|
+
const state = await this.readAgentState();
|
|
143
|
+
const turnNumber = parseTurnNumber(turnId);
|
|
144
|
+
const found = {};
|
|
145
|
+
let endSequence = state?.nextMessageSequence ?? 1;
|
|
146
|
+
let firstSequence = 1;
|
|
147
|
+
while (endSequence > firstSequence) {
|
|
148
|
+
const startSequence = Math.max(firstSequence, endSequence - storedMessagePageSize);
|
|
149
|
+
const page = await this.readStoredMessages(startSequence, endSequence);
|
|
150
|
+
const messages = page.messages;
|
|
151
|
+
firstSequence = page.firstSequence;
|
|
152
|
+
let hasEarlierTurn = false;
|
|
153
|
+
for (const message of messages) {
|
|
154
|
+
if (message === undefined) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (message.turnId !== turnId) {
|
|
158
|
+
hasEarlierTurn ||= (parseTurnNumber(message.turnId) ?? 0) < (turnNumber ?? 0);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (message.toolCallId === toolCallId) {
|
|
162
|
+
if (message.role === "tool") {
|
|
163
|
+
found.toolResult = message;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
found.toolCall = message;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (hasEarlierTurn || (found.toolCall !== undefined && found.toolResult !== undefined)) {
|
|
171
|
+
return found;
|
|
172
|
+
}
|
|
173
|
+
endSequence = startSequence;
|
|
174
|
+
}
|
|
175
|
+
return found;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Reads stored messages with sequences in `[startSequence, endSequence)`, in sequence order, from the
|
|
179
|
+
* `AgentMessages` window and the `AgentMessageChunks` instances that `AgentMessageIndex` names. A message
|
|
180
|
+
* that retention deleted reads as `undefined`. A commit between the index read and the instance reads moves
|
|
181
|
+
* messages, so the read repeats with the new index.
|
|
182
|
+
* @returns The messages and the sequence of the oldest stored message.
|
|
183
|
+
* @throws Error when the index keeps changing for every attempt, or a stored message is missing.
|
|
184
|
+
*/
|
|
185
|
+
async readStoredMessages(startSequence, endSequence) {
|
|
186
|
+
let [index] = await this.client.getAttributes(this.flowId, this.flow.agentMessageIndex);
|
|
187
|
+
for (let attempt = 1;; attempt += 1) {
|
|
188
|
+
const firstSequence = index?.firstSequence ?? 1;
|
|
189
|
+
const chunkStarts = new Set();
|
|
190
|
+
const windowSequences = [];
|
|
191
|
+
for (let sequence = Math.max(firstSequence, startSequence); sequence < endSequence; sequence += 1) {
|
|
192
|
+
const range = index === undefined ? undefined : findMessageChunkRange(index, sequence);
|
|
193
|
+
if (range === undefined) {
|
|
194
|
+
windowSequences.push(sequence);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
chunkStarts.add(range.firstSequence);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const chunkReads = [...chunkStarts].map((chunkStart) => this.flow.agentMessageChunks.instance(messageSequenceKey(chunkStart)));
|
|
201
|
+
const windowReads = windowSequences.map((sequence) => this.flow.agentMessages.instance(messageSequenceKey(sequence)));
|
|
202
|
+
const values = (await this.client.getAttributes(this.flowId, ...[this.flow.agentMessageIndex, ...chunkReads, ...windowReads]));
|
|
203
|
+
const readIndex = values[0];
|
|
204
|
+
// A rollover or retention between the two reads moved messages, so read again with the new index.
|
|
205
|
+
if (!isSameMessageLayout(index, readIndex)) {
|
|
206
|
+
if (attempt >= maximumStoredMessageReadAttempts) {
|
|
207
|
+
throw new Error(`the stored messages of session ${this.flowId} moved during ${maximumStoredMessageReadAttempts} reads`);
|
|
208
|
+
}
|
|
209
|
+
index = readIndex;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const bySequence = new Map();
|
|
213
|
+
for (const value of values.slice(1, 1 + chunkReads.length)) {
|
|
214
|
+
for (const message of value?.messages ?? []) {
|
|
215
|
+
bySequence.set(message.sequence, message);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
for (const [offset, value] of values.slice(1 + chunkReads.length).entries()) {
|
|
219
|
+
const sequence = windowSequences[offset];
|
|
220
|
+
if (sequence !== undefined && value !== undefined) {
|
|
221
|
+
bySequence.set(sequence, value);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const messages = [];
|
|
225
|
+
for (let sequence = startSequence; sequence < endSequence; sequence += 1) {
|
|
226
|
+
const message = bySequence.get(sequence);
|
|
227
|
+
if (message === undefined && sequence >= firstSequence) {
|
|
228
|
+
throw new Error(`session ${this.flowId} has no stored message ${sequence}`);
|
|
229
|
+
}
|
|
230
|
+
messages.push(message);
|
|
231
|
+
}
|
|
232
|
+
return { messages, firstSequence };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function isSameMessageLayout(left, right) {
|
|
237
|
+
return (left?.firstSequence === right?.firstSequence &&
|
|
238
|
+
left?.windowFirstSequence === right?.windowFirstSequence &&
|
|
239
|
+
left?.chunks.length === right?.chunks.length);
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=agent-session-record-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session-record-reader.js","sourceRoot":"","sources":["../../../src/ui-stream/agent-session-record-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { type Client } from "@superdurable/dex";
|
|
2
|
+
import type { AgentFrameworkRunner, DeferredToolOutcome } from "../agent-framework-runner.js";
|
|
3
|
+
import type { AgentSessionFlow } from "../agent-session-flow.js";
|
|
4
|
+
import { type AgentUIMessageStreamOptions } from "./agent-ui-message-stream.js";
|
|
5
|
+
/**
|
|
6
|
+
* Request header name for a UI stream resume token.
|
|
7
|
+
*
|
|
8
|
+
* Send the token in this header rather than the URL: a token can reach 64 KiB, beyond many URL limits.
|
|
9
|
+
*/
|
|
10
|
+
export declare const agentResumeTokenHeaderName = "x-agent-resume-token";
|
|
11
|
+
/** {@link AgentUIMessageStreamOptions} plus headers to add to the Response. */
|
|
12
|
+
export interface AgentUIMessageStreamResponseOptions extends AgentUIMessageStreamOptions {
|
|
13
|
+
/** Extra response headers; they override the protocol headers with the same name. */
|
|
14
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
15
|
+
}
|
|
16
|
+
/** Options of {@link sendAgentUserMessageWithUIMessageStream}. */
|
|
17
|
+
export interface AgentUserMessageUIStreamOptions extends Omit<AgentUIMessageStreamResponseOptions, "resumeToken"> {
|
|
18
|
+
/** Text of the user message. */
|
|
19
|
+
readonly text: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One tool approval decision, the content of an AI SDK `tool-approval-response`.
|
|
23
|
+
*
|
|
24
|
+
* `useChat` records it on a tool part when the application calls `addToolApprovalResponse`.
|
|
25
|
+
*/
|
|
26
|
+
export interface AgentToolApprovalResponse {
|
|
27
|
+
/** Approval ID from the `tool-approval-request` part: the `interrupt_id` of the pending interrupt. */
|
|
28
|
+
readonly approvalId: string;
|
|
29
|
+
/** Whether the tool call may run. */
|
|
30
|
+
readonly approved: boolean;
|
|
31
|
+
/** Message the model sees after a rejection. Ignored on approval. */
|
|
32
|
+
readonly reason?: string | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Turn whose assistant message holds the decision, such as `"turn-3"`, or `undefined` when unknown.
|
|
35
|
+
* {@link resolveAgentToolApprovalsWithUIMessageStream} treats a decision bound to another turn than the
|
|
36
|
+
* active one as stale, so a stale browser tab cannot answer a later turn's call that reuses a tool call
|
|
37
|
+
* ID. {@link readAgentToolApprovalResponses} sets it from the message ID.
|
|
38
|
+
*/
|
|
39
|
+
readonly turnId?: string | undefined;
|
|
40
|
+
}
|
|
41
|
+
/** Options of {@link resolveAgentToolApproval}. */
|
|
42
|
+
export interface AgentToolApprovalOptions {
|
|
43
|
+
/** Client used for the RPC. */
|
|
44
|
+
readonly client: Client;
|
|
45
|
+
/** The agent session Flow. */
|
|
46
|
+
readonly flow: AgentSessionFlow<AgentFrameworkRunner<DeferredToolOutcome>>;
|
|
47
|
+
/** Session ID: the Flow ID of the agent session. */
|
|
48
|
+
readonly flowId: string;
|
|
49
|
+
/** The decision to send. */
|
|
50
|
+
readonly approval: AgentToolApprovalResponse;
|
|
51
|
+
}
|
|
52
|
+
/** Options of {@link resolveAgentToolApprovalsWithUIMessageStream}. */
|
|
53
|
+
export interface AgentToolApprovalsUIStreamOptions extends AgentUIMessageStreamResponseOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Decisions from the browser, such as the result of {@link readAgentToolApprovalResponses}. They are
|
|
56
|
+
* untrusted: only the first decision per approval ID counts, at most 100 are read, and only interrupts
|
|
57
|
+
* pending in the session's active turn are resolved, by decisions bound to that turn or to none.
|
|
58
|
+
*/
|
|
59
|
+
readonly approvals: readonly AgentToolApprovalResponse[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns a streaming AI SDK UI message stream Response for one agent turn, or 204 when there is none.
|
|
63
|
+
*
|
|
64
|
+
* Mount it as the reconnect endpoint of `useChat`, `GET <api>/<chatId>/stream` by default, with the chat ID
|
|
65
|
+
* as the session ID; the route must check that the caller may read that session. It writes
|
|
66
|
+
* {@link streamAgentUIMessageChunks} as Server-Sent Events with the protocol headers, a keep-alive
|
|
67
|
+
* comment after each empty long poll, and `data: [DONE]` at the end. It stops reading when the browser
|
|
68
|
+
* closes the response.
|
|
69
|
+
*
|
|
70
|
+
* Use the default `DefaultChatTransport`, whose resumed streams count as replays. A stream started with a
|
|
71
|
+
* token replays the token's turn, and one started without a token replays the active turn; either way
|
|
72
|
+
* its `start` part makes the browser reset the message and rebuild it, whatever it held. With
|
|
73
|
+
* `continueAfterResumeToken`, a stream continues exactly after the last part the browser received and
|
|
74
|
+
* sends no `start` part; use it only while the browser still holds that message. Before it answers 200,
|
|
75
|
+
* the helper reads once to check the token's Dex position; a position Dex rejects restarts the turn from
|
|
76
|
+
* its first retained event.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* // Server: GET /api/chat/:id/stream
|
|
81
|
+
* export async function GET(request: Request, sessionId: string): Promise<Response> {
|
|
82
|
+
* await authorizeSession(request, sessionId);
|
|
83
|
+
* return createAgentUIMessageStreamResponse({
|
|
84
|
+
* client, flow, flowId: sessionId,
|
|
85
|
+
* resumeToken: request.headers.get(agentResumeTokenHeaderName) ?? undefined,
|
|
86
|
+
* signal: request.signal,
|
|
87
|
+
* });
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* // Browser
|
|
91
|
+
* let resumeToken: string | undefined = initial.resumeToken ?? undefined;
|
|
92
|
+
* const chat = useChat({
|
|
93
|
+
* id: sessionId,
|
|
94
|
+
* messages: initial.messages,
|
|
95
|
+
* resume: resumeToken !== undefined,
|
|
96
|
+
* onData: (part) => {
|
|
97
|
+
* if (part.type === "data-agent-resume-token") resumeToken = part.data as string;
|
|
98
|
+
* },
|
|
99
|
+
* transport: new DefaultChatTransport({
|
|
100
|
+
* api: "/api/chat",
|
|
101
|
+
* prepareReconnectToStreamRequest: ({ id }) => ({
|
|
102
|
+
* api: `/api/chat/${id}/stream`,
|
|
103
|
+
* headers: resumeToken === undefined ? {} : { "x-agent-resume-token": resumeToken },
|
|
104
|
+
* }),
|
|
105
|
+
* }),
|
|
106
|
+
* sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
* @param options - Session, start position, polling, and extra headers.
|
|
110
|
+
* @returns 200 with the stream; 204 when the token's turn already finished, or when the turn to replay is
|
|
111
|
+
* not active or not on the Stream; 400 with a text body when `resumeToken` is invalid.
|
|
112
|
+
* @throws {RangeError} When `pollTimeoutMs` is not a positive whole number of seconds.
|
|
113
|
+
* @throws {DexServiceError} When reading the start position fails.
|
|
114
|
+
*/
|
|
115
|
+
export declare function createAgentUIMessageStreamResponse(options: AgentUIMessageStreamResponseOptions): Promise<Response>;
|
|
116
|
+
/**
|
|
117
|
+
* Queues a user message and returns the AI SDK UI message stream Response of the turn it starts.
|
|
118
|
+
*
|
|
119
|
+
* Mount it as the send endpoint of `useChat`, `POST <api>` by default, when the last message in the
|
|
120
|
+
* request body is a user message. The chat ID in the body comes from the browser, so the route must check
|
|
121
|
+
* that the caller may write to that session. The helper reads the session's turn count and the Stream
|
|
122
|
+
* position first and then calls `send_user_message`, so the stream follows the next turn that starts
|
|
123
|
+
* after the message was queued. When an earlier turn is still running, the stream waits for it to end.
|
|
124
|
+
* When other messages were queued before this one, the stream follows the turn of the oldest of them.
|
|
125
|
+
*
|
|
126
|
+
* The session's committed state ends the stream even when no event of the turn reaches the Stream, such
|
|
127
|
+
* as with the Server's Stream Store disabled: once that turn ended, the stream finishes with reason
|
|
128
|
+
* `other`, and the application reloads the stored messages. The RPC needs a running Worker.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* // POST /api/chat
|
|
133
|
+
* export async function POST(request: Request): Promise<Response> {
|
|
134
|
+
* const { id, messages } = await request.json();
|
|
135
|
+
* await authorizeSession(request, id);
|
|
136
|
+
* const lastMessage = messages.at(-1);
|
|
137
|
+
* if (lastMessage.role === "assistant") {
|
|
138
|
+
* return resolveAgentToolApprovalsWithUIMessageStream({
|
|
139
|
+
* client, flow, flowId: id, approvals: readAgentToolApprovalResponses(lastMessage) });
|
|
140
|
+
* }
|
|
141
|
+
* const text = lastMessage.parts.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
142
|
+
* return sendAgentUserMessageWithUIMessageStream({ client, flow, flowId: id, text, signal: request.signal });
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
* @param options - Session, message text, polling, and extra headers.
|
|
146
|
+
* @returns 200 with the stream; 400 with a text body when the text is blank.
|
|
147
|
+
* @throws {RangeError} When `pollTimeoutMs` is not a positive whole number of seconds.
|
|
148
|
+
* @throws {FlowNotActiveOrNotFoundError} When the session is not running.
|
|
149
|
+
* @throws {DexServiceError} When a read or the RPC fails.
|
|
150
|
+
*/
|
|
151
|
+
export declare function sendAgentUserMessageWithUIMessageStream(options: AgentUserMessageUIStreamOptions): Promise<Response>;
|
|
152
|
+
/**
|
|
153
|
+
* Sends one tool approval decision to the session's `resolve_interrupt` RPC.
|
|
154
|
+
*
|
|
155
|
+
* Call it with each AI SDK `tool-approval-response`: its `approvalId` is the `interrupt_id`, and its
|
|
156
|
+
* `reason` becomes the rejection message the model sees. It retries `RpcLockConflictError`, which a call
|
|
157
|
+
* that races the approval Step can raise, for up to 5 seconds. It resolves any pending interrupt of the
|
|
158
|
+
* session, so the route must check that the caller may decide for that session. The RPC needs a running
|
|
159
|
+
* Worker.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* const isResolved = await resolveAgentToolApproval({
|
|
164
|
+
* client, flow, flowId: sessionId,
|
|
165
|
+
* approval: { approvalId: "call_42", approved: false, reason: "Use the sandbox account" },
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
* @param options - Session and decision.
|
|
169
|
+
* @returns `true` when the interrupt was pending and is now resolved; `false` when it is unknown, already
|
|
170
|
+
* resolved, or past its deadline.
|
|
171
|
+
* @throws {RpcLockConflictError} When the lock stays busy for 5 seconds.
|
|
172
|
+
* @throws {FlowNotActiveOrNotFoundError} When the session is not running.
|
|
173
|
+
*/
|
|
174
|
+
export declare function resolveAgentToolApproval(options: AgentToolApprovalOptions): Promise<boolean>;
|
|
175
|
+
/**
|
|
176
|
+
* Returns the tool approval decisions recorded on an AI SDK assistant message.
|
|
177
|
+
*
|
|
178
|
+
* `useChat` sets a tool part to `approval-responded` when the application calls
|
|
179
|
+
* `addToolApprovalResponse`, then sends the message list with `sendAutomaticallyWhen`. Pass the last
|
|
180
|
+
* message of that request body. The message comes from the browser, so every field is checked; parts
|
|
181
|
+
* that are not well-formed responded approvals are skipped.
|
|
182
|
+
*
|
|
183
|
+
* Each decision is bound to the message's turn when the message ID is `<turnId>-assistant`, as the agent UI
|
|
184
|
+
* streams and snapshots name assistant messages; a message with another ID gives unbound decisions.
|
|
185
|
+
*
|
|
186
|
+
* @param message - An AI SDK `UIMessage`, typically the last message of a `useChat` request body.
|
|
187
|
+
* @returns One decision per `approval-responded` tool part, in part order; empty for anything else.
|
|
188
|
+
*/
|
|
189
|
+
export declare function readAgentToolApprovalResponses(message: unknown): AgentToolApprovalResponse[];
|
|
190
|
+
/**
|
|
191
|
+
* Sends tool approval decisions and returns the AI SDK UI message stream Response that continues the turn.
|
|
192
|
+
*
|
|
193
|
+
* Mount it in the send endpoint of `useChat` for requests whose last message is an assistant message,
|
|
194
|
+
* which `sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses` sends after the
|
|
195
|
+
* application answered every approval. The decisions and the chat ID come from the browser, so the route
|
|
196
|
+
* must check that the caller may decide for that session. Only interrupts that are pending in the
|
|
197
|
+
* session's active turn are resolved.
|
|
198
|
+
*
|
|
199
|
+
* The stream continues the same assistant message. A decision that is no longer pending, because another
|
|
200
|
+
* client or a deadline settled the call or its turn ended, gets the call's known outcome, or an error
|
|
201
|
+
* part when none is known, so the browser leaves `approval-responded` and does not send the decision
|
|
202
|
+
* again. Decisions bound to another turn than the active one, such as from a stale browser tab, are all
|
|
203
|
+
* stale, and the stream then ends after their outcomes. With `resumeToken`, the latest `data-agent-resume-token`, the stream continues exactly after the
|
|
204
|
+
* paused stream. Without one it reads the Stream position and the active turn's tool calls before
|
|
205
|
+
* sending the decisions. The RPCs need a running Worker.
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* return resolveAgentToolApprovalsWithUIMessageStream({
|
|
210
|
+
* client, flow, flowId: id, approvals: readAgentToolApprovalResponses(messages.at(-1)) });
|
|
211
|
+
* ```
|
|
212
|
+
* @param options - Session, decisions, optional resume token, polling, and extra headers.
|
|
213
|
+
* @returns 200 with the stream, which holds only the stale decisions' outcomes and a `finish` part when
|
|
214
|
+
* no turn is active; 400 with a text body when `resumeToken` is invalid.
|
|
215
|
+
* @throws {RangeError} When `pollTimeoutMs` is not a positive whole number of seconds.
|
|
216
|
+
* @throws {RpcLockConflictError} When a decision's lock stays busy for 5 seconds.
|
|
217
|
+
* @throws {DexServiceError} When a read or an RPC fails.
|
|
218
|
+
*/
|
|
219
|
+
export declare function resolveAgentToolApprovalsWithUIMessageStream(options: AgentToolApprovalsUIStreamOptions): Promise<Response>;
|