@intelligo-dev/chat 1.0.0-beta.5
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 +75 -0
- package/dist/body.d.ts +41 -0
- package/dist/body.d.ts.map +1 -0
- package/dist/body.js +113 -0
- package/dist/body.js.map +1 -0
- package/dist/client.d.ts +56 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +62 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +195 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +20 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/handler.d.ts +30 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +544 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +19 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +34 -0
- package/dist/messages.js.map +1 -0
- package/dist/quota.d.ts +24 -0
- package/dist/quota.d.ts.map +1 -0
- package/dist/quota.js +41 -0
- package/dist/quota.js.map +1 -0
- package/dist/testing.d.ts +43 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +89 -0
- package/dist/testing.js.map +1 -0
- package/dist/title.d.ts +7 -0
- package/dist/title.d.ts.map +1 -0
- package/dist/title.js +15 -0
- package/dist/title.js.map +1 -0
- package/dist/usage.d.ts +19 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +26 -0
- package/dist/usage.js.map +1 -0
- package/dist/windowing.d.ts +39 -0
- package/dist/windowing.d.ts.map +1 -0
- package/dist/windowing.js +80 -0
- package/dist/windowing.js.map +1 -0
- package/package.json +63 -0
package/dist/handler.js
ADDED
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat transport: one turn, from request to settled execution.
|
|
3
|
+
*
|
|
4
|
+
* onRequest → parse → authenticate → rate limit → load the row →
|
|
5
|
+
* resolveAgent → feature gate → create the row → prepareMessages →
|
|
6
|
+
* executions.begin() → streamText → settle → persist.
|
|
7
|
+
*
|
|
8
|
+
* Framework-agnostic on the request side: Web `Request` in, `Response`
|
|
9
|
+
* out. A Next.js route file is two lines
|
|
10
|
+
* (`export const { POST, DELETE } = createChatHandler(config)`), and a
|
|
11
|
+
* Hono app or a test calls the same functions. The request's headers
|
|
12
|
+
* reach `requireWorkspace()` through `core/request-context`, bound
|
|
13
|
+
* once by the composition root — never through `next/*` here.
|
|
14
|
+
*
|
|
15
|
+
* Entitlement is decided at `executions.begin()`, after the agent and
|
|
16
|
+
* model are resolved, so the hold matches what will actually run
|
|
17
|
+
* (ADR-0003, ADR-0007). Everything before it is cheaper and answers
|
|
18
|
+
* without opening an execution.
|
|
19
|
+
*
|
|
20
|
+
* Every terminal path settles exactly once: `complete()` is
|
|
21
|
+
* compare-and-swap in the boundary, so whichever of finish, abort or
|
|
22
|
+
* error gets there first wins and the others are no-ops.
|
|
23
|
+
*/
|
|
24
|
+
import { convertToModelMessages, createUIMessageStream, createUIMessageStreamResponse, generateId, stepCountIs, streamText, } from "ai";
|
|
25
|
+
import { requireWorkspace } from "@intelligo-dev/auth";
|
|
26
|
+
import { checkRateLimit, getWorkspaceBilling, hasFeature, } from "@intelligo-dev/billing";
|
|
27
|
+
import { createConversation, deleteConversation, deleteTrailingMessages, getConversation, getMessages, isConversationServiceError, renameConversation, upsertMessages, } from "@intelligo-dev/core/conversations";
|
|
28
|
+
import { createLogger } from "@intelligo-dev/core/logger";
|
|
29
|
+
import { parseChatBody } from "./body.js";
|
|
30
|
+
import { CHAT_ERROR_STATUS, DEFAULT_CHAT_MESSAGES, refuse } from "./errors.js";
|
|
31
|
+
import { lastUserMessage, toUIMessages } from "./messages.js";
|
|
32
|
+
import { truncateTitle } from "./title.js";
|
|
33
|
+
import { pickUsage, sumStepUsage } from "./usage.js";
|
|
34
|
+
import { applyConversationWindow, extractText } from "./windowing.js";
|
|
35
|
+
const log = createLogger("Chat");
|
|
36
|
+
function errorMessage(error) {
|
|
37
|
+
return error instanceof Error ? error.message : String(error);
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Defaults
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
const DEFAULT_FEATURE_KEY = "chat";
|
|
43
|
+
const DEFAULT_CAPABILITY = "chat.message";
|
|
44
|
+
const DEFAULT_AGENT_ID = "assistant";
|
|
45
|
+
const DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant embedded in a SaaS product. Be concise and direct.";
|
|
46
|
+
const DEFAULT_MAX_MESSAGE_LENGTH = 8000;
|
|
47
|
+
const DEFAULT_MAX_STEPS = 5;
|
|
48
|
+
const DEFAULT_WINDOW = { maxMessages: 40 };
|
|
49
|
+
async function defaultAuthenticate() {
|
|
50
|
+
const { workspace, user } = await requireWorkspace();
|
|
51
|
+
return { workspaceId: workspace.id, userId: user.id };
|
|
52
|
+
}
|
|
53
|
+
async function defaultRateLimit(actor) {
|
|
54
|
+
const billing = await getWorkspaceBilling(actor.workspaceId);
|
|
55
|
+
return checkRateLimit(actor.workspaceId, billing.plan?.slug ?? "free");
|
|
56
|
+
}
|
|
57
|
+
function rateLimitHeaders(decision) {
|
|
58
|
+
const headers = {};
|
|
59
|
+
if (decision.limit !== undefined) {
|
|
60
|
+
headers["X-RateLimit-Limit"] = String(decision.limit);
|
|
61
|
+
}
|
|
62
|
+
if (decision.remaining !== undefined) {
|
|
63
|
+
headers["X-RateLimit-Remaining"] = String(decision.remaining);
|
|
64
|
+
}
|
|
65
|
+
if (decision.resetAt !== undefined) {
|
|
66
|
+
headers["X-RateLimit-Reset"] = String(Math.ceil(decision.resetAt.getTime() / 1000));
|
|
67
|
+
}
|
|
68
|
+
if (decision.retryAfterSeconds !== undefined) {
|
|
69
|
+
headers["Retry-After"] = String(decision.retryAfterSeconds);
|
|
70
|
+
}
|
|
71
|
+
return headers;
|
|
72
|
+
}
|
|
73
|
+
export function createChatHandler(config) {
|
|
74
|
+
const maxMessageLength = config.maxMessageLength ?? DEFAULT_MAX_MESSAGE_LENGTH;
|
|
75
|
+
const attachments = config.attachments ?? false;
|
|
76
|
+
const authenticate = config.authenticate ?? defaultAuthenticate;
|
|
77
|
+
const rateLimit = config.rateLimit === undefined ? defaultRateLimit : config.rateLimit;
|
|
78
|
+
const deriveTitle = config.deriveTitle ?? truncateTitle;
|
|
79
|
+
const events = config.onTurn ?? {};
|
|
80
|
+
/** Telemetry must never fail a turn. */
|
|
81
|
+
async function emit(run) {
|
|
82
|
+
if (!run)
|
|
83
|
+
return;
|
|
84
|
+
try {
|
|
85
|
+
await run();
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
log.warn("onTurn hook threw", { error: errorMessage(error) });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function messagesFor(request) {
|
|
92
|
+
return config.messages ? config.messages(request) : DEFAULT_CHAT_MESSAGES;
|
|
93
|
+
}
|
|
94
|
+
function refusal(t, code, error, where, extra = {}, headers = {}) {
|
|
95
|
+
void emit(() => events.refuse?.({
|
|
96
|
+
...where,
|
|
97
|
+
code,
|
|
98
|
+
status: CHAT_ERROR_STATUS[code],
|
|
99
|
+
...(extra.reasonCode ? { reasonCode: extra.reasonCode } : {}),
|
|
100
|
+
}));
|
|
101
|
+
void t;
|
|
102
|
+
return refuse(code, error, extra, headers);
|
|
103
|
+
}
|
|
104
|
+
async function resolveAgent(turn) {
|
|
105
|
+
if (config.resolveAgent)
|
|
106
|
+
return config.resolveAgent(turn);
|
|
107
|
+
const shorthand = config.agent ?? {};
|
|
108
|
+
const tools = typeof shorthand.tools === "function"
|
|
109
|
+
? await shorthand.tools(turn)
|
|
110
|
+
: shorthand.tools;
|
|
111
|
+
return {
|
|
112
|
+
// A conversation keeps the agent it was created with.
|
|
113
|
+
id: turn.conversation?.agentId ?? shorthand.id ?? DEFAULT_AGENT_ID,
|
|
114
|
+
systemPrompt: shorthand.systemPrompt ?? DEFAULT_SYSTEM_PROMPT,
|
|
115
|
+
...(tools ? { tools } : {}),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function prepare(turn, incoming) {
|
|
119
|
+
if (config.prepareMessages)
|
|
120
|
+
return config.prepareMessages(turn, incoming);
|
|
121
|
+
const windowing = config.windowing === undefined ? DEFAULT_WINDOW : config.windowing;
|
|
122
|
+
if (windowing === false)
|
|
123
|
+
return { messages: incoming };
|
|
124
|
+
return { messages: applyConversationWindow(incoming, windowing).windowed };
|
|
125
|
+
}
|
|
126
|
+
async function loadRow(actor, id) {
|
|
127
|
+
try {
|
|
128
|
+
return { ok: true, row: await getConversation(actor, id) };
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (isConversationServiceError(error) && error.code === "not_found") {
|
|
132
|
+
return { ok: true, row: null };
|
|
133
|
+
}
|
|
134
|
+
return { ok: false, error };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// -------------------------------------------------------------------------
|
|
138
|
+
// POST — stream a reply
|
|
139
|
+
// -------------------------------------------------------------------------
|
|
140
|
+
async function POST(request) {
|
|
141
|
+
await config.onRequest?.();
|
|
142
|
+
const t = await messagesFor(request);
|
|
143
|
+
const nowhere = { actor: null, conversationId: null };
|
|
144
|
+
let json;
|
|
145
|
+
try {
|
|
146
|
+
json = await request.json();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return refusal(t, "BAD_REQUEST", t("invalidBody"), nowhere);
|
|
150
|
+
}
|
|
151
|
+
const parsed = parseChatBody(json, { maxMessageLength, attachments });
|
|
152
|
+
if (!parsed.ok) {
|
|
153
|
+
const { key, params } = parsed.rejection;
|
|
154
|
+
return refusal(t, "BAD_REQUEST", t(key, params), nowhere);
|
|
155
|
+
}
|
|
156
|
+
const body = parsed.body;
|
|
157
|
+
const where = { actor: null, conversationId: body.id };
|
|
158
|
+
let actor;
|
|
159
|
+
try {
|
|
160
|
+
actor = await authenticate(request);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return refusal(t, "UNAUTHORIZED", t("unauthorized"), where);
|
|
164
|
+
}
|
|
165
|
+
where.actor = actor;
|
|
166
|
+
let limitHeaders = {};
|
|
167
|
+
if (rateLimit !== false) {
|
|
168
|
+
const decision = await rateLimit(actor);
|
|
169
|
+
limitHeaders = rateLimitHeaders(decision);
|
|
170
|
+
if (!decision.allowed) {
|
|
171
|
+
const seconds = decision.retryAfterSeconds ?? 60;
|
|
172
|
+
return refusal(t, "RATE_LIMITED", t("rateLimited", { seconds }), where, { retryAfterSeconds: seconds }, limitHeaders);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const loaded = await loadRow(actor, body.id);
|
|
176
|
+
if (!loaded.ok) {
|
|
177
|
+
// `forbidden` is another tenant's id. Answer as if it did not
|
|
178
|
+
// exist rather than confirm that it does.
|
|
179
|
+
if (isConversationServiceError(loaded.error) &&
|
|
180
|
+
loaded.error.code === "forbidden") {
|
|
181
|
+
return refusal(t, "NOT_FOUND", t("notFound"), where);
|
|
182
|
+
}
|
|
183
|
+
log.error("Failed to load conversation", {
|
|
184
|
+
conversationId: body.id,
|
|
185
|
+
error: errorMessage(loaded.error),
|
|
186
|
+
});
|
|
187
|
+
return refusal(t, "INTERNAL", t("internalError"), where);
|
|
188
|
+
}
|
|
189
|
+
const context = {
|
|
190
|
+
...actor,
|
|
191
|
+
request,
|
|
192
|
+
conversationId: body.id,
|
|
193
|
+
body: body.extra,
|
|
194
|
+
conversation: loaded.row,
|
|
195
|
+
trigger: body.trigger,
|
|
196
|
+
};
|
|
197
|
+
let agent;
|
|
198
|
+
try {
|
|
199
|
+
agent = await resolveAgent(context);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
log.error("resolveAgent failed", {
|
|
203
|
+
conversationId: body.id,
|
|
204
|
+
error: errorMessage(error),
|
|
205
|
+
});
|
|
206
|
+
await emit(() => events.fail?.({ turn: context, error, phase: "unhandled" }));
|
|
207
|
+
return refusal(t, "INTERNAL", t("internalError"), where);
|
|
208
|
+
}
|
|
209
|
+
const featureKey = agent.featureKey === undefined
|
|
210
|
+
? config.featureKey === undefined
|
|
211
|
+
? DEFAULT_FEATURE_KEY
|
|
212
|
+
: config.featureKey
|
|
213
|
+
: agent.featureKey;
|
|
214
|
+
if (featureKey !== null) {
|
|
215
|
+
const allowed = await hasFeature(actor.workspaceId, featureKey);
|
|
216
|
+
if (!allowed) {
|
|
217
|
+
return refusal(t, "FEATURE_GATED", t("featureGated"), where);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const modelId = agent.modelId ?? config.model.defaultId;
|
|
221
|
+
const capability = agent.capability ?? config.capability ?? DEFAULT_CAPABILITY;
|
|
222
|
+
const maxSteps = agent.maxSteps ?? config.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
223
|
+
// A title that resolves later is applied after the stream — a
|
|
224
|
+
// model-written title must not delay the first token.
|
|
225
|
+
let pendingTitle = null;
|
|
226
|
+
if (!loaded.row) {
|
|
227
|
+
const opening = body.messages.find((message) => message.role === "user");
|
|
228
|
+
const titled = deriveTitle(opening ? extractText(opening.parts) : "", context);
|
|
229
|
+
let title = null;
|
|
230
|
+
if (titled instanceof Promise)
|
|
231
|
+
pendingTitle = titled;
|
|
232
|
+
else
|
|
233
|
+
title = titled;
|
|
234
|
+
try {
|
|
235
|
+
context.conversation = await createConversation(actor, {
|
|
236
|
+
id: body.id,
|
|
237
|
+
agentId: agent.id,
|
|
238
|
+
modelId,
|
|
239
|
+
title,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
log.error("Failed to create conversation", {
|
|
244
|
+
conversationId: body.id,
|
|
245
|
+
error: errorMessage(error),
|
|
246
|
+
});
|
|
247
|
+
return refusal(t, "INTERNAL", t("internalError"), where);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else if (body.trigger === "regenerate-message") {
|
|
251
|
+
// The client dropped the reply it is regenerating; drop what the
|
|
252
|
+
// row holds after the user message that gets a second answer.
|
|
253
|
+
const user = lastUserMessage(body.messages);
|
|
254
|
+
if (user) {
|
|
255
|
+
try {
|
|
256
|
+
await deleteTrailingMessages(actor, { id: user.id });
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
// The user message may never have been persisted (a failed
|
|
260
|
+
// first attempt). Regenerating still makes sense.
|
|
261
|
+
log.warn("Could not trim messages before regenerate", {
|
|
262
|
+
conversationId: body.id,
|
|
263
|
+
error: errorMessage(error),
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const turn = {
|
|
269
|
+
...context,
|
|
270
|
+
agent,
|
|
271
|
+
history: async () => toUIMessages(await getMessages(actor, body.id)),
|
|
272
|
+
};
|
|
273
|
+
let prepared;
|
|
274
|
+
try {
|
|
275
|
+
prepared = await prepare(turn, body.messages);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
log.error("prepareMessages failed", {
|
|
279
|
+
conversationId: body.id,
|
|
280
|
+
error: errorMessage(error),
|
|
281
|
+
});
|
|
282
|
+
await emit(() => events.fail?.({ turn, error, phase: "unhandled" }));
|
|
283
|
+
return refusal(t, "INTERNAL", t("internalError"), where);
|
|
284
|
+
}
|
|
285
|
+
const metadata = {
|
|
286
|
+
conversationId: body.id,
|
|
287
|
+
agentId: agent.id,
|
|
288
|
+
...(config.metadata ? config.metadata(turn) : {}),
|
|
289
|
+
};
|
|
290
|
+
// Entitlement, decided against the model that is about to run.
|
|
291
|
+
const run = await config.executions.begin({
|
|
292
|
+
workspaceId: actor.workspaceId,
|
|
293
|
+
userId: actor.userId,
|
|
294
|
+
capability,
|
|
295
|
+
model: modelId,
|
|
296
|
+
metadata,
|
|
297
|
+
});
|
|
298
|
+
if (!run.allowed) {
|
|
299
|
+
// 402 for anything the workspace can fix by paying; 503 when this
|
|
300
|
+
// deployment has no billing configured at all.
|
|
301
|
+
const notConfigured = run.code === "billing_not_configured";
|
|
302
|
+
return refusal(t, notConfigured ? "BILLING_NOT_CONFIGURED" : "QUOTA_EXCEEDED", run.reason ??
|
|
303
|
+
t(notConfigured ? "billingNotConfigured" : "quotaExceeded"), where, { ...(run.code ? { reasonCode: run.code } : {}) }, limitHeaders);
|
|
304
|
+
}
|
|
305
|
+
const model = await config.model.resolve(modelId, context);
|
|
306
|
+
const modelMessages = await convertToModelMessages(prepared.messages);
|
|
307
|
+
const tools = agent.tools && Object.keys(agent.tools).length > 0
|
|
308
|
+
? agent.tools
|
|
309
|
+
: undefined;
|
|
310
|
+
const stopWhen = [
|
|
311
|
+
stepCountIs(maxSteps),
|
|
312
|
+
...(Array.isArray(agent.stopWhen)
|
|
313
|
+
? agent.stopWhen
|
|
314
|
+
: agent.stopWhen
|
|
315
|
+
? [agent.stopWhen]
|
|
316
|
+
: []),
|
|
317
|
+
];
|
|
318
|
+
await emit(() => events.start?.({
|
|
319
|
+
turn,
|
|
320
|
+
executionId: run.id,
|
|
321
|
+
requestId: run.requestId,
|
|
322
|
+
modelId,
|
|
323
|
+
}));
|
|
324
|
+
// Whole-run usage, captured from streamText's own `onFinish` (which
|
|
325
|
+
// fires when the model run ends, before the UI stream drains) and
|
|
326
|
+
// read back in the outer `onFinish`. `totalUsage`, not `usage`:
|
|
327
|
+
// with tools bound, `usage` is the LAST step only and a five-step
|
|
328
|
+
// turn would be billed for one.
|
|
329
|
+
let captured;
|
|
330
|
+
const settle = async (usage, detail) => {
|
|
331
|
+
const normalized = config.normalizeUsage
|
|
332
|
+
? config.normalizeUsage(usage)
|
|
333
|
+
: usage;
|
|
334
|
+
// Settling can throw (unrecorded usage must not be reported as
|
|
335
|
+
// success). Log and continue so a settlement failure does not
|
|
336
|
+
// also cost the user their message history.
|
|
337
|
+
try {
|
|
338
|
+
await run.complete({
|
|
339
|
+
usage: normalized,
|
|
340
|
+
model: modelId,
|
|
341
|
+
metadata: { ...metadata, aborted: detail.aborted },
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
log.error("Execution settlement failed", {
|
|
346
|
+
conversationId: body.id,
|
|
347
|
+
executionId: run.id,
|
|
348
|
+
requestId: run.requestId,
|
|
349
|
+
error: errorMessage(error),
|
|
350
|
+
});
|
|
351
|
+
await emit(() => events.fail?.({ turn, error, phase: "settlement" }));
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
await emit(() => events.complete?.({
|
|
355
|
+
turn,
|
|
356
|
+
executionId: run.id,
|
|
357
|
+
modelId,
|
|
358
|
+
usage: normalized,
|
|
359
|
+
aborted: detail.aborted,
|
|
360
|
+
finishReason: captured?.finishReason,
|
|
361
|
+
rawFinishReason: captured?.rawFinishReason,
|
|
362
|
+
providerMetadata: captured?.providerMetadata,
|
|
363
|
+
warnings: captured?.warnings,
|
|
364
|
+
}));
|
|
365
|
+
};
|
|
366
|
+
const applyTitle = async () => {
|
|
367
|
+
if (!pendingTitle)
|
|
368
|
+
return null;
|
|
369
|
+
try {
|
|
370
|
+
const title = await pendingTitle;
|
|
371
|
+
if (!title)
|
|
372
|
+
return null;
|
|
373
|
+
// Only while still untitled: two first turns racing must not
|
|
374
|
+
// overwrite each other's title.
|
|
375
|
+
const current = await getConversation(actor, body.id);
|
|
376
|
+
if (current.title !== null)
|
|
377
|
+
return current.title;
|
|
378
|
+
await renameConversation(actor, body.id, title);
|
|
379
|
+
return title;
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
log.warn("Deferred title failed", {
|
|
383
|
+
conversationId: body.id,
|
|
384
|
+
error: errorMessage(error),
|
|
385
|
+
});
|
|
386
|
+
await emit(() => events.fail?.({ turn, error, phase: "title" }));
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
const stream = createUIMessageStream({
|
|
391
|
+
// Without this, `onFinish` sees only the reply and a tool-approval
|
|
392
|
+
// continuation loses its message id. With it, the finished
|
|
393
|
+
// transcript is the prepared messages plus the reply.
|
|
394
|
+
originalMessages: prepared.messages,
|
|
395
|
+
execute: async ({ writer }) => {
|
|
396
|
+
const result = streamText({
|
|
397
|
+
model,
|
|
398
|
+
system: prepared.system ?? agent.systemPrompt,
|
|
399
|
+
messages: modelMessages,
|
|
400
|
+
...(tools
|
|
401
|
+
? {
|
|
402
|
+
tools,
|
|
403
|
+
stopWhen,
|
|
404
|
+
...(agent.activeTools
|
|
405
|
+
? {
|
|
406
|
+
experimental_activeTools: agent.activeTools,
|
|
407
|
+
}
|
|
408
|
+
: {}),
|
|
409
|
+
}
|
|
410
|
+
: {}),
|
|
411
|
+
// Stop the model when the client goes away. Without this the
|
|
412
|
+
// run continues server-side to completion — billed in full
|
|
413
|
+
// for a reply nobody receives — and `onAbort` never fires.
|
|
414
|
+
abortSignal: request.signal,
|
|
415
|
+
onFinish: ({ totalUsage, finishReason, rawFinishReason, providerMetadata, warnings, }) => {
|
|
416
|
+
captured = {
|
|
417
|
+
usage: pickUsage(totalUsage),
|
|
418
|
+
finishReason,
|
|
419
|
+
rawFinishReason,
|
|
420
|
+
providerMetadata,
|
|
421
|
+
warnings: warnings,
|
|
422
|
+
};
|
|
423
|
+
},
|
|
424
|
+
onAbort: async ({ steps }) => {
|
|
425
|
+
await settle(sumStepUsage(steps), { aborted: true });
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
writer.merge(result.toUIMessageStream({ sendReasoning: config.reasoning ?? false }));
|
|
429
|
+
const title = await applyTitle();
|
|
430
|
+
if (title) {
|
|
431
|
+
writer.write({
|
|
432
|
+
type: "data-chat-title",
|
|
433
|
+
data: title,
|
|
434
|
+
transient: true,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
generateId,
|
|
439
|
+
onFinish: async ({ responseMessage, isContinuation }) => {
|
|
440
|
+
if (captured) {
|
|
441
|
+
await settle(captured.usage, { aborted: false });
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
// The stream closed without the model run reporting usage and
|
|
445
|
+
// without an abort or error having settled it. Failing
|
|
446
|
+
// releases the hold and leaves a `failed` row an operator can
|
|
447
|
+
// see — settling zero tokens as `succeeded` would hide it.
|
|
448
|
+
void run.fail({ error: new Error("stream ended without usage") });
|
|
449
|
+
}
|
|
450
|
+
if (config.persist === false)
|
|
451
|
+
return;
|
|
452
|
+
const userMessage = lastUserMessage(body.messages);
|
|
453
|
+
try {
|
|
454
|
+
if (config.persist) {
|
|
455
|
+
await config.persist(turn, {
|
|
456
|
+
userMessage,
|
|
457
|
+
responseMessage,
|
|
458
|
+
isContinuation,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
await upsertMessages(body.id, [
|
|
463
|
+
...(userMessage && !isContinuation ? [userMessage] : []),
|
|
464
|
+
responseMessage,
|
|
465
|
+
]);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
log.error("Message persistence failed", {
|
|
470
|
+
conversationId: body.id,
|
|
471
|
+
error: errorMessage(error),
|
|
472
|
+
});
|
|
473
|
+
await emit(() => events.fail?.({ turn, error, phase: "persistence" }));
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
onError: (error) => {
|
|
477
|
+
// fail() is a no-op if complete() already won, so a late error
|
|
478
|
+
// after a settled stream cannot corrupt the row. The AI SDK
|
|
479
|
+
// does not await this callback, so nothing here is.
|
|
480
|
+
void run.fail({ error });
|
|
481
|
+
void emit(() => events.fail?.({ turn, error, phase: "stream" }));
|
|
482
|
+
return t("streamError");
|
|
483
|
+
},
|
|
484
|
+
});
|
|
485
|
+
return createUIMessageStreamResponse({ stream, headers: limitHeaders });
|
|
486
|
+
}
|
|
487
|
+
// -------------------------------------------------------------------------
|
|
488
|
+
// DELETE — remove a conversation
|
|
489
|
+
// -------------------------------------------------------------------------
|
|
490
|
+
async function DELETE(request) {
|
|
491
|
+
await config.onRequest?.();
|
|
492
|
+
const t = await messagesFor(request);
|
|
493
|
+
let id = new URL(request.url).searchParams.get("id");
|
|
494
|
+
if (!id) {
|
|
495
|
+
try {
|
|
496
|
+
const json = (await request.json());
|
|
497
|
+
if (typeof json.id === "string")
|
|
498
|
+
id = json.id;
|
|
499
|
+
}
|
|
500
|
+
catch {
|
|
501
|
+
// No body: the query string was the only place to look.
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
if (!id) {
|
|
505
|
+
return refusal(t, "BAD_REQUEST", t("invalidBody"), {
|
|
506
|
+
actor: null,
|
|
507
|
+
conversationId: null,
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
let actor;
|
|
511
|
+
try {
|
|
512
|
+
actor = await authenticate(request);
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
return refusal(t, "UNAUTHORIZED", t("unauthorized"), {
|
|
516
|
+
actor: null,
|
|
517
|
+
conversationId: id,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
try {
|
|
521
|
+
await deleteConversation(actor, id);
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
if (isConversationServiceError(error) &&
|
|
525
|
+
(error.code === "not_found" || error.code === "forbidden")) {
|
|
526
|
+
return refusal(t, "NOT_FOUND", t("notFound"), {
|
|
527
|
+
actor,
|
|
528
|
+
conversationId: id,
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
log.error("Failed to delete conversation", {
|
|
532
|
+
conversationId: id,
|
|
533
|
+
error: errorMessage(error),
|
|
534
|
+
});
|
|
535
|
+
return refusal(t, "INTERNAL", t("internalError"), {
|
|
536
|
+
actor,
|
|
537
|
+
conversationId: id,
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
return Response.json({ success: true });
|
|
541
|
+
}
|
|
542
|
+
return { POST, DELETE };
|
|
543
|
+
}
|
|
544
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intelligo-dev/chat — the AI-SDK-native chat transport.
|
|
3
|
+
*
|
|
4
|
+
* A Route Handler as a function: `createChatHandler(config)` returns
|
|
5
|
+
* `{ POST, DELETE }` over Web `Request`/`Response`, and runs every turn
|
|
6
|
+
* through auth, rate limit, feature gate, conversation persistence and
|
|
7
|
+
* the execution boundary. The UI is not here — it installs from the
|
|
8
|
+
* registry as consumer-owned source (ADR-0002, ADR-0010) and imports
|
|
9
|
+
* only `@intelligo-dev/chat/client`.
|
|
10
|
+
*
|
|
11
|
+
* Not an agent abstraction (ADR-0003): the config takes AI SDK tools,
|
|
12
|
+
* an AI SDK model and AI SDK stop conditions, natively. A Mastra agent
|
|
13
|
+
* records executions through `@intelligo-dev/mastra` instead.
|
|
14
|
+
*/
|
|
15
|
+
export { createChatHandler } from "./handler.js";
|
|
16
|
+
export { truncateTitle } from "./title.js";
|
|
17
|
+
export type { ChatHandler } from "./handler.js";
|
|
18
|
+
export type { ChatActor, ChatAttachmentPolicy, ChatMessageKey, ChatMessageParams, ChatMessages, ChatServerConfig, ChatTurn, ChatTurnContext, ChatTurnEvents, PreparedTurn, RateLimitDecision, ResolvedAgent, } from "./config.js";
|
|
19
|
+
export { CHAT_ERROR_STATUS, DEFAULT_CHAT_MESSAGES } from "./errors.js";
|
|
20
|
+
export { parseChatBody } from "./body.js";
|
|
21
|
+
export type { ChatBody, ParsedChatBody } from "./body.js";
|
|
22
|
+
export { getChatQuotaState } from "./quota.js";
|
|
23
|
+
export { lastUserMessage, toUIMessages } from "./messages.js";
|
|
24
|
+
export { pickUsage, sumStepUsage } from "./usage.js";
|
|
25
|
+
export type { TokenUsage } from "./usage.js";
|
|
26
|
+
export { applyConversationWindow, estimateConversationTokens, estimateTokenCount, extractText, } from "./windowing.js";
|
|
27
|
+
export type { ConversationWindow, ConversationWindowOptions, } from "./windowing.js";
|
|
28
|
+
export { CHAT_ERROR_CODES, parseChatError } from "./client.js";
|
|
29
|
+
export type { ChatErrorBody, ChatErrorCode, ChatQuotaState } from "./client.js";
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,YAAY,EACV,SAAS,EACT,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intelligo-dev/chat — the AI-SDK-native chat transport.
|
|
3
|
+
*
|
|
4
|
+
* A Route Handler as a function: `createChatHandler(config)` returns
|
|
5
|
+
* `{ POST, DELETE }` over Web `Request`/`Response`, and runs every turn
|
|
6
|
+
* through auth, rate limit, feature gate, conversation persistence and
|
|
7
|
+
* the execution boundary. The UI is not here — it installs from the
|
|
8
|
+
* registry as consumer-owned source (ADR-0002, ADR-0010) and imports
|
|
9
|
+
* only `@intelligo-dev/chat/client`.
|
|
10
|
+
*
|
|
11
|
+
* Not an agent abstraction (ADR-0003): the config takes AI SDK tools,
|
|
12
|
+
* an AI SDK model and AI SDK stop conditions, natively. A Mastra agent
|
|
13
|
+
* records executions through `@intelligo-dev/mastra` instead.
|
|
14
|
+
*/
|
|
15
|
+
export { createChatHandler } from "./handler.js";
|
|
16
|
+
export { truncateTitle } from "./title.js";
|
|
17
|
+
export { CHAT_ERROR_STATUS, DEFAULT_CHAT_MESSAGES } from "./errors.js";
|
|
18
|
+
export { parseChatBody } from "./body.js";
|
|
19
|
+
export { getChatQuotaState } from "./quota.js";
|
|
20
|
+
export { lastUserMessage, toUIMessages } from "./messages.js";
|
|
21
|
+
export { pickUsage, sumStepUsage } from "./usage.js";
|
|
22
|
+
export { applyConversationWindow, estimateConversationTokens, estimateTokenCount, extractText, } from "./windowing.js";
|
|
23
|
+
export { CHAT_ERROR_CODES, parseChatError } from "./client.js";
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAkBxC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAElD,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,WAAW,GACZ,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Between the rows core stores and the transcript the AI SDK renders.
|
|
3
|
+
*/
|
|
4
|
+
import type { UIMessage } from "ai";
|
|
5
|
+
type MessageRow = {
|
|
6
|
+
id: string;
|
|
7
|
+
role: string;
|
|
8
|
+
parts: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Stored `messages.parts` is a JSON string (ADR-0009's schema note); a
|
|
12
|
+
* row that fails to parse is dropped rather than failing the whole
|
|
13
|
+
* conversation. Tool-role rows are not part of the UI transcript.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toUIMessages(rows: ReadonlyArray<MessageRow>): UIMessage[];
|
|
16
|
+
/** The last message when it is the user's turn, else null. */
|
|
17
|
+
export declare function lastUserMessage(messages: ReadonlyArray<UIMessage>): UIMessage | null;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,KAAK,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAM9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,SAAS,EAAE,CAazE;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,GACjC,SAAS,GAAG,IAAI,CAGlB"}
|