({
messages,
systemPrompt,
thinkingConfig,
tools,
signal,
options,
}: {
messages: Message[]
systemPrompt: SystemPrompt
thinkingConfig: ThinkingConfig
tools: Tools
signal: AbortSignal
options: Options
})
| 734 | } |
| 735 | |
| 736 | export async function queryModelWithoutStreaming({ |
| 737 | messages, |
| 738 | systemPrompt, |
| 739 | thinkingConfig, |
| 740 | tools, |
| 741 | signal, |
| 742 | options, |
| 743 | }: { |
| 744 | messages: Message[] |
| 745 | systemPrompt: SystemPrompt |
| 746 | thinkingConfig: ThinkingConfig |
| 747 | tools: Tools |
| 748 | signal: AbortSignal |
| 749 | options: Options |
| 750 | }): Promise<AssistantMessage> { |
| 751 | // Store the assistant message but continue consuming the generator to ensure |
| 752 | // logAPISuccessAndDuration gets called (which happens after all yields) |
| 753 | let assistantMessage: AssistantMessage | undefined |
| 754 | for await (const message of withStreamingVCR(messages, async function* () { |
| 755 | yield* queryModel( |
| 756 | messages, |
| 757 | systemPrompt, |
| 758 | thinkingConfig, |
| 759 | tools, |
| 760 | signal, |
| 761 | options, |
| 762 | ) |
| 763 | })) { |
| 764 | if (message.type === 'assistant') { |
| 765 | assistantMessage = message |
| 766 | } |
| 767 | } |
| 768 | if (!assistantMessage) { |
| 769 | // If the signal was aborted, throw APIUserAbortError instead of a generic error |
| 770 | // This allows callers to handle abort scenarios gracefully |
| 771 | if (signal.aborted) { |
| 772 | throw new APIUserAbortError() |
| 773 | } |
| 774 | throw new Error('No assistant message found') |
| 775 | } |
| 776 | return assistantMessage |
| 777 | } |
| 778 | |
| 779 | export async function* queryModelWithStreaming({ |
| 780 | messages, |
no test coverage detected