@copilotkit/aimock 1.35.1 → 1.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +22 -0
  3. package/dist/agui-types.d.cts.map +1 -1
  4. package/dist/agui-types.d.ts.map +1 -1
  5. package/dist/cli.cjs +2 -0
  6. package/dist/cli.cjs.map +1 -1
  7. package/dist/cli.js +2 -0
  8. package/dist/cli.js.map +1 -1
  9. package/dist/config-loader.cjs +9 -0
  10. package/dist/config-loader.cjs.map +1 -1
  11. package/dist/config-loader.d.cts +4 -0
  12. package/dist/config-loader.d.cts.map +1 -1
  13. package/dist/config-loader.d.ts +4 -0
  14. package/dist/config-loader.d.ts.map +1 -1
  15. package/dist/config-loader.js +9 -0
  16. package/dist/config-loader.js.map +1 -1
  17. package/dist/fal-audio.cjs +1 -0
  18. package/dist/fal-audio.cjs.map +1 -1
  19. package/dist/fal-audio.js +1 -0
  20. package/dist/fal-audio.js.map +1 -1
  21. package/dist/fal.cjs +4 -1
  22. package/dist/fal.cjs.map +1 -1
  23. package/dist/fal.d.cts.map +1 -1
  24. package/dist/fal.d.ts.map +1 -1
  25. package/dist/fal.js +4 -1
  26. package/dist/fal.js.map +1 -1
  27. package/dist/provider-auth.cjs +170 -0
  28. package/dist/provider-auth.cjs.map +1 -0
  29. package/dist/provider-auth.js +168 -0
  30. package/dist/provider-auth.js.map +1 -0
  31. package/dist/recorder.cjs +5 -1
  32. package/dist/recorder.cjs.map +1 -1
  33. package/dist/recorder.d.cts.map +1 -1
  34. package/dist/recorder.d.ts.map +1 -1
  35. package/dist/recorder.js +5 -1
  36. package/dist/recorder.js.map +1 -1
  37. package/dist/types.d.cts +13 -0
  38. package/dist/types.d.cts.map +1 -1
  39. package/dist/types.d.ts +13 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/vector-types.d.cts.map +1 -1
  42. package/dist/vector-types.d.ts.map +1 -1
  43. package/package.json +1 -1
