@happyvertical/smrt-chat 0.53.4 → 0.53.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/AGENTS.md +10 -9
- package/README.md +11 -2
- package/dist/chunks/{chat-stream-DigP1_dw.js → chat-stream-DJQO6uHe.js} +2 -2
- package/dist/chunks/{chat-stream-DigP1_dw.js.map → chat-stream-DJQO6uHe.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/smrt-knowledge.json +5 -5
- package/dist/sveltekit.d.ts +84 -11
- package/dist/sveltekit.d.ts.map +1 -1
- package/dist/sveltekit.js +265 -57
- package/dist/sveltekit.js.map +1 -1
- package/package.json +16 -16
package/dist/sveltekit.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { i as clientRequestMessageId, n as ChatService, t as ChatClientRequestConflictError } from "./chunks/ChatService-Dl5tsK_F.js";
|
|
2
|
-
import { D as runAssistantTurn, E as createSessionContinuationStore, j as MAX_CLIENT_TOOL_RESULT_CHARS, w as createAssistantTurnResponse, z as sanitizeClientToolDeclarations } from "./chunks/chat-stream-
|
|
2
|
+
import { D as runAssistantTurn, E as createSessionContinuationStore, P as buildManifestToolCatalog, j as MAX_CLIENT_TOOL_RESULT_CHARS, v as ASSISTANT_TURN_GENERIC_ERROR, w as createAssistantTurnResponse, z as sanitizeClientToolDeclarations } from "./chunks/chat-stream-DJQO6uHe.js";
|
|
3
|
+
import { getCurrentSessionPermissionContext, getRequestScopedDatabase } from "@happyvertical/smrt-users";
|
|
4
|
+
import { getConfig, loadConfig, resolveConfiguredAIProvider, toAIClientOptions } from "@happyvertical/smrt-config";
|
|
3
5
|
//#region src/sveltekit.ts
|
|
4
6
|
var AssistantRouteError = class extends Error {
|
|
5
7
|
constructor(status, code, message) {
|
|
@@ -60,6 +62,29 @@ async function resolveValue(value, context) {
|
|
|
60
62
|
if (typeof value === "function") return value(context);
|
|
61
63
|
return value;
|
|
62
64
|
}
|
|
65
|
+
var configLoad;
|
|
66
|
+
async function configuredAssistantAI() {
|
|
67
|
+
if (getConfig() === null) {
|
|
68
|
+
configLoad ??= loadConfig().catch((error) => {
|
|
69
|
+
configLoad = void 0;
|
|
70
|
+
throw error;
|
|
71
|
+
});
|
|
72
|
+
await configLoad;
|
|
73
|
+
}
|
|
74
|
+
const options = toAIClientOptions(resolveConfiguredAIProvider());
|
|
75
|
+
const { getAI } = await import("@happyvertical/ai");
|
|
76
|
+
return getAI(options);
|
|
77
|
+
}
|
|
78
|
+
function unprovidedToolNames(requested, offered, registeredOnly) {
|
|
79
|
+
const provided = new Set(offered.map((tool) => tool.slug));
|
|
80
|
+
const missing = requested.filter((name) => !provided.has(name));
|
|
81
|
+
if (!registeredOnly || missing.length === 0) return missing;
|
|
82
|
+
const collections = new Set(buildManifestToolCatalog({ all: true }).map((tool) => tool.collection));
|
|
83
|
+
return missing.filter((name) => {
|
|
84
|
+
const dot = name.lastIndexOf(".");
|
|
85
|
+
return dot > 0 && collections.has(name.slice(0, dot));
|
|
86
|
+
});
|
|
87
|
+
}
|
|
63
88
|
async function readBounded(request, max) {
|
|
64
89
|
const declared = Number(request.headers.get("content-length"));
|
|
65
90
|
const tooLarge = () => new AssistantRouteError(413, "payload_too_large", "The request is too large.");
|
|
@@ -209,8 +234,17 @@ function matchRoute(segments) {
|
|
|
209
234
|
};
|
|
210
235
|
return null;
|
|
211
236
|
}
|
|
212
|
-
function mountAssistantRoutes(options) {
|
|
213
|
-
if (
|
|
237
|
+
function mountAssistantRoutes(options = {}) {
|
|
238
|
+
if ("ai" in options && options.ai == null) throw new Error("mountAssistantRoutes: `ai` was passed but is empty. Pass an AI client or a factory, or omit `ai` to use the smrt.config `ai` block.");
|
|
239
|
+
const aiSource = options.ai ?? configuredAssistantAI;
|
|
240
|
+
if (options.tools === void 0 && !options.actions && Array.isArray(options.allowedTools) && typeof options.extraTools !== "function") {
|
|
241
|
+
const extra = new Set((options.extraTools ?? []).map((tool) => tool.slug));
|
|
242
|
+
const requested = options.allowedTools.filter((name) => typeof name === "string" && name.length > 0 && !extra.has(name));
|
|
243
|
+
if (requested.length > 0) {
|
|
244
|
+
const unknown = unprovidedToolNames(requested, buildManifestToolCatalog({ allowedTools: requested }), true);
|
|
245
|
+
if (unknown.length > 0) throw new Error(`mountAssistantRoutes: allowedTools names ${unknown.join(", ")}, which no manifest operation or extraTools entry provides.`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
214
248
|
const agentId = options.agentId ?? "smrt-assistant";
|
|
215
249
|
const paramName = options.paramName ?? "path";
|
|
216
250
|
const maxBody = options.maxBodyBytes ?? 1048576;
|
|
@@ -228,6 +262,7 @@ function mountAssistantRoutes(options) {
|
|
|
228
262
|
} catch {}
|
|
229
263
|
};
|
|
230
264
|
const abandonedTurnMs = options.abandonedTurnMs ?? 9e5;
|
|
265
|
+
const turnStartTimeoutMs = options.turnStartTimeoutMs ?? 6e4;
|
|
231
266
|
const segmentsOf = (event) => {
|
|
232
267
|
const param = event.params?.[paramName];
|
|
233
268
|
let path = typeof param === "string" ? param : void 0;
|
|
@@ -239,10 +274,22 @@ function mountAssistantRoutes(options) {
|
|
|
239
274
|
if (path === void 0) return null;
|
|
240
275
|
return path.split("/").filter((segment) => segment.length > 0);
|
|
241
276
|
};
|
|
242
|
-
const
|
|
277
|
+
const runtime = options.runtime;
|
|
278
|
+
const dbOption = options.db !== void 0 || !runtime ? options.db : () => runtime.databaseConfig();
|
|
279
|
+
const requestDbs = /* @__PURE__ */ new WeakMap();
|
|
280
|
+
const dbFor = (context) => {
|
|
281
|
+
let db = requestDbs.get(context);
|
|
282
|
+
if (!db) {
|
|
283
|
+
db = resolveValue(dbOption, context);
|
|
284
|
+
requestDbs.set(context, db);
|
|
285
|
+
}
|
|
286
|
+
return db;
|
|
287
|
+
};
|
|
288
|
+
const chatFor = async (context) => {
|
|
289
|
+
const db = await dbFor(context);
|
|
243
290
|
const chat = await ChatService.create({
|
|
244
|
-
tenantId: principal.tenantId,
|
|
245
|
-
...
|
|
291
|
+
tenantId: context.principal.tenantId,
|
|
292
|
+
...db ? { db } : {}
|
|
246
293
|
});
|
|
247
294
|
await chat.initialize();
|
|
248
295
|
return chat;
|
|
@@ -276,10 +323,10 @@ function mountAssistantRoutes(options) {
|
|
|
276
323
|
};
|
|
277
324
|
const resolveAI = async (context, model) => {
|
|
278
325
|
try {
|
|
279
|
-
const ai = typeof
|
|
326
|
+
const ai = typeof aiSource === "function" ? await aiSource({
|
|
280
327
|
...context,
|
|
281
328
|
...model ? { model } : {}
|
|
282
|
-
}) :
|
|
329
|
+
}) : aiSource;
|
|
283
330
|
if (!ai || typeof ai.chat !== "function") throw new Error("The AI factory returned no client.");
|
|
284
331
|
return ai;
|
|
285
332
|
} catch (error) {
|
|
@@ -287,6 +334,24 @@ function mountAssistantRoutes(options) {
|
|
|
287
334
|
throw new AssistantRouteError(503, "assistant_unavailable", "The assistant is unavailable right now. Please try again later.");
|
|
288
335
|
}
|
|
289
336
|
};
|
|
337
|
+
const manifestToolsFor = async (context, allowedTools, extraTools, db) => {
|
|
338
|
+
if (options.tools !== void 0) return await resolveValue(options.tools, context) ?? [];
|
|
339
|
+
const extra = new Set(extraTools.map((tool) => tool.slug));
|
|
340
|
+
const requested = allowedTools.filter((name) => !extra.has(name));
|
|
341
|
+
if (requested.length === 0) return [];
|
|
342
|
+
const tools = buildManifestToolCatalog({
|
|
343
|
+
...db ? { db } : {},
|
|
344
|
+
allowedTools: requested
|
|
345
|
+
});
|
|
346
|
+
if (!options.actions) {
|
|
347
|
+
const unknown = unprovidedToolNames(requested, tools, false);
|
|
348
|
+
if (unknown.length > 0) {
|
|
349
|
+
safeLog(/* @__PURE__ */ new Error(`mountAssistantRoutes: allowedTools names ${unknown.join(", ")}, which no manifest operation or extraTools entry provides.`));
|
|
350
|
+
throw new AssistantRouteError(503, "assistant_unavailable", "The assistant is unavailable right now. Please try again later.");
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return tools;
|
|
354
|
+
};
|
|
290
355
|
const continuationStoreFor = (context, chat, session) => {
|
|
291
356
|
if (options.continuations) return options.continuations({
|
|
292
357
|
...context,
|
|
@@ -301,18 +366,33 @@ function mountAssistantRoutes(options) {
|
|
|
301
366
|
return current && current.participantProfileId === principal.profileId && current.isActive() ? current : null;
|
|
302
367
|
});
|
|
303
368
|
};
|
|
304
|
-
const
|
|
305
|
-
const { principal } = context;
|
|
369
|
+
const prepareTurn = async (context, body) => {
|
|
306
370
|
const model = resolveModel(body.model);
|
|
307
371
|
const allowedTools = await allowedToolsFor(context);
|
|
308
372
|
const clientTools = sanitizeClientToolDeclarations(body.clientTools, options.clientToolAllowList ?? []);
|
|
309
373
|
const ai = await resolveAI(context, model);
|
|
310
|
-
const
|
|
374
|
+
const abort = new AbortController();
|
|
375
|
+
const requestSignal = context.event.request.signal;
|
|
376
|
+
if (requestSignal.aborted) abort.abort();
|
|
377
|
+
else requestSignal.addEventListener("abort", () => abort.abort(), { once: true });
|
|
378
|
+
return {
|
|
379
|
+
abort,
|
|
380
|
+
ai,
|
|
381
|
+
model,
|
|
382
|
+
allowedTools,
|
|
383
|
+
clientTools
|
|
384
|
+
};
|
|
385
|
+
};
|
|
386
|
+
const turnSetup = async (context, chat, session, thread, prepared, mirror = true) => {
|
|
387
|
+
const { principal } = context;
|
|
388
|
+
const { abort, ai, model, allowedTools, clientTools } = prepared;
|
|
389
|
+
const [extraTools, systemPrompt, db] = await Promise.all([
|
|
311
390
|
resolveValue(options.extraTools, context),
|
|
312
|
-
resolveValue(options.
|
|
313
|
-
|
|
391
|
+
resolveValue(options.systemPrompt, context),
|
|
392
|
+
dbFor(context)
|
|
314
393
|
]);
|
|
315
|
-
|
|
394
|
+
const tools = await manifestToolsFor(context, allowedTools, extraTools ?? [], db);
|
|
395
|
+
if (options.authorInvocation && mirror) {
|
|
316
396
|
const current = session.getAllowedTools();
|
|
317
397
|
if (current.length !== allowedTools.length || current.some((tool, index) => tool !== allowedTools[index])) await chat.updateAgentSessionConfig({
|
|
318
398
|
agentSessionId: String(session.id),
|
|
@@ -322,10 +402,6 @@ function mountAssistantRoutes(options) {
|
|
|
322
402
|
});
|
|
323
403
|
}
|
|
324
404
|
const continuations = continuationStoreFor(context, chat, session);
|
|
325
|
-
const abort = new AbortController();
|
|
326
|
-
const requestSignal = context.event.request.signal;
|
|
327
|
-
if (requestSignal.aborted) abort.abort();
|
|
328
|
-
else requestSignal.addEventListener("abort", () => abort.abort(), { once: true });
|
|
329
405
|
return {
|
|
330
406
|
abort,
|
|
331
407
|
ai,
|
|
@@ -340,10 +416,10 @@ function mountAssistantRoutes(options) {
|
|
|
340
416
|
tenantId: principal.tenantId,
|
|
341
417
|
allowedTools
|
|
342
418
|
},
|
|
343
|
-
...
|
|
419
|
+
...db ? { db } : {},
|
|
344
420
|
...systemPrompt ? { systemPrompt } : {},
|
|
345
421
|
extraTools: [...extraTools ?? []],
|
|
346
|
-
tools: [...tools
|
|
422
|
+
tools: [...tools],
|
|
347
423
|
clientTools,
|
|
348
424
|
continuations,
|
|
349
425
|
continuationKey: String(thread.id),
|
|
@@ -383,8 +459,103 @@ function mountAssistantRoutes(options) {
|
|
|
383
459
|
onError: safeLog,
|
|
384
460
|
onCancel: () => abort.abort()
|
|
385
461
|
});
|
|
462
|
+
const respondWithTurn = async (context, chat, session, thread, prepared, setup, first, start, durableSend) => {
|
|
463
|
+
const transaction = requestTransaction();
|
|
464
|
+
if (!transaction) return stream(detached(first, pump(start(chat, setup))).events, prepared.abort);
|
|
465
|
+
const isActive = transaction.isActive;
|
|
466
|
+
if (!runtime || typeof isActive !== "function") {
|
|
467
|
+
const turn = detached(first, pump(start(chat, setup)));
|
|
468
|
+
await turn.settled;
|
|
469
|
+
return stream(turn.events, prepared.abort);
|
|
470
|
+
}
|
|
471
|
+
const { principal } = context;
|
|
472
|
+
const bound = {
|
|
473
|
+
id: principal.userId,
|
|
474
|
+
tenantId: principal.tenantId,
|
|
475
|
+
scopes: Object.freeze([...principal.permissions ?? getCurrentSessionPermissionContext()?.permissions ?? []])
|
|
476
|
+
};
|
|
477
|
+
const settleFailed = async (messageId, onlyIfStored = false) => {
|
|
478
|
+
try {
|
|
479
|
+
await runtime.runAsPrincipal(bound, async () => {
|
|
480
|
+
const settleChat = await chatFor({
|
|
481
|
+
event: context.event,
|
|
482
|
+
principal
|
|
483
|
+
});
|
|
484
|
+
if (onlyIfStored) {
|
|
485
|
+
if (!(await settleChat.getThreadMessageReplies({
|
|
486
|
+
threadId: String(thread.id),
|
|
487
|
+
messageId,
|
|
488
|
+
actorProfileId: principal.profileId,
|
|
489
|
+
tenantId: principal.tenantId
|
|
490
|
+
}))?.message) return;
|
|
491
|
+
}
|
|
492
|
+
await settleOutcome(settleChat, principal, String(thread.id), messageId)("failed");
|
|
493
|
+
});
|
|
494
|
+
} catch (settleError) {
|
|
495
|
+
safeLog(settleError);
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
const settleLateSend = async (requestActive, messageId) => {
|
|
499
|
+
try {
|
|
500
|
+
if (await requestEnded(requestActive, abandonedTurnMs)) await settleFailed(messageId, true);
|
|
501
|
+
else safeLog(/* @__PURE__ */ new Error("mountAssistantRoutes: the request transaction never ended; its send was not settled."));
|
|
502
|
+
} catch (error) {
|
|
503
|
+
safeLog(error);
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
const ownLifetime = async (emit) => {
|
|
507
|
+
const held = [];
|
|
508
|
+
let sendConfirmed = false;
|
|
509
|
+
const requestActive = () => isActive.call(transaction);
|
|
510
|
+
try {
|
|
511
|
+
if (!await requestEnded(requestActive, turnStartTimeoutMs)) {
|
|
512
|
+
if (durableSend) settleLateSend(requestActive, durableSend);
|
|
513
|
+
throw new Error("mountAssistantRoutes: the request transaction did not end; the turn did not run.");
|
|
514
|
+
}
|
|
515
|
+
await runtime.runAsPrincipal(bound, async (granted) => {
|
|
516
|
+
const turnContext = {
|
|
517
|
+
event: context.event,
|
|
518
|
+
principal: {
|
|
519
|
+
...principal,
|
|
520
|
+
permissions: effectiveScopes(granted, bound.scopes)
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
const turnChat = await chatFor(turnContext);
|
|
524
|
+
if (durableSend) {
|
|
525
|
+
if (!(await turnChat.getThreadMessageReplies({
|
|
526
|
+
threadId: String(thread.id),
|
|
527
|
+
messageId: durableSend,
|
|
528
|
+
actorProfileId: principal.profileId,
|
|
529
|
+
tenantId: principal.tenantId
|
|
530
|
+
}))?.message) throw new Error("mountAssistantRoutes: the send was not stored; the turn did not run.");
|
|
531
|
+
sendConfirmed = true;
|
|
532
|
+
}
|
|
533
|
+
const turnSetupInLifetime = await turnSetup(turnContext, turnChat, session, thread, prepared, false);
|
|
534
|
+
for await (const event of start(turnChat, turnSetupInLifetime)) if (held.length > 0 || HELD_UNTIL_COMMIT.has(event.type)) held.push(event);
|
|
535
|
+
else emit(event);
|
|
536
|
+
});
|
|
537
|
+
for (const event of held) emit(event);
|
|
538
|
+
} catch (error) {
|
|
539
|
+
safeLog(error);
|
|
540
|
+
if (durableSend && sendConfirmed) await settleFailed(durableSend);
|
|
541
|
+
emit({
|
|
542
|
+
type: "error",
|
|
543
|
+
error: ASSISTANT_TURN_GENERIC_ERROR,
|
|
544
|
+
code: "internal_error"
|
|
545
|
+
});
|
|
546
|
+
emit({
|
|
547
|
+
type: "status",
|
|
548
|
+
status: {
|
|
549
|
+
state: "error",
|
|
550
|
+
label: ASSISTANT_TURN_GENERIC_ERROR
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
return stream(detached(first, ownLifetime).events, prepared.abort);
|
|
556
|
+
};
|
|
386
557
|
const listThreads = async (context) => {
|
|
387
|
-
const chat = await chatFor(context
|
|
558
|
+
const chat = await chatFor(context);
|
|
388
559
|
const session = await findSession(chat, context.principal);
|
|
389
560
|
if (!session?.chatRoomId) return json({ items: [] });
|
|
390
561
|
return json({ items: (await chat.listRoomThreads({
|
|
@@ -398,7 +569,7 @@ function mountAssistantRoutes(options) {
|
|
|
398
569
|
const title = typeof body.title === "string" ? body.title.trim() : "";
|
|
399
570
|
if (!title || title.length > MAX_TITLE_LENGTH) throw badRequest(`A title of 1 to ${MAX_TITLE_LENGTH} characters is required.`);
|
|
400
571
|
const { principal } = context;
|
|
401
|
-
const chat = await chatFor(
|
|
572
|
+
const chat = await chatFor(context);
|
|
402
573
|
const allowedTools = await allowedToolsFor(context);
|
|
403
574
|
const { session } = await chat.createAgentSession({
|
|
404
575
|
tenantId: principal.tenantId,
|
|
@@ -417,7 +588,7 @@ function mountAssistantRoutes(options) {
|
|
|
417
588
|
};
|
|
418
589
|
const loadMessages = async (context, threadId) => {
|
|
419
590
|
const { principal } = context;
|
|
420
|
-
const chat = await chatFor(
|
|
591
|
+
const chat = await chatFor(context);
|
|
421
592
|
const session = await findSession(chat, principal);
|
|
422
593
|
await requireOwnThread(chat, principal, session, threadId);
|
|
423
594
|
return json({ items: (await chat.getThreadMessages({
|
|
@@ -508,7 +679,7 @@ function mountAssistantRoutes(options) {
|
|
|
508
679
|
if (hasAttachments && !options.attachments) throw badRequest("This assistant does not accept attachments.", "attachments_unsupported");
|
|
509
680
|
resolveModel(body.model);
|
|
510
681
|
const { principal } = context;
|
|
511
|
-
const chat = await chatFor(
|
|
682
|
+
const chat = await chatFor(context);
|
|
512
683
|
const session = await findSession(chat, principal);
|
|
513
684
|
const thread = await requireOwnThread(chat, principal, session, threadId);
|
|
514
685
|
if (!session?.chatRoomId) throw notFound();
|
|
@@ -533,7 +704,8 @@ function mountAssistantRoutes(options) {
|
|
|
533
704
|
...record.url ? { url: record.url } : {}
|
|
534
705
|
}));
|
|
535
706
|
}
|
|
536
|
-
const
|
|
707
|
+
const prepared = await prepareTurn(context, body);
|
|
708
|
+
const setup = await turnSetup(context, chat, session, thread, prepared);
|
|
537
709
|
const recordFailure = settleOutcome(chat, principal, threadId, reservationId);
|
|
538
710
|
let userMessage;
|
|
539
711
|
try {
|
|
@@ -574,17 +746,17 @@ function mountAssistantRoutes(options) {
|
|
|
574
746
|
});
|
|
575
747
|
}
|
|
576
748
|
}
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
history: history.slice(-historyLimit),
|
|
580
|
-
userMessage: content,
|
|
581
|
-
originMessageId: userWire.id,
|
|
582
|
-
onState: recordTurnState(chat, principal, threadId)
|
|
583
|
-
});
|
|
584
|
-
return stream(detached({
|
|
749
|
+
const transcript = history.slice(-historyLimit);
|
|
750
|
+
return await respondWithTurn(context, chat, session, thread, prepared, setup, {
|
|
585
751
|
type: "message",
|
|
586
752
|
message: userWire
|
|
587
|
-
},
|
|
753
|
+
}, (turnChat, turnSetupFor) => runAssistantTurn({
|
|
754
|
+
...turnSetupFor.turn,
|
|
755
|
+
history: transcript,
|
|
756
|
+
userMessage: content,
|
|
757
|
+
originMessageId: userWire.id,
|
|
758
|
+
onState: recordTurnState(turnChat, principal, threadId)
|
|
759
|
+
}), userWire.id);
|
|
588
760
|
} catch (error) {
|
|
589
761
|
await recordFailure("failed");
|
|
590
762
|
throw error;
|
|
@@ -610,19 +782,20 @@ function mountAssistantRoutes(options) {
|
|
|
610
782
|
});
|
|
611
783
|
resolveModel(body.model);
|
|
612
784
|
const { principal } = context;
|
|
613
|
-
const chat = await chatFor(
|
|
785
|
+
const chat = await chatFor(context);
|
|
614
786
|
const session = await findSession(chat, principal);
|
|
615
787
|
const thread = await requireOwnThread(chat, principal, session, threadId);
|
|
616
788
|
if (!session) throw notFound();
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
789
|
+
const prepared = await prepareTurn(context, body);
|
|
790
|
+
const setup = await turnSetup(context, chat, session, thread, prepared);
|
|
791
|
+
return respondWithTurn(context, chat, session, thread, prepared, setup, null, (turnChat, turnSetupFor) => runAssistantTurn({
|
|
792
|
+
...turnSetupFor.turn,
|
|
620
793
|
resume: {
|
|
621
794
|
continuationId,
|
|
622
795
|
results
|
|
623
796
|
},
|
|
624
|
-
onState: recordTurnState(
|
|
625
|
-
}))
|
|
797
|
+
onState: recordTurnState(turnChat, principal, threadId)
|
|
798
|
+
}));
|
|
626
799
|
};
|
|
627
800
|
const uploadAttachment = async (context) => {
|
|
628
801
|
const storage = options.attachments;
|
|
@@ -658,8 +831,9 @@ function mountAssistantRoutes(options) {
|
|
|
658
831
|
if (!adapter) throw new Error("No data-surface action adapter resolved.");
|
|
659
832
|
const { principal } = context;
|
|
660
833
|
const allowedTools = await allowedToolsFor(context);
|
|
834
|
+
const db = await dbFor(context);
|
|
661
835
|
const actionContext = { principal: {
|
|
662
|
-
...
|
|
836
|
+
...db ? { db } : {},
|
|
663
837
|
principal: {
|
|
664
838
|
runAsUserId: principal.userId,
|
|
665
839
|
tenantId: principal.tenantId,
|
|
@@ -726,7 +900,38 @@ function mountAssistantRoutes(options) {
|
|
|
726
900
|
handle
|
|
727
901
|
};
|
|
728
902
|
}
|
|
729
|
-
|
|
903
|
+
var HELD_UNTIL_COMMIT = /* @__PURE__ */ new Set([
|
|
904
|
+
"client_tool_calls",
|
|
905
|
+
"done",
|
|
906
|
+
"error"
|
|
907
|
+
]);
|
|
908
|
+
var DEFAULT_ASSISTANT_TURN_START_TIMEOUT_MS = 6e4;
|
|
909
|
+
function requestTransaction() {
|
|
910
|
+
if (getCurrentSessionPermissionContext()?.postgresRls !== true) return null;
|
|
911
|
+
return getRequestScopedDatabase() ?? null;
|
|
912
|
+
}
|
|
913
|
+
function effectiveScopes(granted, cap) {
|
|
914
|
+
const scopes = granted?.scopes;
|
|
915
|
+
if (!Array.isArray(scopes) || !scopes.every((scope) => typeof scope === "string")) throw new Error("mountAssistantRoutes: runtime.runAsPrincipal bound no effective scopes.");
|
|
916
|
+
const allowed = cap ? new Set(cap) : void 0;
|
|
917
|
+
return scopes.filter((scope) => !allowed || allowed.has(scope));
|
|
918
|
+
}
|
|
919
|
+
async function requestEnded(isActive, timeoutMs) {
|
|
920
|
+
const deadline = Date.now() + timeoutMs;
|
|
921
|
+
let delay = 2;
|
|
922
|
+
while (isActive()) {
|
|
923
|
+
if (Date.now() >= deadline) return false;
|
|
924
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
925
|
+
delay = Math.min(delay * 2, 50);
|
|
926
|
+
}
|
|
927
|
+
return true;
|
|
928
|
+
}
|
|
929
|
+
function pump(events) {
|
|
930
|
+
return async (emit) => {
|
|
931
|
+
for await (const event of events) emit(event);
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
function detached(first, produce) {
|
|
730
935
|
const buffer = first ? [first] : [];
|
|
731
936
|
let finished = false;
|
|
732
937
|
let notify = null;
|
|
@@ -735,31 +940,34 @@ function detached(first, events) {
|
|
|
735
940
|
notify = null;
|
|
736
941
|
resume?.();
|
|
737
942
|
};
|
|
738
|
-
(async () => {
|
|
943
|
+
const settled = (async () => {
|
|
739
944
|
try {
|
|
740
|
-
|
|
945
|
+
await produce((event) => {
|
|
741
946
|
buffer.push(event);
|
|
742
947
|
wake();
|
|
743
|
-
}
|
|
948
|
+
});
|
|
744
949
|
} catch {} finally {
|
|
745
950
|
finished = true;
|
|
746
951
|
wake();
|
|
747
952
|
}
|
|
748
953
|
})();
|
|
749
|
-
return
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
954
|
+
return {
|
|
955
|
+
events: (async function* () {
|
|
956
|
+
for (;;) {
|
|
957
|
+
if (buffer.length > 0) {
|
|
958
|
+
yield buffer.shift();
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
if (finished) return;
|
|
962
|
+
await new Promise((resolve) => {
|
|
963
|
+
notify = resolve;
|
|
964
|
+
});
|
|
754
965
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
});
|
|
759
|
-
}
|
|
760
|
-
})();
|
|
966
|
+
})(),
|
|
967
|
+
settled
|
|
968
|
+
};
|
|
761
969
|
}
|
|
762
970
|
//#endregion
|
|
763
|
-
export { ASSISTANT_DOCK_SESSION_KEY, AssistantRouteError, DEFAULT_ASSISTANT_ABANDONED_TURN_MS, DEFAULT_ASSISTANT_AGENT_ID, DEFAULT_ASSISTANT_MAX_ATTACHMENT_BYTES, DEFAULT_ASSISTANT_MAX_BODY_BYTES, mountAssistantRoutes, resolveAssistantPrincipalFromLocals, toAssistantMessageWire, toAssistantThreadWire };
|
|
971
|
+
export { ASSISTANT_DOCK_SESSION_KEY, AssistantRouteError, DEFAULT_ASSISTANT_ABANDONED_TURN_MS, DEFAULT_ASSISTANT_AGENT_ID, DEFAULT_ASSISTANT_MAX_ATTACHMENT_BYTES, DEFAULT_ASSISTANT_MAX_BODY_BYTES, DEFAULT_ASSISTANT_TURN_START_TIMEOUT_MS, mountAssistantRoutes, resolveAssistantPrincipalFromLocals, toAssistantMessageWire, toAssistantThreadWire };
|
|
764
972
|
|
|
765
973
|
//# sourceMappingURL=sveltekit.js.map
|