@@ -14,7 +14,11 @@ import {
1414 OPENAI_API_BASE_URL ,
1515 firstClassProviderById ,
1616} from "../../packages/first-class-providers/src/index.js" ;
17- import { normalizeOpenAICompatibleBaseURL , type Settings } from "./settings.js" ;
17+ import {
18+ normalizeOpenAICompatibleBaseURL ,
19+ type ProviderSettings ,
20+ type Settings ,
21+ } from "./settings.js" ;
1822import {
1923 resolveSessionEffort ,
2024 type ReasoningEffort ,
@@ -43,6 +47,19 @@ function catalogEntry(
4347 return catalog . find ( ( e ) => e . name === provider ) ;
4448}
4549
50+ // Resolve the API key to send for a provider: the catalog entry wins, then
51+ // the operator's settings row, else the field is omitted entirely.
52+ function apiKeyFor (
53+ entry : ProviderCatalogEntry | undefined ,
54+ providerSettings : ProviderSettings | undefined ,
55+ ) : { apiKey : string } | Record < string , never > {
56+ return entry ?. apiKey !== undefined
57+ ? { apiKey : entry . apiKey }
58+ : providerSettings ?. apiKey !== undefined
59+ ? { apiKey : providerSettings . apiKey }
60+ : { } ;
61+ }
62+
4663// First-party OpenAI reasoning models reject `max_tokens` and require
4764// `max_completion_tokens`. The requirement is declared per model on the
4865// first-class OpenAI API-key path's `maxCompletionTokensModels` field — never
@@ -129,11 +146,7 @@ export function buildInferenceSourceForRef(
129146 ) {
130147 return buildGoSource ( {
131148 id : ref . provider ,
132- ...( entry ?. apiKey !== undefined
133- ? { apiKey : entry . apiKey }
134- : providerSettings ?. apiKey !== undefined
135- ? { apiKey : providerSettings . apiKey }
136- : { } ) ,
149+ ...apiKeyFor ( entry , providerSettings ) ,
137150 model : ref . model ,
138151 sessionId : ctx . sessionId ,
139152 ...( effort !== undefined ? { reasoningEffort : effort } : { } ) ,
@@ -147,11 +160,7 @@ export function buildInferenceSourceForRef(
147160 ) {
148161 return buildZenSource ( {
149162 id : ref . provider ,
150- ...( entry ?. apiKey !== undefined
151- ? { apiKey : entry . apiKey }
152- : providerSettings ?. apiKey !== undefined
153- ? { apiKey : providerSettings . apiKey }
154- : { } ) ,
163+ ...apiKeyFor ( entry , providerSettings ) ,
155164 model : ref . model ,
156165 sessionId : ctx . sessionId ,
157166 ...( effort !== undefined ? { reasoningEffort : effort } : { } ) ,
@@ -161,23 +170,15 @@ export function buildInferenceSourceForRef(
161170 return buildAnthropicSource ( {
162171 id : ref . provider ,
163172 baseURL,
164- ...( entry ?. apiKey !== undefined
165- ? { apiKey : entry . apiKey }
166- : providerSettings ?. apiKey !== undefined
167- ? { apiKey : providerSettings . apiKey }
168- : { } ) ,
173+ ...apiKeyFor ( entry , providerSettings ) ,
169174 model : ref . model ,
170175 } ) ;
171176 }
172177 if ( entry ?. bifrostVirtualKey === true ) {
173178 return buildBifrostSource ( {
174179 id : ref . provider ,
175180 baseURL,
176- ...( entry ?. apiKey !== undefined
177- ? { apiKey : entry . apiKey }
178- : providerSettings ?. apiKey !== undefined
179- ? { apiKey : providerSettings . apiKey }
180- : { } ) ,
181+ ...apiKeyFor ( entry , providerSettings ) ,
181182 model : ref . model ,
182183 ...( effort !== undefined ? { reasoningEffort : effort } : { } ) ,
183184 } ) ;
@@ -210,11 +211,7 @@ export function buildInferenceSourceForRef(
210211 return buildOpenAISource ( {
211212 id : ref . provider ,
212213 baseURL,
213- ...( entry ?. apiKey !== undefined
214- ? { apiKey : entry . apiKey }
215- : providerSettings ?. apiKey !== undefined
216- ? { apiKey : providerSettings . apiKey }
217- : { } ) ,
214+ ...apiKeyFor ( entry , providerSettings ) ,
218215 model : ref . model ,
219216 ...( customEffort !== undefined ? { reasoningEffort : customEffort } : { } ) ,
220217 ...( maxTokens !== undefined ? { maxTokens } : { } ) ,
0 commit comments