1- import {
2- LlmRunner ,
3- LocalLlmConstrainedOutputGenerateRequestOptions ,
4- LocalLlmConstrainedOutputGenerateResponse ,
5- LocalLlmGenerateFilesRequestOptions ,
6- LocalLlmGenerateFilesResponse ,
7- LocalLlmGenerateTextRequestOptions ,
8- LocalLlmGenerateTextResponse ,
9- PromptDataMessage ,
10- } from './llm-runner.js' ;
1+ import { AnthropicProviderOptions } from '@ai-sdk/anthropic' ;
2+ import { GoogleGenerativeAIProviderOptions } from '@ai-sdk/google' ;
3+ import { OpenAIResponsesProviderOptions } from '@ai-sdk/openai' ;
114import {
125 FilePart ,
136 generateObject ,
@@ -16,43 +9,31 @@ import {
169 ModelMessage ,
1710 SystemModelMessage ,
1811 TextPart ,
19- wrapLanguageModel ,
2012} from 'ai' ;
21- import { google , GoogleGenerativeAIProviderOptions } from '@ai-sdk/google' ;
22- import { anthropic , AnthropicProviderOptions } from '@ai-sdk/anthropic' ;
23- import { openai , OpenAIResponsesProviderOptions } from '@ai-sdk/openai' ;
2413import z from 'zod' ;
25- import { callWithTimeout } from '../utils/timeout.js' ;
26- import { combineAbortSignals } from '../utils/abort-signal.js' ;
27- import { anthropicThinkingWithStructuredResponseMiddleware } from './ai-sdk-claude-thinking-patch.js' ;
14+ import { combineAbortSignals } from '../../utils/abort-signal.js' ;
15+ import { callWithTimeout } from '../../utils/timeout.js' ;
16+ import {
17+ LlmRunner ,
18+ LocalLlmConstrainedOutputGenerateRequestOptions ,
19+ LocalLlmConstrainedOutputGenerateResponse ,
20+ LocalLlmGenerateFilesRequestOptions ,
21+ LocalLlmGenerateFilesResponse ,
22+ LocalLlmGenerateTextRequestOptions ,
23+ LocalLlmGenerateTextResponse ,
24+ PromptDataMessage ,
25+ } from '../llm-runner.js' ;
26+ import { ANTHROPIC_MODELS , getAiSdkModelOptionsForAnthropic } from './anthropic.js' ;
27+ import { getAiSdkModelOptionsForGoogle , GOOGLE_MODELS } from './google.js' ;
28+ import { getAiSdkModelOptionsForOpenAI , OPENAI_MODELS } from './openai.js' ;
2829
29- const SUPPORTED_MODELS = [
30- 'claude-opus-4.1-no-thinking' ,
31- 'claude-opus-4.1-with-thinking-16k' ,
32- 'claude-opus-4.1-with-thinking-32k' ,
33- 'claude-sonnet-4.5-no-thinking' ,
34- 'claude-sonnet-4.5-with-thinking-16k' ,
35- 'claude-sonnet-4.5-with-thinking-32k' ,
36- 'gemini-2.5-flash-lite' ,
37- 'gemini-2.5-flash' ,
38- 'gemini-2.5-flash-with-thinking-dynamic' ,
39- 'gemini-2.5-flash-with-thinking-16k' ,
40- 'gemini-2.5-flash-with-thinking-24k' ,
41- 'gemini-2.5-pro' ,
42- 'gemini-3-pro-preview' ,
43- 'gpt-5.1-no-thinking' ,
44- 'gpt-5.1-thinking-low' ,
45- 'gpt-5.1-thinking-high' ,
46- 'gpt-5.1-thinking-medium' ,
47- ] as const ;
30+ const SUPPORTED_MODELS = [ ...GOOGLE_MODELS , ...ANTHROPIC_MODELS , ...OPENAI_MODELS ] as const ;
4831
4932// Increased to a very high value as we rely on an actual timeout
5033// that aborts stuck LLM requests. WCS is targeting stability here;
5134// even if it involves many exponential backoff-waiting.
5235const DEFAULT_MAX_RETRIES = 100000 ;
5336
54- const claude16kThinkingTokenBudget = 16_000 ;
55- const claude32kThinkingTokenBudget = 32_000 ;
5637export class AiSDKRunner implements LlmRunner {
5738 displayName = 'AI SDK' ;
5839 id = 'ai-sdk' ;
@@ -164,100 +145,14 @@ export class AiSDKRunner implements LlmRunner {
164145 | { google : GoogleGenerativeAIProviderOptions }
165146 | { openai : OpenAIResponsesProviderOptions } ;
166147 } > {
167- const modelName = request . model as ( typeof SUPPORTED_MODELS ) [ number ] ;
168- switch ( modelName ) {
169- case 'claude-opus-4.1-no-thinking' :
170- case 'claude-opus-4.1-with-thinking-16k' :
171- case 'claude-opus-4.1-with-thinking-32k' :
172- case 'claude-sonnet-4.5-no-thinking' :
173- case 'claude-sonnet-4.5-with-thinking-16k' :
174- case 'claude-sonnet-4.5-with-thinking-32k' : {
175- const thinkingEnabled = modelName . includes ( '-with-thinking' ) ;
176- const thinkingBudget = ! thinkingEnabled
177- ? undefined
178- : modelName . endsWith ( '-32k' )
179- ? claude32kThinkingTokenBudget
180- : claude16kThinkingTokenBudget ;
181- const isOpus4_1Model = modelName . includes ( 'opus-4.1' ) ;
182- const model = anthropic ( isOpus4_1Model ? 'claude-opus-4-1' : 'claude-sonnet-4-5' ) ;
183- return {
184- model : thinkingEnabled
185- ? wrapLanguageModel ( {
186- model,
187- middleware : anthropicThinkingWithStructuredResponseMiddleware ,
188- } )
189- : model ,
190- providerOptions : {
191- anthropic : {
192- sendReasoning : thinkingEnabled ,
193- thinking : {
194- type : thinkingEnabled ? 'enabled' : 'disabled' ,
195- budgetTokens : thinkingBudget ,
196- } ,
197- } satisfies AnthropicProviderOptions ,
198- } ,
199- } ;
200- }
201- case 'gemini-2.5-flash-lite' :
202- case 'gemini-2.5-flash' :
203- case 'gemini-2.5-pro' :
204- case 'gemini-3-pro-preview' :
205- return {
206- model : google ( modelName ) ,
207- providerOptions : {
208- google : {
209- thinkingConfig : {
210- includeThoughts : request . thinkingConfig ?. includeThoughts ,
211- } ,
212- } satisfies GoogleGenerativeAIProviderOptions ,
213- } ,
214- } ;
215- case 'gemini-2.5-flash-with-thinking-dynamic' :
216- case 'gemini-2.5-flash-with-thinking-16k' :
217- case 'gemini-2.5-flash-with-thinking-24k' :
218- // -1 means "dynamic thinking budget":
219- // https://ai.google.dev/gemini-api/docs/thinking#set-budget.
220- let thinkingBudget = - 1 ;
221- if ( modelName . endsWith ( '-16k' ) ) {
222- thinkingBudget = 16_000 ;
223- } else if ( modelName . endsWith ( '-24k' ) ) {
224- thinkingBudget = 24_000 ;
225- }
226- return {
227- model : google ( 'gemini-2.5-flash' ) ,
228- providerOptions : {
229- google : {
230- thinkingConfig : {
231- thinkingBudget : thinkingBudget ,
232- includeThoughts : true ,
233- } ,
234- } satisfies GoogleGenerativeAIProviderOptions ,
235- } ,
236- } ;
237- case 'gpt-5.1-no-thinking' :
238- case 'gpt-5.1-thinking-low' :
239- case 'gpt-5.1-thinking-medium' :
240- case 'gpt-5.1-thinking-high' :
241- let reasoningEffort : string = 'none' ;
242- if ( modelName === 'gpt-5.1-thinking-high' ) {
243- reasoningEffort = 'high' ;
244- } else if ( modelName === 'gpt-5.1-thinking-medium' ) {
245- reasoningEffort = 'medium' ;
246- } else if ( modelName === 'gpt-5.1-thinking-low' ) {
247- reasoningEffort = 'low' ;
248- }
249- return {
250- model : openai ( 'gpt-5.1' ) ,
251- providerOptions : {
252- openai : {
253- reasoningEffort,
254- reasoningSummary : 'detailed' ,
255- } satisfies OpenAIResponsesProviderOptions ,
256- } ,
257- } ;
258- default :
259- throw new Error ( `Unexpected model in AI SDK runner: ${ request . model } .` ) ;
148+ const result =
149+ ( await getAiSdkModelOptionsForGoogle ( request . model ) ) ??
150+ ( await getAiSdkModelOptionsForAnthropic ( request . model ) ) ??
151+ ( await getAiSdkModelOptionsForOpenAI ( request . model ) ) ;
152+ if ( result === null ) {
153+ throw new Error ( `Unexpected unsupported model: ${ request . model } ` ) ;
260154 }
155+ return result ;
261156 }
262157
263158 private _convertRequestToMessagesList (
0 commit comments