@@ -8,10 +8,11 @@ import {
88 checkLiveUserInput ,
99 getLiveUserInputIds ,
1010} from '@codebuff/agent-runtime/live-user-inputs'
11- import { PROFIT_MARGIN } from '@codebuff/common/old-constants'
11+ import { models , PROFIT_MARGIN } from '@codebuff/common/old-constants'
1212import { buildArray } from '@codebuff/common/util/array'
1313import { getErrorObject } from '@codebuff/common/util/error'
1414import { convertCbToModelMessages } from '@codebuff/common/util/messages'
15+ import { isExplicitlyDefinedModel } from '@codebuff/common/util/model-utils'
1516import { StopSequenceHandler } from '@codebuff/common/util/stop-sequence'
1617import { streamText , APICallError , generateText , generateObject } from 'ai'
1718
@@ -24,8 +25,8 @@ import type {
2425 PromptAiSdkStructuredInput ,
2526 PromptAiSdkStructuredOutput ,
2627} from '@codebuff/common/types/contracts/llm'
27- import type { Logger } from '@codebuff/common/types/contracts/logger'
2828import type { ParamsOf } from '@codebuff/common/types/function-params'
29+ import type { JSONObject } from '@codebuff/common/types/json'
2930import type { OpenRouterProviderOptions } from '@openrouter/ai-sdk-provider'
3031import type z from 'zod/v4'
3132
@@ -37,18 +38,59 @@ type OpenRouterUsageAccounting = {
3738 }
3839}
3940
41+ // Provider routing documentation: https://openrouter.ai/docs/features/provider-routing
42+ const providerOrder = {
43+ [ models . openrouter_claude_sonnet_4 ] : [
44+ 'Google' ,
45+ 'Anthropic' ,
46+ 'Amazon Bedrock' ,
47+ ] ,
48+ [ models . openrouter_claude_sonnet_4_5 ] : [
49+ 'Google' ,
50+ 'Anthropic' ,
51+ 'Amazon Bedrock' ,
52+ ] ,
53+ [ models . openrouter_claude_opus_4 ] : [ 'Google' , 'Anthropic' ] ,
54+ }
55+
4056function calculateUsedCredits ( params : { costDollars : number } ) : number {
4157 const { costDollars } = params
4258
4359 return Math . round ( costDollars * ( 1 + PROFIT_MARGIN ) * 100 )
4460}
4561
62+ function getProviderOptions ( params : {
63+ model : string
64+ runId : string
65+ clientSessionId : string
66+ } ) : { codebuff : JSONObject } {
67+ const { model, runId, clientSessionId } = params
68+
69+ // Set allow_fallbacks based on whether model is explicitly defined
70+ const isExplicitlyDefined = isExplicitlyDefinedModel ( model )
71+
72+ return {
73+ // Could either be "codebuff" or "openaiCompatible"
74+ codebuff : {
75+ // All values here get appended to the request body
76+ codebuff_metadata : {
77+ run_id : runId ,
78+ client_id : clientSessionId ,
79+ } ,
80+ transforms : [ 'middle-out' ] ,
81+ provider : {
82+ order : providerOrder [ model as keyof typeof providerOrder ] ,
83+ allow_fallbacks : ! isExplicitlyDefined ,
84+ } ,
85+ } ,
86+ }
87+ }
88+
4689function getAiSdkModel ( params : {
4790 apiKey : string
4891 model : string
49- logger : Logger
5092} ) : LanguageModelV2 {
51- const { apiKey, model, logger } = params
93+ const { apiKey, model } = params
5294
5395 const openrouterUsage : OpenRouterUsageAccounting = {
5496 cost : null ,
@@ -58,7 +100,7 @@ function getAiSdkModel(params: {
58100 }
59101
60102 const codebuffBackendModel = new OpenAICompatibleChatLanguageModel ( model , {
61- provider : 'codebuff.chat ' ,
103+ provider : 'codebuff' ,
62104 url : ( { path : endpoint } ) =>
63105 new URL ( path . join ( '/api/v1' , endpoint ) , WEBSITE_URL ) . toString ( ) ,
64106 headers : ( ) => ( {
@@ -132,14 +174,7 @@ export async function* promptAiSdkStream(
132174 prompt : undefined ,
133175 model : aiSDKModel ,
134176 messages : convertCbToModelMessages ( params ) ,
135- providerOptions : {
136- codebuff : {
137- codebuff_metadata : {
138- run_id : params . runId ,
139- client_id : params . clientSessionId ,
140- } ,
141- } ,
142- } ,
177+ providerOptions : getProviderOptions ( params ) ,
143178 } )
144179
145180 let content = ''
@@ -285,14 +320,7 @@ export async function promptAiSdk(
285320 prompt : undefined ,
286321 model : aiSDKModel ,
287322 messages : convertCbToModelMessages ( params ) ,
288- providerOptions : {
289- codebuff : {
290- codebuff_metadata : {
291- run_id : params . runId ,
292- client_id : params . clientSessionId ,
293- } ,
294- } ,
295- } ,
323+ providerOptions : getProviderOptions ( params ) ,
296324 } )
297325 const content = response . text
298326
@@ -343,14 +371,7 @@ export async function promptAiSdkStructured<T>(
343371 model : aiSDKModel ,
344372 output : 'object' ,
345373 messages : convertCbToModelMessages ( params ) ,
346- providerOptions : {
347- codebuff : {
348- codebuff_metadata : {
349- run_id : params . runId ,
350- client_id : params . clientSessionId ,
351- } ,
352- } ,
353- } ,
374+ providerOptions : getProviderOptions ( params ) ,
354375 } )
355376
356377 const content = response . object
0 commit comments