import {CoreTool, streamObject, streamText, TextStreamPart} from "ai"; import { EventObject, ObservableActorLogic} from "xstate"; import {fromEventAsyncGenerator} from "@/xstate/generator"; import {aiOptions, FromDefault, OneOf, StreamObjectOptions, StreamTextOptions} from "./options"; import {LanguageModelV1} from "@ai-sdk/provider"; export function fromAIEventStream, TOptions extends FromDefault =FromDefault, TTools extends OneOf & Record =OneOf & Record>( defaultOptions?: TDefaultOptions){ return fromEventAsyncGenerator( async function * ({input, self, emit}){ const resolvedOptions = await aiOptions(self._parent?.getSnapshot()?.context, defaultOptions, input as any); console.log('Resolved Options', resolvedOptions); try { const {fullStream, text} = await streamText(resolvedOptions); for await (const part of fullStream) { yield part; if (part.type == "text-delta") { emit({ type: 'text-delta', data: part.textDelta }) } } yield { type: 'output', output: await text } } catch (e) { console.error(e); throw e; } }) satisfies ObservableActorLogic| {type:"output", output:string}, TOptions | string, {type:"text-delta", data:string} > } export type AIStream=ReturnType>; type ElementStreamPart = {type:'element' | 'text'} & EventObject; export function fromAIElementStream>, TOptions extends FromDefault, TDefaultOptions > =FromDefault, TDefaultOptions >>( defaultOptions?: TDefaultOptions){ type TContext = OBJECT | {type:'output', output:OBJECT[]} | ElementStreamPart; return fromEventAsyncGenerator( async function * ({input, self, emit}):AsyncGenerator{ const resolvedOptions = await aiOptions>(self._parent?.getSnapshot()?.context, defaultOptions, input); console.log('Resolved Options', "system:",resolvedOptions.system ,"prompt",resolvedOptions.prompt ); const {elementStream, object} = await streamObject({ ...resolvedOptions, output: 'array' }); for await (const {type,...part} of elementStream) { yield { type: type ?? 'element', ...part } as TContext } yield { type: 'output', output: await object } }) satisfies ObservableActorLogic }