feat(ai): pass provider-resolved env to APIs

This commit is contained in:
Mario Zechner
2026-06-23 13:39:39 +02:00
parent 5a8ea0bc81
commit 2cbce395fb
7 changed files with 97 additions and 5 deletions
+39
View File
@@ -102,6 +102,45 @@ describe("ImagesModels", () => {
expect(calls[1].options?.apiKey).toBe("explicit");
});
it("merges provider-resolved env into image options", async () => {
const calls: GenerateCall[] = [];
const models = createImagesModels();
models.setProvider(
createImagesProvider({
id: "p1",
auth: {
apiKey: {
name: "Test key",
resolve: async () => ({
auth: { apiKey: "provider-key" },
env: { PROVIDER_ONLY: "provider", SHARED: "provider" },
}),
},
},
models: [testImageModel("p1", "model-a")],
api: {
generateImages: async (model, _context, options) => {
calls.push({ model, options });
return okResult(model);
},
},
}),
);
const model = models.getModel("p1", "model-a")!;
await models.generateImages(model, context, {
apiKey: "request-key",
env: { REQUEST_ONLY: "request", SHARED: "request" },
});
expect(calls[0].options?.apiKey).toBe("request-key");
expect(calls[0].options?.env).toEqual({
PROVIDER_ONLY: "provider",
REQUEST_ONLY: "request",
SHARED: "request",
});
});
it("returns an error result for unknown providers and unconfigured auth rejections", async () => {
const models = createImagesModels({ authContext: fakeAuthContext({}) });
const ghost = await models.generateImages(testImageModel("ghost", "m"), context);
+41
View File
@@ -168,6 +168,47 @@ describe("createProvider", () => {
expect(calls).toEqual(["a:model-a", "b:model-b"]);
});
it("merges provider-resolved env into stream options", async () => {
let capturedEnv: Record<string, string> | undefined;
let capturedApiKey: string | undefined;
const envModel = { ...testModel("api-a", "model-a"), provider: "env-provider" };
const provider = createProvider({
id: "env-provider",
auth: {
apiKey: {
name: "Test",
resolve: async () => ({
auth: { apiKey: "provider-key" },
env: { PROVIDER_ONLY: "provider", SHARED: "provider" },
}),
},
},
models: [envModel],
api: {
stream: (model, _context, options) => {
capturedEnv = options?.env;
capturedApiKey = options?.apiKey;
return recordingStreams("a", []).stream(model, _context, options);
},
streamSimple: (model, _context, options) => {
capturedEnv = options?.env;
capturedApiKey = options?.apiKey;
return recordingStreams("a", []).streamSimple(model, _context, options);
},
},
});
const models = createModels();
models.setProvider(provider);
await models.completeSimple(envModel, context, {
apiKey: "request-key",
env: { REQUEST_ONLY: "request", SHARED: "request" },
});
expect(capturedApiKey).toBe("request-key");
expect(capturedEnv).toEqual({ PROVIDER_ONLY: "provider", REQUEST_ONLY: "request", SHARED: "request" });
});
it("produces a stream error for a model whose api has no implementation", async () => {
const provider = createProvider({
id: "mixed",