pr_01m47d24b0e6n91zwymwxg0vpx/services/runner/src/model-env.test.ts

70 lines2,989 bytesCodeBlame
1import assert from "node:assert/strict";
2import { createServer } from "node:http";
3import { test } from "node:test";
4
5import { type ConfiguredModel, modelEnv } from "./model-env.ts";
6
7const model: ConfiguredModel = {
8 id: "balanced",
9 label: "Balanced",
10 description: "",
11 modelName: "Claude Sonnet 5.5",
12 model: "claude-sonnet-5-5",
13};
14const direct = { ANTHROPIC_API_KEY: "sk-test", AI_GATEWAY_ID: "", CLOUDFLARE_ACCOUNT_ID: "acct" };
15
16test("without a gateway, requests go to the provider directly", () => {
17 const vars = modelEnv(direct, model);
18 assert.equal(vars.ANTHROPIC_BASE_URL, undefined);
19 assert.equal(vars.ANTHROPIC_MODEL, "claude-sonnet-5-5");
20 assert.equal(vars.AGENT_MODEL_NAME, "Claude Sonnet 5.5 (Balanced)");
21});
22
23test("with a gateway, requests go through it", () => {
24 const vars = modelEnv({ ...direct, AI_GATEWAY_ID: "g1t" }, model);
25 assert.equal(vars.ANTHROPIC_BASE_URL, "https://gateway.ai.cloudflare.com/v1/acct/g1t/anthropic");
26 assert.equal(vars.ANTHROPIC_CUSTOM_HEADERS, undefined);
27});
28
29test("an authenticated gateway is sent its token", () => {
30 const vars = modelEnv({ ...direct, AI_GATEWAY_ID: "g1t", AI_GATEWAY_TOKEN: "tok" }, model);
31 assert.equal(vars.ANTHROPIC_CUSTOM_HEADERS, "cf-aig-authorization: Bearer tok");
32});
33
34// A stand-in for the gateway: what a sandbox's agent sends, given these
35// variables, arrives at the gateway's path with both credentials.
36test("a request built from these variables reaches a gateway as expected", async () => {
37 const seen: { url?: string; key?: string; gateway?: string; model?: string } = {};
38 const server = createServer((request, response) => {
39 let body = "";
40 request.on("data", (chunk) => (body += chunk));
41 request.on("end", () => {
42 seen.url = request.url;
43 seen.key = request.headers["x-api-key"] as string;
44 seen.gateway = request.headers["cf-aig-authorization"] as string;
45 seen.model = JSON.parse(body).model;
46 response.setHeader("content-type", "application/json");
47 response.end(JSON.stringify({ type: "message", content: [] }));
48 });
49 });
50 await new Promise<void>((resolve) => server.listen(0, resolve));
51 const { port } = server.address() as { port: number };
52
53 const vars = modelEnv({ ...direct, AI_GATEWAY_ID: "g1t", AI_GATEWAY_TOKEN: "tok" }, model);
54 // Same path as the real gateway, on the stand-in's address.
55 const base = vars.ANTHROPIC_BASE_URL.replace("https://gateway.ai.cloudflare.com", `http://localhost:${port}`);
56 const [name, value] = vars.ANTHROPIC_CUSTOM_HEADERS.split(": ");
57 await fetch(`${base}/v1/messages`, {
58 method: "POST",
59 headers: { "x-api-key": vars.ANTHROPIC_API_KEY, [name]: value, "content-type": "application/json" },
60 body: JSON.stringify({ model: vars.ANTHROPIC_MODEL, max_tokens: 1, messages: [] }),
61 });
62 server.close();
63
64 assert.deepEqual(seen, {
65 url: "/v1/acct/g1t/anthropic/v1/messages",
66 key: "sk-test",
67 gateway: "Bearer tok",
68 model: "claude-sonnet-5-5",
69 });
70});