UNPKG

create-mf2-app

Version:

The stack AI moves fast with.

119 lines (113 loc) 3.38 kB
import { v } from "convex/values"; import { components } from "../_generated/api"; import { query, action, mutation, internalMutation, } from "../_generated/server"; import { abortStream, listStreams } from "@convex-dev/agent"; import { agent } from "../agents/simple"; import { smoothStream } from "ai"; import { authorizeThreadAccess } from "../threads"; export const abortStreamByOrder = mutation({ args: { threadId: v.string(), order: v.number() }, handler: async (ctx, { threadId, order }) => { await authorizeThreadAccess(ctx, threadId); if ( await abortStream(ctx, components.agent, { threadId, order, reason: "Aborting explicitly", }) ) { console.log("Aborted stream", threadId, order); } else { console.log("No stream found", threadId, order); } }, }); export const streamThenAbortAsync = action({ args: {}, handler: async (ctx) => { const { thread, threadId } = await agent.createThread(ctx, { title: "Thread with aborted message", }); const result = await thread.streamText( { prompt: "Write an essay on the importance of effusive dialogue", experimental_transform: smoothStream({ chunking: "line" }), onError: (error) => { console.error(error); }, }, { saveStreamDeltas: { chunking: "line" } } ); let canceled = false; try { for await (const chunk of result.textStream) { console.log(chunk); if (!canceled) { await abortStream(ctx, components.agent, { threadId, order: result.order, reason: "Aborting explicitly", }); canceled = true; } } } catch (error) { console.warn("Catching what should be an AbortError", error); } }, }); export const list = query({ args: { threadId: v.string() }, handler: async (ctx, { threadId }) => { return listStreams(ctx, components.agent, { threadId }); }, }); export const abortStreamByStreamId = internalMutation({ args: { threadId: v.string() }, handler: async (ctx, { threadId }) => { const streams = await listStreams(ctx, components.agent, { threadId }); for (const stream of streams) { console.log("Aborting stream", stream); await abortStream(ctx, components.agent, { reason: "Aborting via async call", streamId: stream.streamId, }); } if (!streams.length) { console.log("No streams found"); } }, }); export const streamThenUseAbortSignal = action({ args: {}, handler: async (ctx) => { const { thread } = await agent.createThread(ctx, { title: "Thread using abortSignal", }); const abortController = new AbortController(); const result = await thread.streamText( { prompt: "Write an essay on the importance of effusive dialogue", abortSignal: abortController.signal, experimental_transform: smoothStream({ chunking: "line" }), }, { saveStreamDeltas: { chunking: "line" } } ); setTimeout(() => { abortController.abort(); }, 1000); try { for await (const chunk of result.textStream) { console.log(chunk); } } catch (error) { console.warn("Catching what should be an AbortError", error); } await result.consumeStream(); }, });