Skip to content

Commit 76d62d5

Browse files
committed
fix: treat provider-default auth mode as fallback-triggering no-auth
1 parent 9b9141a commit 76d62d5

2 files changed

Lines changed: 103 additions & 3 deletions

File tree

src/cron/isolated-agent/model-preflight.runtime.test.ts

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ describe("preflightCronModelProvider", () => {
8888
}
8989
if (request.auth) {
9090
const auth = request.auth;
91-
if (auth.mode === "authorization-bearer") {
91+
if (auth.mode === "provider-default") {
92+
result.auth = { mode: "provider-default" };
93+
hasContent = true;
94+
} else if (auth.mode === "authorization-bearer") {
9295
const token = typeof auth.token === "string" ? auth.token.trim() : "";
9396
if (token) {
9497
result.auth = { mode: "authorization-bearer", token };
@@ -1192,6 +1195,99 @@ describe("preflightCronModelProvider", () => {
11921195
);
11931196
});
11941197

1198+
it("treats provider-default auth mode as fallback-triggering no-auth", async () => {
1199+
mockReachableResponse(200);
1200+
resolveApiKeyForProviderMock.mockResolvedValueOnce({
1201+
apiKey: "provider-default-key",
1202+
mode: "api-key",
1203+
source: "env",
1204+
});
1205+
1206+
const result = await preflightCronModelProvider({
1207+
cfg: {
1208+
models: {
1209+
providers: {
1210+
test: {
1211+
api: "openai-completions",
1212+
baseUrl: "http://127.0.0.1:8080",
1213+
request: { auth: { mode: "provider-default" } },
1214+
models: [],
1215+
},
1216+
},
1217+
},
1218+
},
1219+
provider: "test",
1220+
model: "test-model",
1221+
});
1222+
1223+
expect(result).toEqual({ status: "available" });
1224+
// Primary call: provider-default auth passed to resolver
1225+
expect(resolveProviderRequestHeadersMock).toHaveBeenNthCalledWith(
1226+
1,
1227+
expect.objectContaining({
1228+
request: { auth: { mode: "provider-default" } },
1229+
}),
1230+
);
1231+
// Fallback call: resolved bearer auth replaces provider-default
1232+
expect(resolveProviderRequestHeadersMock).toHaveBeenNthCalledWith(
1233+
2,
1234+
expect.objectContaining({
1235+
request: {
1236+
auth: { mode: "authorization-bearer", token: "provider-default-key" },
1237+
},
1238+
}),
1239+
);
1240+
const request = requireFetchPreflightRequest();
1241+
expect(request.init?.headers).toHaveProperty("Authorization", "Bearer provider-default-key");
1242+
});
1243+
1244+
it("preserves request.headers in fallback when provider-default mode is configured", async () => {
1245+
mockReachableResponse(200);
1246+
resolveApiKeyForProviderMock.mockResolvedValueOnce({
1247+
apiKey: "pd-key-with-headers",
1248+
mode: "api-key",
1249+
source: "env",
1250+
});
1251+
1252+
const result = await preflightCronModelProvider({
1253+
cfg: {
1254+
models: {
1255+
providers: {
1256+
test: {
1257+
api: "openai-completions",
1258+
baseUrl: "http://127.0.0.1:8080",
1259+
headers: { "X-Proxy-Route": "us-east" },
1260+
request: {
1261+
auth: { mode: "provider-default" },
1262+
headers: { "X-Tenant-Id": "tenant-xyz" },
1263+
},
1264+
models: [],
1265+
},
1266+
},
1267+
},
1268+
},
1269+
provider: "test",
1270+
model: "test-model",
1271+
});
1272+
1273+
expect(result).toEqual({ status: "available" });
1274+
// Fallback call: request.headers preserved, auth replaced with bearer
1275+
expect(resolveProviderRequestHeadersMock).toHaveBeenNthCalledWith(
1276+
2,
1277+
expect.objectContaining({
1278+
defaultHeaders: { "X-Proxy-Route": "us-east" },
1279+
request: {
1280+
headers: { "X-Tenant-Id": "tenant-xyz" },
1281+
auth: { mode: "authorization-bearer", token: "pd-key-with-headers" },
1282+
},
1283+
}),
1284+
);
1285+
const request = requireFetchPreflightRequest();
1286+
expect(request.init?.headers).toHaveProperty("Authorization", "Bearer pd-key-with-headers");
1287+
expect(request.init?.headers).toHaveProperty("X-Tenant-Id", "tenant-xyz");
1288+
expect(request.init?.headers).toHaveProperty("X-Proxy-Route", "us-east");
1289+
});
1290+
11951291
// ── Provider-level headers (P1) — verify providerConfig.headers pass through defaultHeaders ──
11961292

11971293
it("sends provider-level headers when providerConfig.headers is set", async () => {

src/cron/isolated-agent/model-preflight.runtime.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,12 @@ export async function preflightCronModelProvider(params: {
253253
// requestOverrides so proxy/tenant headers are not lost when fallback auth
254254
// is applied. Skip when request auth was provided — the resolver already
255255
// handled it, and adding a Bearer token from the credential profile would
256-
// incorrectly override custom header-mode auth.
257-
if (!requestOverrides?.auth) {
256+
// incorrectly override custom header-mode auth. provider-default mode is
257+
// treated as "use default provider auth" — the resolver does not inject
258+
// headers for it, so fallback to credential lookup.
259+
const hasExplicitAuth =
260+
requestOverrides?.auth && requestOverrides.auth.mode !== "provider-default";
261+
if (!hasExplicitAuth) {
258262
try {
259263
const resolved = await resolveApiKeyForProvider({
260264
provider: params.provider,

0 commit comments

Comments
 (0)