UNPKG

@convex-dev/agent

Version:

A agent component for Convex.

96 lines 4.57 kB
import { type BetterOmit, type ErrorMessage, type Expand } from "convex-helpers"; import { type UsePaginatedQueryResult } from "convex/react"; import type { FunctionArgs, FunctionReference, PaginationOptions, PaginationResult } from "convex/server"; import type { SyncStreamsReturnValue } from "../client/types.js"; import type { StreamArgs } from "../validators.js"; import type { StreamQuery } from "./types.js"; import { type UIMessage, type UIStatus } from "../UIMessages.js"; export type UIMessageLike = { order: number; stepOrder: number; status: UIStatus; parts: UIMessage["parts"]; role: UIMessage["role"]; }; export type UIMessagesQuery<Args = unknown, M extends UIMessageLike = UIMessageLike> = FunctionReference<"query", "public", { threadId: string; paginationOpts: PaginationOptions; /** * If { stream: true } is passed, it will also query for stream deltas. * In order for this to work, the query must take as an argument streamArgs. */ streamArgs?: StreamArgs; } & Args, PaginationResult<M> & { streams?: SyncStreamsReturnValue; }>; export type UIMessagesQueryArgs<Query extends UIMessagesQuery<unknown, UIMessageLike>> = Query extends UIMessagesQuery<unknown, UIMessageLike> ? Expand<BetterOmit<FunctionArgs<Query>, "paginationOpts" | "streamArgs">> : never; export type UIMessagesQueryResult<Query extends UIMessagesQuery<unknown, UIMessageLike>> = Query extends UIMessagesQuery<unknown, infer M> ? M : never; /** * A hook that fetches UIMessages from a thread. * * It's similar to useThreadMessages, for endpoints that return UIMessages. * The streaming messages are materialized as UIMessages. The rest are passed * through from the query. * * This hook is a wrapper around `usePaginatedQuery` and `useStreamingUIMessages`. * It will fetch both full messages and streaming messages, and merge them together. * * The query must take as arguments `{ threadId, paginationOpts }` and return a * pagination result of objects similar to UIMessage: * * For streaming, it should look like this: * ```ts * export const listThreadMessages = query({ * args: { * threadId: v.string(), * paginationOpts: paginationOptsValidator, * streamArgs: vStreamArgs, * ... other arguments you want * }, * handler: async (ctx, args) => { * // await authorizeThreadAccess(ctx, threadId); * // NOTE: listUIMessages returns UIMessages, not MessageDocs. * const paginated = await listUIMessages(ctx, components.agent, args); * const streams = await syncStreams(ctx, components.agent, args); * // Here you could filter out / modify the documents & stream deltas. * return { ...paginated, streams }; * }, * }); * ``` * * Then the hook can be used like this: * ```ts * const { results, status, loadMore } = useUIMessages( * api.myModule.listThreadMessages, * { threadId }, * { initialNumItems: 10, stream: true } * ); * ``` * * @param query The query to use to fetch messages. * It must take as arguments `{ threadId, paginationOpts }` and return a * pagination result of objects similar to UIMessage: * Required fields: (role, parts, status, order, stepOrder). * To support streaming, it must also take in `streamArgs: vStreamArgs` and * return a `streams` object returned from `syncStreams`. * @param args The arguments to pass to the query other than `paginationOpts` * and `streamArgs`. So `{ threadId }` at minimum, plus any other arguments that * you want to pass to the query. * @param options The options for the query. Similar to usePaginatedQuery. * To enable streaming, pass `stream: true`. * @returns The messages. If stream is true, it will return a list of messages * that includes both full messages and streaming messages. * The streaming messages are materialized as UIMessages. The rest are passed * through from the query. */ export declare function useUIMessages<Query extends UIMessagesQuery<any, any>>(query: Query, args: UIMessagesQueryArgs<Query> | "skip", options: { initialNumItems: number; stream?: Query extends StreamQuery ? boolean : ErrorMessage<"To enable streaming, your query must take in streamArgs: vStreamArgs and return a streams object returned from syncStreams. See docs.">; skipStreamIds?: string[]; }): UsePaginatedQueryResult<UIMessagesQueryResult<Query>>; export declare function dedupeMessages<M extends { order: number; stepOrder: number; status: UIStatus; }>(messages: M[], streamMessages: M[]): M[]; //# sourceMappingURL=useUIMessages.d.ts.map