({
messages,
systemPrompt,
thinkingConfig,
tools,
signal,
options,
}: {
messages: Message[]
systemPrompt: SystemPrompt
thinkingConfig: ThinkingConfig
tools: Tools
signal: AbortSignal
options: Options
})
| 707 | } |
| 708 | |
| 709 | export async function queryModelWithoutStreaming({ |
| 710 | messages, |
| 711 | systemPrompt, |
| 712 | thinkingConfig, |
| 713 | tools, |
| 714 | signal, |
| 715 | options, |
| 716 | }: { |
| 717 | messages: Message[] |
| 718 | systemPrompt: SystemPrompt |
| 719 | thinkingConfig: ThinkingConfig |
| 720 | tools: Tools |
| 721 | signal: AbortSignal |
| 722 | options: Options |
| 723 | }): Promise<AssistantMessage> { |
| 724 | // Store the assistant message but continue consuming the generator to ensure |
| 725 | // logAPISuccessAndDuration gets called (which happens after all yields) |
| 726 | let assistantMessage: AssistantMessage | undefined |
| 727 | for await (const message of withStreamingVCR(messages, async function* () { |
| 728 | yield* queryModel( |
| 729 | messages, |
| 730 | systemPrompt, |
| 731 | thinkingConfig, |
| 732 | tools, |
| 733 | signal, |
| 734 | options, |
| 735 | ) |
| 736 | })) { |
| 737 | if (message.type === 'assistant') { |
| 738 | assistantMessage = message |
| 739 | } |
| 740 | } |
| 741 | if (!assistantMessage) { |
| 742 | // If the signal was aborted, throw APIUserAbortError instead of a generic error |
| 743 | // This allows callers to handle abort scenarios gracefully |
| 744 | if (signal.aborted) { |
| 745 | throw new APIUserAbortError() |
| 746 | } |
| 747 | throw new Error('No assistant message found') |
| 748 | } |
| 749 | return assistantMessage |
| 750 | } |
| 751 | |
| 752 | export async function* queryModelWithStreaming({ |
| 753 | messages, |
no test coverage detected