@x12i/ai-gateway 11.0.5 → 11.1.0

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 (77) hide show
  1. package/dist/gateway-config.d.ts +4 -4
  2. package/dist/gateway-config.js +18 -53
  3. package/dist/gateway-log-levels.d.ts +3 -1
  4. package/dist/gateway-log-levels.js +2 -1
  5. package/dist/gateway-retry.d.ts +2 -2
  6. package/dist/gateway-router.d.ts +42 -0
  7. package/dist/gateway-router.js +118 -0
  8. package/dist/gateway-utils.d.ts +2 -2
  9. package/dist/gateway-utils.js +1 -1
  10. package/dist/gateway.d.ts +2 -3
  11. package/dist/gateway.js +4 -16
  12. package/dist/index.d.ts +9 -13
  13. package/dist/index.js +7 -13
  14. package/dist/openrouter-runtime-adapter/index.d.ts +1 -3
  15. package/dist/openrouter-runtime-adapter/index.js +1 -3
  16. package/dist/openrouter-runtime-adapter/map-gateway-request.d.ts +1 -2
  17. package/dist/openrouter-runtime-adapter/map-gateway-request.js +0 -1
  18. package/dist/openrouter-runtime-adapter/map-runtime-errors.d.ts +14 -3
  19. package/dist/openrouter-runtime-adapter/map-runtime-errors.js +13 -3
  20. package/dist/openrouter-runtime-adapter/map-runtime-response.d.ts +2 -2
  21. package/dist/openrouter-runtime-adapter/map-server-tools.d.ts +1 -1
  22. package/dist/openrouter-runtime-adapter/should-use-openrouter-runtime.d.ts +1 -6
  23. package/dist/openrouter-runtime-adapter/should-use-openrouter-runtime.js +1 -6
  24. package/dist/router-errors.d.ts +52 -0
  25. package/dist/router-errors.js +115 -0
  26. package/dist/router-types.d.ts +147 -0
  27. package/dist/router-types.js +4 -0
  28. package/dist/types.d.ts +11 -16
  29. package/dist-cjs/gateway-config.cjs +18 -53
  30. package/dist-cjs/gateway-config.d.ts +4 -4
  31. package/dist-cjs/gateway-log-levels.cjs +2 -1
  32. package/dist-cjs/gateway-log-levels.d.ts +3 -1
  33. package/dist-cjs/gateway-retry.d.ts +2 -2
  34. package/dist-cjs/gateway-router.cjs +118 -0
  35. package/dist-cjs/gateway-router.d.ts +42 -0
  36. package/dist-cjs/gateway-utils.cjs +1 -1
  37. package/dist-cjs/gateway-utils.d.ts +2 -2
  38. package/dist-cjs/gateway.cjs +4 -16
  39. package/dist-cjs/gateway.d.ts +2 -3
  40. package/dist-cjs/index.cjs +7 -13
  41. package/dist-cjs/index.d.ts +9 -13
  42. package/dist-cjs/openrouter-runtime-adapter/index.cjs +1 -3
  43. package/dist-cjs/openrouter-runtime-adapter/index.d.ts +1 -3
  44. package/dist-cjs/openrouter-runtime-adapter/map-gateway-request.cjs +0 -1
  45. package/dist-cjs/openrouter-runtime-adapter/map-gateway-request.d.ts +1 -2
  46. package/dist-cjs/openrouter-runtime-adapter/map-runtime-errors.cjs +13 -3
  47. package/dist-cjs/openrouter-runtime-adapter/map-runtime-errors.d.ts +14 -3
  48. package/dist-cjs/openrouter-runtime-adapter/map-runtime-response.d.ts +2 -2
  49. package/dist-cjs/openrouter-runtime-adapter/map-server-tools.d.ts +1 -1
  50. package/dist-cjs/openrouter-runtime-adapter/should-use-openrouter-runtime.cjs +1 -6
  51. package/dist-cjs/openrouter-runtime-adapter/should-use-openrouter-runtime.d.ts +1 -6
  52. package/dist-cjs/router-errors.cjs +115 -0
  53. package/dist-cjs/router-errors.d.ts +52 -0
  54. package/dist-cjs/router-types.cjs +4 -0
  55. package/dist-cjs/router-types.d.ts +147 -0
  56. package/dist-cjs/types.d.ts +11 -16
  57. package/package.json +5 -6
  58. package/dist/gateway-provider-auto-register.d.ts +0 -17
  59. package/dist/gateway-provider-auto-register.js +0 -159
  60. package/dist/gateway-provider.d.ts +0 -54
  61. package/dist/gateway-provider.js +0 -202
  62. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-adapter.d.ts +0 -23
  63. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-adapter.js +0 -31
  64. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-provider.d.ts +0 -10
  65. package/dist/openrouter-runtime-adapter/create-openrouter-runtime-provider.js +0 -152
  66. package/dist/openrouter-runtime-adapter/register-openrouter-runtime.d.ts +0 -10
  67. package/dist/openrouter-runtime-adapter/register-openrouter-runtime.js +0 -19
  68. package/dist-cjs/gateway-provider-auto-register.cjs +0 -159
  69. package/dist-cjs/gateway-provider-auto-register.d.ts +0 -17
  70. package/dist-cjs/gateway-provider.cjs +0 -202
  71. package/dist-cjs/gateway-provider.d.ts +0 -54
  72. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-adapter.cjs +0 -31
  73. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-adapter.d.ts +0 -23
  74. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-provider.cjs +0 -152
  75. package/dist-cjs/openrouter-runtime-adapter/create-openrouter-runtime-provider.d.ts +0 -10
  76. package/dist-cjs/openrouter-runtime-adapter/register-openrouter-runtime.cjs +0 -19
  77. package/dist-cjs/openrouter-runtime-adapter/register-openrouter-runtime.d.ts +0 -10
