UNPKG

@assistant-ui/react

Version:

Typescript/React library for AI Chat

1 lines 8.08 kB
{"version":3,"sources":["../../../src/runtimes/edge/EdgeChatAdapter.ts"],"sourcesContent":["import {\n ChatModelAdapter,\n ChatModelRunOptions,\n} from \"../local/ChatModelAdapter\";\nimport { toCoreMessages } from \"./converters/toCoreMessages\";\nimport { toLanguageModelTools } from \"./converters/toLanguageModelTools\";\nimport { EdgeRuntimeRequestOptions } from \"./EdgeRuntimeRequestOptions\";\nimport { toolResultStream } from \"./streams/toolResultStream\";\nimport { toLanguageModelMessages } from \"./converters\";\nimport { ThreadMessage } from \"../../types\";\nimport { Tool } from \"../../model-context\";\nimport { z } from \"zod\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport { JSONSchema7 } from \"json-schema\";\nimport {\n AssistantMessageAccumulator,\n DataStreamDecoder,\n} from \"assistant-stream\";\n\nexport function asAsyncIterable<T>(\n source: ReadableStream<T>,\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator]: () => {\n const reader = source.getReader();\n return {\n async next(): Promise<IteratorResult<T, undefined>> {\n const { done, value } = await reader.read();\n return done\n ? { done: true, value: undefined }\n : { done: false, value };\n },\n };\n },\n };\n}\n\ntype HeadersValue = Record<string, string> | Headers;\n\nexport type EdgeChatAdapterOptions = {\n api: string;\n\n // experimental_prepareRequestBody?: (options: {\n // id: string;\n // messages: UIMessage[];\n // requestData?: JSONValue;\n // requestBody?: object;\n // }) => unknown;\n\n // onToolCall?: ({\n // toolCall,\n // }: {\n // toolCall: UIMessageToolInvocation;\n // }) => void | Promise<unknown> | unknown;\n\n /**\n * Callback function to be called when the API response is received.\n */\n onResponse?: (response: Response) => void | Promise<void>;\n /**\n * Optional callback function that is called when the assistant message is finished streaming.\n */\n onFinish?: (message: ThreadMessage) => void;\n /**\n * Callback function to be called when an error is encountered.\n */\n onError?: (error: Error) => void;\n\n credentials?: RequestCredentials;\n\n /**\n * Headers to be sent with the request.\n * Can be a static headers object or a function that returns a Promise of headers.\n */\n headers?: HeadersValue | (() => Promise<HeadersValue>);\n\n body?: object;\n\n /**\n * @deprecated Renamed to `sendExtraMessageFields`.\n */\n unstable_sendMessageIds?: boolean;\n\n /**\n * When enabled, the adapter will not strip `id` from messages in the messages array.\n */\n sendExtraMessageFields?: boolean;\n\n /**\n * When enabled, the adapter will send messages in the format expected by the Vercel AI SDK Core.\n * This feature will be removed in the future in favor of a better solution.\n *\n * `v2` sends frontend tools in a format that can be directly passed to `stremaText`\n */\n unstable_AISDKInterop?: boolean | \"v2\" | undefined;\n};\n\nconst toAISDKTools = (tools: Record<string, Tool<any, any>>) => {\n return Object.fromEntries(\n Object.entries(tools).map(([name, tool]) => [\n name,\n {\n ...(tool.description ? { description: tool.description } : undefined),\n parameters: (tool.parameters instanceof z.ZodType\n ? zodToJsonSchema(tool.parameters)\n : tool.parameters) as JSONSchema7,\n },\n ]),\n );\n};\n\nexport class EdgeChatAdapter implements ChatModelAdapter {\n constructor(private options: EdgeChatAdapterOptions) {}\n\n async *run({\n messages,\n runConfig,\n abortSignal,\n context,\n unstable_assistantMessageId,\n unstable_getMessage,\n }: ChatModelRunOptions) {\n const headersValue =\n typeof this.options.headers === \"function\"\n ? await this.options.headers()\n : this.options.headers;\n\n const headers = new Headers(headersValue);\n headers.set(\"Content-Type\", \"application/json\");\n\n const result = await fetch(this.options.api, {\n method: \"POST\",\n headers,\n credentials: this.options.credentials ?? \"same-origin\",\n body: JSON.stringify({\n system: context.system,\n messages: this.options.unstable_AISDKInterop\n ? (toLanguageModelMessages(messages, {\n unstable_includeId:\n this.options.unstable_sendMessageIds ||\n this.options.sendExtraMessageFields,\n }) as EdgeRuntimeRequestOptions[\"messages\"]) // TODO figure out a better way to do this\n : toCoreMessages(messages, {\n unstable_includeId:\n this.options.unstable_sendMessageIds ||\n this.options.sendExtraMessageFields,\n }),\n tools: context.tools\n ? this.options.unstable_AISDKInterop === \"v2\"\n ? (toAISDKTools(context.tools) as any)\n : toLanguageModelTools(context.tools)\n : [],\n unstable_assistantMessageId,\n runConfig,\n ...context.callSettings,\n ...context.config,\n\n ...this.options.body,\n } satisfies EdgeRuntimeRequestOptions),\n signal: abortSignal,\n });\n\n await this.options.onResponse?.(result);\n\n try {\n if (!result.ok) {\n throw new Error(`Status ${result.status}: ${await result.text()}`);\n }\n if (!result.body) {\n throw new Error(\"Response body is null\");\n }\n\n const stream = result.body\n .pipeThrough(new DataStreamDecoder())\n .pipeThrough(toolResultStream(context.tools, abortSignal))\n .pipeThrough(new AssistantMessageAccumulator());\n\n for await (const update of asAsyncIterable(stream)) {\n yield update;\n }\n\n this.options.onFinish?.(unstable_getMessage());\n } catch (error: unknown) {\n this.options.onError?.(error as Error);\n throw error;\n }\n }\n}\n"],"mappings":";AAIA,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AAErC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AAGxC,SAAS,SAAS;AAClB,OAAO,qBAAqB;AAE5B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,SAAS,gBACd,QACkB;AAClB,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,GAAG,MAAM;AAC5B,YAAM,SAAS,OAAO,UAAU;AAChC,aAAO;AAAA,QACL,MAAM,OAA8C;AAClD,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,iBAAO,OACH,EAAE,MAAM,MAAM,OAAO,OAAU,IAC/B,EAAE,MAAM,OAAO,MAAM;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AA8DA,IAAM,eAAe,CAAC,UAA0C;AAC9D,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;AAAA,MAC1C;AAAA,MACA;AAAA,QACE,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI;AAAA,QAC3D,YAAa,KAAK,sBAAsB,EAAE,UACtC,gBAAgB,KAAK,UAAU,IAC/B,KAAK;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,kBAAN,MAAkD;AAAA,EACvD,YAAoB,SAAiC;AAAjC;AAAA,EAAkC;AAAA,EAEtD,OAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAwB;AACtB,UAAM,eACJ,OAAO,KAAK,QAAQ,YAAY,aAC5B,MAAM,KAAK,QAAQ,QAAQ,IAC3B,KAAK,QAAQ;AAEnB,UAAM,UAAU,IAAI,QAAQ,YAAY;AACxC,YAAQ,IAAI,gBAAgB,kBAAkB;AAE9C,UAAM,SAAS,MAAM,MAAM,KAAK,QAAQ,KAAK;AAAA,MAC3C,QAAQ;AAAA,MACR;AAAA,MACA,aAAa,KAAK,QAAQ,eAAe;AAAA,MACzC,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,UAAU,KAAK,QAAQ,wBAClB,wBAAwB,UAAU;AAAA,UACjC,oBACE,KAAK,QAAQ,2BACb,KAAK,QAAQ;AAAA,QACjB,CAAC,IACD,eAAe,UAAU;AAAA,UACvB,oBACE,KAAK,QAAQ,2BACb,KAAK,QAAQ;AAAA,QACjB,CAAC;AAAA,QACL,OAAO,QAAQ,QACX,KAAK,QAAQ,0BAA0B,OACpC,aAAa,QAAQ,KAAK,IAC3B,qBAAqB,QAAQ,KAAK,IACpC,CAAC;AAAA,QACL;AAAA,QACA;AAAA,QACA,GAAG,QAAQ;AAAA,QACX,GAAG,QAAQ;AAAA,QAEX,GAAG,KAAK,QAAQ;AAAA,MAClB,CAAqC;AAAA,MACrC,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,KAAK,QAAQ,aAAa,MAAM;AAEtC,QAAI;AACF,UAAI,CAAC,OAAO,IAAI;AACd,cAAM,IAAI,MAAM,UAAU,OAAO,MAAM,KAAK,MAAM,OAAO,KAAK,CAAC,EAAE;AAAA,MACnE;AACA,UAAI,CAAC,OAAO,MAAM;AAChB,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,YAAM,SAAS,OAAO,KACnB,YAAY,IAAI,kBAAkB,CAAC,EACnC,YAAY,iBAAiB,QAAQ,OAAO,WAAW,CAAC,EACxD,YAAY,IAAI,4BAA4B,CAAC;AAEhD,uBAAiB,UAAU,gBAAgB,MAAM,GAAG;AAClD,cAAM;AAAA,MACR;AAEA,WAAK,QAAQ,WAAW,oBAAoB,CAAC;AAAA,IAC/C,SAAS,OAAgB;AACvB,WAAK,QAAQ,UAAU,KAAc;AACrC,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":[]}