@tidblink/server 0.0.0-stage → 0.4.0-rc.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/LICENSE +201 -0
- package/README.md +1182 -2
- package/dist/audio.d.ts +72 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +168 -0
- package/dist/audio.js.map +1 -0
- package/dist/backend-connection.d.ts +89 -0
- package/dist/backend-connection.d.ts.map +1 -0
- package/dist/backend-connection.js +300 -0
- package/dist/backend-connection.js.map +1 -0
- package/dist/backend-pool.d.ts +93 -0
- package/dist/backend-pool.d.ts.map +1 -0
- package/dist/backend-pool.js +419 -0
- package/dist/backend-pool.js.map +1 -0
- package/dist/client-tool-executor.d.ts +31 -0
- package/dist/client-tool-executor.d.ts.map +1 -0
- package/dist/client-tool-executor.js +190 -0
- package/dist/client-tool-executor.js.map +1 -0
- package/dist/client-tools.d.ts +21 -0
- package/dist/client-tools.d.ts.map +1 -0
- package/dist/client-tools.js +48 -0
- package/dist/client-tools.js.map +1 -0
- package/dist/connector-callback.d.ts +92 -0
- package/dist/connector-callback.d.ts.map +1 -0
- package/dist/connector-callback.js +155 -0
- package/dist/connector-callback.js.map +1 -0
- package/dist/connectors.d.ts +66 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +71 -0
- package/dist/connectors.js.map +1 -0
- package/dist/control.d.ts +17 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +52 -0
- package/dist/control.js.map +1 -0
- package/dist/errors.d.ts +103 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +115 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +158 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +110 -0
- package/dist/events.js.map +1 -0
- package/dist/files.d.ts +129 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +388 -0
- package/dist/files.js.map +1 -0
- package/dist/history.d.ts +279 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +91 -0
- package/dist/history.js.map +1 -0
- package/dist/http.d.ts +88 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +302 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/organization.d.ts +87 -0
- package/dist/organization.d.ts.map +1 -0
- package/dist/organization.js +112 -0
- package/dist/organization.js.map +1 -0
- package/dist/realtime.d.ts +90 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +111 -0
- package/dist/realtime.js.map +1 -0
- package/dist/session-connection.d.ts +144 -0
- package/dist/session-connection.d.ts.map +1 -0
- package/dist/session-connection.js +334 -0
- package/dist/session-connection.js.map +1 -0
- package/dist/session-send.d.ts +49 -0
- package/dist/session-send.d.ts.map +1 -0
- package/dist/session-send.js +179 -0
- package/dist/session-send.js.map +1 -0
- package/dist/session.d.ts +165 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +253 -0
- package/dist/session.js.map +1 -0
- package/dist/skills.d.ts +103 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +98 -0
- package/dist/skills.js.map +1 -0
- package/dist/sse.d.ts +10 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +50 -0
- package/dist/sse.js.map +1 -0
- package/dist/template-switch.d.ts +51 -0
- package/dist/template-switch.d.ts.map +1 -0
- package/dist/template-switch.js +81 -0
- package/dist/template-switch.js.map +1 -0
- package/dist/templates.d.ts +129 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +92 -0
- package/dist/templates.js.map +1 -0
- package/dist/turn.d.ts +47 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +210 -0
- package/dist/turn.js.map +1 -0
- package/dist/usage.d.ts +278 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +22 -0
- package/dist/usage.js.map +1 -0
- package/dist/user.d.ts +55 -0
- package/dist/user.d.ts.map +1 -0
- package/dist/user.js +52 -0
- package/dist/user.js.map +1 -0
- package/examples/control-turn.mjs +53 -0
- package/examples/create-session.mjs +82 -0
- package/examples/http-connector.mjs +127 -0
- package/examples/lamp-backend.mjs +175 -0
- package/examples/prepare-realtime-connection.mjs +72 -0
- package/examples/read-usage.mjs +44 -0
- package/examples/send-message.mjs +48 -0
- package/examples/submit-audio.mjs +57 -0
- package/examples/upload-file.mjs +58 -0
- package/package.json +59 -4
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { validateClientTools, } from "./client-tools.js";
|
|
2
|
+
import { ClientToolExecutor } from "./client-tool-executor.js";
|
|
3
|
+
import { TiDBLinkApiError, TiDBLinkError } from "./errors.js";
|
|
4
|
+
import { asKnownSessionEvent, sessionEventFrom, } from "./events.js";
|
|
5
|
+
import { HttpClient, requestOptions, requireKnownKeys } from "./http.js";
|
|
6
|
+
import { requireOpenRealtimeConnectionReceipt, requireRealtimeConnectGrantReceipt, } from "./realtime.js";
|
|
7
|
+
import { sendOverConnection, } from "./session-send.js";
|
|
8
|
+
const DECIMAL = /^(0|[1-9][0-9]*)$/;
|
|
9
|
+
/** Whether `cursor` is at or before `last`; opaque cursors never compare. */
|
|
10
|
+
const notAfter = (cursor, last) => last !== undefined &&
|
|
11
|
+
DECIMAL.test(cursor) &&
|
|
12
|
+
DECIMAL.test(last) &&
|
|
13
|
+
BigInt(cursor) <= BigInt(last);
|
|
14
|
+
/**
|
|
15
|
+
* A Session attached over this process's Backend Connections. It receives
|
|
16
|
+
* the Session's events, in order and without gaps, across reconnects and
|
|
17
|
+
* replica moves, until `close()` or until `closed` reports why it ended.
|
|
18
|
+
*/
|
|
19
|
+
export class SessionConnection {
|
|
20
|
+
sessionId;
|
|
21
|
+
userId;
|
|
22
|
+
/** Resolves once, with why the connection ended. */
|
|
23
|
+
closed;
|
|
24
|
+
#pool;
|
|
25
|
+
#http;
|
|
26
|
+
#options;
|
|
27
|
+
#declarations;
|
|
28
|
+
#attachment;
|
|
29
|
+
#cursor;
|
|
30
|
+
#generation;
|
|
31
|
+
#link;
|
|
32
|
+
#ended;
|
|
33
|
+
#settle;
|
|
34
|
+
#queue = Promise.resolve();
|
|
35
|
+
#executor;
|
|
36
|
+
/** Waiting for the next attach, or for the end. */
|
|
37
|
+
#linkWaiters = [];
|
|
38
|
+
/** Event buffers of `send()` calls in flight. */
|
|
39
|
+
#watchers = new Set();
|
|
40
|
+
/** @internal Use `session.connect()`. */
|
|
41
|
+
constructor(pool, http, userId, sessionId, options, declarations) {
|
|
42
|
+
this.#pool = pool;
|
|
43
|
+
this.#http = http;
|
|
44
|
+
this.userId = userId;
|
|
45
|
+
this.sessionId = sessionId;
|
|
46
|
+
this.#options = options;
|
|
47
|
+
this.#declarations = declarations;
|
|
48
|
+
this.#cursor = options.cursor;
|
|
49
|
+
this.closed = new Promise((resolve) => {
|
|
50
|
+
this.#settle = resolve;
|
|
51
|
+
});
|
|
52
|
+
// An executing connection runs the Session's calls, declared here or not.
|
|
53
|
+
this.#executor = options.observe
|
|
54
|
+
? undefined
|
|
55
|
+
: new ClientToolExecutor({
|
|
56
|
+
pool,
|
|
57
|
+
sessionId,
|
|
58
|
+
handlers: options.tools ?? {},
|
|
59
|
+
report: (error) => this.#report(error),
|
|
60
|
+
});
|
|
61
|
+
this.#attachment = {
|
|
62
|
+
sessionId,
|
|
63
|
+
attachParams: () => this.#attachParams(),
|
|
64
|
+
attached: (result, link) => this.#attached(result, link),
|
|
65
|
+
notify: (method, params, link) => this.#notify(method, params, link),
|
|
66
|
+
ended: (end) => this.#end(end),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Cursor of the last event whose callbacks completed, or the Session's
|
|
71
|
+
* position when the connection attached if none has arrived since.
|
|
72
|
+
*/
|
|
73
|
+
get cursor() {
|
|
74
|
+
return this.#cursor;
|
|
75
|
+
}
|
|
76
|
+
/** The Session's attachment generation from the latest attach. */
|
|
77
|
+
get generation() {
|
|
78
|
+
return this.#generation;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Release the Session. Events stop, and calls published later go to no one
|
|
82
|
+
* until another connection attaches. Calls already running finish and
|
|
83
|
+
* their results are still submitted.
|
|
84
|
+
*/
|
|
85
|
+
async close() {
|
|
86
|
+
if (this.#ended)
|
|
87
|
+
return;
|
|
88
|
+
this.#end({ reason: "closed" });
|
|
89
|
+
await this.#pool.detach(this.#attachment);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Send a user message over the connection and wait for the Turn it starts,
|
|
93
|
+
* or the active Turn it steers. `onProgress` receives the assistant's draft
|
|
94
|
+
* from the pushed events; the result is read once the Turn finished, with
|
|
95
|
+
* the same shape and errors as `session.turn()`. A message whose answer was
|
|
96
|
+
* lost to a reconnect is sent again with the same `clientEventId`, which
|
|
97
|
+
* the core deduplicates.
|
|
98
|
+
*/
|
|
99
|
+
send(text, options) {
|
|
100
|
+
return sendOverConnection({
|
|
101
|
+
sessionId: this.sessionId,
|
|
102
|
+
http: this.#http,
|
|
103
|
+
closed: this.closed,
|
|
104
|
+
link: (signal, after) => this.#nextLink(signal, after),
|
|
105
|
+
report: (error) => this.#report(error),
|
|
106
|
+
watch: () => this.#watch(),
|
|
107
|
+
}, text, options);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Prepare the Session's Realtime connection and return what a device needs
|
|
111
|
+
* to join it directly: the WebSocket URL and a short-lived connect token.
|
|
112
|
+
* When a Realtime connection is already live, a new token for it is
|
|
113
|
+
* returned instead and `audio` is not applied.
|
|
114
|
+
*/
|
|
115
|
+
async realtimeGrant(input = {}, options) {
|
|
116
|
+
requireKnownKeys(input, ["audio", "metadata"], "Realtime grant input");
|
|
117
|
+
const request = requestOptions(options);
|
|
118
|
+
const path = `/sessions/${encodeURIComponent(this.sessionId)}/realtime`;
|
|
119
|
+
try {
|
|
120
|
+
const result = await this.#http.postResponse(path, input, {
|
|
121
|
+
...request,
|
|
122
|
+
outcomeUnknown: true,
|
|
123
|
+
});
|
|
124
|
+
const opened = requireOpenRealtimeConnectionReceipt(result.data, result.requestId);
|
|
125
|
+
return {
|
|
126
|
+
websocketUrl: opened.websocketUrl,
|
|
127
|
+
connectToken: opened.connectToken,
|
|
128
|
+
connectTokenExpiresAt: opened.connectTokenExpiresAt,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (!(error instanceof TiDBLinkApiError) || error.code !== "realtime_connection_live")
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
const result = await this.#http.postResponse(`${path}/connect-tokens`, undefined, {
|
|
136
|
+
...request,
|
|
137
|
+
outcomeUnknown: true,
|
|
138
|
+
});
|
|
139
|
+
return requireRealtimeConnectGrantReceipt(result.data, result.requestId);
|
|
140
|
+
}
|
|
141
|
+
/** @internal */
|
|
142
|
+
async attach() {
|
|
143
|
+
await this.#pool.attach(this.#attachment);
|
|
144
|
+
}
|
|
145
|
+
#report(error) {
|
|
146
|
+
if (this.#options.onError) {
|
|
147
|
+
try {
|
|
148
|
+
this.#options.onError(error);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
catch (thrown) {
|
|
152
|
+
error = thrown;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
queueMicrotask(() => {
|
|
156
|
+
throw error;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
#attachParams() {
|
|
160
|
+
return {
|
|
161
|
+
userId: this.userId,
|
|
162
|
+
sessionId: this.sessionId,
|
|
163
|
+
...(this.#options.observe ? { kind: "observing" } : {}),
|
|
164
|
+
...(this.#declarations ? { tools: this.#declarations } : {}),
|
|
165
|
+
...(this.#cursor === undefined ? {} : { cursor: this.#cursor }),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
#attached(result, link) {
|
|
169
|
+
this.#link = link;
|
|
170
|
+
this.#generation = result.generation;
|
|
171
|
+
// Without a resume point, delivery starts after the attach position.
|
|
172
|
+
this.#cursor ??= result.cursor;
|
|
173
|
+
this.#wakeLinkWaiters();
|
|
174
|
+
}
|
|
175
|
+
#wakeLinkWaiters() {
|
|
176
|
+
const waiters = this.#linkWaiters;
|
|
177
|
+
this.#linkWaiters = [];
|
|
178
|
+
for (const waiter of waiters)
|
|
179
|
+
waiter.resolve();
|
|
180
|
+
}
|
|
181
|
+
/** The open link holding the attachment, other than `after`; waits for a re-attach. */
|
|
182
|
+
async #nextLink(signal, after) {
|
|
183
|
+
for (;;) {
|
|
184
|
+
signal.throwIfAborted();
|
|
185
|
+
if (this.#ended)
|
|
186
|
+
throw new TiDBLinkError(`The Session connection ended (${this.#ended.reason}); connect again to send`);
|
|
187
|
+
const link = this.#link;
|
|
188
|
+
if (link && link.open && link !== after)
|
|
189
|
+
return link;
|
|
190
|
+
await new Promise((resolve, reject) => {
|
|
191
|
+
const onAbort = () => reject(signal.reason);
|
|
192
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
193
|
+
this.#linkWaiters.push({
|
|
194
|
+
resolve: () => {
|
|
195
|
+
signal.removeEventListener("abort", onAbort);
|
|
196
|
+
resolve();
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
// A link that closed without a re-attach yet: look again shortly.
|
|
200
|
+
if (link && !link.open)
|
|
201
|
+
setTimeout(() => this.#wakeLinkWaiters(), 100);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
#watch() {
|
|
206
|
+
const watcher = { events: [], wake: () => undefined };
|
|
207
|
+
this.#watchers.add(watcher);
|
|
208
|
+
return {
|
|
209
|
+
next: async (signal) => {
|
|
210
|
+
for (;;) {
|
|
211
|
+
const event = watcher.events.shift();
|
|
212
|
+
if (event)
|
|
213
|
+
return event;
|
|
214
|
+
if (this.#ended)
|
|
215
|
+
return undefined;
|
|
216
|
+
signal.throwIfAborted();
|
|
217
|
+
await new Promise((resolve, reject) => {
|
|
218
|
+
const onAbort = () => reject(signal.reason);
|
|
219
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
220
|
+
watcher.wake = () => {
|
|
221
|
+
signal.removeEventListener("abort", onAbort);
|
|
222
|
+
watcher.wake = () => undefined;
|
|
223
|
+
resolve();
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
stop: () => {
|
|
229
|
+
this.#watchers.delete(watcher);
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
#notify(method, params, link) {
|
|
234
|
+
if (this.#ended)
|
|
235
|
+
return;
|
|
236
|
+
if (method === "tool.call") {
|
|
237
|
+
this.#executor?.receive(params, link);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (method !== "session.event")
|
|
241
|
+
return;
|
|
242
|
+
let event;
|
|
243
|
+
try {
|
|
244
|
+
event = sessionEventFrom(params.event, params.cursor, {
|
|
245
|
+
sessionId: this.sessionId,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
this.#queue = this.#queue.then(() => this.#report(error));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
// One event at a time, so that callbacks and saved cursors follow the Session's order.
|
|
253
|
+
this.#queue = this.#queue.then(() => this.#deliver(event));
|
|
254
|
+
}
|
|
255
|
+
async #deliver(event) {
|
|
256
|
+
// A re-attach replays from the last completed event; skip what already ran.
|
|
257
|
+
if (this.#ended || notAfter(event.cursor, this.#cursor))
|
|
258
|
+
return;
|
|
259
|
+
const options = this.#options;
|
|
260
|
+
await this.#run(() => options.onEvent?.(event));
|
|
261
|
+
const known = asKnownSessionEvent(event);
|
|
262
|
+
if (known?.type === "agent.session.realtime.input_transcript.completed")
|
|
263
|
+
await this.#run(() => options.onTranscript?.(known.data));
|
|
264
|
+
if (known?.type === "agent.session.realtime.response.completed")
|
|
265
|
+
await this.#run(() => options.onResponse?.(known.data));
|
|
266
|
+
this.#cursor = event.cursor;
|
|
267
|
+
for (const watcher of this.#watchers) {
|
|
268
|
+
watcher.events.push(event);
|
|
269
|
+
watcher.wake();
|
|
270
|
+
}
|
|
271
|
+
await this.#run(() => options.onCursor?.(event.cursor));
|
|
272
|
+
}
|
|
273
|
+
async #run(callback) {
|
|
274
|
+
try {
|
|
275
|
+
await callback();
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
this.#report(error);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
#end(end) {
|
|
282
|
+
if (this.#ended)
|
|
283
|
+
return;
|
|
284
|
+
this.#ended = end;
|
|
285
|
+
this.#link = undefined;
|
|
286
|
+
this.#settle(end);
|
|
287
|
+
this.#wakeLinkWaiters();
|
|
288
|
+
for (const watcher of this.#watchers)
|
|
289
|
+
watcher.wake();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/** Check `connect()` options and turn tool handlers into declarations. */
|
|
293
|
+
export function connectDeclarations(options) {
|
|
294
|
+
requireKnownKeys(options, ["tools", "observe", "cursor", "onCursor", "onEvent", "onTranscript", "onResponse", "onError"], "Session connection options");
|
|
295
|
+
for (const key of ["onCursor", "onEvent", "onTranscript", "onResponse", "onError"])
|
|
296
|
+
if (options[key] !== undefined && typeof options[key] !== "function")
|
|
297
|
+
throw new TypeError(`${key} must be a function`);
|
|
298
|
+
if (options.observe !== undefined && typeof options.observe !== "boolean")
|
|
299
|
+
throw new TypeError("observe must be a boolean");
|
|
300
|
+
if (options.cursor !== undefined &&
|
|
301
|
+
(typeof options.cursor !== "string" || !/^(0|[1-9][0-9]{0,14})$/.test(options.cursor)))
|
|
302
|
+
throw new TypeError("cursor must be an event cursor received from this Session");
|
|
303
|
+
if (options.tools === undefined)
|
|
304
|
+
return undefined;
|
|
305
|
+
if (options.observe)
|
|
306
|
+
throw new TypeError("An observing connection cannot declare Client Tools");
|
|
307
|
+
if (typeof options.tools !== "object" || options.tools === null || Array.isArray(options.tools))
|
|
308
|
+
throw new TypeError("tools must map each Client Tool name to its handler");
|
|
309
|
+
const declarations = Object.entries(options.tools).map(([name, handler]) => {
|
|
310
|
+
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(name))
|
|
311
|
+
throw new TypeError(`Client Tool name ${JSON.stringify(name)} must be 1-64 letters, digits, _ or -`);
|
|
312
|
+
requireKnownKeys(handler, ["description", "parameters", "run"], `Client Tool ${name}`);
|
|
313
|
+
if (typeof handler.run !== "function")
|
|
314
|
+
throw new TypeError(`Client Tool ${name} requires a run function`);
|
|
315
|
+
return {
|
|
316
|
+
type: "function",
|
|
317
|
+
name,
|
|
318
|
+
description: handler.description,
|
|
319
|
+
parameters: handler.parameters,
|
|
320
|
+
};
|
|
321
|
+
});
|
|
322
|
+
validateClientTools(declarations);
|
|
323
|
+
return declarations;
|
|
324
|
+
}
|
|
325
|
+
/** Open a Session connection; resolves once the first attach took effect. */
|
|
326
|
+
export async function connectSession(http, pool, userId, sessionId, options = {}) {
|
|
327
|
+
if (!pool || !userId)
|
|
328
|
+
throw new TiDBLinkError("connect() needs a Session selected through OrganizationClient.user(userId)");
|
|
329
|
+
const declarations = connectDeclarations(options);
|
|
330
|
+
const connection = new SessionConnection(pool, http, userId, sessionId, options, declarations);
|
|
331
|
+
await connection.attach();
|
|
332
|
+
return connection;
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=session-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-connection.js","sourceRoot":"","sources":["../src/session-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { BackendLink } from "./backend-pool.js";
|
|
2
|
+
import type { SessionEvent } from "./events.js";
|
|
3
|
+
import { HttpClient } from "./http.js";
|
|
4
|
+
import type { BillingTag } from "./session.js";
|
|
5
|
+
import { type TurnResult } from "./turn.js";
|
|
6
|
+
export interface SendOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Stable identity of this message in the Session's command namespace,
|
|
9
|
+
* shared with REST. Persist it before sending to recover the result after a
|
|
10
|
+
* crash with `session.waitForResult(clientEventId)`. Default: a random UUID.
|
|
11
|
+
*/
|
|
12
|
+
clientEventId?: string;
|
|
13
|
+
userFileIds?: string[];
|
|
14
|
+
clarificationSourceTurnId?: string;
|
|
15
|
+
billingTag?: BillingTag | null;
|
|
16
|
+
/**
|
|
17
|
+
* The assistant's draft so far, each time it grows. Each call carries the
|
|
18
|
+
* complete draft: replace what you showed, do not append.
|
|
19
|
+
*/
|
|
20
|
+
onProgress?: (draft: string) => void;
|
|
21
|
+
/** Local deadline for the whole call; default 60 seconds. Never cancels the Turn. */
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
}
|
|
25
|
+
/** What `send()` needs from its Session connection. */
|
|
26
|
+
export interface SendChannel {
|
|
27
|
+
readonly sessionId: string;
|
|
28
|
+
readonly http: HttpClient;
|
|
29
|
+
/** The link that holds the attachment now, or the next one; rejects once the connection ended. */
|
|
30
|
+
link(signal: AbortSignal, after?: BackendLink): Promise<BackendLink>;
|
|
31
|
+
/** Resolves when the connection ends. */
|
|
32
|
+
readonly closed: Promise<unknown>;
|
|
33
|
+
/** Report an error that does not end the call. */
|
|
34
|
+
report(error: unknown): void;
|
|
35
|
+
/** Start buffering this connection's events, in delivery order. */
|
|
36
|
+
watch(): EventWatch;
|
|
37
|
+
}
|
|
38
|
+
export interface EventWatch {
|
|
39
|
+
/** The next event, or `undefined` once the connection ended. */
|
|
40
|
+
next(signal: AbortSignal): Promise<SessionEvent | undefined>;
|
|
41
|
+
stop(): void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Submit a user message over the connection and wait for the Turn it starts
|
|
45
|
+
* or steers: progress from the pushed events, and the result read once the
|
|
46
|
+
* Turn's terminal event arrives.
|
|
47
|
+
*/
|
|
48
|
+
export declare function sendOverConnection(channel: SendChannel, text: string | [string, ...string[]], options?: SendOptions): Promise<TurnResult>;
|
|
49
|
+
//# sourceMappingURL=session-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-send.d.ts","sourceRoot":"","sources":["../src/session-send.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,UAAU,EAA+C,MAAM,WAAW,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,kGAAkG;IAClG,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrE,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,kDAAkD;IAClD,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,mEAAmE;IACnE,KAAK,IAAI,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IAC7D,IAAI,IAAI,IAAI,CAAC;CACd;AAkBD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EACpC,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAiKrB"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { BackendConnectionClosedError, BackendRequestError, InputNotAppliedError, OutcomeUnknownError, TiDBLinkError, TurnWaitTimeoutError, } from "./errors.js";
|
|
2
|
+
import { requireInteraction } from "./history.js";
|
|
3
|
+
import { HttpClient, requireCreationKey, requireKnownKeys, sleep } from "./http.js";
|
|
4
|
+
import { validateMessageData, validateWaitOptions, waitForResult, } from "./turn.js";
|
|
5
|
+
/** How long a finished Turn's result waits for the Session's release, and at least for its read. */
|
|
6
|
+
const RELEASE_WAIT_MS = 5_000;
|
|
7
|
+
const aborted = (signal) => new Promise((_, reject) => {
|
|
8
|
+
if (signal.aborted)
|
|
9
|
+
reject(signal.reason);
|
|
10
|
+
signal.addEventListener("abort", () => reject(signal.reason), { once: true });
|
|
11
|
+
});
|
|
12
|
+
/** Refusals after which the same message may go out on the next link. */
|
|
13
|
+
const MOVE_ON = new Set(["connection_draining", "session_not_attached"]);
|
|
14
|
+
const isAmbiguous = (error) => error instanceof BackendConnectionClosedError ||
|
|
15
|
+
(error instanceof BackendRequestError && error.code === -32603);
|
|
16
|
+
/**
|
|
17
|
+
* Submit a user message over the connection and wait for the Turn it starts
|
|
18
|
+
* or steers: progress from the pushed events, and the result read once the
|
|
19
|
+
* Turn's terminal event arrives.
|
|
20
|
+
*/
|
|
21
|
+
export async function sendOverConnection(channel, text, options = {}) {
|
|
22
|
+
requireKnownKeys(options, [
|
|
23
|
+
"clientEventId",
|
|
24
|
+
"userFileIds",
|
|
25
|
+
"clarificationSourceTurnId",
|
|
26
|
+
"billingTag",
|
|
27
|
+
"onProgress",
|
|
28
|
+
"timeoutMs",
|
|
29
|
+
"signal",
|
|
30
|
+
], "Send options");
|
|
31
|
+
const { clientEventId = crypto.randomUUID(), onProgress, timeoutMs, signal } = options;
|
|
32
|
+
requireCreationKey(clientEventId);
|
|
33
|
+
if (onProgress !== undefined && typeof onProgress !== "function")
|
|
34
|
+
throw new TypeError("onProgress must be a function");
|
|
35
|
+
const data = {
|
|
36
|
+
text,
|
|
37
|
+
...(options.userFileIds === undefined ? {} : { userFileIds: options.userFileIds }),
|
|
38
|
+
...(options.clarificationSourceTurnId === undefined
|
|
39
|
+
? {}
|
|
40
|
+
: { clarificationSourceTurnId: options.clarificationSourceTurnId }),
|
|
41
|
+
...(options.billingTag === undefined ? {} : { billingTag: options.billingTag }),
|
|
42
|
+
};
|
|
43
|
+
validateMessageData(data);
|
|
44
|
+
const { timeoutMs: limit } = validateWaitOptions(timeoutMs === undefined ? {} : { timeoutMs });
|
|
45
|
+
signal?.throwIfAborted();
|
|
46
|
+
const startedAt = Date.now();
|
|
47
|
+
const deadline = AbortSignal.timeout(limit);
|
|
48
|
+
const stop = signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
49
|
+
const { sessionId } = channel;
|
|
50
|
+
// Events of the Turn may arrive before the receipt.
|
|
51
|
+
const watch = channel.watch();
|
|
52
|
+
let receipt;
|
|
53
|
+
let ambiguous = false;
|
|
54
|
+
let turnFinished = false;
|
|
55
|
+
try {
|
|
56
|
+
receipt = await submit();
|
|
57
|
+
if (receipt.rejection || receipt.mode === "rejected")
|
|
58
|
+
throw new InputNotAppliedError(sessionId, clientEventId, receipt.turnId);
|
|
59
|
+
if (receipt.result.status === "running")
|
|
60
|
+
await untilFinished(receipt.turnId);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (error instanceof InputNotAppliedError || error instanceof BackendRequestError)
|
|
64
|
+
throw error;
|
|
65
|
+
// Nothing reached the core: the error is definite.
|
|
66
|
+
if (receipt === undefined && !ambiguous)
|
|
67
|
+
throw error;
|
|
68
|
+
const ErrorClass = deadline.aborted && !signal?.aborted ? TurnWaitTimeoutError : OutcomeUnknownError;
|
|
69
|
+
throw new ErrorClass(receipt === undefined
|
|
70
|
+
? "The message's outcome is unknown; recover it with session.waitForResult(clientEventId)"
|
|
71
|
+
: "Local wait stopped before the Turn finished; query or wait for the original input", {
|
|
72
|
+
sessionId,
|
|
73
|
+
inputId: clientEventId,
|
|
74
|
+
...(receipt ? { turnId: receipt.turnId } : {}),
|
|
75
|
+
cause: error,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
watch.stop();
|
|
80
|
+
}
|
|
81
|
+
// The terminal event arrived (or the connection ended): read the settled result.
|
|
82
|
+
const remaining = Math.max(0, limit - (Date.now() - startedAt));
|
|
83
|
+
return waitForResult(channel.http, sessionId, clientEventId, {
|
|
84
|
+
// A finished Turn's result is read even when the local deadline just passed.
|
|
85
|
+
timeoutMs: turnFinished ? Math.max(remaining, RELEASE_WAIT_MS) : remaining,
|
|
86
|
+
pollIntervalMs: 100,
|
|
87
|
+
...(signal ? { signal } : {}),
|
|
88
|
+
});
|
|
89
|
+
async function submit() {
|
|
90
|
+
let link;
|
|
91
|
+
for (;;) {
|
|
92
|
+
link = await channel.link(stop, link);
|
|
93
|
+
let result;
|
|
94
|
+
try {
|
|
95
|
+
result = await Promise.race([
|
|
96
|
+
link.request("session.send", { sessionId, clientEventId, data }),
|
|
97
|
+
aborted(stop),
|
|
98
|
+
// Ended while the answer was outstanding: the core may have accepted it.
|
|
99
|
+
channel.closed.then(() => {
|
|
100
|
+
throw new BackendConnectionClosedError({
|
|
101
|
+
code: 1000,
|
|
102
|
+
message: "The Session connection ended before the message's answer arrived",
|
|
103
|
+
});
|
|
104
|
+
}),
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (isAmbiguous(error)) {
|
|
109
|
+
// The core may have accepted it; the same clientEventId replays the receipt.
|
|
110
|
+
ambiguous = true;
|
|
111
|
+
if (error instanceof BackendRequestError) {
|
|
112
|
+
// An internal error on a live connection: try the same one again shortly.
|
|
113
|
+
await Promise.race([sleep(200), aborted(stop)]);
|
|
114
|
+
link = undefined;
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (error instanceof BackendRequestError && MOVE_ON.has(error.reason ?? ""))
|
|
119
|
+
continue;
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
const interaction = result?.interaction;
|
|
123
|
+
const parsed = requireInteraction(interaction, clientEventId, undefined);
|
|
124
|
+
if (parsed.kind !== "message" || !parsed.message || parsed.message.role !== "user")
|
|
125
|
+
throw new TiDBLinkError("session.send returned a different command receipt");
|
|
126
|
+
return parsed;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Follow the Turn until it finished and the Session released it, so that
|
|
131
|
+
* the next message starts a new Turn instead of steering a finished one.
|
|
132
|
+
*/
|
|
133
|
+
async function untilFinished(turnId) {
|
|
134
|
+
let finished = false;
|
|
135
|
+
let release;
|
|
136
|
+
for (;;) {
|
|
137
|
+
let event;
|
|
138
|
+
try {
|
|
139
|
+
event = await watch.next(release ?? stop);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
// The result exists; only the release is still outstanding.
|
|
143
|
+
if (finished)
|
|
144
|
+
return;
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
// The connection ended; the REST read below still establishes the result.
|
|
148
|
+
if (!event)
|
|
149
|
+
return;
|
|
150
|
+
if (event.type === "agent.session.idle") {
|
|
151
|
+
const released = event.data.turnId;
|
|
152
|
+
// Released without a terminal event (kept for checkpoint recovery): the REST read decides.
|
|
153
|
+
if (released === turnId || event.turnId === turnId)
|
|
154
|
+
return;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (event.turnId !== turnId)
|
|
158
|
+
continue;
|
|
159
|
+
const payload = event.data;
|
|
160
|
+
if (event.type === "agent.session.turn.output_text.snapshot" &&
|
|
161
|
+
typeof payload.payload?.text === "string") {
|
|
162
|
+
try {
|
|
163
|
+
onProgress?.(payload.payload.text);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
// A failing display callback does not change the Turn.
|
|
167
|
+
channel.report(error);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (payload.event === "turn_finished" && !finished) {
|
|
171
|
+
finished = true;
|
|
172
|
+
turnFinished = true;
|
|
173
|
+
// The release normally follows at once; do not hold a known result for long.
|
|
174
|
+
release = AbortSignal.any([stop, AbortSignal.timeout(RELEASE_WAIT_MS)]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=session-send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-send.js","sourceRoot":"","sources":["../src/session-send.ts"],"names":[],"mappings":"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"}
|