@@ -1,6 +1,16 @@
1
- import { OpenRouterHttpError, RuntimeConfigError, } from '@x12i/openrouter-runtime';
2
1
  import { GatewayPolicyViolationError, GatewayValidationError, ProviderConfigError, ProviderInvokeError, } from '../instruction-errors.js';
3
2
  import { buildPartialMetadataFromRuntimeResponse, buildRouterLikeEnvelopeFromRuntimeResponse, } from './map-runtime-response.js';
3
+ function isRuntimeConfigError(err) {
4
+ return (err instanceof Error &&
5
+ err.name === 'RuntimeConfigError' &&
6
+ typeof err.code === 'string');
7
+ }
8
+ function isOpenRouterHttpError(err) {
9
+ return (err instanceof Error &&
10
+ err.name === 'OpenRouterHttpError' &&
11
+ typeof err.status === 'number' &&
12
+ typeof err.code === 'string');
13
+ }
4
14
  function attachRouterEnvelopeToError(err, response) {
5
15
  const envelope = buildRouterLikeEnvelopeFromRuntimeResponse(response);
6
16
  err.response = envelope;
@@ -52,7 +62,7 @@ export function throwMappedRuntimeResponseErrors(response) {
52
62
  throw err;
53
63
  }
54
64
  export function mapRuntimeErrorToGatewayError(err) {
55
- if (err instanceof RuntimeConfigError) {
65
+ if (isRuntimeConfigError(err)) {
56
66
  try {
57
67
  throwMappedRuntimeConfigError(err);
58
68
  }
@@ -60,7 +70,7 @@ export function mapRuntimeErrorToGatewayError(err) {
60
70
  return mapped;
61
71
  }
62
72
  }
63
- if (err instanceof OpenRouterHttpError) {
73
+ if (isOpenRouterHttpError(err)) {
64
74
  try {
65
75
  throwMappedOpenRouterHttpError(err);
66
76
  }
@@ -1,5 +1,5 @@
1
- import type { AIResponse } from '@x12i/ai-providers-router';
2
- import type { RuntimeResponse } from '@x12i/openrouter-runtime';
1
+ import type { AIResponse } from '../router-types.js';
2
+ import type { RuntimeResponse } from '@x12i/ai-router-runtime';
3
3
  import type { GatewayCitation, GatewayGeneratedImage, GatewayOpenRouterRuntimeMetadata, GatewayPatchProposal, GatewayServerToolUsageMap } from '../types.js';
4
4
  export declare function mapRuntimeToolUsage(toolUsage: RuntimeResponse['toolUsage']): GatewayServerToolUsageMap;
5
5
  export declare function mapRuntimeCitations(citations: RuntimeResponse['citations']): GatewayCitation[];
@@ -1,3 +1,3 @@
1
1
  import type { GatewayServerToolsConfig } from '../types.js';
2
- import type { RuntimeServerToolsPolicy } from '@x12i/openrouter-runtime';
2
+ import type { RuntimeServerToolsPolicy } from '@x12i/ai-router-runtime';
3
3
  export declare function mapGatewayServerTools(config?: GatewayServerToolsConfig): RuntimeServerToolsPolicy | undefined;
@@ -1,11 +1,6 @@
1
1
  import type { GatewayConfig } from '../types.js';
2
2
  /**
3
- * Whether the gateway should register @x12i/openrouter-runtime instead of the router's legacy OpenRouter provider.
4
- *
5
- * - AI_GATEWAY_USE_LEGACY_OPENROUTER=1 → legacy router OpenRouter
6
- * - AI_GATEWAY_USE_OPENROUTER_RUNTIME=0 → legacy
7
- * - GatewayConfig.openrouterRuntime.enabled=false → legacy
8
- * - default → runtime enabled
3
+ * Whether OpenRouter runtime path is enabled (always true with @x12i/ai-router-runtime).
9
4
  */
10
5
  export declare function shouldUseOpenRouterRuntime(config?: GatewayConfig): boolean;
11
6
  export declare function resolveOpenRouterRuntimeDefaults(config?: GatewayConfig): {
@@ -1,10 +1,5 @@
1
1
  /**
2
- * Whether the gateway should register @x12i/openrouter-runtime instead of the router's legacy OpenRouter provider.
3
- *
4
- * - AI_GATEWAY_USE_LEGACY_OPENROUTER=1 → legacy router OpenRouter
5
- * - AI_GATEWAY_USE_OPENROUTER_RUNTIME=0 → legacy
6
- * - GatewayConfig.openrouterRuntime.enabled=false → legacy
7
- * - default → runtime enabled
2
+ * Whether OpenRouter runtime path is enabled (always true with @x12i/ai-router-runtime).
8
3
  */
9
4
  export function shouldUseOpenRouterRuntime(config) {
10
5
  const legacyEnv = process.env.AI_GATEWAY_USE_LEGACY_OPENROUTER;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Router error types and enrichment helpers for gateway consumers.
3
+ */
4
+ export declare const PROVIDER_FAILURE_CODES: readonly ["OPENROUTER_API_KEY_MISSING", "PROVIDER_AUTH_FAILED", "PROVIDER_RATE_LIMITED", "PROVIDER_QUOTA_EXCEEDED", "PROVIDER_MODEL_NOT_FOUND", "PROVIDER_GATEWAY_UNREACHABLE", "PROVIDER_NOT_REGISTERED", "PROVIDER_REQUEST_FAILED", "PROVIDER_INVOKE_FAILED"];
5
+ export type ProviderFailureCode = (typeof PROVIDER_FAILURE_CODES)[number];
6
+ export type ProviderAttemptDetail = {
7
+ provider: string;
8
+ modelId?: string;
9
+ httpStatus?: number;
10
+ message: string;
11
+ code: ProviderFailureCode;
12
+ retryable?: boolean;
13
+ };
14
+ export declare function operatorHintForProviderFailureCode(code: ProviderFailureCode): string;
15
+ export type FallbackAttempt = {
16
+ provider: string;
17
+ model?: string;
18
+ httpStatus?: number;
19
+ code?: ProviderFailureCode;
20
+ message?: string;
21
+ error: Error;
22
+ responsePreview?: string;
23
+ };
24
+ export declare class ProviderNotFoundError extends Error {
25
+ constructor(providerName: string);
26
+ }
27
+ export declare class OpenRouterApiKeyMissingError extends Error {
28
+ readonly code: "OPENROUTER_API_KEY_MISSING";
29
+ constructor();
30
+ }
31
+ export declare class FallbackExhaustedError extends Error {
32
+ attempts: FallbackAttempt[];
33
+ code?: ProviderFailureCode;
34
+ operatorHint?: string;
35
+ details?: {
36
+ providerAttempts: ProviderAttemptDetail[];
37
+ };
38
+ constructor(attempts: FallbackAttempt[]);
39
+ }
40
+ export declare function buildProviderAttemptDetail(input: {
41
+ provider: string;
42
+ modelId?: string;
43
+ httpStatus?: number;
44
+ message: string;
45
+ code?: ProviderFailureCode;
46
+ err?: unknown;
47
+ }): ProviderAttemptDetail;
48
+ export declare function providerAttemptsFromFallbackAttempts(attempts: FallbackAttempt[]): ProviderAttemptDetail[];
49
+ export declare function enrichRunTaskError(err: Error, input?: {
50
+ providerAttempts?: ProviderAttemptDetail[];
51
+ code?: ProviderFailureCode;
52
+ }): Error;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Router error types and enrichment helpers for gateway consumers.
3
+ */
4
+ export const PROVIDER_FAILURE_CODES = [
5
+ 'OPENROUTER_API_KEY_MISSING',
6
+ 'PROVIDER_AUTH_FAILED',
7
+ 'PROVIDER_RATE_LIMITED',
8
+ 'PROVIDER_QUOTA_EXCEEDED',
9
+ 'PROVIDER_MODEL_NOT_FOUND',
10
+ 'PROVIDER_GATEWAY_UNREACHABLE',
11
+ 'PROVIDER_NOT_REGISTERED',
12
+ 'PROVIDER_REQUEST_FAILED',
13
+ 'PROVIDER_INVOKE_FAILED',
14
+ ];
15
+ const OPERATOR_HINTS = {
16
+ OPENROUTER_API_KEY_MISSING: 'Set OPENROUTER_API_KEY or OPEN_ROUTER_KEY, or pass apiKey when creating the runtime.',
17
+ PROVIDER_AUTH_FAILED: 'Check that the OpenRouter API key is present, valid, and authorized for this route.',
18
+ PROVIDER_RATE_LIMITED: 'Retry after the provider rate limit resets or reduce request concurrency.',
19
+ PROVIDER_QUOTA_EXCEEDED: 'Check provider billing, credits, quota, and project limits.',
20
+ PROVIDER_MODEL_NOT_FOUND: 'Verify the model id and whether it is available through OpenRouter for this account.',
21
+ PROVIDER_GATEWAY_UNREACHABLE: 'Retry later; the provider gateway was unreachable or timed out.',
22
+ PROVIDER_NOT_REGISTERED: 'Provider module is not registered; install and configure the provider package.',
23
+ PROVIDER_REQUEST_FAILED: 'Provider call failed; inspect providerAttempts in error.details for per-attempt diagnostics.',
24
+ PROVIDER_INVOKE_FAILED: 'Provider call failed; inspect providerAttempts in error.details for per-attempt diagnostics.',
25
+ };
26
+ export function operatorHintForProviderFailureCode(code) {
27
+ return OPERATOR_HINTS[code];
28
+ }
29
+ export class ProviderNotFoundError extends Error {
30
+ constructor(providerName) {
31
+ super(`Provider not found: ${providerName}`);
32
+ this.name = 'ProviderNotFoundError';
33
+ }
34
+ }
35
+ export class OpenRouterApiKeyMissingError extends Error {
36
+ code = 'OPENROUTER_API_KEY_MISSING';
37
+ constructor() {
38
+ super('OPENROUTER_API_KEY is required for OpenRouter routing');
39
+ this.name = 'OpenRouterApiKeyMissingError';
40
+ }
41
+ }
42
+ export class FallbackExhaustedError extends Error {
43
+ attempts;
44
+ code;
45
+ operatorHint;
46
+ details;
47
+ constructor(attempts) {
48
+ super('All providers in the fallback chain failed');
49
+ this.name = 'FallbackExhaustedError';
50
+ this.attempts = attempts;
51
+ }
52
+ }
53
+ function classifyProviderFailure(err) {
54
+ const message = err instanceof Error ? err.message : typeof err === 'string' ? err : String(err ?? '');
55
+ const lower = message.toLowerCase();
56
+ if (lower.includes('openrouter_api_key') || lower.includes('api key missing')) {
57
+ return 'OPENROUTER_API_KEY_MISSING';
58
+ }
59
+ if (lower.includes('rate limit') || lower.includes('429'))
60
+ return 'PROVIDER_RATE_LIMITED';
61
+ if (lower.includes('quota') || lower.includes('insufficient'))
62
+ return 'PROVIDER_QUOTA_EXCEEDED';
63
+ if (lower.includes('model not found') || lower.includes('404'))
64
+ return 'PROVIDER_MODEL_NOT_FOUND';
65
+ if (lower.includes('unauthorized') || lower.includes('401') || lower.includes('403')) {
66
+ return 'PROVIDER_AUTH_FAILED';
67
+ }
68
+ if (lower.includes('fetch failed') ||
69
+ lower.includes('econnrefused') ||
70
+ lower.includes('etimedout') ||
71
+ lower.includes('network')) {
72
+ return 'PROVIDER_GATEWAY_UNREACHABLE';
73
+ }
74
+ return 'PROVIDER_REQUEST_FAILED';
75
+ }
76
+ export function buildProviderAttemptDetail(input) {
77
+ return {
78
+ provider: input.provider,
79
+ ...(input.modelId !== undefined ? { modelId: input.modelId } : {}),
80
+ ...(input.httpStatus !== undefined ? { httpStatus: input.httpStatus } : {}),
81
+ message: input.message,
82
+ code: input.code ?? classifyProviderFailure(input.err ?? input.message),
83
+ };
84
+ }
85
+ export function providerAttemptsFromFallbackAttempts(attempts) {
86
+ return attempts.map((a) => buildProviderAttemptDetail({
87
+ provider: String(a.provider),
88
+ modelId: a.model,
89
+ httpStatus: a.httpStatus,
90
+ message: a.message ?? a.error.message,
91
+ code: a.code,
92
+ err: a.error,
93
+ }));
94
+ }
95
+ function resolveExhaustedFailureCode(providerAttempts) {
96
+ if (providerAttempts.length === 0)
97
+ return 'PROVIDER_REQUEST_FAILED';
98
+ return providerAttempts[providerAttempts.length - 1].code;
99
+ }
100
+ export function enrichRunTaskError(err, input) {
101
+ const existingCode = err.code;
102
+ const providerAttempts = input?.providerAttempts ??
103
+ (err instanceof FallbackExhaustedError ? providerAttemptsFromFallbackAttempts(err.attempts) : []);
104
+ const code = input?.code ??
105
+ existingCode ??
106
+ (providerAttempts.length > 0 ? resolveExhaustedFailureCode(providerAttempts) : undefined) ??
107
+ classifyProviderFailure(err);
108
+ const enriched = err;
109
+ enriched.code = code;
110
+ enriched.operatorHint = operatorHintForProviderFailureCode(code);
111
+ if (providerAttempts.length > 0) {
112
+ enriched.details = { providerAttempts };
113
+ }
114
+ return enriched;
115
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Router-level types for @x12i/ai-gateway (backed by @x12i/ai-router-runtime).
3
+ */
4
+ import type { LogLevel, Logxer, StackLoggingOptions } from '@x12i/logxer';
5
+ import type { ProviderFailureCode } from './router-errors.js';
6
+ export type RouterMode = 'sync' | 'stream' | 'batch';
7
+ export type NormalizedUsage = {
8
+ promptTokens: number;
9
+ completionTokens: number;
10
+ totalTokens: number;
11
+ };
12
+ export type ActivityCostStatus = 'priced' | 'unpriced';
13
+ export type ProviderModelRef = {
14
+ engine?: string;
15
+ provider?: string;
16
+ model?: string;
17
+ };
18
+ export type AttemptErrorSummary = {
19
+ name: string;
20
+ message: string;
21
+ code: ProviderFailureCode;
22
+ httpStatus?: number;
23
+ responsePreview?: string;
24
+ };
25
+ export type DiagnosticsMetadata = {
26
+ provider?: string;
27
+ region?: string;
28
+ modelUsed?: string;
29
+ costUsd?: number;
30
+ cost?: number;
31
+ costStatus?: ActivityCostStatus;
32
+ maxTokensRequested?: number;
33
+ requestIds?: Record<string, string | undefined>;
34
+ timing?: {
35
+ startedAt: number;
36
+ endedAt: number;
37
+ durationMs: number;
38
+ };
39
+ latencyMs?: number;
40
+ attempts?: unknown[];
41
+ failureCode?: ProviderFailureCode;
42
+ providerAttempts?: unknown[];
43
+ operatorHint?: string;
44
+ normalization?: {
45
+ normalizedConfig?: Record<string, unknown>;
46
+ warnings?: string[];
47
+ };
48
+ [key: string]: unknown;
49
+ };
50
+ /**
51
+ * Router configuration shared between gateway init and standalone router factory.
52
+ */
53
+ export interface GatewayRouterConfig {
54
+ usageTracker?: {
55
+ recordRequest(event: {
56
+ provider: string;
57
+ timestamp: number;
58
+ duration: number;
59
+ tokens: {
60
+ input: number;
61
+ output: number;
62
+ total: number;
63
+ };
64
+ cost?: number;
65
+ success: boolean;
66
+ }): void;
67
+ };
68
+ verbose?: boolean;
69
+ logLevel?: LogLevel;
70
+ logging?: StackLoggingOptions;
71
+ logger?: Logxer;
72
+ timeoutMs?: number;
73
+ defaultTimeoutMs?: number;
74
+ preferOpenRouter?: boolean;
75
+ /** @deprecated Use preferOpenRouter. */
76
+ useOpenRouter?: boolean;
77
+ openrouter?: {
78
+ apiKey?: string;
79
+ httpReferer?: string;
80
+ xTitle?: string;
81
+ };
82
+ fallbackChain?: ProviderModelRef[];
83
+ defaultProvider?: string;
84
+ autoDiscover?: boolean;
85
+ }
86
+ export interface AIRouterRequest {
87
+ requestId?: string;
88
+ request: Record<string, unknown>;
89
+ provider?: string;
90
+ mode: RouterMode;
91
+ exec?: {
92
+ timeoutMs?: number;
93
+ retries?: number;
94
+ idempotencyKey?: string;
95
+ signal?: AbortSignal;
96
+ };
97
+ }
98
+ export type NormalizedRouterOutput = {
99
+ parsed?: Record<string, unknown>;
100
+ };
101
+ export interface AIResponse {
102
+ requestId: string;
103
+ provider: string;
104
+ rawResponse: unknown;
105
+ outputText?: string;
106
+ output?: NormalizedRouterOutput;
107
+ usage?: NormalizedUsage;
108
+ reasoning: {
109
+ requested: {
110
+ effort: string;
111
+ visibility: string;
112
+ };
113
+ applied: {
114
+ effort: string;
115
+ visibility: string;
116
+ };
117
+ artifacts: {
118
+ encrypted?: unknown[];
119
+ summary?: {
120
+ text: string;
121
+ format: string;
122
+ };
123
+ trace?: {
124
+ text: string;
125
+ format: string;
126
+ };
127
+ };
128
+ availability: {
129
+ supportsEffort: boolean;
130
+ supportsSummary: boolean;
131
+ supportsTrace: boolean;
132
+ supportsEncrypted: boolean;
133
+ };
134
+ warnings?: unknown[];
135
+ };
136
+ metadata?: DiagnosticsMetadata;
137
+ }
138
+ export interface HealthCheckResult {
139
+ provider: string;
140
+ healthy: boolean;
141
+ latencyMs?: number;
142
+ error?: string;
143
+ }
144
+ /** @deprecated Use {@link GatewayRouterConfig}. */
145
+ export type RouterConfig = GatewayRouterConfig;
146
+ /** Backward-compatible alias for {@link GatewayRouter}. */
147
+ export type LLMProviderRouter = import('./gateway-router.js').GatewayRouter;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Router-level types for @x12i/ai-gateway (backed by @x12i/ai-router-runtime).
3
+ */
4
+ export {};
package/dist/types.d.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Extends router types with gateway-specific enhancements
5
5
  */
6
- import { AIResponse, LLMProviderRouter, type RouterConfig } from '@x12i/ai-providers-router';
6
+ import type { AIResponse, GatewayRouterConfig } from './router-types.js';
7
+ import type { GatewayRouter } from './gateway-router.js';
7
8
  type AIProvider = string;
8
9
  type AIModel = string;
9
10
  export type UsageTier = string;
@@ -366,7 +367,7 @@ export type GatewayInvokeRejectionMetadata = {
366
367
  */
367
368
  fallbackAttempts?: GatewayFallbackAttempt[];
368
369
  /**
369
- * Structured per-attempt diagnostics (`@x12i/ai-providers-router` 4.10).
370
+ * Structured per-attempt diagnostics from the gateway fallback chain.
370
371
  * Same attempts as {@link fallbackAttempts} when enriched; prefer this for UIs.
371
372
  */
372
373
  providerAttempts?: Array<{
@@ -399,7 +400,7 @@ export type GatewayFallbackAttempt = {
399
400
  model?: string;
400
401
  httpStatus?: number;
401
402
  error: string;
402
- /** Stable sub-code from `@x12i/ai-providers-router` ≥ 4.10 (`PROVIDER_AUTH_FAILED`, …). */
403
+ /** Stable sub-code (`PROVIDER_AUTH_FAILED`, …). */
403
404
  code?: string;
404
405
  responsePreview?: string;
405
406
  };
@@ -456,18 +457,12 @@ export type ActivityIdentity = {
456
457
  };
457
458
  /** Re-export parser template options for gateway consumers (MUST/optional protocol, subPathSearch, smartInput, etc.). */
458
459
  export type { SmartInputConfig, SmartInputRenderOptions, TemplateRenderOptions } from '@x12i/rendrix';
459
- type LLMRequest = Parameters<LLMProviderRouter['invoke']>[0];
460
- type LLMResponse = Awaited<ReturnType<LLMProviderRouter['invoke']>>;
460
+ type LLMRequest = Parameters<GatewayRouter['invoke']>[0];
461
+ type LLMResponse = Awaited<ReturnType<GatewayRouter['invoke']>>;
461
462
  /**
462
463
  * Gateway configuration extending router configuration
463
464
  *
464
- * RouterConfig already includes:
465
- * - defaultProvider?: LLMProvider (from llm-provider-interface)
466
- * - fallbackChain?: LLMProvider[]
467
- * - autoDiscover?: boolean
468
- * - usageTracker?: UsageTracker
469
- *
470
- * We don't need to redeclare these - they're inherited from RouterConfig
465
+ * GatewayRouterConfig fields (defaultProvider, fallbackChain, usageTracker, …) are inherited below.
471
466
  */
472
467
  /**
473
468
  * Provider + model reference used for defaults and fallbacks
@@ -578,7 +573,7 @@ export interface ModelConfig {
578
573
  }
579
574
  /** Alias for {@link ModelConfig} in gateway documentation. */
580
575
  export type GatewayModelConfig = ModelConfig;
581
- export interface GatewayConfig extends Omit<RouterConfig, 'defaultEngine' | 'logger'> {
576
+ export interface GatewayConfig extends Omit<GatewayRouterConfig, 'logger'> {
582
577
  /**
583
578
  * Default target (engine + model) for routing
584
579
  */
@@ -610,8 +605,8 @@ export interface GatewayConfig extends Omit<RouterConfig, 'defaultEngine' | 'log
610
605
  /**
611
606
  * Process-wide package log level registry (logxer ≥ 4.5).
612
607
  * Merged after `applyPackageLogLevelsFromEnv()` on first gateway init.
613
- * `logging` (from {@link RouterConfig}) is forwarded to the gateway logger and router.
614
- * @example `{ default: 'warn', levels: { AI_GATEWAY: 'info', AI_PROVIDER_ROUTER: 'debug' } }`
608
+ * `logging` is forwarded to the gateway logger and router runtime.
609
+ * @example `{ default: 'warn', levels: { AI_GATEWAY: 'info', AI_ROUTER_RUNTIME: 'debug' } }`
615
610
  */
616
611
  packageLogLevels?: PackageLogLevelsConfig;
617
612
  /**
@@ -627,7 +622,7 @@ export interface GatewayConfig extends Omit<RouterConfig, 'defaultEngine' | 'log
627
622
  packageName?: string;
628
623
  /**
629
624
  * Full payload logging for gateway-owned verbose lines (`AI_GATEWAY_VERBOSE=true`).
630
- * Separate from log threshold (`AI_GATEWAY_LOGS_LEVEL=verbose`). Router I/O payloads use the same flag via `RouterConfig.verbose`.
625
+ * Separate from log threshold (`AI_GATEWAY_LOGS_LEVEL=verbose`). Router I/O payloads use the same flag via `GatewayRouterConfig.verbose`.
631
626
  */
632
627
  verbose?: boolean;
633
628
  /**
@@ -6,12 +6,11 @@ import * as fs from 'fs';
6
6
  import * as path from 'path';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { resolveOpenRouterApiKey, resolvePreferOpenRouter, } from './openrouter-routing.js';
9
- import { LLMProviderRouter } from '@x12i/ai-providers-router';
9
+ import { GatewayRouter } from './gateway-router.js';
10
10
  import { createGatewayLogger } from './logger-factory.js';
11
11
  import { ActivityManager } from './activity-manager.js';
12
12
  import { UsageTracker } from './usage-tracker.js';
13
13
  import { mergeTemplateRenderOptions } from './template-render-merge.js';
14
- import { registerOpenRouterRuntime, shouldUseOpenRouterRuntime, } from './openrouter-runtime-adapter/index.js';
15
14
  /** Resolve current module directory across ESM/CJS builds. */
16
15
  function getModuleDir() {
17
16
  if (typeof __dirname !== 'undefined') {
@@ -83,12 +82,12 @@ export function loadConfig(logger) {
83
82
  */
84
83
  export function setupRequestInterceptor(router, logger) {
85
84
  logger.debug('Setting up request interceptor for jobId propagation and config cleanup');
86
- router.addRequestInterceptor(async (request, provider) => {
85
+ router.addRequestInterceptor(async (request) => {
87
86
  const identityJobId = request?.identity?.jobId;
88
87
  if (typeof identityJobId === 'string' && identityJobId.trim().length > 0) {
89
88
  logger.verbose('Propagating identity.jobId to request metadata', {
90
89
  jobId: identityJobId,
91
- provider: provider?.getProviderName?.() || 'unknown'
90
+ provider: 'openrouter'
92
91
  });
93
92
  if (!request.config) {
94
93
  request.config = {};
@@ -99,7 +98,7 @@ export function setupRequestInterceptor(router, logger) {
99
98
  request.config.metadata.jobId = identityJobId;
100
99
  }
101
100
  if (request.config && 'provider' in request.config) {
102
- logger.debug('Removing provider from config before passing to provider', {
101
+ logger.debug('Removing provider from config before passing to router', {
103
102
  provider: request.config.provider
104
103
  });
105
104
  const { provider: _, ...cleanConfig } = request.config;
@@ -126,59 +125,25 @@ export function initializeGatewayComponents(config) {
126
125
  defaultEngine: config.defaultEngine,
127
126
  hasTemplateRenderingDefaults: !!defaultTemplateRendering
128
127
  });
129
- const routerConfig = {};
130
- const defaultTarget = config.defaultTarget;
131
- if (defaultTarget) {
132
- routerConfig.defaultTarget = defaultTarget;
133
- }
134
- else if (config.defaultProvider !== undefined) {
135
- routerConfig.defaultProvider = config.defaultProvider;
136
- }
137
- else if (config.defaultEngine !== undefined) {
138
- routerConfig.defaultProvider = config.defaultEngine;
139
- }
140
- const fallbackChain = config.fallbackChain;
141
- if (fallbackChain) {
142
- routerConfig.fallbackChain = fallbackChain;
143
- }
144
- else if (config.fallbackChain !== undefined) {
145
- routerConfig.fallbackChain = config.fallbackChain;
146
- }
147
- if (config.autoDiscover !== undefined)
148
- routerConfig.autoDiscover = config.autoDiscover;
149
- if (config.usageTracker !== undefined)
150
- routerConfig.usageTracker = config.usageTracker;
151
- if (config.verbose !== undefined)
152
- routerConfig.verbose = config.verbose;
153
- if (config.logLevel !== undefined)
154
- routerConfig.logLevel = config.logLevel;
155
- if (config.logging !== undefined)
156
- routerConfig.logging = config.logging;
157
128
  const openRouterKey = resolveOpenRouterApiKey(config);
158
129
  const preferOpenRouter = resolvePreferOpenRouter(config);
159
- if (openRouterKey) {
160
- routerConfig.openrouter = { apiKey: openRouterKey };
161
- routerConfig.openRouter = {
162
- enabled: true,
163
- prefer: preferOpenRouter,
164
- };
165
- if (preferOpenRouter) {
166
- routerConfig.defaultMode = 'openrouter';
167
- }
168
- }
169
- const router = new LLMProviderRouter(routerConfig);
130
+ const router = new GatewayRouter({
131
+ verbose: config.verbose,
132
+ logLevel: config.logLevel,
133
+ logging: config.logging,
134
+ logger,
135
+ usageTracker: config.usageTracker,
136
+ openrouterRuntime: config.openrouterRuntime,
137
+ ...(openRouterKey ? { openrouter: { apiKey: openRouterKey } } : {}),
138
+ });
170
139
  setupRequestInterceptor(router, logger);
171
- if (openRouterKey && shouldUseOpenRouterRuntime(config)) {
172
- registerOpenRouterRuntime(router, {
173
- apiKey: openRouterKey,
174
- logger,
175
- runtimeConfig: config.openrouterRuntime,
140
+ if (openRouterKey) {
141
+ logger.debug('OpenRouter runtime enabled via @x12i/ai-router-runtime', {
142
+ openrouterRuntimeEnabled: config.openrouterRuntime?.enabled !== false,
176
143
  });
177
144
  }
178
- else if (openRouterKey) {
179
- logger.debug('OpenRouter legacy provider path enabled (runtime disabled)', {
180
- AI_GATEWAY_USE_OPENROUTER_RUNTIME: process.env.AI_GATEWAY_USE_OPENROUTER_RUNTIME,
181
- AI_GATEWAY_USE_LEGACY_OPENROUTER: process.env.AI_GATEWAY_USE_LEGACY_OPENROUTER,
145
+ else {
146
+ logger.debug('OpenRouter runtime not configured (OPENROUTER_API_KEY missing)', {
182
147
  openrouterRuntimeEnabled: config.openrouterRuntime?.enabled,
183
148
  });
184
149
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { GatewayConfig } from './types.js';
6
6
  import type { Logxer } from '@x12i/logxer';
7
- import { LLMProviderRouter } from '@x12i/ai-providers-router';
7
+ import { GatewayRouter } from './gateway-router.js';
8
8
  import { ActivityManager } from './activity-manager.js';
9
9
  import { UsageTracker } from './usage-tracker.js';
10
10
  import type { MessageBuilderConfig } from './message-builder.js';
@@ -12,7 +12,7 @@ import type { TemplateRenderOptions } from '@x12i/rendrix';
12
12
  export interface GatewayConfigContext {
13
13
  config: GatewayConfig;
14
14
  logger: Logxer;
15
- router: LLMProviderRouter;
15
+ router: GatewayRouter;
16
16
  activityManager: ActivityManager;
17
17
  usageTracker: UsageTracker;
18
18
  messageBuilderConfig: MessageBuilderConfig;
@@ -27,13 +27,13 @@ export declare function loadConfig(logger: Logxer): {
27
27
  /**
28
28
  * Sets up request interceptor for jobId propagation and config cleanup
29
29
  */
30
- export declare function setupRequestInterceptor(router: LLMProviderRouter, logger: Logxer): void;
30
+ export declare function setupRequestInterceptor(router: GatewayRouter, logger: Logxer): void;
31
31
  /**
32
32
  * Initializes gateway components
33
33
  */
34
34
  export declare function initializeGatewayComponents(config: GatewayConfig): {
35
35
  logger: Logxer;
36
- router: LLMProviderRouter;
36
+ router: GatewayRouter;
37
37
  activityManager: ActivityManager;
38
38
  usageTracker: UsageTracker;
39
39
  messageBuilderConfig: MessageBuilderConfig;
@@ -3,7 +3,8 @@
3
3
  * @see node_modules/@x12i/logxer/docs/package-log-levels-stack.md
4
4
  */
5
5
  import { applyPackageLogLevelsFromEnv, mergePackageLogLevelsConfig } from '@x12i/logxer';
6
- import { ROUTER_LOG_ENV_PREFIX } from '@x12i/ai-providers-router';
6
+ /** @deprecated Use {@link ROUTER_LOG_ENV_PREFIX} from gateway-router. Kept for env var compatibility. */
7
+ export const ROUTER_LOG_ENV_PREFIX = 'AI_ROUTER_RUNTIME';
7
8
  /** Stable ERC 2.0 env prefix — controls `AI_GATEWAY_LOGS_LEVEL`, etc. */
8
9
  export const GATEWAY_LOG_ENV_PREFIX = 'AI_GATEWAY';
9
10
  /**
@@ -3,6 +3,8 @@
3
3
  * @see node_modules/@x12i/logxer/docs/package-log-levels-stack.md
4
4
  */
5
5
  import { type PackageLogLevelsConfig } from '@x12i/logxer';
6
+ /** @deprecated Use {@link ROUTER_LOG_ENV_PREFIX} from gateway-router. Kept for env var compatibility. */
7
+ export declare const ROUTER_LOG_ENV_PREFIX = "AI_ROUTER_RUNTIME";
6
8
  /** Stable ERC 2.0 env prefix — controls `AI_GATEWAY_LOGS_LEVEL`, etc. */
7
9
  export declare const GATEWAY_LOG_ENV_PREFIX = "AI_GATEWAY";
8
10
  /**
@@ -17,7 +19,7 @@ export declare const GATEWAY_LOGXER_PACKAGE: {
17
19
  /** Known `envPrefix` values in this package's dependency stack (for hosts / `.env`). */
18
20
  export declare const GATEWAY_STACK_LOG_PREFIXES: {
19
21
  readonly gateway: "AI_GATEWAY";
20
- readonly router: "AI_PROVIDER_ROUTER";
22
+ readonly router: "AI_ROUTER_RUNTIME";
21
23
  readonly flexMd: "FLEX_MD";
22
24
  };
23
25
  /**