@omnicross/core 0.1.0 → 0.1.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.
- package/dist/ApiConverter.cjs +799 -0
- package/dist/ApiConverter.d.cts +82 -0
- package/dist/ApiConverter.d.ts +82 -0
- package/dist/ApiConverter.js +763 -0
- package/dist/BuiltinToolExecutor-BluWyeob.d.ts +81 -0
- package/dist/BuiltinToolExecutor-CS2WpXhM.d.cts +81 -0
- package/dist/CompletionService-7fCmKAP3.d.ts +212 -0
- package/dist/CompletionService-DtOF_War.d.cts +212 -0
- package/dist/{ProviderProxy-f_8ziIhW.d.cts → ProviderProxy-C-xqrkKi.d.ts} +7 -2
- package/dist/{ProviderProxy-vjt8sQQk.d.ts → ProviderProxy-CnMQYN59.d.cts} +7 -2
- package/dist/completion/BuiltinToolExecutor.cjs +327 -0
- package/dist/completion/BuiltinToolExecutor.d.cts +4 -0
- package/dist/completion/BuiltinToolExecutor.d.ts +4 -0
- package/dist/completion/BuiltinToolExecutor.js +296 -0
- package/dist/completion/CompletionService.cjs +3487 -0
- package/dist/completion/CompletionService.d.cts +21 -0
- package/dist/completion/CompletionService.d.ts +21 -0
- package/dist/completion/CompletionService.js +3461 -0
- package/dist/completion/NativeSearchInjector.cjs +196 -0
- package/dist/completion/NativeSearchInjector.d.cts +42 -0
- package/dist/completion/NativeSearchInjector.d.ts +42 -0
- package/dist/completion/NativeSearchInjector.js +167 -0
- package/dist/completion/ProviderSearchInjector.cjs +87 -0
- package/dist/completion/ProviderSearchInjector.d.cts +47 -0
- package/dist/completion/ProviderSearchInjector.d.ts +47 -0
- package/dist/completion/ProviderSearchInjector.js +60 -0
- package/dist/completion/native-search-types.cjs +67 -0
- package/dist/completion/native-search-types.d.cts +3 -0
- package/dist/completion/native-search-types.d.ts +3 -0
- package/dist/completion/native-search-types.js +38 -0
- package/dist/completion/openrouter-headers.cjs +72 -0
- package/dist/completion/openrouter-headers.d.cts +44 -0
- package/dist/completion/openrouter-headers.d.ts +44 -0
- package/dist/completion/openrouter-headers.js +42 -0
- package/dist/completion/openrouter-models.cjs +86 -0
- package/dist/completion/openrouter-models.d.cts +27 -0
- package/dist/completion/openrouter-models.d.ts +27 -0
- package/dist/completion/openrouter-models.js +59 -0
- package/dist/completion/types.cjs +18 -0
- package/dist/completion/types.d.cts +3 -0
- package/dist/completion/types.d.ts +3 -0
- package/dist/completion/types.js +0 -0
- package/dist/completion/url-builder.cjs +138 -0
- package/dist/completion/url-builder.d.cts +87 -0
- package/dist/completion/url-builder.d.ts +87 -0
- package/dist/completion/url-builder.js +104 -0
- package/dist/completion.d.cts +148 -7
- package/dist/completion.d.ts +148 -7
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +27 -90
- package/dist/index.d.ts +27 -90
- package/dist/index.js +1 -0
- package/dist/outbound-api/routeResolver.cjs +221 -0
- package/dist/outbound-api/routeResolver.d.cts +18 -0
- package/dist/outbound-api/routeResolver.d.ts +18 -0
- package/dist/outbound-api/routeResolver.js +192 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +5 -2
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +5 -2
- package/dist/outbound-api/types.cjs +18 -0
- package/dist/{types-CbCN2NQP.d.ts → outbound-api/types.d.cts} +17 -3
- package/dist/{types-CGGrKqC_.d.cts → outbound-api/types.d.ts} +17 -3
- package/dist/outbound-api/types.js +0 -0
- package/dist/outbound-api.cjs +1 -0
- package/dist/outbound-api.d.cts +14 -87
- package/dist/outbound-api.d.ts +14 -87
- package/dist/outbound-api.js +1 -0
- package/dist/pipeline/AuthSource.cjs +18 -0
- package/dist/pipeline/AuthSource.d.cts +101 -0
- package/dist/pipeline/AuthSource.d.ts +101 -0
- package/dist/pipeline/AuthSource.js +0 -0
- package/dist/pipeline/LlmConfigProviderAuth.cjs +169 -0
- package/dist/pipeline/LlmConfigProviderAuth.d.cts +86 -0
- package/dist/pipeline/LlmConfigProviderAuth.d.ts +86 -0
- package/dist/pipeline/LlmConfigProviderAuth.js +142 -0
- package/dist/pipeline/SubscriptionAuthSource.d.cts +165 -3
- package/dist/pipeline/SubscriptionAuthSource.d.ts +165 -3
- package/dist/pipeline/executeProviderCall.cjs +70 -0
- package/dist/pipeline/executeProviderCall.d.cts +149 -0
- package/dist/pipeline/executeProviderCall.d.ts +149 -0
- package/dist/pipeline/executeProviderCall.js +45 -0
- package/dist/pipeline/resolveProviderChain.cjs +47 -0
- package/dist/pipeline/resolveProviderChain.d.cts +58 -0
- package/dist/pipeline/resolveProviderChain.d.ts +58 -0
- package/dist/pipeline/resolveProviderChain.js +22 -0
- package/dist/pipeline/resolveSubscriptionChain.cjs +68 -0
- package/dist/pipeline/resolveSubscriptionChain.d.cts +68 -0
- package/dist/pipeline/resolveSubscriptionChain.d.ts +68 -0
- package/dist/pipeline/resolveSubscriptionChain.js +43 -0
- package/dist/ports/provider-config-source.cjs +18 -0
- package/dist/ports/provider-config-source.d.cts +51 -0
- package/dist/ports/provider-config-source.d.ts +51 -0
- package/dist/ports/provider-config-source.js +0 -0
- package/dist/ports/web-search-backend.cjs +18 -0
- package/dist/ports/web-search-backend.d.cts +29 -0
- package/dist/ports/web-search-backend.d.ts +29 -0
- package/dist/ports/web-search-backend.js +0 -0
- package/dist/ports.d.cts +10 -7
- package/dist/ports.d.ts +10 -7
- package/dist/provider-proxy/ProviderProxy.cjs +4643 -0
- package/dist/provider-proxy/ProviderProxy.d.cts +16 -0
- package/dist/provider-proxy/ProviderProxy.d.ts +16 -0
- package/dist/provider-proxy/ProviderProxy.js +4618 -0
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +5 -2
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +5 -2
- package/dist/provider-proxy/types.d.cts +406 -8
- package/dist/provider-proxy/types.d.ts +406 -8
- package/dist/provider-proxy.cjs +1 -0
- package/dist/provider-proxy.d.cts +8 -5
- package/dist/provider-proxy.d.ts +8 -5
- package/dist/provider-proxy.js +1 -0
- package/dist/routeResolver-BrbK6ja9.d.cts +88 -0
- package/dist/routeResolver-HE-ZO0fO.d.ts +88 -0
- package/dist/transformer/anthropicBetaInject.cjs +51 -0
- package/dist/transformer/anthropicBetaInject.d.cts +20 -0
- package/dist/transformer/anthropicBetaInject.d.ts +20 -0
- package/dist/transformer/anthropicBetaInject.js +25 -0
- package/dist/transformer/transformers/AnthropicTransformer.cjs +1017 -0
- package/dist/transformer/transformers/AnthropicTransformer.d.cts +148 -0
- package/dist/transformer/transformers/AnthropicTransformer.d.ts +148 -0
- package/dist/transformer/transformers/AnthropicTransformer.js +990 -0
- package/dist/transformer/transformers/ReasoningTransformer.cjs +273 -0
- package/dist/transformer/transformers/ReasoningTransformer.d.cts +47 -0
- package/dist/transformer/transformers/ReasoningTransformer.d.ts +47 -0
- package/dist/transformer/transformers/ReasoningTransformer.js +253 -0
- package/dist/transformer/transformers.cjs +3206 -0
- package/dist/transformer/transformers.d.cts +100 -0
- package/dist/transformer/transformers.d.ts +100 -0
- package/dist/transformer/transformers.js +3174 -0
- package/dist/transformer.d.cts +8 -31
- package/dist/transformer.d.ts +8 -31
- package/dist/types-BScIHmPr.d.cts +153 -0
- package/dist/types-BScIHmPr.d.ts +153 -0
- package/package.json +3 -3
- package/dist/SubscriptionAuthSource-Cr4fVEYY.d.cts +0 -264
- package/dist/SubscriptionAuthSource-D89zmiSS.d.ts +0 -264
- package/dist/index-BTSmc9Sm.d.ts +0 -645
- package/dist/index-DXazdTzZ.d.cts +0 -645
- package/dist/types-DCzHkhJt.d.ts +0 -467
- package/dist/types-DZIQbgp0.d.cts +0 -467
package/dist/outbound-api.d.cts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import './
|
|
1
|
+
import { EndpointRoutingConfig, OutboundApiDeps, OutboundApiServerStatus, OutboundFormatUrls, OutboundApiServerConfig, OutboundKeyDb, OutboundApiKeyCreated, RequestRole } from './outbound-api/types.cjs';
|
|
2
|
+
export { OutboundApiKeyInfo, OutboundEndpoint, OutboundKeyDbRow } from './outbound-api/types.cjs';
|
|
3
|
+
import { IngressFormat } from './provider-proxy/types.cjs';
|
|
4
|
+
export { S as SUBSCRIPTION_PROVIDER_IDS, e as endpointSupportsSubscription, i as isSubscriptionProviderId, r as resolveRoute } from './routeResolver-BrbK6ja9.cjs';
|
|
5
|
+
import './ports/provider-config-source.cjs';
|
|
6
|
+
import '@omnicross/contracts/llm-config';
|
|
7
|
+
import './transformer/types.cjs';
|
|
8
|
+
import './transformer/TransformerService.cjs';
|
|
9
|
+
import './ProviderProxy-CnMQYN59.cjs';
|
|
6
10
|
import 'node:http';
|
|
7
11
|
import '@omnicross/contracts/completion-types';
|
|
12
|
+
import '@omnicross/contracts/subscription-types';
|
|
8
13
|
import '@omnicross/contracts/usage-types';
|
|
9
14
|
import './ApiKeyPoolService-BmMkau07.cjs';
|
|
10
|
-
import '
|
|
11
|
-
import './SubscriptionAuthSource
|
|
15
|
+
import './pipeline/AuthSource.cjs';
|
|
16
|
+
import './pipeline/SubscriptionAuthSource.cjs';
|
|
12
17
|
import './pipeline/SubscriptionAuthStrategy.cjs';
|
|
13
|
-
import './
|
|
14
|
-
import './transformer/TransformerService.cjs';
|
|
18
|
+
import './ports/web-search-backend.cjs';
|
|
15
19
|
import '@omnicross/contracts/websearch-types';
|
|
16
20
|
|
|
17
21
|
/**
|
|
@@ -218,83 +222,6 @@ declare function detectRequestRole(ingressFormat: IngressFormat, body: Record<st
|
|
|
218
222
|
/** Map a settings endpoint id to the provider-proxy ingress format. */
|
|
219
223
|
declare function endpointToIngressFormat(endpoint: 'chat' | 'responses' | 'messages' | 'gemini'): IngressFormat;
|
|
220
224
|
|
|
221
|
-
/**
|
|
222
|
-
* subscriptionSupport — single source of truth for (a) which provider ids are
|
|
223
|
-
* subscription-backed and (b) which outbound endpoints can soundly serve a
|
|
224
|
-
* subscription route (`outbound-api-server`, design D2 + review M1/m1).
|
|
225
|
-
*
|
|
226
|
-
* The subscription-id catalog mirrors `SubscriptionProviderRegistry`'s ids; the
|
|
227
|
-
* static fast-path is backstopped at runtime by a live registry lookup (see
|
|
228
|
-
* `isSubscriptionProviderId`) so it degrades gracefully if it drifts. Both
|
|
229
|
-
* `routeResolver` and `apiServerHandlers` import from here — no duplicated set.
|
|
230
|
-
*
|
|
231
|
-
* @module outbound-api/subscriptionSupport
|
|
232
|
-
*/
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* The registry-aligned subscription provider ids — the outbound layer's SSOT
|
|
236
|
-
* fast-path. NOTE: `SubscriptionProviderId` is currently a `z.string()` alias,
|
|
237
|
-
* so this `readonly SubscriptionProviderId[]` typing does NOT compile-enforce
|
|
238
|
-
* alignment with the registry; drift is instead tolerated at runtime by
|
|
239
|
-
* `isSubscriptionProviderId`'s live `registry.getProfile` fallback.
|
|
240
|
-
*/
|
|
241
|
-
declare const SUBSCRIPTION_PROVIDER_IDS: readonly SubscriptionProviderId[];
|
|
242
|
-
/**
|
|
243
|
-
* True when a provider id refers to a subscription-backed provider. Checks the
|
|
244
|
-
* registry-aligned static catalog first, then falls back to a live registry
|
|
245
|
-
* lookup (so a registry addition is honored even before this list is updated).
|
|
246
|
-
*
|
|
247
|
-
* NOTE (review m2): this classifies by id string. The resolver MUST confirm the
|
|
248
|
-
* id does not resolve to a real BYO provider row before treating it as
|
|
249
|
-
* subscription-backed — see `routeResolver` (BYO rows win).
|
|
250
|
-
*/
|
|
251
|
-
declare function isSubscriptionProviderId(providerId: string): boolean;
|
|
252
|
-
/** True when the endpoint's ingress can soundly serve a subscription route. */
|
|
253
|
-
declare function endpointSupportsSubscription(endpoint: OutboundEndpoint): boolean;
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* routeResolver — turn an endpoint's `EndpointRoutingConfig` + the detected
|
|
257
|
-
* request role into a `RouteContext` for the shared `provider-proxy` dispatch
|
|
258
|
-
* (`outbound-api-server`, design D2).
|
|
259
|
-
*
|
|
260
|
-
* Steps:
|
|
261
|
-
* 1. Pick the model for the role (vision → default fallback when `visionModel`
|
|
262
|
-
* is unset; vision is optional).
|
|
263
|
-
* 2. Parse the chosen `"providerId,modelId"` ref.
|
|
264
|
-
* 3. Gate by `useSubscription`: OFF → only BYO-key providers are eligible
|
|
265
|
-
* (subscription-backed providers excluded); ON → subscription-backed
|
|
266
|
-
* providers are eligible.
|
|
267
|
-
* 4. Resolve the provider (BYO via the `ProviderConfigSource`; subscription via the
|
|
268
|
-
* subscription registry) and build the `RouteContext` exactly as the
|
|
269
|
-
* internal callers do.
|
|
270
|
-
* 5. Return a clear `503`-style error when the role's required model is unset,
|
|
271
|
-
* the provider is unavailable, or the subscription gate excludes it.
|
|
272
|
-
*
|
|
273
|
-
* @module outbound-api/routeResolver
|
|
274
|
-
*/
|
|
275
|
-
|
|
276
|
-
/** A 503-style resolution failure. */
|
|
277
|
-
interface RouteResolveError {
|
|
278
|
-
status: number;
|
|
279
|
-
message: string;
|
|
280
|
-
}
|
|
281
|
-
type RouteResolveResult = {
|
|
282
|
-
ok: true;
|
|
283
|
-
route: RouteContext;
|
|
284
|
-
usedRole: RequestRole;
|
|
285
|
-
} | {
|
|
286
|
-
ok: false;
|
|
287
|
-
error: RouteResolveError;
|
|
288
|
-
};
|
|
289
|
-
/** Resolve a route for one authenticated outbound request. */
|
|
290
|
-
declare function resolveRoute(args: {
|
|
291
|
-
config: EndpointRoutingConfig;
|
|
292
|
-
role: RequestRole;
|
|
293
|
-
ingressFormat: IngressFormat;
|
|
294
|
-
llmConfig: ProviderConfigSource;
|
|
295
|
-
sessionId?: string | null;
|
|
296
|
-
}): Promise<RouteResolveResult>;
|
|
297
|
-
|
|
298
225
|
/**
|
|
299
226
|
* Outbound API server module — barrel + singleton accessor.
|
|
300
227
|
*
|
|
@@ -317,4 +244,4 @@ declare function getOutboundApiServer(deps?: OutboundApiDeps, onPortChange?: (po
|
|
|
317
244
|
/** Reset the singleton (tests / teardown only). */
|
|
318
245
|
declare function __resetOutboundApiServerForTests(): void;
|
|
319
246
|
|
|
320
|
-
export { type ApiServerSettingsStore, type ApplyConfigInput, DEFAULT_OUTBOUND_PORT, EndpointRoutingConfig, OUTBOUND_API_SERVER_CONFIG_KEY, OutboundApiDeps, OutboundApiKeyCreated, OutboundApiServer, OutboundApiServerConfig, OutboundApiServerStatus,
|
|
247
|
+
export { type ApiServerSettingsStore, type ApplyConfigInput, DEFAULT_OUTBOUND_PORT, EndpointRoutingConfig, OUTBOUND_API_SERVER_CONFIG_KEY, OutboundApiDeps, OutboundApiKeyCreated, OutboundApiServer, OutboundApiServerConfig, OutboundApiServerStatus, OutboundFormatUrls, OutboundKeyDb, OutboundRateLimiter, RequestRole, __resetOutboundApiServerForTests, createNamedKey, defaultServerConfig, detectRequestRole, endpointToIngressFormat, formatUrls, getOutboundApiServer, hashKey, loadServerConfig, mergeServerConfig, normalizeServerConfig, saveServerConfig, verifyPresentedKey };
|
package/dist/outbound-api.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import './
|
|
1
|
+
import { EndpointRoutingConfig, OutboundApiDeps, OutboundApiServerStatus, OutboundFormatUrls, OutboundApiServerConfig, OutboundKeyDb, OutboundApiKeyCreated, RequestRole } from './outbound-api/types.js';
|
|
2
|
+
export { OutboundApiKeyInfo, OutboundEndpoint, OutboundKeyDbRow } from './outbound-api/types.js';
|
|
3
|
+
import { IngressFormat } from './provider-proxy/types.js';
|
|
4
|
+
export { S as SUBSCRIPTION_PROVIDER_IDS, e as endpointSupportsSubscription, i as isSubscriptionProviderId, r as resolveRoute } from './routeResolver-HE-ZO0fO.js';
|
|
5
|
+
import './ports/provider-config-source.js';
|
|
6
|
+
import '@omnicross/contracts/llm-config';
|
|
7
|
+
import './transformer/types.js';
|
|
8
|
+
import './transformer/TransformerService.js';
|
|
9
|
+
import './ProviderProxy-C-xqrkKi.js';
|
|
6
10
|
import 'node:http';
|
|
7
11
|
import '@omnicross/contracts/completion-types';
|
|
12
|
+
import '@omnicross/contracts/subscription-types';
|
|
8
13
|
import '@omnicross/contracts/usage-types';
|
|
9
14
|
import './ApiKeyPoolService-BmMkau07.js';
|
|
10
|
-
import '
|
|
11
|
-
import './SubscriptionAuthSource
|
|
15
|
+
import './pipeline/AuthSource.js';
|
|
16
|
+
import './pipeline/SubscriptionAuthSource.js';
|
|
12
17
|
import './pipeline/SubscriptionAuthStrategy.js';
|
|
13
|
-
import './
|
|
14
|
-
import './transformer/TransformerService.js';
|
|
18
|
+
import './ports/web-search-backend.js';
|
|
15
19
|
import '@omnicross/contracts/websearch-types';
|
|
16
20
|
|
|
17
21
|
/**
|
|
@@ -218,83 +222,6 @@ declare function detectRequestRole(ingressFormat: IngressFormat, body: Record<st
|
|
|
218
222
|
/** Map a settings endpoint id to the provider-proxy ingress format. */
|
|
219
223
|
declare function endpointToIngressFormat(endpoint: 'chat' | 'responses' | 'messages' | 'gemini'): IngressFormat;
|
|
220
224
|
|
|
221
|
-
/**
|
|
222
|
-
* subscriptionSupport — single source of truth for (a) which provider ids are
|
|
223
|
-
* subscription-backed and (b) which outbound endpoints can soundly serve a
|
|
224
|
-
* subscription route (`outbound-api-server`, design D2 + review M1/m1).
|
|
225
|
-
*
|
|
226
|
-
* The subscription-id catalog mirrors `SubscriptionProviderRegistry`'s ids; the
|
|
227
|
-
* static fast-path is backstopped at runtime by a live registry lookup (see
|
|
228
|
-
* `isSubscriptionProviderId`) so it degrades gracefully if it drifts. Both
|
|
229
|
-
* `routeResolver` and `apiServerHandlers` import from here — no duplicated set.
|
|
230
|
-
*
|
|
231
|
-
* @module outbound-api/subscriptionSupport
|
|
232
|
-
*/
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* The registry-aligned subscription provider ids — the outbound layer's SSOT
|
|
236
|
-
* fast-path. NOTE: `SubscriptionProviderId` is currently a `z.string()` alias,
|
|
237
|
-
* so this `readonly SubscriptionProviderId[]` typing does NOT compile-enforce
|
|
238
|
-
* alignment with the registry; drift is instead tolerated at runtime by
|
|
239
|
-
* `isSubscriptionProviderId`'s live `registry.getProfile` fallback.
|
|
240
|
-
*/
|
|
241
|
-
declare const SUBSCRIPTION_PROVIDER_IDS: readonly SubscriptionProviderId[];
|
|
242
|
-
/**
|
|
243
|
-
* True when a provider id refers to a subscription-backed provider. Checks the
|
|
244
|
-
* registry-aligned static catalog first, then falls back to a live registry
|
|
245
|
-
* lookup (so a registry addition is honored even before this list is updated).
|
|
246
|
-
*
|
|
247
|
-
* NOTE (review m2): this classifies by id string. The resolver MUST confirm the
|
|
248
|
-
* id does not resolve to a real BYO provider row before treating it as
|
|
249
|
-
* subscription-backed — see `routeResolver` (BYO rows win).
|
|
250
|
-
*/
|
|
251
|
-
declare function isSubscriptionProviderId(providerId: string): boolean;
|
|
252
|
-
/** True when the endpoint's ingress can soundly serve a subscription route. */
|
|
253
|
-
declare function endpointSupportsSubscription(endpoint: OutboundEndpoint): boolean;
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* routeResolver — turn an endpoint's `EndpointRoutingConfig` + the detected
|
|
257
|
-
* request role into a `RouteContext` for the shared `provider-proxy` dispatch
|
|
258
|
-
* (`outbound-api-server`, design D2).
|
|
259
|
-
*
|
|
260
|
-
* Steps:
|
|
261
|
-
* 1. Pick the model for the role (vision → default fallback when `visionModel`
|
|
262
|
-
* is unset; vision is optional).
|
|
263
|
-
* 2. Parse the chosen `"providerId,modelId"` ref.
|
|
264
|
-
* 3. Gate by `useSubscription`: OFF → only BYO-key providers are eligible
|
|
265
|
-
* (subscription-backed providers excluded); ON → subscription-backed
|
|
266
|
-
* providers are eligible.
|
|
267
|
-
* 4. Resolve the provider (BYO via the `ProviderConfigSource`; subscription via the
|
|
268
|
-
* subscription registry) and build the `RouteContext` exactly as the
|
|
269
|
-
* internal callers do.
|
|
270
|
-
* 5. Return a clear `503`-style error when the role's required model is unset,
|
|
271
|
-
* the provider is unavailable, or the subscription gate excludes it.
|
|
272
|
-
*
|
|
273
|
-
* @module outbound-api/routeResolver
|
|
274
|
-
*/
|
|
275
|
-
|
|
276
|
-
/** A 503-style resolution failure. */
|
|
277
|
-
interface RouteResolveError {
|
|
278
|
-
status: number;
|
|
279
|
-
message: string;
|
|
280
|
-
}
|
|
281
|
-
type RouteResolveResult = {
|
|
282
|
-
ok: true;
|
|
283
|
-
route: RouteContext;
|
|
284
|
-
usedRole: RequestRole;
|
|
285
|
-
} | {
|
|
286
|
-
ok: false;
|
|
287
|
-
error: RouteResolveError;
|
|
288
|
-
};
|
|
289
|
-
/** Resolve a route for one authenticated outbound request. */
|
|
290
|
-
declare function resolveRoute(args: {
|
|
291
|
-
config: EndpointRoutingConfig;
|
|
292
|
-
role: RequestRole;
|
|
293
|
-
ingressFormat: IngressFormat;
|
|
294
|
-
llmConfig: ProviderConfigSource;
|
|
295
|
-
sessionId?: string | null;
|
|
296
|
-
}): Promise<RouteResolveResult>;
|
|
297
|
-
|
|
298
225
|
/**
|
|
299
226
|
* Outbound API server module — barrel + singleton accessor.
|
|
300
227
|
*
|
|
@@ -317,4 +244,4 @@ declare function getOutboundApiServer(deps?: OutboundApiDeps, onPortChange?: (po
|
|
|
317
244
|
/** Reset the singleton (tests / teardown only). */
|
|
318
245
|
declare function __resetOutboundApiServerForTests(): void;
|
|
319
246
|
|
|
320
|
-
export { type ApiServerSettingsStore, type ApplyConfigInput, DEFAULT_OUTBOUND_PORT, EndpointRoutingConfig, OUTBOUND_API_SERVER_CONFIG_KEY, OutboundApiDeps, OutboundApiKeyCreated, OutboundApiServer, OutboundApiServerConfig, OutboundApiServerStatus,
|
|
247
|
+
export { type ApiServerSettingsStore, type ApplyConfigInput, DEFAULT_OUTBOUND_PORT, EndpointRoutingConfig, OUTBOUND_API_SERVER_CONFIG_KEY, OutboundApiDeps, OutboundApiKeyCreated, OutboundApiServer, OutboundApiServerConfig, OutboundApiServerStatus, OutboundFormatUrls, OutboundKeyDb, OutboundRateLimiter, RequestRole, __resetOutboundApiServerForTests, createNamedKey, defaultServerConfig, detectRequestRole, endpointToIngressFormat, formatUrls, getOutboundApiServer, hashKey, loadServerConfig, mergeServerConfig, normalizeServerConfig, saveServerConfig, verifyPresentedKey };
|
package/dist/outbound-api.js
CHANGED
|
@@ -3791,6 +3791,7 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
|
|
|
3791
3791
|
extendedContext: hints.extendedContext ?? null,
|
|
3792
3792
|
passThrough: hints.passThrough,
|
|
3793
3793
|
passThroughAuthToken: hints.passThroughAuthToken ?? null,
|
|
3794
|
+
resolvePassThroughAuthToken: hints.resolvePassThroughAuthToken ?? null,
|
|
3794
3795
|
subscriptionProfile: hints.subscriptionProfile ?? null,
|
|
3795
3796
|
maxConcurrency: hints.maxConcurrency,
|
|
3796
3797
|
webSearchService: hints.webSearchService ?? null,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/pipeline/AuthSource.ts
|
|
17
|
+
var AuthSource_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(AuthSource_exports);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuthSource — unified outbound-authentication strategy for the provider
|
|
3
|
+
* request pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Phase 2 of the `provider-request-pipeline` OpenSpec change (design D3).
|
|
6
|
+
*
|
|
7
|
+
* The three consumer paths (the wire-format proxy handler, the host engine
|
|
8
|
+
* adapter, TransformerHandler) each authenticate differently:
|
|
9
|
+
*
|
|
10
|
+
* - provider-key (+ ApiKeyPool failover) — LLM-config provider rows
|
|
11
|
+
* - subscription `AuthStrategy` (+ 401 refresh + fallback) — code-cli OAuth
|
|
12
|
+
* - OAuth pass-through — SDK forwards its own Bearer
|
|
13
|
+
*
|
|
14
|
+
* `AuthSource` is the single contract that unifies these. THIS PHASE ONLY
|
|
15
|
+
* DEFINES the interface and provides three behavior-preserving WRAPPERS
|
|
16
|
+
* (`LlmConfigProviderAuth`, `SubscriptionAuthSource`, `OAuthPassThroughAuth`)
|
|
17
|
+
* around the existing logic. NO caller is routed through it yet — the core
|
|
18
|
+
* (`executeProviderCall`) is NOT changed to consume `ctx.auth`, and
|
|
19
|
+
* the host handler's branch structure is UNCHANGED. Wiring (and
|
|
20
|
+
* the `onResult` pool-rotation integration) is Phase 3.
|
|
21
|
+
*
|
|
22
|
+
* @module pipeline/AuthSource
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Hints an `AuthSource` may need to vary header formatting per request.
|
|
26
|
+
*
|
|
27
|
+
* Mirrors the subscription-side `AuthApplyHints` (which uses optional
|
|
28
|
+
* `upstreamUrl` / `resolvedModel`) but with REQUIRED fields, since the
|
|
29
|
+
* pipeline always knows both at the point it applies headers. Adapters that
|
|
30
|
+
* wrap the looser subscription shape map these across at the boundary.
|
|
31
|
+
*/
|
|
32
|
+
interface AuthApplyHints {
|
|
33
|
+
/** Resolved upstream URL the request will be sent to. */
|
|
34
|
+
upstreamUrl: string;
|
|
35
|
+
/** Resolved model id for the request. */
|
|
36
|
+
model: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Result of {@link AuthSource.onResult}.
|
|
40
|
+
*
|
|
41
|
+
* `rebound` is `true` when the auth source rotated to a different credential
|
|
42
|
+
* (e.g. ApiKeyPool re-bound the session to a new key after a 429). `newKey`
|
|
43
|
+
* carries the freshly-resolved key string when a rotation produced one, so a
|
|
44
|
+
* caller MAY retry the same call once with it. Mirrors the
|
|
45
|
+
* `{ newKey | null }` contract of `ApiKeyPoolService.reportError` lifted into
|
|
46
|
+
* a structured shape.
|
|
47
|
+
*/
|
|
48
|
+
interface AuthResultOutcome {
|
|
49
|
+
/** Whether the credential was rotated/re-bound as a result of this status. */
|
|
50
|
+
rebound: boolean;
|
|
51
|
+
/** The new resolved key when a rotation produced one; omitted otherwise. */
|
|
52
|
+
newKey?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A pluggable outbound-authentication source for one provider request.
|
|
56
|
+
*
|
|
57
|
+
* Implementations OWN exactly the auth concern: which headers carry the
|
|
58
|
+
* credential, how to recover from a 401, where the request should be sent
|
|
59
|
+
* (when the credential dictates the endpoint), and how to react to a final
|
|
60
|
+
* HTTP status (pool rotation / refresh). The pipeline core composes the rest.
|
|
61
|
+
*/
|
|
62
|
+
interface AuthSource {
|
|
63
|
+
/**
|
|
64
|
+
* Inject the authentication headers for this request, mutating `headers`
|
|
65
|
+
* in place. Implementations MAY refresh expiring tokens here.
|
|
66
|
+
*
|
|
67
|
+
* NOTE (Phase 2 boundary, see report): exactly WHAT this owns vs what the
|
|
68
|
+
* ingress assembles (content-type, OpenRouter app headers, proxy auth
|
|
69
|
+
* stripping) is intentionally left to the caller this phase. The wrappers
|
|
70
|
+
* preserve their source's CURRENT header behavior verbatim.
|
|
71
|
+
*/
|
|
72
|
+
applyHeaders(headers: Record<string, string>, hints: AuthApplyHints): Promise<void> | void;
|
|
73
|
+
/**
|
|
74
|
+
* Called when the upstream returns 401. Return `true` to ask the caller to
|
|
75
|
+
* retry once with freshly-applied headers; `false` to surface the 401.
|
|
76
|
+
* Optional — sources without a refresh notion omit it.
|
|
77
|
+
*/
|
|
78
|
+
onUnauthorized?(): Promise<boolean>;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the upstream URL the request should target, when the credential
|
|
81
|
+
* dictates it (e.g. a subscription profile's per-model endpoint). Returns
|
|
82
|
+
* `undefined` when the source does not override the URL (the ingress keeps
|
|
83
|
+
* its own URL logic). Optional.
|
|
84
|
+
*/
|
|
85
|
+
resolveUpstreamUrl?(model: string): string | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* React to a final HTTP status (pool participation seam — design D5).
|
|
88
|
+
*
|
|
89
|
+
* For the provider-key source this reports the status to the
|
|
90
|
+
* `ApiKeyPoolService` (cooldown / disable / re-bind) and returns whether it
|
|
91
|
+
* rotated plus any new key. THIS PHASE ONLY: `onResult` is implemented and
|
|
92
|
+
* unit-tested in isolation; NO caller invokes it yet. Phase 3 wires it into
|
|
93
|
+
* `fetchWithRetry`. Optional.
|
|
94
|
+
*
|
|
95
|
+
* @param status The final HTTP status, or `null` for non-HTTP failures
|
|
96
|
+
* (e.g. network errors). Non-reportable statuses no-op.
|
|
97
|
+
*/
|
|
98
|
+
onResult?(status: number | null): Promise<AuthResultOutcome>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type { AuthApplyHints, AuthResultOutcome, AuthSource };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuthSource — unified outbound-authentication strategy for the provider
|
|
3
|
+
* request pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Phase 2 of the `provider-request-pipeline` OpenSpec change (design D3).
|
|
6
|
+
*
|
|
7
|
+
* The three consumer paths (the wire-format proxy handler, the host engine
|
|
8
|
+
* adapter, TransformerHandler) each authenticate differently:
|
|
9
|
+
*
|
|
10
|
+
* - provider-key (+ ApiKeyPool failover) — LLM-config provider rows
|
|
11
|
+
* - subscription `AuthStrategy` (+ 401 refresh + fallback) — code-cli OAuth
|
|
12
|
+
* - OAuth pass-through — SDK forwards its own Bearer
|
|
13
|
+
*
|
|
14
|
+
* `AuthSource` is the single contract that unifies these. THIS PHASE ONLY
|
|
15
|
+
* DEFINES the interface and provides three behavior-preserving WRAPPERS
|
|
16
|
+
* (`LlmConfigProviderAuth`, `SubscriptionAuthSource`, `OAuthPassThroughAuth`)
|
|
17
|
+
* around the existing logic. NO caller is routed through it yet — the core
|
|
18
|
+
* (`executeProviderCall`) is NOT changed to consume `ctx.auth`, and
|
|
19
|
+
* the host handler's branch structure is UNCHANGED. Wiring (and
|
|
20
|
+
* the `onResult` pool-rotation integration) is Phase 3.
|
|
21
|
+
*
|
|
22
|
+
* @module pipeline/AuthSource
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Hints an `AuthSource` may need to vary header formatting per request.
|
|
26
|
+
*
|
|
27
|
+
* Mirrors the subscription-side `AuthApplyHints` (which uses optional
|
|
28
|
+
* `upstreamUrl` / `resolvedModel`) but with REQUIRED fields, since the
|
|
29
|
+
* pipeline always knows both at the point it applies headers. Adapters that
|
|
30
|
+
* wrap the looser subscription shape map these across at the boundary.
|
|
31
|
+
*/
|
|
32
|
+
interface AuthApplyHints {
|
|
33
|
+
/** Resolved upstream URL the request will be sent to. */
|
|
34
|
+
upstreamUrl: string;
|
|
35
|
+
/** Resolved model id for the request. */
|
|
36
|
+
model: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Result of {@link AuthSource.onResult}.
|
|
40
|
+
*
|
|
41
|
+
* `rebound` is `true` when the auth source rotated to a different credential
|
|
42
|
+
* (e.g. ApiKeyPool re-bound the session to a new key after a 429). `newKey`
|
|
43
|
+
* carries the freshly-resolved key string when a rotation produced one, so a
|
|
44
|
+
* caller MAY retry the same call once with it. Mirrors the
|
|
45
|
+
* `{ newKey | null }` contract of `ApiKeyPoolService.reportError` lifted into
|
|
46
|
+
* a structured shape.
|
|
47
|
+
*/
|
|
48
|
+
interface AuthResultOutcome {
|
|
49
|
+
/** Whether the credential was rotated/re-bound as a result of this status. */
|
|
50
|
+
rebound: boolean;
|
|
51
|
+
/** The new resolved key when a rotation produced one; omitted otherwise. */
|
|
52
|
+
newKey?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A pluggable outbound-authentication source for one provider request.
|
|
56
|
+
*
|
|
57
|
+
* Implementations OWN exactly the auth concern: which headers carry the
|
|
58
|
+
* credential, how to recover from a 401, where the request should be sent
|
|
59
|
+
* (when the credential dictates the endpoint), and how to react to a final
|
|
60
|
+
* HTTP status (pool rotation / refresh). The pipeline core composes the rest.
|
|
61
|
+
*/
|
|
62
|
+
interface AuthSource {
|
|
63
|
+
/**
|
|
64
|
+
* Inject the authentication headers for this request, mutating `headers`
|
|
65
|
+
* in place. Implementations MAY refresh expiring tokens here.
|
|
66
|
+
*
|
|
67
|
+
* NOTE (Phase 2 boundary, see report): exactly WHAT this owns vs what the
|
|
68
|
+
* ingress assembles (content-type, OpenRouter app headers, proxy auth
|
|
69
|
+
* stripping) is intentionally left to the caller this phase. The wrappers
|
|
70
|
+
* preserve their source's CURRENT header behavior verbatim.
|
|
71
|
+
*/
|
|
72
|
+
applyHeaders(headers: Record<string, string>, hints: AuthApplyHints): Promise<void> | void;
|
|
73
|
+
/**
|
|
74
|
+
* Called when the upstream returns 401. Return `true` to ask the caller to
|
|
75
|
+
* retry once with freshly-applied headers; `false` to surface the 401.
|
|
76
|
+
* Optional — sources without a refresh notion omit it.
|
|
77
|
+
*/
|
|
78
|
+
onUnauthorized?(): Promise<boolean>;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the upstream URL the request should target, when the credential
|
|
81
|
+
* dictates it (e.g. a subscription profile's per-model endpoint). Returns
|
|
82
|
+
* `undefined` when the source does not override the URL (the ingress keeps
|
|
83
|
+
* its own URL logic). Optional.
|
|
84
|
+
*/
|
|
85
|
+
resolveUpstreamUrl?(model: string): string | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* React to a final HTTP status (pool participation seam — design D5).
|
|
88
|
+
*
|
|
89
|
+
* For the provider-key source this reports the status to the
|
|
90
|
+
* `ApiKeyPoolService` (cooldown / disable / re-bind) and returns whether it
|
|
91
|
+
* rotated plus any new key. THIS PHASE ONLY: `onResult` is implemented and
|
|
92
|
+
* unit-tested in isolation; NO caller invokes it yet. Phase 3 wires it into
|
|
93
|
+
* `fetchWithRetry`. Optional.
|
|
94
|
+
*
|
|
95
|
+
* @param status The final HTTP status, or `null` for non-HTTP failures
|
|
96
|
+
* (e.g. network errors). Non-reportable statuses no-op.
|
|
97
|
+
*/
|
|
98
|
+
onResult?(status: number | null): Promise<AuthResultOutcome>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type { AuthApplyHints, AuthResultOutcome, AuthSource };
|
|
File without changes
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/pipeline/LlmConfigProviderAuth.ts
|
|
21
|
+
var LlmConfigProviderAuth_exports = {};
|
|
22
|
+
__export(LlmConfigProviderAuth_exports, {
|
|
23
|
+
LlmConfigProviderAuth: () => LlmConfigProviderAuth
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(LlmConfigProviderAuth_exports);
|
|
26
|
+
|
|
27
|
+
// src/openrouter.ts
|
|
28
|
+
function isOpenRouterProvider(provider) {
|
|
29
|
+
const baseUrl = (provider.api_base_url || "").toLowerCase();
|
|
30
|
+
return baseUrl.includes("openrouter.ai");
|
|
31
|
+
}
|
|
32
|
+
var OPENROUTER_APP_HEADERS = {
|
|
33
|
+
"HTTP-Referer": "https://omnicross.dev",
|
|
34
|
+
"X-Title": "omnicross"
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/completion/url-builder.ts
|
|
38
|
+
var import_endpoint_resolver = require("@omnicross/contracts/endpoint-resolver");
|
|
39
|
+
function resolveApiFormat(provider) {
|
|
40
|
+
if (provider.apiFormat) {
|
|
41
|
+
return provider.apiFormat;
|
|
42
|
+
}
|
|
43
|
+
if (provider.chatApiFormat) {
|
|
44
|
+
return provider.chatApiFormat;
|
|
45
|
+
}
|
|
46
|
+
if (provider.apiType === "claudecode" || provider.apiType === "anthropic") {
|
|
47
|
+
return "anthropic";
|
|
48
|
+
}
|
|
49
|
+
if (provider.apiType === "google") {
|
|
50
|
+
return "google";
|
|
51
|
+
}
|
|
52
|
+
return "openai";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/completion/header-builder.ts
|
|
56
|
+
function getProviderHeaders(provider, apiKey) {
|
|
57
|
+
const format = resolveApiFormat(provider);
|
|
58
|
+
let headers;
|
|
59
|
+
switch (format) {
|
|
60
|
+
case "anthropic":
|
|
61
|
+
headers = {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
"x-api-key": apiKey,
|
|
64
|
+
"anthropic-version": "2025-01-10"
|
|
65
|
+
// Required for extended thinking feature
|
|
66
|
+
};
|
|
67
|
+
break;
|
|
68
|
+
case "google":
|
|
69
|
+
headers = {
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
"x-goog-api-key": apiKey
|
|
72
|
+
};
|
|
73
|
+
break;
|
|
74
|
+
case "azure-openai":
|
|
75
|
+
headers = {
|
|
76
|
+
"Content-Type": "application/json",
|
|
77
|
+
"api-key": apiKey
|
|
78
|
+
};
|
|
79
|
+
break;
|
|
80
|
+
case "openai":
|
|
81
|
+
case "openai-response":
|
|
82
|
+
default:
|
|
83
|
+
headers = {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
"Authorization": `Bearer ${apiKey}`
|
|
86
|
+
};
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
if (isOpenRouterProvider(provider)) {
|
|
90
|
+
return { ...headers, ...OPENROUTER_APP_HEADERS };
|
|
91
|
+
}
|
|
92
|
+
return headers;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/pipeline/LlmConfigProviderAuth.ts
|
|
96
|
+
function isReportableStatus(status) {
|
|
97
|
+
return status === 429 || status === 529 || status === 401 || status === 403;
|
|
98
|
+
}
|
|
99
|
+
var LlmConfigProviderAuth = class {
|
|
100
|
+
provider;
|
|
101
|
+
apiKeyPool;
|
|
102
|
+
providerId;
|
|
103
|
+
sessionId;
|
|
104
|
+
/**
|
|
105
|
+
* The current resolved key. Mutable so a Phase-3 caller can read the
|
|
106
|
+
* rotated key after `onResult`; this phase it is only set at construction
|
|
107
|
+
* and updated inside `onResult` (mirroring the inline re-point in
|
|
108
|
+
* `callWithPoolReporting`).
|
|
109
|
+
*/
|
|
110
|
+
apiKey;
|
|
111
|
+
constructor(opts) {
|
|
112
|
+
this.provider = opts.provider;
|
|
113
|
+
this.apiKey = opts.apiKey;
|
|
114
|
+
this.apiKeyPool = opts.apiKeyPool ?? null;
|
|
115
|
+
this.providerId = opts.providerId;
|
|
116
|
+
this.sessionId = opts.sessionId;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Merge the provider auth headers (and content-type / OpenRouter app
|
|
120
|
+
* headers) into `headers`, exactly as a direct `getProviderHeaders` call
|
|
121
|
+
* would produce them. `hints` are accepted for contract symmetry but the
|
|
122
|
+
* provider-key path does not vary headers by URL/model.
|
|
123
|
+
*/
|
|
124
|
+
applyHeaders(headers, _hints) {
|
|
125
|
+
const authHeaders = getProviderHeaders(this.provider, this.apiKey);
|
|
126
|
+
for (const [k, v] of Object.entries(authHeaders)) {
|
|
127
|
+
headers[k] = v;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* React to the final HTTP status — the pool-rotation seam (design D5).
|
|
132
|
+
*
|
|
133
|
+
* Reproduces `callWithPoolReporting`'s reportable + success branches:
|
|
134
|
+
* - reportable status (429/529/401/403) on a pool-backed request →
|
|
135
|
+
* `reportError(providerId, sessionId, status)`; when it hands back a
|
|
136
|
+
* `newKey` the session was re-bound, so we adopt it (`this.apiKey`) and
|
|
137
|
+
* return `{ rebound: true, newKey }`. When no key is available it returns
|
|
138
|
+
* `{ rebound: false }` (the session is still cooled/disabled by the report).
|
|
139
|
+
* - success / any 2xx → `reportSuccess(sessionId)`; `{ rebound: false }`.
|
|
140
|
+
* - non-reportable, non-success, or non-pool request → no-op
|
|
141
|
+
* `{ rebound: false }`.
|
|
142
|
+
*
|
|
143
|
+
* NOTE: no caller invokes this in Phase 2; it is unit-tested in isolation.
|
|
144
|
+
*/
|
|
145
|
+
async onResult(status) {
|
|
146
|
+
const pool = this.apiKeyPool;
|
|
147
|
+
const providerId = this.providerId;
|
|
148
|
+
const sessionId = this.sessionId;
|
|
149
|
+
if (!pool || !providerId || !sessionId) {
|
|
150
|
+
return { rebound: false };
|
|
151
|
+
}
|
|
152
|
+
if (isReportableStatus(status)) {
|
|
153
|
+
const newKey = await pool.reportError(providerId, sessionId, status);
|
|
154
|
+
if (newKey) {
|
|
155
|
+
this.apiKey = newKey;
|
|
156
|
+
return { rebound: true, newKey };
|
|
157
|
+
}
|
|
158
|
+
return { rebound: false };
|
|
159
|
+
}
|
|
160
|
+
if (status !== null && status >= 200 && status < 300) {
|
|
161
|
+
pool.reportSuccess(sessionId);
|
|
162
|
+
}
|
|
163
|
+
return { rebound: false };
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
167
|
+
0 && (module.exports = {
|
|
168
|
+
LlmConfigProviderAuth
|
|
169
|
+
});
|