@@ -0,0 +1,168 @@
1
+ //#region src/provider-auth.ts
2
+ /**
3
+ * Default marker prefix identifying a "dummy" credential that a caller sends
4
+ * only to satisfy an SDK's non-empty API-key requirement (e.g. `sk-aimock-...`).
5
+ * A caller credential that is absent OR begins with this prefix is treated as a
6
+ * placeholder that aimock is free to override with its own built-in upstream key.
7
+ * A caller credential that does NOT begin with this prefix is treated as a real
8
+ * key and forwarded verbatim (the caller overrides aimock).
9
+ *
10
+ * Overridable via the `AIMOCK_DUMMY_KEY_MARKER` env var for setups that mint
11
+ * placeholder keys under a different prefix.
12
+ */
13
+ const DEFAULT_DUMMY_KEY_MARKER = "sk-aimock-";
14
+ /** Resolve the active dummy-key marker, honoring the env override. */
15
+ function getDummyKeyMarker() {
16
+ const override = process.env.AIMOCK_DUMMY_KEY_MARKER;
17
+ return override && override.length > 0 ? override : DEFAULT_DUMMY_KEY_MARKER;
18
+ }
19
+ const PROVIDER_AUTH_SCHEMES = {
20
+ openai: { kind: "bearer" },
21
+ openrouter: { kind: "bearer" },
22
+ cohere: { kind: "bearer" },
23
+ grok: { kind: "bearer" },
24
+ ollama: { kind: "bearer" },
25
+ anthropic: { kind: "x-api-key" },
26
+ gemini: { kind: "x-goog-api-key" },
27
+ "gemini-interactions": { kind: "x-goog-api-key" },
28
+ veo: { kind: "x-goog-api-key" },
29
+ azure: { kind: "api-key" },
30
+ elevenlabs: { kind: "xi-api-key" },
31
+ fal: { kind: "fal-key" }
32
+ };
33
+ /**
34
+ * Case-insensitively delete a header from a forward-header map, returning the
35
+ * value that was present (if any). Header maps preserve the original casing of
36
+ * incoming headers, so we can't assume a canonical key.
37
+ */
38
+ function takeHeader(headers, name) {
39
+ const lowerName = name.toLowerCase();
40
+ let found;
41
+ for (const key of Object.keys(headers)) if (key.toLowerCase() === lowerName) {
42
+ found = headers[key];
43
+ delete headers[key];
44
+ }
45
+ return found;
46
+ }
47
+ /**
48
+ * Extract the caller's credential value for a given auth scheme from the
49
+ * forwarded headers, if present. For bearer, strips the `Bearer ` prefix.
50
+ */
51
+ function readCallerCredential(headers, scheme) {
52
+ if (scheme.kind === "bearer" || scheme.kind === "fal-key") {
53
+ const raw = scanHeader(headers, "authorization");
54
+ if (raw === void 0) return void 0;
55
+ const prefix = scheme.kind === "fal-key" ? "Key" : "Bearer";
56
+ const match = new RegExp(`^\\s*${prefix}\\s+(.+)$`, "i").exec(raw);
57
+ return match ? match[1].trim() : raw.trim();
58
+ }
59
+ return scanHeader(headers, authHeaderName(scheme));
60
+ }
61
+ /**
62
+ * The wire header name a non-Authorization scheme carries its credential in.
63
+ * (bearer/fal-key both use `Authorization` and are handled separately.)
64
+ */
65
+ function authHeaderName(scheme) {
66
+ switch (scheme.kind) {
67
+ case "x-api-key": return "x-api-key";
68
+ case "x-goog-api-key": return "x-goog-api-key";
69
+ case "api-key": return "api-key";
70
+ case "xi-api-key": return "xi-api-key";
71
+ case "bearer":
72
+ case "fal-key": return "authorization";
73
+ }
74
+ }
75
+ /** Case-insensitive header lookup that does not mutate the map. */
76
+ function scanHeader(headers, name) {
77
+ const lowerName = name.toLowerCase();
78
+ for (const key of Object.keys(headers)) if (key.toLowerCase() === lowerName) return headers[key];
79
+ }
80
+ /**
81
+ * Decide whether aimock should override the caller's credential with its own
82
+ * built-in key. Override when the caller sent no credential OR sent a dummy
83
+ * placeholder (prefixed with the active marker). A real caller key is left
84
+ * untouched so the caller can always override aimock.
85
+ */
86
+ function shouldOverride(callerCredential, marker) {
87
+ if (callerCredential === void 0 || callerCredential.length === 0) return true;
88
+ return callerCredential.startsWith(marker);
89
+ }
90
+ /**
91
+ * Inject aimock's built-in upstream credential into the forwarded headers when
92
+ * appropriate (opt-in, backward-compatible). Mutates `forwardHeaders` in place
93
+ * and may mutate `target` (query-param schemes; none currently).
94
+ *
95
+ * Precedence:
96
+ * - No built-in key configured for this provider → no-op (forward verbatim).
97
+ * - Provider not a static-key scheme → no-op (Bedrock SigV4 / Vertex AI OAuth).
98
+ * - Caller credential absent or dummy-prefixed → inject built-in key.
99
+ * - Caller credential is a real key → forward it unchanged.
100
+ *
101
+ * @param forwardHeaders headers already built by buildForwardHeaders(req)
102
+ * @param target upstream URL (reserved for query-param auth schemes)
103
+ * @param providerKey which provider this request is routed to
104
+ * @param builtinKey aimock's configured key for this provider (if any)
105
+ */
106
+ function applyProviderAuth(forwardHeaders, target, providerKey, builtinKey) {
107
+ if (!builtinKey) return;
108
+ const scheme = PROVIDER_AUTH_SCHEMES[providerKey];
109
+ if (!scheme) return;
110
+ const marker = getDummyKeyMarker();
111
+ if (!shouldOverride(readCallerCredential(forwardHeaders, scheme), marker)) return;
112
+ switch (scheme.kind) {
113
+ case "bearer":
114
+ takeHeader(forwardHeaders, "authorization");
115
+ forwardHeaders["Authorization"] = `Bearer ${builtinKey}`;
116
+ break;
117
+ case "fal-key":
118
+ takeHeader(forwardHeaders, "authorization");
119
+ forwardHeaders["Authorization"] = `Key ${builtinKey}`;
120
+ break;
121
+ case "x-api-key":
122
+ takeHeader(forwardHeaders, "x-api-key");
123
+ forwardHeaders["x-api-key"] = builtinKey;
124
+ break;
125
+ case "x-goog-api-key":
126
+ takeHeader(forwardHeaders, "x-goog-api-key");
127
+ forwardHeaders["x-goog-api-key"] = builtinKey;
128
+ break;
129
+ case "api-key":
130
+ takeHeader(forwardHeaders, "api-key");
131
+ forwardHeaders["api-key"] = builtinKey;
132
+ break;
133
+ case "xi-api-key":
134
+ takeHeader(forwardHeaders, "xi-api-key");
135
+ forwardHeaders["xi-api-key"] = builtinKey;
136
+ break;
137
+ }
138
+ }
139
+ /**
140
+ * Read per-provider built-in keys from the environment. Returns undefined when
141
+ * no provider key is configured so the feature stays fully inert by default.
142
+ *
143
+ * Each wired static-key provider reads `AIMOCK_PROVIDER_<PROVIDER>_KEY`. An
144
+ * empty-string value is treated as unset (existing truthiness pattern), keeping
145
+ * the feature inert. `gemini-interactions` is not read here: it reuses the
146
+ * Gemini key via the lookup-key remap in `proxyAndRecord`. Signed/OAuth
147
+ * providers (`bedrock`, `vertexai`) have no env var — aimock never rewrites
148
+ * their auth.
149
+ */
150
+ function readProviderKeysFromEnv(env = process.env) {
151
+ const keys = {};
152
+ if (env.AIMOCK_PROVIDER_OPENAI_KEY) keys.openai = env.AIMOCK_PROVIDER_OPENAI_KEY;
153
+ if (env.AIMOCK_PROVIDER_ANTHROPIC_KEY) keys.anthropic = env.AIMOCK_PROVIDER_ANTHROPIC_KEY;
154
+ if (env.AIMOCK_PROVIDER_GEMINI_KEY) keys.gemini = env.AIMOCK_PROVIDER_GEMINI_KEY;
155
+ if (env.AIMOCK_PROVIDER_OPENROUTER_KEY) keys.openrouter = env.AIMOCK_PROVIDER_OPENROUTER_KEY;
156
+ if (env.AIMOCK_PROVIDER_COHERE_KEY) keys.cohere = env.AIMOCK_PROVIDER_COHERE_KEY;
157
+ if (env.AIMOCK_PROVIDER_GROK_KEY) keys.grok = env.AIMOCK_PROVIDER_GROK_KEY;
158
+ if (env.AIMOCK_PROVIDER_OLLAMA_KEY) keys.ollama = env.AIMOCK_PROVIDER_OLLAMA_KEY;
159
+ if (env.AIMOCK_PROVIDER_VEO_KEY) keys.veo = env.AIMOCK_PROVIDER_VEO_KEY;
160
+ if (env.AIMOCK_PROVIDER_AZURE_KEY) keys.azure = env.AIMOCK_PROVIDER_AZURE_KEY;
161
+ if (env.AIMOCK_PROVIDER_ELEVENLABS_KEY) keys.elevenlabs = env.AIMOCK_PROVIDER_ELEVENLABS_KEY;
162
+ if (env.AIMOCK_PROVIDER_FAL_KEY) keys.fal = env.AIMOCK_PROVIDER_FAL_KEY;
163
+ return Object.keys(keys).length > 0 ? keys : void 0;
164
+ }
165
+
166
+ //#endregion
167
+ export { applyProviderAuth, readProviderKeysFromEnv };
168
+ //# sourceMappingURL=provider-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-auth.js","names":[],"sources":["../src/provider-auth.ts"],"sourcesContent":["import type { RecordProviderKey } from \"./types.js\";\n\n/**\n * Default marker prefix identifying a \"dummy\" credential that a caller sends\n * only to satisfy an SDK's non-empty API-key requirement (e.g. `sk-aimock-...`).\n * A caller credential that is absent OR begins with this prefix is treated as a\n * placeholder that aimock is free to override with its own built-in upstream key.\n * A caller credential that does NOT begin with this prefix is treated as a real\n * key and forwarded verbatim (the caller overrides aimock).\n *\n * Overridable via the `AIMOCK_DUMMY_KEY_MARKER` env var for setups that mint\n * placeholder keys under a different prefix.\n */\nexport const DEFAULT_DUMMY_KEY_MARKER = \"sk-aimock-\";\n\n/** Resolve the active dummy-key marker, honoring the env override. */\nexport function getDummyKeyMarker(): string {\n const override = process.env.AIMOCK_DUMMY_KEY_MARKER;\n return override && override.length > 0 ? override : DEFAULT_DUMMY_KEY_MARKER;\n}\n\n/**\n * How a given provider carries its API credential on the wire. aimock injects\n * its built-in key using the provider's native scheme so the upstream accepts\n * it. Providers whose auth is a signed/exchanged credential (Bedrock SigV4,\n * Vertex AI OAuth) are deliberately absent — those are NOT simple static-key\n * schemes, so aimock never rewrites their auth and always forwards the caller's\n * credential unchanged.\n *\n * Scheme kinds (all static long-lived keys):\n * - bearer `Authorization: Bearer <key>` (OpenAI, OpenRouter, Cohere, Grok/xAI, Ollama)\n * - fal-key `Authorization: Key <key>` (fal.ai — note the `Key ` prefix, NOT `Bearer`)\n * - x-api-key `x-api-key: <key>` (Anthropic)\n * - x-goog-api-key `x-goog-api-key: <key>` (Gemini, Gemini Interactions, Veo)\n * - api-key `api-key: <key>` (Azure OpenAI static-key auth)\n * - xi-api-key `xi-api-key: <key>` (ElevenLabs)\n *\n * Note on Azure: Azure OpenAI also supports Microsoft Entra ID `Authorization:\n * Bearer <token>` OAuth. aimock only ever injects the static `api-key` header,\n * and a real Entra bearer token from the caller is never dummy-prefixed, so it\n * is always forwarded verbatim (the caller overrides aimock).\n */\ntype AuthScheme =\n | { kind: \"bearer\" } // Authorization: Bearer <key>\n | { kind: \"fal-key\" } // Authorization: Key <key>\n | { kind: \"x-api-key\" } // x-api-key: <key>\n | { kind: \"x-goog-api-key\" } // x-goog-api-key: <key>\n | { kind: \"api-key\" } // api-key: <key>\n | { kind: \"xi-api-key\" }; // xi-api-key: <key>\n\nconst PROVIDER_AUTH_SCHEMES: Partial<Record<RecordProviderKey, AuthScheme>> = {\n // Bearer-token providers.\n openai: { kind: \"bearer\" },\n openrouter: { kind: \"bearer\" },\n cohere: { kind: \"bearer\" },\n grok: { kind: \"bearer\" }, // xAI\n ollama: { kind: \"bearer\" }, // Ollama Cloud / bearer-gated Ollama servers\n // Anthropic.\n anthropic: { kind: \"x-api-key\" },\n // Google (Gemini + Veo) use the x-goog-api-key header scheme.\n gemini: { kind: \"x-goog-api-key\" },\n \"gemini-interactions\": { kind: \"x-goog-api-key\" },\n veo: { kind: \"x-goog-api-key\" },\n // Azure OpenAI static-key auth.\n azure: { kind: \"api-key\" },\n // ElevenLabs.\n elevenlabs: { kind: \"xi-api-key\" },\n // fal.ai — uses the `Key ` prefix on Authorization, NOT `Bearer `.\n fal: { kind: \"fal-key\" },\n};\n\n/**\n * Case-insensitively delete a header from a forward-header map, returning the\n * value that was present (if any). Header maps preserve the original casing of\n * incoming headers, so we can't assume a canonical key.\n */\nfunction takeHeader(headers: Record<string, string>, name: string): string | undefined {\n const lowerName = name.toLowerCase();\n let found: string | undefined;\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lowerName) {\n found = headers[key];\n delete headers[key];\n }\n }\n return found;\n}\n\n/**\n * Extract the caller's credential value for a given auth scheme from the\n * forwarded headers, if present. For bearer, strips the `Bearer ` prefix.\n */\nfunction readCallerCredential(\n headers: Record<string, string>,\n scheme: AuthScheme,\n): string | undefined {\n if (scheme.kind === \"bearer\" || scheme.kind === \"fal-key\") {\n const raw = scanHeader(headers, \"authorization\");\n if (raw === undefined) return undefined;\n // Strip the scheme prefix (`Bearer ` for bearer, `Key ` for fal) if present,\n // otherwise treat the whole value as the credential.\n const prefix = scheme.kind === \"fal-key\" ? \"Key\" : \"Bearer\";\n const match = new RegExp(`^\\\\s*${prefix}\\\\s+(.+)$`, \"i\").exec(raw);\n return match ? match[1].trim() : raw.trim();\n }\n return scanHeader(headers, authHeaderName(scheme));\n}\n\n/**\n * The wire header name a non-Authorization scheme carries its credential in.\n * (bearer/fal-key both use `Authorization` and are handled separately.)\n */\nfunction authHeaderName(scheme: AuthScheme): string {\n switch (scheme.kind) {\n case \"x-api-key\":\n return \"x-api-key\";\n case \"x-goog-api-key\":\n return \"x-goog-api-key\";\n case \"api-key\":\n return \"api-key\";\n case \"xi-api-key\":\n return \"xi-api-key\";\n case \"bearer\":\n case \"fal-key\":\n return \"authorization\";\n }\n}\n\n/** Case-insensitive header lookup that does not mutate the map. */\nfunction scanHeader(headers: Record<string, string>, name: string): string | undefined {\n const lowerName = name.toLowerCase();\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lowerName) return headers[key];\n }\n return undefined;\n}\n\n/**\n * Decide whether aimock should override the caller's credential with its own\n * built-in key. Override when the caller sent no credential OR sent a dummy\n * placeholder (prefixed with the active marker). A real caller key is left\n * untouched so the caller can always override aimock.\n */\nfunction shouldOverride(callerCredential: string | undefined, marker: string): boolean {\n if (callerCredential === undefined || callerCredential.length === 0) return true;\n return callerCredential.startsWith(marker);\n}\n\n/**\n * Inject aimock's built-in upstream credential into the forwarded headers when\n * appropriate (opt-in, backward-compatible). Mutates `forwardHeaders` in place\n * and may mutate `target` (query-param schemes; none currently).\n *\n * Precedence:\n * - No built-in key configured for this provider → no-op (forward verbatim).\n * - Provider not a static-key scheme → no-op (Bedrock SigV4 / Vertex AI OAuth).\n * - Caller credential absent or dummy-prefixed → inject built-in key.\n * - Caller credential is a real key → forward it unchanged.\n *\n * @param forwardHeaders headers already built by buildForwardHeaders(req)\n * @param target upstream URL (reserved for query-param auth schemes)\n * @param providerKey which provider this request is routed to\n * @param builtinKey aimock's configured key for this provider (if any)\n */\nexport function applyProviderAuth(\n forwardHeaders: Record<string, string>,\n target: URL,\n providerKey: RecordProviderKey,\n builtinKey: string | undefined,\n): void {\n void target; // reserved for future query-param schemes (e.g. Gemini ?key=)\n if (!builtinKey) return; // feature inert for this provider\n\n const scheme = PROVIDER_AUTH_SCHEMES[providerKey];\n if (!scheme) return; // signed/OAuth provider — never rewrite auth\n\n const marker = getDummyKeyMarker();\n const callerCredential = readCallerCredential(forwardHeaders, scheme);\n if (!shouldOverride(callerCredential, marker)) return; // caller sent a real key\n\n // Strip any existing auth headers for this scheme (across casings) before\n // setting aimock's key, so a dummy caller key can't linger alongside ours.\n switch (scheme.kind) {\n case \"bearer\":\n takeHeader(forwardHeaders, \"authorization\");\n forwardHeaders[\"Authorization\"] = `Bearer ${builtinKey}`;\n break;\n case \"fal-key\":\n takeHeader(forwardHeaders, \"authorization\");\n forwardHeaders[\"Authorization\"] = `Key ${builtinKey}`;\n break;\n case \"x-api-key\":\n takeHeader(forwardHeaders, \"x-api-key\");\n forwardHeaders[\"x-api-key\"] = builtinKey;\n break;\n case \"x-goog-api-key\":\n takeHeader(forwardHeaders, \"x-goog-api-key\");\n forwardHeaders[\"x-goog-api-key\"] = builtinKey;\n break;\n case \"api-key\":\n takeHeader(forwardHeaders, \"api-key\");\n forwardHeaders[\"api-key\"] = builtinKey;\n break;\n case \"xi-api-key\":\n takeHeader(forwardHeaders, \"xi-api-key\");\n forwardHeaders[\"xi-api-key\"] = builtinKey;\n break;\n }\n}\n\n/**\n * Read per-provider built-in keys from the environment. Returns undefined when\n * no provider key is configured so the feature stays fully inert by default.\n *\n * Each wired static-key provider reads `AIMOCK_PROVIDER_<PROVIDER>_KEY`. An\n * empty-string value is treated as unset (existing truthiness pattern), keeping\n * the feature inert. `gemini-interactions` is not read here: it reuses the\n * Gemini key via the lookup-key remap in `proxyAndRecord`. Signed/OAuth\n * providers (`bedrock`, `vertexai`) have no env var — aimock never rewrites\n * their auth.\n */\nexport function readProviderKeysFromEnv(\n env: NodeJS.ProcessEnv = process.env,\n): Partial<Record<RecordProviderKey, string>> | undefined {\n const keys: Partial<Record<RecordProviderKey, string>> = {};\n if (env.AIMOCK_PROVIDER_OPENAI_KEY) keys.openai = env.AIMOCK_PROVIDER_OPENAI_KEY;\n if (env.AIMOCK_PROVIDER_ANTHROPIC_KEY) keys.anthropic = env.AIMOCK_PROVIDER_ANTHROPIC_KEY;\n if (env.AIMOCK_PROVIDER_GEMINI_KEY) keys.gemini = env.AIMOCK_PROVIDER_GEMINI_KEY;\n if (env.AIMOCK_PROVIDER_OPENROUTER_KEY) keys.openrouter = env.AIMOCK_PROVIDER_OPENROUTER_KEY;\n if (env.AIMOCK_PROVIDER_COHERE_KEY) keys.cohere = env.AIMOCK_PROVIDER_COHERE_KEY;\n if (env.AIMOCK_PROVIDER_GROK_KEY) keys.grok = env.AIMOCK_PROVIDER_GROK_KEY;\n if (env.AIMOCK_PROVIDER_OLLAMA_KEY) keys.ollama = env.AIMOCK_PROVIDER_OLLAMA_KEY;\n if (env.AIMOCK_PROVIDER_VEO_KEY) keys.veo = env.AIMOCK_PROVIDER_VEO_KEY;\n if (env.AIMOCK_PROVIDER_AZURE_KEY) keys.azure = env.AIMOCK_PROVIDER_AZURE_KEY;\n if (env.AIMOCK_PROVIDER_ELEVENLABS_KEY) keys.elevenlabs = env.AIMOCK_PROVIDER_ELEVENLABS_KEY;\n if (env.AIMOCK_PROVIDER_FAL_KEY) keys.fal = env.AIMOCK_PROVIDER_FAL_KEY;\n return Object.keys(keys).length > 0 ? keys : undefined;\n}\n"],"mappings":"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"}
package/dist/recorder.cjs CHANGED
@@ -6,6 +6,7 @@ const require_router = require('./router.cjs');
6
6
  const require_sse_writer = require('./sse-writer.cjs');
