@vibes.diy/api-svc 2.0.0-dev-cli-i → 2.0.0-dev-cli-l
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 +20 -5
- package/cf-serve.js +16 -3
- package/cf-serve.js.map +1 -1
- package/intern/get-model-defaults.js.map +1 -1
- package/intern/write-apps.js +2 -7
- package/intern/write-apps.js.map +1 -1
- package/package.json +21 -21
- package/public/get-chat-details.js +1 -2
- package/public/get-chat-details.js.map +1 -1
- package/public/list-models.d.ts +1 -1
- package/public/list-models.js +4 -1
- package/public/list-models.js.map +1 -1
- package/public/prompt-chat-section.d.ts +19 -7
- package/public/prompt-chat-section.js +381 -197
- package/public/prompt-chat-section.js.map +1 -1
- package/usage-report/inspect-db-report.js +3 -76
- package/usage-report/inspect-db-report.js.map +1 -1
- package/vibes-msg-evento.js +1 -2
- package/vibes-msg-evento.js.map +1 -1
- package/public/prompt-chat-add-fs.d.ts +0 -3
- package/public/prompt-chat-add-fs.js +0 -37
- package/public/prompt-chat-add-fs.js.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Result, Option, EventoResult, exception2Result, chunkyAsync, BuildURI, pathOps, URI, } from "@adviser/cement";
|
|
2
2
|
import { scopey } from "@adviser/scopey";
|
|
3
|
-
import { isReqCreationPromptChatSection, isReqPromptApplicationChatSection, parseArrayWarning, PromptAndBlockMsgs, reqPromptChatSection, } from "@vibes.diy/api-types";
|
|
3
|
+
import { isReqCreationPromptChatSection, isReqPromptApplicationChatSection, isReqPromptFSChatSection, isReqPromptFSUpdateChatSection, isReqPromptImageChatSection, isReqPromptLLMChatSection, parseArrayWarning, PromptAndBlockMsgs, reqPromptChatSection, isPromptReq, isReqPromptFSSetChatSection, parseArray, vibeFile, isVibeCodeBlock, } from "@vibes.diy/api-types";
|
|
4
4
|
import { ensureLogger } from "@fireproof/core-runtime";
|
|
5
5
|
import { type } from "arktype";
|
|
6
6
|
import { checkAuth } from "../check-auth.js";
|
|
7
7
|
import { unwrapMsgBase, wrapMsgBase } from "../unwrap-msg-base.js";
|
|
8
|
-
import { and, eq } from "drizzle-orm/sql/expressions";
|
|
9
|
-
import { createStatsCollector, createLineStream, createDataStream, createSseStream, createDeltaStream, createSectionsStream, isBlockEnd, isCodeBegin, isCodeEnd, isCodeLine,
|
|
8
|
+
import { and, desc, eq } from "drizzle-orm/sql/expressions";
|
|
9
|
+
import { createStatsCollector, createLineStream, createDataStream, createSseStream, createDeltaStream, createSectionsStream, isBlockEnd, isCodeBegin, isCodeEnd, isCodeLine, FileSystemRef, isBlockStreamMsg, } from "@vibes.diy/call-ai-v2";
|
|
10
10
|
import { makeBaseSystemPrompt, resolveEffectiveModel } from "@vibes.diy/prompts";
|
|
11
11
|
import { ensureAppSlugItem } from "./ensure-app-slug-item.js";
|
|
12
12
|
import { getModelDefaults } from "../intern/get-model-defaults.js";
|
|
@@ -232,6 +232,340 @@ async function injectSystemPrompt(vctx, chatId, model) {
|
|
|
232
232
|
],
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
|
+
async function getResChatFromMode(vctx, req, orig) {
|
|
236
|
+
const iResChat = await vctx.sql.db
|
|
237
|
+
.select()
|
|
238
|
+
.from(vctx.sql.tables.chatContexts)
|
|
239
|
+
.where(and(eq(vctx.sql.tables.chatContexts.userId, req._auth.verifiedAuth.claims.userId), eq(vctx.sql.tables.chatContexts.chatId, req.chatId)))
|
|
240
|
+
.limit(1)
|
|
241
|
+
.then((r) => r[0]);
|
|
242
|
+
if (!iResChat) {
|
|
243
|
+
if (isReqCreationPromptChatSection(orig)) {
|
|
244
|
+
return Result.Err(`Creation Chat ID ${req.chatId} not found`);
|
|
245
|
+
}
|
|
246
|
+
else if (isReqPromptApplicationChatSection(orig)) {
|
|
247
|
+
return Result.Err(`Application Chat ID ${req.chatId} not found`);
|
|
248
|
+
}
|
|
249
|
+
else if (isReqPromptImageChatSection(orig)) {
|
|
250
|
+
return Result.Err(`Image Chat ID ${req.chatId} not found`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const resChat = { ...iResChat, mode: orig.mode };
|
|
254
|
+
return Result.Ok(resChat);
|
|
255
|
+
}
|
|
256
|
+
async function handlerLlmRequest({ scope, ctx, vctx, blockSeq, req, resChat, promptId, }) {
|
|
257
|
+
await scope
|
|
258
|
+
.evalResult(async () => {
|
|
259
|
+
const r = await appendBlockEvent({
|
|
260
|
+
ctx,
|
|
261
|
+
vctx,
|
|
262
|
+
req,
|
|
263
|
+
promptId,
|
|
264
|
+
blockSeq: blockSeq,
|
|
265
|
+
evt: {
|
|
266
|
+
type: "prompt.req",
|
|
267
|
+
streamId: promptId,
|
|
268
|
+
chatId: req.chatId,
|
|
269
|
+
seq: blockSeq,
|
|
270
|
+
request: req.prompt,
|
|
271
|
+
timestamp: new Date(),
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
blockSeq++;
|
|
275
|
+
return r;
|
|
276
|
+
})
|
|
277
|
+
.do();
|
|
278
|
+
const modelId = await scope
|
|
279
|
+
.evalResult(async () => {
|
|
280
|
+
const r = await getModelDefaults(vctx, { appSlug: resChat.appSlug, userSlug: resChat.userSlug });
|
|
281
|
+
if (r.isErr()) {
|
|
282
|
+
return Result.Err(r);
|
|
283
|
+
}
|
|
284
|
+
switch (req.mode) {
|
|
285
|
+
case "chat":
|
|
286
|
+
return Result.Ok(req.prompt.model ?? r.Ok().chat.model.id);
|
|
287
|
+
case "app":
|
|
288
|
+
return Result.Ok(req.prompt.model ?? r.Ok().app.model.id);
|
|
289
|
+
case "img":
|
|
290
|
+
return Result.Ok(req.prompt.model ?? r.Ok().img.model.id);
|
|
291
|
+
default:
|
|
292
|
+
return Result.Err(`Unknown prompt mode: ${req.mode}`);
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
.do();
|
|
296
|
+
const withSystemPrompt = await scope
|
|
297
|
+
.evalResult(async () => {
|
|
298
|
+
let withSystemPrompt = Result.Ok({
|
|
299
|
+
model: modelId,
|
|
300
|
+
messages: [],
|
|
301
|
+
});
|
|
302
|
+
if (req.mode === "chat") {
|
|
303
|
+
withSystemPrompt = await injectSystemPrompt(vctx, req.chatId, req.prompt.model ?? modelId);
|
|
304
|
+
}
|
|
305
|
+
else if (req.mode === "app") {
|
|
306
|
+
withSystemPrompt = Result.Ok({
|
|
307
|
+
model: req.prompt.model ?? modelId,
|
|
308
|
+
messages: req.prompt.messages,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return withSystemPrompt;
|
|
312
|
+
})
|
|
313
|
+
.do();
|
|
314
|
+
const llmReq = {
|
|
315
|
+
...{
|
|
316
|
+
...req.prompt,
|
|
317
|
+
messages: withSystemPrompt.messages,
|
|
318
|
+
},
|
|
319
|
+
...vctx.params.llm.enforced,
|
|
320
|
+
model: withSystemPrompt.model,
|
|
321
|
+
headers: vctx.params.llm.headers,
|
|
322
|
+
logprobs: true,
|
|
323
|
+
stream: true,
|
|
324
|
+
};
|
|
325
|
+
const res = await scope
|
|
326
|
+
.evalResult(async () => {
|
|
327
|
+
console.log(promptId, "Sending LLM request:", llmReq.model);
|
|
328
|
+
const res = await vctx.llmRequest(llmReq);
|
|
329
|
+
if (!res.ok) {
|
|
330
|
+
return Result.Err(`LLM request failed with status ${res.status} :${llmReq.model} : ${res.statusText}`);
|
|
331
|
+
}
|
|
332
|
+
if (!res.body) {
|
|
333
|
+
return Result.Err(`LLM request returned no body`);
|
|
334
|
+
}
|
|
335
|
+
return Result.Ok(res);
|
|
336
|
+
})
|
|
337
|
+
.do();
|
|
338
|
+
return { res, blockSeq };
|
|
339
|
+
}
|
|
340
|
+
async function handleEndMsg({ collectedMsgs, vctx, req, ctx, resChat, promptId, value, blockSeq, }) {
|
|
341
|
+
const r = await handlePromptContext({ vctx, req, promptId, resChat, value, blockSeq, collectedMsgs });
|
|
342
|
+
if (r.isErr()) {
|
|
343
|
+
return Result.Err(r);
|
|
344
|
+
}
|
|
345
|
+
blockSeq = r.Ok().blockSeq;
|
|
346
|
+
const rEvt = await appendBlockEvent({
|
|
347
|
+
ctx,
|
|
348
|
+
vctx,
|
|
349
|
+
req,
|
|
350
|
+
promptId,
|
|
351
|
+
blockSeq: blockSeq++,
|
|
352
|
+
evt: { ...value, fsRef: r.Ok().fsRef.toValue() },
|
|
353
|
+
emitMode: "emit-only",
|
|
354
|
+
});
|
|
355
|
+
for (const conn of vctx.connections) {
|
|
356
|
+
const chatCtx = conn.chatIds.get(req.chatId);
|
|
357
|
+
const promptIdCtx = chatCtx?.promptIds.get(promptId);
|
|
358
|
+
if (promptIdCtx && chatCtx) {
|
|
359
|
+
chatCtx.promptIds.delete(promptId);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (rEvt.isErr()) {
|
|
363
|
+
return Result.Err(rEvt);
|
|
364
|
+
}
|
|
365
|
+
return Result.Ok(blockSeq);
|
|
366
|
+
}
|
|
367
|
+
async function handleLlmResponse({ scope, vctx, req, ctx, res, resChat, promptId, blockSeq, }) {
|
|
368
|
+
await scope
|
|
369
|
+
.evalResult(async () => {
|
|
370
|
+
const pipeline = res
|
|
371
|
+
.body.pipeThrough(createStatsCollector(promptId, 1000))
|
|
372
|
+
.pipeThrough(createLineStream(promptId))
|
|
373
|
+
.pipeThrough(createDataStream(promptId))
|
|
374
|
+
.pipeThrough(createSseStream(promptId))
|
|
375
|
+
.pipeThrough(createDeltaStream(promptId, () => vctx.sthis.nextId(12).str))
|
|
376
|
+
.pipeThrough(createSectionsStream(promptId, () => vctx.sthis.nextId(12).str));
|
|
377
|
+
const reader = pipeline.getReader();
|
|
378
|
+
let collectedMsgs;
|
|
379
|
+
let chatCtx;
|
|
380
|
+
for (const conn of vctx.connections) {
|
|
381
|
+
const tChatCtx = conn.chatIds.get(req.chatId);
|
|
382
|
+
if (tChatCtx) {
|
|
383
|
+
chatCtx = tChatCtx;
|
|
384
|
+
const promptIdCtx = chatCtx.promptIds.get(promptId);
|
|
385
|
+
if (!promptIdCtx) {
|
|
386
|
+
collectedMsgs = [];
|
|
387
|
+
chatCtx.promptIds.set(promptId, {
|
|
388
|
+
blocks: collectedMsgs,
|
|
389
|
+
promptId,
|
|
390
|
+
type: "vibes.diy.section-event",
|
|
391
|
+
chatId: req.chatId,
|
|
392
|
+
blockSeq: 0,
|
|
393
|
+
timestamp: new Date(),
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
collectedMsgs = promptIdCtx.blocks;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (!collectedMsgs) {
|
|
402
|
+
return Result.Err(`Chat context not found for chatId: ${req.chatId}`);
|
|
403
|
+
}
|
|
404
|
+
while (true) {
|
|
405
|
+
const { done, value } = await reader.read();
|
|
406
|
+
if (done) {
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
if (!isBlockEnd(value)) {
|
|
410
|
+
if (!isBlockStreamMsg(value)) {
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
collectedMsgs.push(value);
|
|
414
|
+
const r = await appendBlockEvent({
|
|
415
|
+
ctx,
|
|
416
|
+
vctx,
|
|
417
|
+
req,
|
|
418
|
+
promptId,
|
|
419
|
+
blockSeq: blockSeq++,
|
|
420
|
+
evt: value,
|
|
421
|
+
emitMode: "emit-only",
|
|
422
|
+
});
|
|
423
|
+
if (r.isErr()) {
|
|
424
|
+
return Result.Err(r);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
collectedMsgs.push(value);
|
|
429
|
+
const x = await handleEndMsg({ collectedMsgs, vctx, req, ctx, resChat, promptId, value, blockSeq });
|
|
430
|
+
if (x.isErr()) {
|
|
431
|
+
return Result.Err(x);
|
|
432
|
+
}
|
|
433
|
+
collectedMsgs.splice(0, collectedMsgs.length);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return Result.Ok();
|
|
437
|
+
})
|
|
438
|
+
.do();
|
|
439
|
+
return blockSeq;
|
|
440
|
+
}
|
|
441
|
+
export async function handleFSPrompt({ scope, vctx, resChat, req, ctx, promptId, }) {
|
|
442
|
+
let fileSystem;
|
|
443
|
+
if (isReqPromptFSSetChatSection(req)) {
|
|
444
|
+
fileSystem = req.fsSet;
|
|
445
|
+
}
|
|
446
|
+
else if (isReqPromptFSUpdateChatSection(req)) {
|
|
447
|
+
const refFS = [];
|
|
448
|
+
if (!req.refFsId) {
|
|
449
|
+
const lastestPrompt = await vctx.sql.db
|
|
450
|
+
.select()
|
|
451
|
+
.from(vctx.sql.tables.promptContexts)
|
|
452
|
+
.innerJoin(vctx.sql.tables.apps, eq(vctx.sql.tables.apps.fsId, vctx.sql.tables.promptContexts.fsId))
|
|
453
|
+
.where(and(eq(vctx.sql.tables.promptContexts.chatId, req.chatId), eq(vctx.sql.tables.promptContexts.promptId, promptId)))
|
|
454
|
+
.orderBy(desc(vctx.sql.tables.promptContexts.created))
|
|
455
|
+
.limit(1)
|
|
456
|
+
.then((r) => r[0]);
|
|
457
|
+
if (lastestPrompt) {
|
|
458
|
+
refFS.push(...parseArray(lastestPrompt.Apps.fileSystem, vibeFile));
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
const mapFS = refFS.reduce((acc, file) => {
|
|
462
|
+
acc.set(file.filename, file);
|
|
463
|
+
return acc;
|
|
464
|
+
}, {});
|
|
465
|
+
req.fsUpdate.update.forEach((update) => {
|
|
466
|
+
mapFS.set(update.filename, update);
|
|
467
|
+
});
|
|
468
|
+
req.fsUpdate.remove?.forEach((item) => {
|
|
469
|
+
mapFS.delete(item.filename);
|
|
470
|
+
});
|
|
471
|
+
fileSystem = Array.from(mapFS.values());
|
|
472
|
+
}
|
|
473
|
+
await scope
|
|
474
|
+
.evalResult(async () => {
|
|
475
|
+
const sectionId = vctx.sthis.nextId(12).str;
|
|
476
|
+
let blockNr = 0;
|
|
477
|
+
const blockId = vctx.sthis.nextId(12).str;
|
|
478
|
+
let blockSeq = 0;
|
|
479
|
+
let bytes = 0;
|
|
480
|
+
const collectedMsgs = [
|
|
481
|
+
{
|
|
482
|
+
type: "block.begin",
|
|
483
|
+
blockId,
|
|
484
|
+
streamId: promptId,
|
|
485
|
+
seq: blockSeq++,
|
|
486
|
+
blockNr: blockNr++,
|
|
487
|
+
timestamp: new Date(),
|
|
488
|
+
},
|
|
489
|
+
...fileSystem.flatMap((file) => {
|
|
490
|
+
if (!isVibeCodeBlock(file)) {
|
|
491
|
+
return [];
|
|
492
|
+
}
|
|
493
|
+
return [
|
|
494
|
+
{
|
|
495
|
+
type: "block.code.begin",
|
|
496
|
+
sectionId,
|
|
497
|
+
lang: file.lang,
|
|
498
|
+
blockId: blockId,
|
|
499
|
+
streamId: promptId,
|
|
500
|
+
seq: blockSeq++,
|
|
501
|
+
blockNr,
|
|
502
|
+
timestamp: new Date(),
|
|
503
|
+
},
|
|
504
|
+
...file.content.split("\n").map((line, lineNr) => {
|
|
505
|
+
bytes += line.length + 1;
|
|
506
|
+
return {
|
|
507
|
+
type: "block.code.line",
|
|
508
|
+
sectionId,
|
|
509
|
+
blockId,
|
|
510
|
+
line,
|
|
511
|
+
streamId: promptId,
|
|
512
|
+
seq: blockSeq++,
|
|
513
|
+
timestamp: new Date(),
|
|
514
|
+
lang: file.lang,
|
|
515
|
+
blockNr,
|
|
516
|
+
lineNr,
|
|
517
|
+
};
|
|
518
|
+
}),
|
|
519
|
+
{
|
|
520
|
+
type: "block.code.end",
|
|
521
|
+
sectionId,
|
|
522
|
+
blockId,
|
|
523
|
+
streamId: promptId,
|
|
524
|
+
seq: blockSeq++,
|
|
525
|
+
timestamp: new Date(),
|
|
526
|
+
lang: file.lang,
|
|
527
|
+
blockNr,
|
|
528
|
+
},
|
|
529
|
+
];
|
|
530
|
+
}),
|
|
531
|
+
];
|
|
532
|
+
const value = {
|
|
533
|
+
type: "block.end",
|
|
534
|
+
stats: {
|
|
535
|
+
toplevel: { lines: 0, bytes: 0 },
|
|
536
|
+
code: { lines: blockSeq, bytes },
|
|
537
|
+
image: { lines: 0, bytes: 0 },
|
|
538
|
+
total: { lines: blockSeq, bytes },
|
|
539
|
+
},
|
|
540
|
+
usage: {
|
|
541
|
+
given: [],
|
|
542
|
+
calculated: {
|
|
543
|
+
prompt_tokens: 0,
|
|
544
|
+
completion_tokens: 0,
|
|
545
|
+
total_tokens: 0,
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
blockId: blockId,
|
|
549
|
+
streamId: promptId,
|
|
550
|
+
seq: blockSeq++,
|
|
551
|
+
blockNr: blockNr,
|
|
552
|
+
timestamp: new Date(),
|
|
553
|
+
};
|
|
554
|
+
collectedMsgs.push(value);
|
|
555
|
+
return handleEndMsg({
|
|
556
|
+
collectedMsgs,
|
|
557
|
+
vctx,
|
|
558
|
+
req,
|
|
559
|
+
ctx,
|
|
560
|
+
resChat,
|
|
561
|
+
promptId,
|
|
562
|
+
value,
|
|
563
|
+
blockSeq,
|
|
564
|
+
});
|
|
565
|
+
})
|
|
566
|
+
.do();
|
|
567
|
+
return Result.Ok();
|
|
568
|
+
}
|
|
235
569
|
export const promptChatSection = {
|
|
236
570
|
hash: "prompt-chat-section-handler",
|
|
237
571
|
validate: unwrapMsgBase(async (msg) => {
|
|
@@ -248,33 +582,51 @@ export const promptChatSection = {
|
|
|
248
582
|
const req = ctx.validated.payload;
|
|
249
583
|
const orig = ctx.enRequest.payload;
|
|
250
584
|
const vctx = ctx.ctx.getOrThrow("vibesApiCtx");
|
|
251
|
-
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
.select()
|
|
255
|
-
.from(vctx.sql.tables.chatContexts)
|
|
256
|
-
.where(and(eq(vctx.sql.tables.chatContexts.chatId, req.chatId), eq(vctx.sql.tables.chatContexts.userId, req._auth.verifiedAuth.claims.userId)))
|
|
257
|
-
.limit(1)
|
|
258
|
-
.then((r) => r[0]);
|
|
259
|
-
if (!iResChat) {
|
|
260
|
-
return Result.Err(`Creation Chat ID ${req.chatId} not found`);
|
|
261
|
-
}
|
|
262
|
-
resChat = { ...iResChat, mode: "chat" };
|
|
585
|
+
const rResChat = await getResChatFromMode(vctx, req, orig);
|
|
586
|
+
if (rResChat.isErr()) {
|
|
587
|
+
return Result.Err(rResChat);
|
|
263
588
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
589
|
+
const resChat = rResChat.Ok();
|
|
590
|
+
let prompSectionAction;
|
|
591
|
+
if (isReqPromptLLMChatSection(orig)) {
|
|
592
|
+
prompSectionAction = async (scope, blockSeq) => {
|
|
593
|
+
const res = await handlerLlmRequest({
|
|
594
|
+
ctx,
|
|
595
|
+
blockSeq,
|
|
596
|
+
scope,
|
|
597
|
+
vctx,
|
|
598
|
+
req: req,
|
|
599
|
+
resChat,
|
|
600
|
+
promptId,
|
|
601
|
+
});
|
|
602
|
+
await handleLlmResponse({
|
|
603
|
+
scope,
|
|
604
|
+
vctx,
|
|
605
|
+
req: req,
|
|
606
|
+
ctx,
|
|
607
|
+
res: res.res,
|
|
608
|
+
resChat,
|
|
609
|
+
promptId,
|
|
610
|
+
blockSeq: res.blockSeq,
|
|
611
|
+
});
|
|
612
|
+
return Result.Ok();
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
if (isReqPromptFSChatSection(orig)) {
|
|
616
|
+
prompSectionAction = async (scope, blockSeq) => {
|
|
617
|
+
return handleFSPrompt({
|
|
618
|
+
scope,
|
|
619
|
+
vctx,
|
|
620
|
+
req: req,
|
|
621
|
+
ctx,
|
|
622
|
+
resChat,
|
|
623
|
+
promptId,
|
|
624
|
+
blockSeq,
|
|
625
|
+
});
|
|
626
|
+
};
|
|
275
627
|
}
|
|
276
|
-
if (!
|
|
277
|
-
return Result.Err(`
|
|
628
|
+
if (!prompSectionAction) {
|
|
629
|
+
return Result.Err(`Unsupported prompt chat section mode: ${orig.mode}`);
|
|
278
630
|
}
|
|
279
631
|
const promptId = vctx.sthis.nextId(96 / 8).str;
|
|
280
632
|
await ctx.send.send(ctx, wrapMsgBase(ctx.validated, {
|
|
@@ -350,175 +702,7 @@ export const promptChatSection = {
|
|
|
350
702
|
}
|
|
351
703
|
})
|
|
352
704
|
.do();
|
|
353
|
-
await scope
|
|
354
|
-
.evalResult(async () => {
|
|
355
|
-
const r = await appendBlockEvent({
|
|
356
|
-
ctx,
|
|
357
|
-
vctx,
|
|
358
|
-
req,
|
|
359
|
-
promptId,
|
|
360
|
-
blockSeq: blockSeq,
|
|
361
|
-
evt: {
|
|
362
|
-
type: "prompt.req",
|
|
363
|
-
streamId: promptId,
|
|
364
|
-
chatId: req.chatId,
|
|
365
|
-
seq: blockSeq,
|
|
366
|
-
request: req.prompt,
|
|
367
|
-
timestamp: new Date(),
|
|
368
|
-
},
|
|
369
|
-
});
|
|
370
|
-
blockSeq++;
|
|
371
|
-
return r;
|
|
372
|
-
})
|
|
373
|
-
.do();
|
|
374
|
-
const modelId = await scope
|
|
375
|
-
.evalResult(async () => {
|
|
376
|
-
const r = await getModelDefaults(vctx, { appSlug: resChat.appSlug, userSlug: resChat.userSlug });
|
|
377
|
-
if (r.isErr()) {
|
|
378
|
-
return Result.Err(r);
|
|
379
|
-
}
|
|
380
|
-
switch (req.mode) {
|
|
381
|
-
case "chat":
|
|
382
|
-
return Result.Ok(req.prompt.model ?? r.Ok().chat.model.id);
|
|
383
|
-
case "app":
|
|
384
|
-
return Result.Ok(req.prompt.model ?? r.Ok().app.model.id);
|
|
385
|
-
case "img":
|
|
386
|
-
return Result.Ok(req.prompt.model ?? r.Ok().img.model.id);
|
|
387
|
-
default:
|
|
388
|
-
return Result.Err(`Unknown prompt mode: ${req.mode}`);
|
|
389
|
-
}
|
|
390
|
-
})
|
|
391
|
-
.do();
|
|
392
|
-
const withSystemPrompt = await scope
|
|
393
|
-
.evalResult(async () => {
|
|
394
|
-
let withSystemPrompt = Result.Ok({
|
|
395
|
-
model: modelId,
|
|
396
|
-
messages: [],
|
|
397
|
-
});
|
|
398
|
-
if (req.mode === "chat") {
|
|
399
|
-
withSystemPrompt = await injectSystemPrompt(vctx, req.chatId, req.prompt.model ?? modelId);
|
|
400
|
-
}
|
|
401
|
-
else if (req.mode === "app") {
|
|
402
|
-
withSystemPrompt = Result.Ok({
|
|
403
|
-
model: req.prompt.model ?? modelId,
|
|
404
|
-
messages: req.prompt.messages,
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
return withSystemPrompt;
|
|
408
|
-
})
|
|
409
|
-
.do();
|
|
410
|
-
const llmReq = {
|
|
411
|
-
...{
|
|
412
|
-
...req.prompt,
|
|
413
|
-
messages: withSystemPrompt.messages,
|
|
414
|
-
},
|
|
415
|
-
...vctx.params.llm.enforced,
|
|
416
|
-
model: withSystemPrompt.model,
|
|
417
|
-
headers: vctx.params.llm.headers,
|
|
418
|
-
logprobs: true,
|
|
419
|
-
stream: true,
|
|
420
|
-
};
|
|
421
|
-
const res = await scope
|
|
422
|
-
.evalResult(async () => {
|
|
423
|
-
console.log(promptId, "Sending LLM request:", llmReq.model);
|
|
424
|
-
const res = await vctx.llmRequest(llmReq);
|
|
425
|
-
if (!res.ok) {
|
|
426
|
-
return Result.Err(`LLM request failed with status ${res.status} :${llmReq.model} : ${res.statusText}`);
|
|
427
|
-
}
|
|
428
|
-
if (!res.body) {
|
|
429
|
-
return Result.Err(`LLM request returned no body`);
|
|
430
|
-
}
|
|
431
|
-
return Result.Ok(res);
|
|
432
|
-
})
|
|
433
|
-
.do();
|
|
434
|
-
await scope
|
|
435
|
-
.evalResult(async () => {
|
|
436
|
-
const pipeline = res
|
|
437
|
-
.body.pipeThrough(createStatsCollector(promptId, 1000))
|
|
438
|
-
.pipeThrough(createLineStream(promptId))
|
|
439
|
-
.pipeThrough(createDataStream(promptId))
|
|
440
|
-
.pipeThrough(createSseStream(promptId))
|
|
441
|
-
.pipeThrough(createDeltaStream(promptId, () => vctx.sthis.nextId(12).str))
|
|
442
|
-
.pipeThrough(createSectionsStream(promptId, () => vctx.sthis.nextId(12).str));
|
|
443
|
-
const reader = pipeline.getReader();
|
|
444
|
-
let collectedMsgs;
|
|
445
|
-
let chatCtx;
|
|
446
|
-
for (const conn of vctx.connections) {
|
|
447
|
-
const tChatCtx = conn.chatIds.get(req.chatId);
|
|
448
|
-
if (tChatCtx) {
|
|
449
|
-
chatCtx = tChatCtx;
|
|
450
|
-
const promptIdCtx = chatCtx.promptIds.get(promptId);
|
|
451
|
-
if (!promptIdCtx) {
|
|
452
|
-
collectedMsgs = [];
|
|
453
|
-
chatCtx.promptIds.set(promptId, {
|
|
454
|
-
blocks: collectedMsgs,
|
|
455
|
-
promptId,
|
|
456
|
-
type: "vibes.diy.section-event",
|
|
457
|
-
chatId: req.chatId,
|
|
458
|
-
blockSeq: 0,
|
|
459
|
-
timestamp: new Date(),
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
collectedMsgs = promptIdCtx.blocks;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
if (!collectedMsgs) {
|
|
468
|
-
return Result.Err(`Chat context not found for chatId: ${req.chatId}`);
|
|
469
|
-
}
|
|
470
|
-
while (true) {
|
|
471
|
-
const { done, value } = await reader.read();
|
|
472
|
-
if (done) {
|
|
473
|
-
break;
|
|
474
|
-
}
|
|
475
|
-
if (!isBlockEnd(value)) {
|
|
476
|
-
if (!isBlockStreamMsg(value)) {
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
collectedMsgs.push(value);
|
|
480
|
-
const r = await appendBlockEvent({
|
|
481
|
-
ctx,
|
|
482
|
-
vctx,
|
|
483
|
-
req,
|
|
484
|
-
promptId,
|
|
485
|
-
blockSeq: blockSeq++,
|
|
486
|
-
evt: value,
|
|
487
|
-
emitMode: "emit-only",
|
|
488
|
-
});
|
|
489
|
-
if (r.isErr()) {
|
|
490
|
-
return Result.Err(r);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
else {
|
|
494
|
-
collectedMsgs.push(value);
|
|
495
|
-
const r = await handlePromptContext({ vctx, req, promptId, resChat, value, blockSeq, collectedMsgs });
|
|
496
|
-
if (r.isErr()) {
|
|
497
|
-
return Result.Err(r);
|
|
498
|
-
}
|
|
499
|
-
const promptIdCtx = chatCtx.promptIds.get(promptId);
|
|
500
|
-
if (promptIdCtx) {
|
|
501
|
-
chatCtx.promptIds.delete(promptId);
|
|
502
|
-
}
|
|
503
|
-
blockSeq = r.Ok().blockSeq;
|
|
504
|
-
const rEvt = await appendBlockEvent({
|
|
505
|
-
ctx,
|
|
506
|
-
vctx,
|
|
507
|
-
req,
|
|
508
|
-
promptId,
|
|
509
|
-
blockSeq: blockSeq++,
|
|
510
|
-
evt: { ...value, fsRef: r.Ok().fsRef.toValue() },
|
|
511
|
-
emitMode: "emit-only",
|
|
512
|
-
});
|
|
513
|
-
if (rEvt.isErr()) {
|
|
514
|
-
return Result.Err(rEvt);
|
|
515
|
-
}
|
|
516
|
-
collectedMsgs.splice(0, collectedMsgs.length);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
return Result.Ok();
|
|
520
|
-
})
|
|
521
|
-
.do();
|
|
705
|
+
await prompSectionAction(scope, blockSeq);
|
|
522
706
|
});
|
|
523
707
|
return Result.Ok(EventoResult.Continue);
|
|
524
708
|
}),
|