Explorar el Código

fix(core): ignore empty provider api keys

Dax Raad hace 3 semanas
padre
commit
0b2e2cbab0

+ 5 - 6
packages/core/src/session/runner/model.ts

@@ -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)
 

+ 42 - 0
packages/core/test/session-runner-model.test.ts

@@ -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)