7
7
  const require_stream_collapse = require('./stream-collapse.cjs');
8
8
  const require_url = require('./url.cjs');
9
+ const require_provider_auth = require('./provider-auth.cjs');
9
10
  let node_http = require("node:http");
10
11
  node_http = require_runtime.__toESM(node_http);
11
12
  let node_crypto = require("node:crypto");
@@ -207,7 +208,9 @@ function persistFixture(opts) {
207
208
  async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures, defaults, rawBody, options) {
208
209
  const record = defaults.record;
209
210
  if (!record) return "not_configured";
210
- const upstreamUrl = record.providers[providerKey === "gemini-interactions" ? "gemini" : providerKey];
211
+ const providers = record.providers;
212
+ const lookupKey = providerKey === "gemini-interactions" ? "gemini" : providerKey;
213
+ const upstreamUrl = providers[lookupKey];
211
214
  if (!upstreamUrl) {
212
215
  defaults.logger.warn(`No upstream URL configured for provider "${providerKey}" — cannot proxy`);
213
216
  return "not_configured";
@@ -226,6 +229,7 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
226
229
  }
227
230
  defaults.logger.warn(`NO FIXTURE MATCH — proxying to ${upstreamUrl}${pathname}`);
228
231
  const forwardHeaders = buildForwardHeaders(req);
232
+ require_provider_auth.applyProviderAuth(forwardHeaders, target, providerKey, record.providerKeys?.[lookupKey]);
229
233
  const requestBody = rawBody ?? JSON.stringify(request);
230
234
  let upstreamStatus;
231
235
  let upstreamHeaders;