@x12i/ai-gateway 9.2.0 → 9.3.4
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/README.md +105 -13
- package/dist/activity-manager.d.ts +1 -0
- package/dist/activity-manager.js +123 -26
- package/dist/ai-tools-client.d.ts +20 -0
- package/dist/ai-tools-client.js +91 -0
- package/dist/gateway-config.d.ts +2 -0
- package/dist/gateway-config.js +2 -1
- package/dist/gateway-mode.d.ts +40 -0
- package/dist/gateway-mode.js +75 -0
- package/dist/gateway-utils.d.ts +28 -1
- package/dist/gateway-utils.js +137 -12
- package/dist/gateway.d.ts +3 -0
- package/dist/gateway.js +34 -6
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/types.d.ts +21 -0
- package/dist-cjs/activity-manager.cjs +137 -45
- package/dist-cjs/activity-manager.d.ts +1 -0
- package/dist-cjs/ai-tools-client.cjs +91 -0
- package/dist-cjs/ai-tools-client.d.ts +20 -0
- package/dist-cjs/config/activity-tracking-config.cjs +1 -4
- package/dist-cjs/content-normalizer/content-normalizer.cjs +3 -8
- package/dist-cjs/content-normalizer/index.cjs +1 -7
- package/dist-cjs/content-normalizer/types.cjs +1 -2
- package/dist-cjs/flex-md-loader.cjs +20 -67
- package/dist-cjs/gateway-config.cjs +25 -63
- package/dist-cjs/gateway-config.d.ts +2 -0
- package/dist-cjs/gateway-conversion.cjs +10 -48
- package/dist-cjs/gateway-instructions.cjs +5 -10
- package/dist-cjs/gateway-log-meta.cjs +9 -14
- package/dist-cjs/gateway-memory.cjs +2 -6
- package/dist-cjs/gateway-messages.cjs +3 -6
- package/dist-cjs/gateway-meta.cjs +1 -4
- package/dist-cjs/gateway-mode.cjs +75 -0
- package/dist-cjs/gateway-mode.d.ts +40 -0
- package/dist-cjs/gateway-provider-auto-register.cjs +2 -38
- package/dist-cjs/gateway-provider.cjs +10 -22
- package/dist-cjs/gateway-rate-limiter-constants.cjs +2 -5
- package/dist-cjs/gateway-rate-limiter.cjs +5 -9
- package/dist-cjs/gateway-retry.cjs +6 -14
- package/dist-cjs/gateway-utils.cjs +160 -89
- package/dist-cjs/gateway-utils.d.ts +28 -1
- package/dist-cjs/gateway-validation.cjs +2 -6
- package/dist-cjs/gateway.cjs +91 -67
- package/dist-cjs/gateway.d.ts +3 -0
- package/dist-cjs/index.cjs +22 -98
- package/dist-cjs/index.d.ts +3 -1
- package/dist-cjs/instruction-errors.cjs +2 -7
- package/dist-cjs/instruction-optimizer.cjs +4 -10
- package/dist-cjs/instructions-parser.cjs +5 -10
- package/dist-cjs/logger-factory.cjs +3 -6
- package/dist-cjs/memory-path-resolution.cjs +8 -18
- package/dist-cjs/message-builder.cjs +11 -47
- package/dist-cjs/object-types-library-integration.cjs +3 -8
- package/dist-cjs/object-types-library.cjs +5 -10
- package/dist-cjs/output-auditor.cjs +1 -4
- package/dist-cjs/output-contract-normalizer.cjs +9 -14
- package/dist-cjs/request-report-generator.cjs +1 -4
- package/dist-cjs/response-analyzer/format-type-detector.cjs +1 -5
- package/dist-cjs/response-analyzer/index.cjs +3 -9
- package/dist-cjs/response-analyzer/object-type-detector.cjs +1 -5
- package/dist-cjs/response-analyzer/response-analyzer.cjs +6 -10
- package/dist-cjs/response-analyzer/types.cjs +1 -2
- package/dist-cjs/response-fallback-fixer.cjs +1 -4
- package/dist-cjs/runtime-objects.cjs +7 -13
- package/dist-cjs/template-parser.cjs +5 -42
- package/dist-cjs/template-render-merge.cjs +2 -6
- package/dist-cjs/troubleshooting-helper.cjs +13 -28
- package/dist-cjs/types.cjs +1 -2
- package/dist-cjs/types.d.ts +21 -0
- package/dist-cjs/usage-tracker.cjs +3 -7
- package/package.json +11 -5
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Gateway Meta Operations Module
|
|
4
3
|
* Handles meta operations like instruction optimization and testing
|
|
5
4
|
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.testInstructions = testInstructions;
|
|
8
5
|
/**
|
|
9
6
|
* Test instructions by running them and analyzing the response
|
|
10
7
|
*/
|
|
11
|
-
async function testInstructions(instructions, testInput, expectedSchema, options, config, gateway, logger) {
|
|
8
|
+
export async function testInstructions(instructions, testInput, expectedSchema, options, config, gateway, logger) {
|
|
12
9
|
// Get internal system action config (instruction audit)
|
|
13
10
|
const internalConfig = config.internalSystemActions?.instructionAudit;
|
|
14
11
|
const defaultEngine = config.defaultEngine || 'openai';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gateway operational mode (prod vs dev/debug) and default model resolution.
|
|
3
|
+
*/
|
|
4
|
+
import { gatewayLogDebug, withActivityIdentity } from './gateway-log-meta.js';
|
|
5
|
+
export const CODE_DEFAULT_MODEL = 'gpt-5-nano';
|
|
6
|
+
/**
|
|
7
|
+
* Operational mode: `GatewayConfig.mode` overrides `process.env.mode` / `MODE`.
|
|
8
|
+
* Only `prod` allows silent default-model substitution; all other values are strict.
|
|
9
|
+
*/
|
|
10
|
+
export function getGatewayOperationalMode(config) {
|
|
11
|
+
if (config?.mode) {
|
|
12
|
+
return config.mode;
|
|
13
|
+
}
|
|
14
|
+
const raw = (process.env.mode ?? process.env.MODE ?? '').toLowerCase();
|
|
15
|
+
if (raw === 'prod')
|
|
16
|
+
return 'prod';
|
|
17
|
+
if (raw === 'dev')
|
|
18
|
+
return 'dev';
|
|
19
|
+
return 'debug';
|
|
20
|
+
}
|
|
21
|
+
export function isProdGatewayMode(mode) {
|
|
22
|
+
return mode === 'prod';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse `provider/model` or bare model id (OpenRouter ids may contain multiple slashes).
|
|
26
|
+
*/
|
|
27
|
+
export function parseModelProviderSpec(spec) {
|
|
28
|
+
const trimmed = spec.trim();
|
|
29
|
+
if (!trimmed) {
|
|
30
|
+
return { model: CODE_DEFAULT_MODEL };
|
|
31
|
+
}
|
|
32
|
+
const slash = trimmed.indexOf('/');
|
|
33
|
+
if (slash === -1) {
|
|
34
|
+
return { model: trimmed };
|
|
35
|
+
}
|
|
36
|
+
const first = trimmed.slice(0, slash);
|
|
37
|
+
const rest = trimmed.slice(slash + 1);
|
|
38
|
+
if (rest.includes('/') && (first === 'openrouter' || first === 'open-router')) {
|
|
39
|
+
return { provider: 'openrouter', model: trimmed };
|
|
40
|
+
}
|
|
41
|
+
return { provider: first, model: rest };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Default model priority: AI_GATEWAY_DEFAULT_MODEL → model-config.json → code constant.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveGatewayDefaultModel(defaultModelConfig, gatewayDefaultEngine) {
|
|
47
|
+
const envSpec = process.env.AI_GATEWAY_DEFAULT_MODEL?.trim();
|
|
48
|
+
if (envSpec) {
|
|
49
|
+
const parsed = parseModelProviderSpec(envSpec);
|
|
50
|
+
return { model: parsed.model, provider: parsed.provider, source: 'env' };
|
|
51
|
+
}
|
|
52
|
+
const jsonModel = typeof defaultModelConfig?.defaultModel === 'string' ? defaultModelConfig.defaultModel : undefined;
|
|
53
|
+
if (jsonModel) {
|
|
54
|
+
const parsed = parseModelProviderSpec(jsonModel);
|
|
55
|
+
const jsonEngine = typeof defaultModelConfig?.defaultEngine === 'string'
|
|
56
|
+
? defaultModelConfig.defaultEngine
|
|
57
|
+
: gatewayDefaultEngine;
|
|
58
|
+
return {
|
|
59
|
+
model: parsed.model,
|
|
60
|
+
provider: parsed.provider ?? jsonEngine,
|
|
61
|
+
source: 'model-config.json'
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
model: CODE_DEFAULT_MODEL,
|
|
66
|
+
provider: gatewayDefaultEngine,
|
|
67
|
+
source: 'code'
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function warnDefaultModelSubstitution(logger, identity, details) {
|
|
71
|
+
logger.warn('Gateway substituted default model for request', withActivityIdentity(identity, {
|
|
72
|
+
...details,
|
|
73
|
+
debugKind: gatewayLogDebug.anomaly
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gateway operational mode (prod vs dev/debug) and default model resolution.
|
|
3
|
+
*/
|
|
4
|
+
import type { Logxer } from '@x12i/logxer';
|
|
5
|
+
import type { ActivityIdentity, GatewayConfig } from './types.js';
|
|
6
|
+
export type GatewayOperationalMode = 'prod' | 'debug' | 'dev';
|
|
7
|
+
export type GatewayDefaultModelSource = 'env' | 'model-config.json' | 'code';
|
|
8
|
+
export type DefaultModelSubstitutionReason = 'no_model_provided' | 'model_resolution_failed' | 'ai_tools_unavailable';
|
|
9
|
+
export declare const CODE_DEFAULT_MODEL = "gpt-5-nano";
|
|
10
|
+
export type ResolvedGatewayDefault = {
|
|
11
|
+
model: string;
|
|
12
|
+
provider?: string;
|
|
13
|
+
source: GatewayDefaultModelSource;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Operational mode: `GatewayConfig.mode` overrides `process.env.mode` / `MODE`.
|
|
17
|
+
* Only `prod` allows silent default-model substitution; all other values are strict.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getGatewayOperationalMode(config?: Pick<GatewayConfig, 'mode'>): GatewayOperationalMode;
|
|
20
|
+
export declare function isProdGatewayMode(mode: GatewayOperationalMode): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Parse `provider/model` or bare model id (OpenRouter ids may contain multiple slashes).
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseModelProviderSpec(spec: string): {
|
|
25
|
+
provider?: string;
|
|
26
|
+
model: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Default model priority: AI_GATEWAY_DEFAULT_MODEL → model-config.json → code constant.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveGatewayDefaultModel(defaultModelConfig?: Record<string, unknown>, gatewayDefaultEngine?: string): ResolvedGatewayDefault;
|
|
32
|
+
export declare function warnDefaultModelSubstitution(logger: Logxer, identity: Partial<ActivityIdentity> | undefined, details: {
|
|
33
|
+
reason: DefaultModelSubstitutionReason;
|
|
34
|
+
mode: GatewayOperationalMode;
|
|
35
|
+
defaultSource: GatewayDefaultModelSource;
|
|
36
|
+
defaultProvider?: string;
|
|
37
|
+
defaultModel: string;
|
|
38
|
+
originalProvider?: string;
|
|
39
|
+
originalModel?: string;
|
|
40
|
+
}): void;
|
|
@@ -1,43 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Gateway Provider Auto-Registration Module
|
|
4
3
|
* Automatically registers providers based on environment variables
|
|
5
4
|
*/
|
|
6
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
39
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.autoRegisterProviders = autoRegisterProviders;
|
|
41
5
|
const PROVIDER_CONFIGS = [
|
|
42
6
|
{
|
|
43
7
|
name: 'openai',
|
|
@@ -90,7 +54,7 @@ const PROVIDER_CONFIGS = [
|
|
|
90
54
|
* @param logger - Logger instance
|
|
91
55
|
* @returns Array of provider names that were successfully registered
|
|
92
56
|
*/
|
|
93
|
-
async function autoRegisterProviders(router, logger) {
|
|
57
|
+
export async function autoRegisterProviders(router, logger) {
|
|
94
58
|
const registeredProviders = [];
|
|
95
59
|
logger.debug('Auto-registering providers from environment variables');
|
|
96
60
|
for (const providerConfig of PROVIDER_CONFIGS) {
|
|
@@ -107,7 +71,7 @@ async function autoRegisterProviders(router, logger) {
|
|
|
107
71
|
// Use dynamic import() for ES module compatibility
|
|
108
72
|
let ProviderClass;
|
|
109
73
|
try {
|
|
110
|
-
const providerModule = await
|
|
74
|
+
const providerModule = await import(providerConfig.packageName);
|
|
111
75
|
ProviderClass = providerModule[providerConfig.className] || providerModule.default;
|
|
112
76
|
if (!ProviderClass) {
|
|
113
77
|
logger.debug(`Provider class ${providerConfig.className} not found in ${providerConfig.packageName}`);
|
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Gateway Provider Module
|
|
4
3
|
* Handles provider management
|
|
5
4
|
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.registerProvider = registerProvider;
|
|
8
|
-
exports.unregisterProvider = unregisterProvider;
|
|
9
|
-
exports.getProvider = getProvider;
|
|
10
|
-
exports.listProviders = listProviders;
|
|
11
|
-
exports.setDefaultProvider = setDefaultProvider;
|
|
12
|
-
exports.setFallbackChain = setFallbackChain;
|
|
13
|
-
exports.addRequestInterceptor = addRequestInterceptor;
|
|
14
|
-
exports.addResponseInterceptor = addResponseInterceptor;
|
|
15
|
-
exports.checkHealth = checkHealth;
|
|
16
|
-
exports.checkAllHealth = checkAllHealth;
|
|
17
5
|
/**
|
|
18
6
|
* Register a provider with the router
|
|
19
7
|
*/
|
|
20
|
-
function registerProvider(provider, router, logger) {
|
|
8
|
+
export function registerProvider(provider, router, logger) {
|
|
21
9
|
// Get provider name - try multiple methods
|
|
22
10
|
let providerName = 'unknown';
|
|
23
11
|
if (typeof provider.getProviderName === 'function') {
|
|
@@ -103,7 +91,7 @@ function registerProvider(provider, router, logger) {
|
|
|
103
91
|
/**
|
|
104
92
|
* Unregister a provider
|
|
105
93
|
*/
|
|
106
|
-
function unregisterProvider(providerName, router, logger) {
|
|
94
|
+
export function unregisterProvider(providerName, router, logger) {
|
|
107
95
|
try {
|
|
108
96
|
// Try to access registry directly to remove the provider
|
|
109
97
|
const registry = router.getProviderRegistry();
|
|
@@ -128,7 +116,7 @@ function unregisterProvider(providerName, router, logger) {
|
|
|
128
116
|
/**
|
|
129
117
|
* Get a provider module
|
|
130
118
|
*/
|
|
131
|
-
function getProvider(providerName, router) {
|
|
119
|
+
export function getProvider(providerName, router) {
|
|
132
120
|
try {
|
|
133
121
|
const registry = router.getProviderRegistry();
|
|
134
122
|
return registry.get(providerName);
|
|
@@ -141,7 +129,7 @@ function getProvider(providerName, router) {
|
|
|
141
129
|
/**
|
|
142
130
|
* List all registered providers
|
|
143
131
|
*/
|
|
144
|
-
function listProviders(router) {
|
|
132
|
+
export function listProviders(router) {
|
|
145
133
|
return router.listProviders();
|
|
146
134
|
}
|
|
147
135
|
/**
|
|
@@ -151,7 +139,7 @@ function listProviders(router) {
|
|
|
151
139
|
* This method is kept for API compatibility but does nothing.
|
|
152
140
|
* Default provider must be set in router config during initialization.
|
|
153
141
|
*/
|
|
154
|
-
function setDefaultProvider(provider, router, logger) {
|
|
142
|
+
export function setDefaultProvider(provider, router, logger) {
|
|
155
143
|
// Router doesn't support changing default provider after initialization
|
|
156
144
|
// Default provider must be set in router config during initialization
|
|
157
145
|
logger.warn('setDefaultProvider called but router does not support changing default provider after initialization', {
|
|
@@ -166,7 +154,7 @@ function setDefaultProvider(provider, router, logger) {
|
|
|
166
154
|
* This method is kept for API compatibility but does nothing.
|
|
167
155
|
* Fallback chain must be set in router config during initialization.
|
|
168
156
|
*/
|
|
169
|
-
function setFallbackChain(chain, router, logger) {
|
|
157
|
+
export function setFallbackChain(chain, router, logger) {
|
|
170
158
|
// Router doesn't support changing fallback chain after initialization
|
|
171
159
|
// Fallback chain must be set in router config during initialization
|
|
172
160
|
logger.warn('setFallbackChain called but router does not support changing fallback chain after initialization', {
|
|
@@ -177,25 +165,25 @@ function setFallbackChain(chain, router, logger) {
|
|
|
177
165
|
/**
|
|
178
166
|
* Add request interceptor
|
|
179
167
|
*/
|
|
180
|
-
function addRequestInterceptor(interceptor, router) {
|
|
168
|
+
export function addRequestInterceptor(interceptor, router) {
|
|
181
169
|
router.addRequestInterceptor(interceptor);
|
|
182
170
|
}
|
|
183
171
|
/**
|
|
184
172
|
* Add response interceptor
|
|
185
173
|
*/
|
|
186
|
-
function addResponseInterceptor(interceptor, router) {
|
|
174
|
+
export function addResponseInterceptor(interceptor, router) {
|
|
187
175
|
router.addResponseInterceptor(interceptor);
|
|
188
176
|
}
|
|
189
177
|
/**
|
|
190
178
|
* Check health of a provider
|
|
191
179
|
*/
|
|
192
|
-
async function checkHealth(provider, router) {
|
|
180
|
+
export async function checkHealth(provider, router) {
|
|
193
181
|
return router.checkHealth(provider);
|
|
194
182
|
}
|
|
195
183
|
/**
|
|
196
184
|
* Check health of all providers
|
|
197
185
|
*/
|
|
198
|
-
async function checkAllHealth(router) {
|
|
186
|
+
export async function checkAllHealth(router) {
|
|
199
187
|
const providers = listProviders(router);
|
|
200
188
|
const results = {};
|
|
201
189
|
for (const provider of providers) {
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Rate Limiter Constants
|
|
4
3
|
*
|
|
5
4
|
* Default values for rate limiting configuration.
|
|
6
5
|
* These defaults ensure the system works safely even if config is missing.
|
|
7
6
|
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.DEFAULT_RATE_LIMIT_ENABLED = exports.DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS = void 0;
|
|
10
7
|
/**
|
|
11
8
|
* Default minimum interval between API calls (in milliseconds)
|
|
12
9
|
* Used when rateLimit.defaultMinIntervalMs is not specified
|
|
13
10
|
*/
|
|
14
|
-
|
|
11
|
+
export const DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS = 500;
|
|
15
12
|
/**
|
|
16
13
|
* Default enabled state for rate limiting
|
|
17
14
|
* Used when rateLimit.enabled is not specified
|
|
18
15
|
*/
|
|
19
|
-
|
|
16
|
+
export const DEFAULT_RATE_LIMIT_ENABLED = true;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Gateway Rate Limiter
|
|
4
3
|
*
|
|
@@ -12,10 +11,8 @@
|
|
|
12
11
|
* and only waits if necessary to maintain minimum intervals between separate API calls.
|
|
13
12
|
* This prevents unnecessary delays when enough time has already passed.
|
|
14
13
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const gateway_retry_js_1 = require("./gateway-retry.cjs");
|
|
18
|
-
const gateway_rate_limiter_constants_js_1 = require("./gateway-rate-limiter-constants.cjs");
|
|
14
|
+
import { sleep } from './gateway-retry.js';
|
|
15
|
+
import { DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS } from './gateway-rate-limiter-constants.js';
|
|
19
16
|
/**
|
|
20
17
|
* Smart Rate Limiter (Between-Calls Only)
|
|
21
18
|
*
|
|
@@ -27,12 +24,12 @@ const gateway_rate_limiter_constants_js_1 = require("./gateway-rate-limiter-cons
|
|
|
27
24
|
*
|
|
28
25
|
* This ensures minimum intervals between separate API calls regardless of what happens between them.
|
|
29
26
|
*/
|
|
30
|
-
class GatewayRateLimiter {
|
|
27
|
+
export class GatewayRateLimiter {
|
|
31
28
|
lastCallTimes = new Map(); // provider -> last call timestamp
|
|
32
29
|
defaultMinIntervalMs;
|
|
33
30
|
providerIntervals = new Map(); // provider -> min interval
|
|
34
31
|
logger;
|
|
35
|
-
constructor(defaultMinIntervalMs =
|
|
32
|
+
constructor(defaultMinIntervalMs = DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS, providerIntervals, logger) {
|
|
36
33
|
this.defaultMinIntervalMs = defaultMinIntervalMs;
|
|
37
34
|
this.logger = logger;
|
|
38
35
|
// Store per-provider intervals
|
|
@@ -69,7 +66,7 @@ class GatewayRateLimiter {
|
|
|
69
66
|
minIntervalMs,
|
|
70
67
|
usingProviderSpecific: this.providerIntervals.has(provider.toLowerCase())
|
|
71
68
|
});
|
|
72
|
-
await
|
|
69
|
+
await sleep(waitTime);
|
|
73
70
|
}
|
|
74
71
|
else {
|
|
75
72
|
this.logger?.verbose('Rate limit OK: enough time has passed', {
|
|
@@ -108,4 +105,3 @@ class GatewayRateLimiter {
|
|
|
108
105
|
}
|
|
109
106
|
}
|
|
110
107
|
}
|
|
111
|
-
exports.GatewayRateLimiter = GatewayRateLimiter;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Gateway Retry Module
|
|
4
3
|
* Handles retry logic for network and server errors
|
|
@@ -6,17 +5,10 @@
|
|
|
6
5
|
* NOTE: Retry delays use SIMPLE SLEEP (not smart rate limiting).
|
|
7
6
|
* Between-calls rate limiting is handled separately in gateway-rate-limiter.ts (smart).
|
|
8
7
|
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.isNetworkError = isNetworkError;
|
|
11
|
-
exports.extractHttpStatusCode = extractHttpStatusCode;
|
|
12
|
-
exports.isRetryableHttpError = isRetryableHttpError;
|
|
13
|
-
exports.isRetryableError = isRetryableError;
|
|
14
|
-
exports.sleep = sleep;
|
|
15
|
-
exports.invokeWithRetry = invokeWithRetry;
|
|
16
8
|
/**
|
|
17
9
|
* Determines if an error is a network error (fetch failed, DNS, connectivity)
|
|
18
10
|
*/
|
|
19
|
-
function isNetworkError(error) {
|
|
11
|
+
export function isNetworkError(error) {
|
|
20
12
|
const message = error.message.toLowerCase();
|
|
21
13
|
const networkPatterns = [
|
|
22
14
|
'fetch failed',
|
|
@@ -35,7 +27,7 @@ function isNetworkError(error) {
|
|
|
35
27
|
/**
|
|
36
28
|
* Extracts HTTP status code from error message or error object properties
|
|
37
29
|
*/
|
|
38
|
-
function extractHttpStatusCode(error) {
|
|
30
|
+
export function extractHttpStatusCode(error) {
|
|
39
31
|
// Try to extract from error message
|
|
40
32
|
const statusMatch = error.message.match(/\b(4\d{2}|5\d{2})\b/);
|
|
41
33
|
if (statusMatch) {
|
|
@@ -59,7 +51,7 @@ function extractHttpStatusCode(error) {
|
|
|
59
51
|
* Retryable: 429 (throttling), 5xx (server errors)
|
|
60
52
|
* Non-retryable: 4xx except 429 (client errors)
|
|
61
53
|
*/
|
|
62
|
-
function isRetryableHttpError(error, statusCode) {
|
|
54
|
+
export function isRetryableHttpError(error, statusCode) {
|
|
63
55
|
// 429 (throttling) is retryable
|
|
64
56
|
if (statusCode === 429) {
|
|
65
57
|
return true;
|
|
@@ -74,7 +66,7 @@ function isRetryableHttpError(error, statusCode) {
|
|
|
74
66
|
/**
|
|
75
67
|
* Determines if an error should be retried
|
|
76
68
|
*/
|
|
77
|
-
function isRetryableError(error) {
|
|
69
|
+
export function isRetryableError(error) {
|
|
78
70
|
// Network errors are always retryable
|
|
79
71
|
if (isNetworkError(error)) {
|
|
80
72
|
return true;
|
|
@@ -94,14 +86,14 @@ function isRetryableError(error) {
|
|
|
94
86
|
/**
|
|
95
87
|
* Sleep helper for retry delays
|
|
96
88
|
*/
|
|
97
|
-
function sleep(ms) {
|
|
89
|
+
export function sleep(ms) {
|
|
98
90
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
99
91
|
}
|
|
100
92
|
/**
|
|
101
93
|
* Invokes router with retry logic for network and server errors
|
|
102
94
|
* Returns response and retry metadata
|
|
103
95
|
*/
|
|
104
|
-
async function invokeWithRetry(routerRequest, retryConfig, jobId, router, logger, hooks) {
|
|
96
|
+
export async function invokeWithRetry(routerRequest, retryConfig, jobId, router, logger, hooks) {
|
|
105
97
|
const maxRetries = retryConfig.maxRetries ?? 3;
|
|
106
98
|
const initialDelay = retryConfig.initialDelay ?? 1000;
|
|
107
99
|
const maxDelay = retryConfig.maxDelay ?? 30000;
|