| | import { preprocessMessages } from "../endpoints/preprocessMessages"; |
| |
|
| | import { generateTitleForConversation } from "./title"; |
| | import { |
| | type MessageUpdate, |
| | MessageUpdateType, |
| | MessageUpdateStatus, |
| | } from "$lib/types/MessageUpdate"; |
| | import { generate } from "./generate"; |
| | import { runMcpFlow } from "./mcp/runMcpFlow"; |
| | import { mergeAsyncGenerators } from "$lib/utils/mergeAsyncGenerators"; |
| | import type { TextGenerationContext } from "./types"; |
| |
|
| | async function* keepAlive(done: AbortSignal): AsyncGenerator<MessageUpdate, undefined, undefined> { |
| | while (!done.aborted) { |
| | yield { |
| | type: MessageUpdateType.Status, |
| | status: MessageUpdateStatus.KeepAlive, |
| | }; |
| | await new Promise((resolve) => setTimeout(resolve, 100)); |
| | } |
| | } |
| |
|
| | export async function* textGeneration(ctx: TextGenerationContext) { |
| | const done = new AbortController(); |
| |
|
| | const titleGen = generateTitleForConversation(ctx.conv, ctx.locals); |
| | const textGen = textGenerationWithoutTitle(ctx, done); |
| | const keepAliveGen = keepAlive(done.signal); |
| |
|
| | |
| |
|
| | yield* mergeAsyncGenerators([titleGen, textGen, keepAliveGen]); |
| | } |
| |
|
| | async function* textGenerationWithoutTitle( |
| | ctx: TextGenerationContext, |
| | done: AbortController |
| | ): AsyncGenerator<MessageUpdate, undefined, undefined> { |
| | yield { |
| | type: MessageUpdateType.Status, |
| | status: MessageUpdateStatus.Started, |
| | }; |
| |
|
| | const { conv, messages } = ctx; |
| | const convId = conv._id; |
| |
|
| | const preprompt = conv.preprompt; |
| |
|
| | const processedMessages = await preprocessMessages(messages, convId); |
| |
|
| | |
| | try { |
| | const mcpGen = runMcpFlow({ |
| | model: ctx.model, |
| | conv, |
| | messages: processedMessages, |
| | assistant: ctx.assistant, |
| | forceMultimodal: ctx.forceMultimodal, |
| | forceTools: ctx.forceTools, |
| | locals: ctx.locals, |
| | preprompt, |
| | abortSignal: ctx.abortController.signal, |
| | }); |
| |
|
| | let step = await mcpGen.next(); |
| | while (!step.done) { |
| | yield step.value; |
| | step = await mcpGen.next(); |
| | } |
| | const didRunMcp = Boolean(step.value); |
| | if (!didRunMcp) { |
| | |
| | yield* generate({ ...ctx, messages: processedMessages }, preprompt); |
| | } |
| | } catch { |
| | |
| | yield* generate({ ...ctx, messages: processedMessages }, preprompt); |
| | } |
| | done.abort(); |
| | } |
| |
|