fix(core): ignore empty provider api keys

This commit is contained in:
Dax Raad
2026-07-20 15:29:13 -04:00
parent 79d0077f63
commit 0b2e2cbab0
2 changed files with 47 additions and 6 deletions
+5 -6
View File
@@ -182,12 +182,11 @@ export const fromCatalogModel = (
credential?: Credential.Value,
dependencies: Dependencies = {},
): Effect.Effect<Model, UnsupportedPackageError> => {
const resolved =
credential?.type !== "key" || credential.metadata === undefined
? model
: produce(model, (draft) => {
draft.body = ProviderV2.mergeOverlay(draft.body, credential.metadata)
})
const resolved = produce(model, (draft) => {
if (draft.settings?.apiKey === "") delete draft.settings.apiKey
if (credential?.type === "key" && credential.metadata !== undefined)
draft.body = ProviderV2.mergeOverlay(draft.body, credential.metadata)
})
const packageName = ProviderV2.packageName(resolved.package)
const key = apiKey(resolved, credential)
@@ -78,6 +78,25 @@ describe("SessionRunnerModel", () => {
}),
)
it.effect("treats an empty configured API key as omitted", () =>
Effect.gen(function* () {
const resolved = yield* SessionRunnerModel.fromCatalogModel(
model(ProviderV2.aisdk("@ai-sdk/openai"), {
settings: { apiKey: "", baseURL: "https://openai.example/v1" },
}),
)
const headers = yield* resolved.route.auth.apply({
request: LLM.request({ model: resolved, prompt: "Hello" }),
method: "POST",
url: "https://openai.example/v1/responses",
body: "{}",
headers: Headers.empty,
})
expect(headers.authorization).toBeUndefined()
}),
)
it.effect("uses merged API settings for OpenAI-compatible auth and request defaults", () =>
Effect.gen(function* () {
const resolved = yield* SessionRunnerModel.fromCatalogModel(
@@ -637,6 +656,29 @@ describe("SessionRunnerModel", () => {
}),
)
it.effect("drops an empty API key before loading an AISDK package", () =>
Effect.gen(function* () {
const native = yield* SessionRunnerModel.fromCatalogModel(
model(ProviderV2.aisdk("@ai-sdk/openai"), {
settings: { baseURL: "https://openai.example/v1" },
}),
)
yield* SessionRunnerModel.fromCatalogModel(
model(ProviderV2.aisdk("@ai-sdk/google"), {
settings: { apiKey: "", baseURL: "https://google.example/v1" },
}),
undefined,
{
loadAISDK: (runtime) =>
Effect.sync(() => {
expect(runtime.settings).not.toHaveProperty("apiKey")
return native
}),
},
)
}),
)
it.effect("reports whether a catalog model declares a provider package", () =>
Effect.sync(() => {
expect(SessionRunnerModel.supported(model(ProviderV2.aisdk("@ai-sdk/openai")))).toBe(true)