paygate-mcp 9.6.0 → 9.7.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.
- package/README.md +6 -3
- package/dist/adaptive-rate-limiter.d.ts +126 -0
- package/dist/adaptive-rate-limiter.d.ts.map +1 -0
- package/dist/adaptive-rate-limiter.js +260 -0
- package/dist/adaptive-rate-limiter.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/retry-policy.d.ts +99 -0
- package/dist/retry-policy.d.ts.map +1 -0
- package/dist/retry-policy.js +224 -0
- package/dist/retry-policy.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +147 -0
- package/dist/server.js.map +1 -1
- package/dist/transforms.d.ts +125 -0
- package/dist/transforms.d.ts.map +1 -0
- package/dist/transforms.js +270 -0
- package/dist/transforms.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Monetize any MCP server with one command. Add API key auth, per-tool pricing, ra
|
|
|
11
11
|
- [Quick Start](#quick-start)
|
|
12
12
|
- [What It Does](#what-it-does)
|
|
13
13
|
- [Usage](#usage) — Local stdio, remote HTTP, multi-server, client SDK
|
|
14
|
-
- [API Reference](#api-reference) — All
|
|
14
|
+
- [API Reference](#api-reference) — All 166+ endpoints
|
|
15
15
|
- [CLI Options](#cli-options)
|
|
16
16
|
- [Deployment](#deployment) — Docker, docker-compose, systemd, PM2
|
|
17
17
|
- [Load Testing](#load-testing) — k6 benchmarking for production
|
|
@@ -66,7 +66,7 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
66
66
|
- **SSE Streaming** — Full MCP Streamable HTTP transport (POST SSE, GET notifications, DELETE sessions)
|
|
67
67
|
- **Audit Log** — Structured audit trail with retention policies, query API, CSV/JSON export
|
|
68
68
|
- **Registry/Discovery** — Agent-discoverable pricing via `/.well-known/mcp-payment`, `/pricing`, and `/.well-known/mcp.json` identity card
|
|
69
|
-
- **OpenAPI 3.1 + Interactive Docs** — Auto-generated spec at `/openapi.json`, Swagger UI at `/docs` — all
|
|
69
|
+
- **OpenAPI 3.1 + Interactive Docs** — Auto-generated spec at `/openapi.json`, Swagger UI at `/docs` — all 166+ endpoints documented
|
|
70
70
|
- **Public Endpoint Rate Limiting** — Configurable per-IP rate limit (default 300/min) on `/health`, `/info`, `/pricing`, `/docs`, `/openapi.json`, `/.well-known/*`, `/robots.txt`, `/` — 429 with Retry-After header
|
|
71
71
|
- **Robots.txt + HEAD Support** — Standard `/robots.txt` (allow public, disallow admin/keys), HEAD method on all public endpoints for uptime monitoring
|
|
72
72
|
- **Prometheus Metrics** — `/metrics` endpoint with counters, gauges, and uptime in standard text format
|
|
@@ -165,6 +165,9 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
165
165
|
- **Usage Plans** — Tiered key policies (free/pro/enterprise) — bundle rate limits, quotas, credit multipliers, and tool ACL into reusable templates, assign keys to plans via `POST /admin/keys/plan`, denied tools rejected with error code `-32403`, CRUD via `GET/POST/DELETE /admin/plans`
|
|
166
166
|
- **Tool Input Schema Validation** — Per-tool JSON Schema validation at the gateway — register schemas to reject invalid payloads before they reach downstream, zero-dependency JSON Schema subset (type, required, enum, minLength, pattern, items), error code `-32602` with detailed errors, manage via `GET/POST/DELETE /admin/tools/schema`
|
|
167
167
|
- **Canary Routing** — Weighted traffic splitting between primary and canary MCP servers — enable zero-downtime upgrades with percentage-based routing (0-100%), unbiased `crypto.randomInt` decisions, per-backend call/error tracking, weight updates without restart, manage via `GET/POST/DELETE /admin/canary`
|
|
168
|
+
- **Request/Response Transforms** — Declarative rewriting of tool call arguments and responses — inject defaults, strip fields, rename keys, and template `{{variables}}` from context, wildcard tool matching, priority ordering, deep clone on apply, import/export for backup, manage via `GET/POST/PUT/DELETE /admin/transforms`
|
|
169
|
+
- **Backend Retry Policy** — Automatic retry with exponential backoff for transient failures — configurable max retries, base/max backoff, full jitter, retry budget (max % of traffic as retries with cold-start grace), per-tool stats, retryable error pattern matching, manage via `GET/POST /admin/retry-policy`
|
|
170
|
+
- **Adaptive Rate Limiting** — Dynamic rate adjustment based on key behavior — auto-tighten for high error rates, auto-boost for good actors, cooldown periods, configurable thresholds, per-key behavior tracking, LRU eviction, batch evaluation, manage via `GET/POST /admin/adaptive-rates`
|
|
168
171
|
- **Anomaly Detection** — `GET /admin/anomalies` identifies unusual patterns: keys with high denial rates, rapid credit depletion, low remaining credits, with severity ratings and detailed descriptions
|
|
169
172
|
- **Usage Forecasting** — `GET /admin/forecast` predicts future credit consumption with per-key depletion estimates, calls remaining, at-risk key identification, system-wide consumption aggregates, and per-tool cost breakdown
|
|
170
173
|
- **Compliance Report** — `GET /admin/compliance` generates compliance-ready report with key governance (expiry coverage), access control (ACL/IP/spending limit coverage), audit trail completeness, weighted overall score, and actionable recommendations
|
|
@@ -478,7 +481,7 @@ A real-time admin UI for managing keys, viewing usage, and monitoring tool calls
|
|
|
478
481
|
| `/.well-known/mcp-payment` | GET | None | Server payment metadata (SEP-2007) |
|
|
479
482
|
| `/.well-known/mcp.json` | GET | None | MCP Server Identity card (discovery) |
|
|
480
483
|
| `/pricing` | GET | None | Full per-tool pricing breakdown |
|
|
481
|
-
| `/openapi.json` | GET | None | OpenAPI 3.1 spec (all
|
|
484
|
+
| `/openapi.json` | GET | None | OpenAPI 3.1 spec (all 166+ endpoints) |
|
|
482
485
|
| `/docs` | GET | None | Interactive API docs (Swagger UI) |
|
|
483
486
|
| `/robots.txt` | GET | None | Crawler directives (allow public, disallow admin/keys) |
|
|
484
487
|
| `/portal` | GET | None | Self-service API key portal (browser UI, auth via X-API-Key prompt) |
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AdaptiveRateLimiter — Dynamic rate limit adjustment based on traffic behavior.
|
|
3
|
+
*
|
|
4
|
+
* Automatically tightens limits for misbehaving keys (high error rates,
|
|
5
|
+
* excessive credit velocity) and loosens limits for well-behaved keys
|
|
6
|
+
* (zero denials, steady usage). Wraps the existing static RateLimiter
|
|
7
|
+
* with a per-key multiplier.
|
|
8
|
+
*
|
|
9
|
+
* Inspired by Apigee adaptive rate limiting and Tyk request throttling.
|
|
10
|
+
* Zero external dependencies.
|
|
11
|
+
*/
|
|
12
|
+
export interface AdaptiveRateConfig {
|
|
13
|
+
/** Enable adaptive rate limiting. */
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
/** Sliding window size in seconds for evaluation. Default 300 (5 min). */
|
|
16
|
+
evaluationWindowSeconds: number;
|
|
17
|
+
/** Error rate threshold (0-1) above which rate is tightened. Default 0.3. */
|
|
18
|
+
errorRateThreshold: number;
|
|
19
|
+
/** If credit spend rate exceeds this × average, tighten. Default 1.5. */
|
|
20
|
+
creditVelocityMultiplier: number;
|
|
21
|
+
/** Never reduce below this % of configured limit. Default 25. */
|
|
22
|
+
minRatePercent: number;
|
|
23
|
+
/** Allow burst up to this % for good behavior. Default 200. */
|
|
24
|
+
maxRatePercent: number;
|
|
25
|
+
/** Hold adjusted rate for at least this many seconds. Default 60. */
|
|
26
|
+
cooldownSeconds: number;
|
|
27
|
+
}
|
|
28
|
+
export interface KeyBehavior {
|
|
29
|
+
totalCalls: number;
|
|
30
|
+
errorCalls: number;
|
|
31
|
+
deniedCalls: number;
|
|
32
|
+
creditsSpent: number;
|
|
33
|
+
/** Current effective multiplier (1.0 = nominal). */
|
|
34
|
+
multiplier: number;
|
|
35
|
+
/** Last time the multiplier was adjusted. */
|
|
36
|
+
lastAdjusted: number;
|
|
37
|
+
/** Sliding window of call timestamps. */
|
|
38
|
+
callTimestamps: number[];
|
|
39
|
+
/** Sliding window of error timestamps. */
|
|
40
|
+
errorTimestamps: number[];
|
|
41
|
+
}
|
|
42
|
+
export interface AdaptiveRateStats {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
config: AdaptiveRateConfig;
|
|
45
|
+
totalKeys: number;
|
|
46
|
+
tightenedKeys: number;
|
|
47
|
+
boostedKeys: number;
|
|
48
|
+
normalKeys: number;
|
|
49
|
+
keyDetails: Array<{
|
|
50
|
+
key: string;
|
|
51
|
+
multiplier: number;
|
|
52
|
+
effectiveRate: string;
|
|
53
|
+
recentCalls: number;
|
|
54
|
+
recentErrors: number;
|
|
55
|
+
errorRate: number;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
export interface AdaptiveRateAdjustment {
|
|
59
|
+
key: string;
|
|
60
|
+
previousMultiplier: number;
|
|
61
|
+
newMultiplier: number;
|
|
62
|
+
reason: string;
|
|
63
|
+
effectiveRate: number;
|
|
64
|
+
baseRate: number;
|
|
65
|
+
}
|
|
66
|
+
export declare class AdaptiveRateLimiter {
|
|
67
|
+
private config;
|
|
68
|
+
private readonly keyBehaviors;
|
|
69
|
+
private readonly maxTrackedKeys;
|
|
70
|
+
constructor(config?: Partial<AdaptiveRateConfig>);
|
|
71
|
+
/**
|
|
72
|
+
* Update configuration at runtime.
|
|
73
|
+
*/
|
|
74
|
+
configure(updates: Partial<AdaptiveRateConfig>): AdaptiveRateConfig;
|
|
75
|
+
/**
|
|
76
|
+
* Record a call for a key.
|
|
77
|
+
*/
|
|
78
|
+
recordCall(apiKey: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Record an error for a key.
|
|
81
|
+
*/
|
|
82
|
+
recordError(apiKey: string): void;
|
|
83
|
+
/**
|
|
84
|
+
* Record a denied request for a key.
|
|
85
|
+
*/
|
|
86
|
+
recordDenied(apiKey: string): void;
|
|
87
|
+
/**
|
|
88
|
+
* Record credits spent by a key.
|
|
89
|
+
*/
|
|
90
|
+
recordCredits(apiKey: string, amount: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* Get the effective rate multiplier for a key.
|
|
93
|
+
* Returns 1.0 if adaptive limiting is disabled.
|
|
94
|
+
*/
|
|
95
|
+
getMultiplier(apiKey: string): number;
|
|
96
|
+
/**
|
|
97
|
+
* Get the effective rate limit for a key.
|
|
98
|
+
*/
|
|
99
|
+
getEffectiveRate(apiKey: string, baseRate: number): number;
|
|
100
|
+
/**
|
|
101
|
+
* Evaluate and adjust the rate multiplier for a key.
|
|
102
|
+
* Call this periodically (e.g., every minute) or on every Nth request.
|
|
103
|
+
*/
|
|
104
|
+
evaluate(apiKey: string): AdaptiveRateAdjustment | null;
|
|
105
|
+
/**
|
|
106
|
+
* Evaluate all tracked keys.
|
|
107
|
+
*/
|
|
108
|
+
evaluateAll(): AdaptiveRateAdjustment[];
|
|
109
|
+
private pruneTimestamps;
|
|
110
|
+
private getOrCreate;
|
|
111
|
+
/**
|
|
112
|
+
* Get adaptive rate statistics.
|
|
113
|
+
*/
|
|
114
|
+
stats(): AdaptiveRateStats;
|
|
115
|
+
/**
|
|
116
|
+
* Reset tracking for a specific key.
|
|
117
|
+
*/
|
|
118
|
+
resetKey(apiKey: string): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Clear all tracking data.
|
|
121
|
+
*/
|
|
122
|
+
clear(): void;
|
|
123
|
+
/** Number of tracked keys. */
|
|
124
|
+
get size(): number;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=adaptive-rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adaptive-rate-limiter.d.ts","sourceRoot":"","sources":["../src/adaptive-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,0EAA0E;IAC1E,uBAAuB,EAAE,MAAM,CAAC;IAChC,6EAA6E;IAC7E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,wBAAwB,EAAE,MAAM,CAAC;IACjC,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,KAAK,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAgBD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;gBAE3B,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAIhD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB;IAWnE;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAOhC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAOjC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMlC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAMnD;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAOrC;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI1D;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAwDvD;;OAEG;IACH,WAAW,IAAI,sBAAsB,EAAE;IASvC,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,WAAW;IAuBnB;;OAEG;IACH,KAAK,IAAI,iBAAiB;IAqC1B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb,8BAA8B;IAC9B,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AdaptiveRateLimiter — Dynamic rate limit adjustment based on traffic behavior.
|
|
4
|
+
*
|
|
5
|
+
* Automatically tightens limits for misbehaving keys (high error rates,
|
|
6
|
+
* excessive credit velocity) and loosens limits for well-behaved keys
|
|
7
|
+
* (zero denials, steady usage). Wraps the existing static RateLimiter
|
|
8
|
+
* with a per-key multiplier.
|
|
9
|
+
*
|
|
10
|
+
* Inspired by Apigee adaptive rate limiting and Tyk request throttling.
|
|
11
|
+
* Zero external dependencies.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.AdaptiveRateLimiter = void 0;
|
|
15
|
+
// ─── Default config ─────────────────────────────────────────────────────────
|
|
16
|
+
const DEFAULT_ADAPTIVE_CONFIG = {
|
|
17
|
+
enabled: false,
|
|
18
|
+
evaluationWindowSeconds: 300,
|
|
19
|
+
errorRateThreshold: 0.3,
|
|
20
|
+
creditVelocityMultiplier: 1.5,
|
|
21
|
+
minRatePercent: 25,
|
|
22
|
+
maxRatePercent: 200,
|
|
23
|
+
cooldownSeconds: 60,
|
|
24
|
+
};
|
|
25
|
+
// ─── AdaptiveRateLimiter Class ──────────────────────────────────────────────
|
|
26
|
+
class AdaptiveRateLimiter {
|
|
27
|
+
config;
|
|
28
|
+
keyBehaviors = new Map();
|
|
29
|
+
maxTrackedKeys = 5000;
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.config = { ...DEFAULT_ADAPTIVE_CONFIG, ...config };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Update configuration at runtime.
|
|
35
|
+
*/
|
|
36
|
+
configure(updates) {
|
|
37
|
+
if (updates.enabled !== undefined)
|
|
38
|
+
this.config.enabled = updates.enabled;
|
|
39
|
+
if (updates.evaluationWindowSeconds !== undefined)
|
|
40
|
+
this.config.evaluationWindowSeconds = Math.max(30, updates.evaluationWindowSeconds);
|
|
41
|
+
if (updates.errorRateThreshold !== undefined)
|
|
42
|
+
this.config.errorRateThreshold = Math.min(1, Math.max(0, updates.errorRateThreshold));
|
|
43
|
+
if (updates.creditVelocityMultiplier !== undefined)
|
|
44
|
+
this.config.creditVelocityMultiplier = Math.max(1, updates.creditVelocityMultiplier);
|
|
45
|
+
if (updates.minRatePercent !== undefined)
|
|
46
|
+
this.config.minRatePercent = Math.min(100, Math.max(1, updates.minRatePercent));
|
|
47
|
+
if (updates.maxRatePercent !== undefined)
|
|
48
|
+
this.config.maxRatePercent = Math.max(100, updates.maxRatePercent);
|
|
49
|
+
if (updates.cooldownSeconds !== undefined)
|
|
50
|
+
this.config.cooldownSeconds = Math.max(0, updates.cooldownSeconds);
|
|
51
|
+
return { ...this.config };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Record a call for a key.
|
|
55
|
+
*/
|
|
56
|
+
recordCall(apiKey) {
|
|
57
|
+
if (!this.config.enabled)
|
|
58
|
+
return;
|
|
59
|
+
const behavior = this.getOrCreate(apiKey);
|
|
60
|
+
behavior.totalCalls++;
|
|
61
|
+
behavior.callTimestamps.push(Date.now());
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Record an error for a key.
|
|
65
|
+
*/
|
|
66
|
+
recordError(apiKey) {
|
|
67
|
+
if (!this.config.enabled)
|
|
68
|
+
return;
|
|
69
|
+
const behavior = this.getOrCreate(apiKey);
|
|
70
|
+
behavior.errorCalls++;
|
|
71
|
+
behavior.errorTimestamps.push(Date.now());
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Record a denied request for a key.
|
|
75
|
+
*/
|
|
76
|
+
recordDenied(apiKey) {
|
|
77
|
+
if (!this.config.enabled)
|
|
78
|
+
return;
|
|
79
|
+
const behavior = this.getOrCreate(apiKey);
|
|
80
|
+
behavior.deniedCalls++;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Record credits spent by a key.
|
|
84
|
+
*/
|
|
85
|
+
recordCredits(apiKey, amount) {
|
|
86
|
+
if (!this.config.enabled)
|
|
87
|
+
return;
|
|
88
|
+
const behavior = this.getOrCreate(apiKey);
|
|
89
|
+
behavior.creditsSpent += amount;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get the effective rate multiplier for a key.
|
|
93
|
+
* Returns 1.0 if adaptive limiting is disabled.
|
|
94
|
+
*/
|
|
95
|
+
getMultiplier(apiKey) {
|
|
96
|
+
if (!this.config.enabled)
|
|
97
|
+
return 1.0;
|
|
98
|
+
const behavior = this.keyBehaviors.get(apiKey);
|
|
99
|
+
if (!behavior)
|
|
100
|
+
return 1.0;
|
|
101
|
+
return behavior.multiplier;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get the effective rate limit for a key.
|
|
105
|
+
*/
|
|
106
|
+
getEffectiveRate(apiKey, baseRate) {
|
|
107
|
+
return Math.round(baseRate * this.getMultiplier(apiKey));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Evaluate and adjust the rate multiplier for a key.
|
|
111
|
+
* Call this periodically (e.g., every minute) or on every Nth request.
|
|
112
|
+
*/
|
|
113
|
+
evaluate(apiKey) {
|
|
114
|
+
if (!this.config.enabled)
|
|
115
|
+
return null;
|
|
116
|
+
const behavior = this.keyBehaviors.get(apiKey);
|
|
117
|
+
if (!behavior)
|
|
118
|
+
return null;
|
|
119
|
+
// Check cooldown
|
|
120
|
+
const now = Date.now();
|
|
121
|
+
const cooldownMs = this.config.cooldownSeconds * 1000;
|
|
122
|
+
if (now - behavior.lastAdjusted < cooldownMs)
|
|
123
|
+
return null;
|
|
124
|
+
// Prune old timestamps
|
|
125
|
+
this.pruneTimestamps(behavior);
|
|
126
|
+
const recentCalls = behavior.callTimestamps.length;
|
|
127
|
+
const recentErrors = behavior.errorTimestamps.length;
|
|
128
|
+
// Need minimum traffic to evaluate
|
|
129
|
+
if (recentCalls < 5)
|
|
130
|
+
return null;
|
|
131
|
+
const previousMultiplier = behavior.multiplier;
|
|
132
|
+
let newMultiplier = 1.0;
|
|
133
|
+
let reason = 'normal behavior';
|
|
134
|
+
// Check error rate
|
|
135
|
+
const errorRate = recentErrors / recentCalls;
|
|
136
|
+
if (errorRate > this.config.errorRateThreshold) {
|
|
137
|
+
// Tighten: reduce to proportional amount
|
|
138
|
+
const tightenFactor = 1 - (errorRate * 0.5); // 30% errors → 0.85x, 60% → 0.7x
|
|
139
|
+
newMultiplier = Math.max(this.config.minRatePercent / 100, tightenFactor);
|
|
140
|
+
reason = `high error rate: ${(errorRate * 100).toFixed(1)}%`;
|
|
141
|
+
}
|
|
142
|
+
else if (errorRate < 0.05 && behavior.deniedCalls === 0) {
|
|
143
|
+
// Boost: reward good behavior
|
|
144
|
+
const boostFactor = 1 + ((1 - errorRate) * 0.3); // up to 1.3x for perfect keys
|
|
145
|
+
newMultiplier = Math.min(this.config.maxRatePercent / 100, boostFactor);
|
|
146
|
+
reason = `good behavior: ${(errorRate * 100).toFixed(1)}% error rate`;
|
|
147
|
+
}
|
|
148
|
+
// Clamp
|
|
149
|
+
newMultiplier = Math.max(this.config.minRatePercent / 100, Math.min(this.config.maxRatePercent / 100, newMultiplier));
|
|
150
|
+
// Only update if significantly different (>5% change)
|
|
151
|
+
if (Math.abs(newMultiplier - previousMultiplier) < 0.05)
|
|
152
|
+
return null;
|
|
153
|
+
behavior.multiplier = newMultiplier;
|
|
154
|
+
behavior.lastAdjusted = now;
|
|
155
|
+
return {
|
|
156
|
+
key: apiKey.slice(0, 8) + '...',
|
|
157
|
+
previousMultiplier,
|
|
158
|
+
newMultiplier,
|
|
159
|
+
reason,
|
|
160
|
+
effectiveRate: 0, // caller fills in with base rate
|
|
161
|
+
baseRate: 0,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Evaluate all tracked keys.
|
|
166
|
+
*/
|
|
167
|
+
evaluateAll() {
|
|
168
|
+
const adjustments = [];
|
|
169
|
+
for (const key of this.keyBehaviors.keys()) {
|
|
170
|
+
const adj = this.evaluate(key);
|
|
171
|
+
if (adj)
|
|
172
|
+
adjustments.push(adj);
|
|
173
|
+
}
|
|
174
|
+
return adjustments;
|
|
175
|
+
}
|
|
176
|
+
pruneTimestamps(behavior) {
|
|
177
|
+
const cutoff = Date.now() - (this.config.evaluationWindowSeconds * 1000);
|
|
178
|
+
behavior.callTimestamps = behavior.callTimestamps.filter(t => t > cutoff);
|
|
179
|
+
behavior.errorTimestamps = behavior.errorTimestamps.filter(t => t > cutoff);
|
|
180
|
+
}
|
|
181
|
+
getOrCreate(apiKey) {
|
|
182
|
+
let behavior = this.keyBehaviors.get(apiKey);
|
|
183
|
+
if (!behavior) {
|
|
184
|
+
// Evict oldest if at capacity
|
|
185
|
+
if (this.keyBehaviors.size >= this.maxTrackedKeys) {
|
|
186
|
+
const firstKey = this.keyBehaviors.keys().next().value;
|
|
187
|
+
if (firstKey)
|
|
188
|
+
this.keyBehaviors.delete(firstKey);
|
|
189
|
+
}
|
|
190
|
+
behavior = {
|
|
191
|
+
totalCalls: 0,
|
|
192
|
+
errorCalls: 0,
|
|
193
|
+
deniedCalls: 0,
|
|
194
|
+
creditsSpent: 0,
|
|
195
|
+
multiplier: 1.0,
|
|
196
|
+
lastAdjusted: 0,
|
|
197
|
+
callTimestamps: [],
|
|
198
|
+
errorTimestamps: [],
|
|
199
|
+
};
|
|
200
|
+
this.keyBehaviors.set(apiKey, behavior);
|
|
201
|
+
}
|
|
202
|
+
return behavior;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get adaptive rate statistics.
|
|
206
|
+
*/
|
|
207
|
+
stats() {
|
|
208
|
+
const keyDetails = [];
|
|
209
|
+
let tightened = 0;
|
|
210
|
+
let boosted = 0;
|
|
211
|
+
let normal = 0;
|
|
212
|
+
for (const [key, behavior] of this.keyBehaviors) {
|
|
213
|
+
this.pruneTimestamps(behavior);
|
|
214
|
+
const recentCalls = behavior.callTimestamps.length;
|
|
215
|
+
const recentErrors = behavior.errorTimestamps.length;
|
|
216
|
+
const errorRate = recentCalls > 0 ? recentErrors / recentCalls : 0;
|
|
217
|
+
if (behavior.multiplier < 0.95)
|
|
218
|
+
tightened++;
|
|
219
|
+
else if (behavior.multiplier > 1.05)
|
|
220
|
+
boosted++;
|
|
221
|
+
else
|
|
222
|
+
normal++;
|
|
223
|
+
keyDetails.push({
|
|
224
|
+
key: key.slice(0, 8) + '...',
|
|
225
|
+
multiplier: Math.round(behavior.multiplier * 100) / 100,
|
|
226
|
+
effectiveRate: `${Math.round(behavior.multiplier * 100)}%`,
|
|
227
|
+
recentCalls,
|
|
228
|
+
recentErrors,
|
|
229
|
+
errorRate: Math.round(errorRate * 100) / 100,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
enabled: this.config.enabled,
|
|
234
|
+
config: { ...this.config },
|
|
235
|
+
totalKeys: this.keyBehaviors.size,
|
|
236
|
+
tightenedKeys: tightened,
|
|
237
|
+
boostedKeys: boosted,
|
|
238
|
+
normalKeys: normal,
|
|
239
|
+
keyDetails,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Reset tracking for a specific key.
|
|
244
|
+
*/
|
|
245
|
+
resetKey(apiKey) {
|
|
246
|
+
return this.keyBehaviors.delete(apiKey);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Clear all tracking data.
|
|
250
|
+
*/
|
|
251
|
+
clear() {
|
|
252
|
+
this.keyBehaviors.clear();
|
|
253
|
+
}
|
|
254
|
+
/** Number of tracked keys. */
|
|
255
|
+
get size() {
|
|
256
|
+
return this.keyBehaviors.size;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
exports.AdaptiveRateLimiter = AdaptiveRateLimiter;
|
|
260
|
+
//# sourceMappingURL=adaptive-rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adaptive-rate-limiter.js","sourceRoot":"","sources":["../src/adaptive-rate-limiter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -89,6 +89,12 @@ export { ToolSchemaValidator } from './schema-validator';
|
|
|
89
89
|
export type { ToolSchema, SchemaNode, ValidationResult, ValidationError, SchemaStats } from './schema-validator';
|
|
90
90
|
export { CanaryRouter } from './canary-router';
|
|
91
91
|
export type { CanaryConfig, CanaryStats, CanaryBackend, CanaryDecision } from './canary-router';
|
|
92
|
+
export { TransformPipeline } from './transforms';
|
|
93
|
+
export type { TransformRule, TransformRuleCreateParams, TransformOperation, TransformDirection, TransformOp, TransformStats, TransformContext } from './transforms';
|
|
94
|
+
export { RetryPolicy } from './retry-policy';
|
|
95
|
+
export type { RetryConfig, RetryStats, RetryResult } from './retry-policy';
|
|
96
|
+
export { AdaptiveRateLimiter } from './adaptive-rate-limiter';
|
|
97
|
+
export type { AdaptiveRateConfig, AdaptiveRateStats, AdaptiveRateAdjustment, KeyBehavior } from './adaptive-rate-limiter';
|
|
92
98
|
export type { PayGateConfig, JsonRpcRequest, JsonRpcResponse, JsonRpcError, ToolCallParams, ToolInfo, ToolPricing, ServerBackendConfig, ApiKeyRecord, UsageEvent, UsageSummary, GateDecision, QuotaConfig, BatchToolCall, BatchGateResult, WebhookFilterRule, KeyListQuery, KeyListResult, } from './types';
|
|
93
99
|
export { DEFAULT_CONFIG } from './types';
|
|
94
100
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACrG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC1F,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC/H,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACrG,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5E,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACpH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACtG,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC/E,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvJ,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9I,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACrH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.parseLogFormat = exports.parseLogLevel = exports.Logger = exports.KeyGroupManager = exports.PluginManager = exports.VALID_ROLES = exports.ROLE_HIERARCHY = exports.AdminKeyManager = exports.TokenRevocationList = exports.ScopedTokenManager = exports.formatDiagnostics = exports.validateConfig = exports.PayGateError = exports.PayGateClient = exports.RedisSync = exports.RedisSubscriber = exports.parseRedisUrl = exports.RedisClient = exports.TeamManager = exports.AlertEngine = exports.AnalyticsEngine = exports.getPortalHtml = exports.getDashboardHtml = exports.MetricsCollector = exports.ToolRegistry = exports.CreditLedger = exports.maskKeyForAudit = exports.AuditLogger = exports.writeSseKeepAlive = exports.writeSseEvent = exports.writeSseHeaders = exports.SessionManager = exports.OAuthProvider = exports.QuotaTracker = exports.WebhookRouter = exports.WebhookEmitter = exports.BackupManager = exports.StripeCheckout = exports.StripeWebhookHandler = exports.RateLimiter = exports.UsageMeter = exports.KeyStore = exports.MultiServerRouter = exports.HttpMcpProxy = exports.McpProxy = exports.Gate = exports.resolveClientIp = exports.getRequestId = exports.generateRequestId = exports.PayGateServer = void 0;
|
|
20
|
-
exports.DEFAULT_CONFIG = exports.CanaryRouter = exports.ToolSchemaValidator = exports.UsagePlanManager = exports.ToolAliasManager = exports.TrafficMirror = exports.ConcurrencyLimiter = exports.BUILT_IN_RULES = exports.ContentGuardrails = exports.complianceReportToCsv = exports.generateComplianceReport = exports.CircuitBreaker = exports.ResponseCache = exports.VALID_LOG_FORMATS = exports.VALID_LOG_LEVELS = void 0;
|
|
20
|
+
exports.DEFAULT_CONFIG = exports.AdaptiveRateLimiter = exports.RetryPolicy = exports.TransformPipeline = exports.CanaryRouter = exports.ToolSchemaValidator = exports.UsagePlanManager = exports.ToolAliasManager = exports.TrafficMirror = exports.ConcurrencyLimiter = exports.BUILT_IN_RULES = exports.ContentGuardrails = exports.complianceReportToCsv = exports.generateComplianceReport = exports.CircuitBreaker = exports.ResponseCache = exports.VALID_LOG_FORMATS = exports.VALID_LOG_LEVELS = void 0;
|
|
21
21
|
var server_1 = require("./server");
|
|
22
22
|
Object.defineProperty(exports, "PayGateServer", { enumerable: true, get: function () { return server_1.PayGateServer; } });
|
|
23
23
|
Object.defineProperty(exports, "generateRequestId", { enumerable: true, get: function () { return server_1.generateRequestId; } });
|
|
@@ -126,6 +126,12 @@ var schema_validator_1 = require("./schema-validator");
|
|
|
126
126
|
Object.defineProperty(exports, "ToolSchemaValidator", { enumerable: true, get: function () { return schema_validator_1.ToolSchemaValidator; } });
|
|
127
127
|
var canary_router_1 = require("./canary-router");
|
|
128
128
|
Object.defineProperty(exports, "CanaryRouter", { enumerable: true, get: function () { return canary_router_1.CanaryRouter; } });
|
|
129
|
+
var transforms_1 = require("./transforms");
|
|
130
|
+
Object.defineProperty(exports, "TransformPipeline", { enumerable: true, get: function () { return transforms_1.TransformPipeline; } });
|
|
131
|
+
var retry_policy_1 = require("./retry-policy");
|
|
132
|
+
Object.defineProperty(exports, "RetryPolicy", { enumerable: true, get: function () { return retry_policy_1.RetryPolicy; } });
|
|
133
|
+
var adaptive_rate_limiter_1 = require("./adaptive-rate-limiter");
|
|
134
|
+
Object.defineProperty(exports, "AdaptiveRateLimiter", { enumerable: true, get: function () { return adaptive_rate_limiter_1.AdaptiveRateLimiter; } });
|
|
129
135
|
var types_1 = require("./types");
|
|
130
136
|
Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return types_1.DEFAULT_CONFIG; } });
|
|
131
137
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RetryPolicy — Configurable automatic retry with exponential backoff and jitter.
|
|
3
|
+
*
|
|
4
|
+
* Wraps downstream MCP tool call forwarding to retry transient failures.
|
|
5
|
+
* Prevents credits being charged for errors that would succeed on retry.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Exponential backoff with optional jitter
|
|
9
|
+
* - Retry budget (max % of traffic as retries to prevent retry storms)
|
|
10
|
+
* - Configurable retryable error patterns
|
|
11
|
+
* - Per-tool override support
|
|
12
|
+
* - Stats tracking (attempts, successes, exhausted)
|
|
13
|
+
*
|
|
14
|
+
* Zero external dependencies.
|
|
15
|
+
*/
|
|
16
|
+
export interface RetryConfig {
|
|
17
|
+
/** Max retry attempts (0 = disabled). Default 3. */
|
|
18
|
+
maxRetries: number;
|
|
19
|
+
/** Base backoff in ms. Default 200. */
|
|
20
|
+
backoffBaseMs: number;
|
|
21
|
+
/** Max backoff cap in ms. Default 5000. */
|
|
22
|
+
backoffMaxMs: number;
|
|
23
|
+
/** Add random jitter to backoff. Default true. */
|
|
24
|
+
jitter: boolean;
|
|
25
|
+
/** Error codes/patterns that trigger retries. Default: internal error, timeout. */
|
|
26
|
+
retryableErrors: Array<string | number>;
|
|
27
|
+
/**
|
|
28
|
+
* Max percentage of recent traffic that can be retries (0-100).
|
|
29
|
+
* Prevents retry storms. Default 20.
|
|
30
|
+
*/
|
|
31
|
+
retryBudgetPercent: number;
|
|
32
|
+
}
|
|
33
|
+
export interface RetryStats {
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
config: RetryConfig;
|
|
36
|
+
totalAttempts: number;
|
|
37
|
+
totalSuccessAfterRetry: number;
|
|
38
|
+
totalExhausted: number;
|
|
39
|
+
recentTraffic: number;
|
|
40
|
+
recentRetries: number;
|
|
41
|
+
budgetUtilization: number;
|
|
42
|
+
perTool: Record<string, {
|
|
43
|
+
attempts: number;
|
|
44
|
+
successes: number;
|
|
45
|
+
exhausted: number;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
export interface RetryResult<T> {
|
|
49
|
+
result: T;
|
|
50
|
+
attempts: number;
|
|
51
|
+
retriedFrom?: string;
|
|
52
|
+
}
|
|
53
|
+
export declare class RetryPolicy {
|
|
54
|
+
private config;
|
|
55
|
+
private enabled;
|
|
56
|
+
private totalAttempts;
|
|
57
|
+
private totalSuccessAfterRetry;
|
|
58
|
+
private totalExhausted;
|
|
59
|
+
private perToolStats;
|
|
60
|
+
private trafficWindow;
|
|
61
|
+
private retryWindow;
|
|
62
|
+
private readonly windowDurationMs;
|
|
63
|
+
constructor(config?: Partial<RetryConfig>);
|
|
64
|
+
/**
|
|
65
|
+
* Update retry configuration at runtime.
|
|
66
|
+
*/
|
|
67
|
+
configure(updates: Partial<RetryConfig>): RetryConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Execute a function with retry policy.
|
|
70
|
+
* The function should throw on retryable errors.
|
|
71
|
+
*/
|
|
72
|
+
execute<T>(toolName: string, fn: () => Promise<T>, isRetryable?: (error: unknown) => boolean): Promise<RetryResult<T>>;
|
|
73
|
+
/**
|
|
74
|
+
* Check if an error is retryable based on config.
|
|
75
|
+
*/
|
|
76
|
+
isRetryableError(error: unknown): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Calculate backoff delay with optional jitter.
|
|
79
|
+
*/
|
|
80
|
+
private calculateBackoff;
|
|
81
|
+
/**
|
|
82
|
+
* Check if we're within the retry budget.
|
|
83
|
+
*/
|
|
84
|
+
private withinBudget;
|
|
85
|
+
private recordTraffic;
|
|
86
|
+
private recordRetry;
|
|
87
|
+
private pruneWindows;
|
|
88
|
+
private getToolStats;
|
|
89
|
+
private sleep;
|
|
90
|
+
/**
|
|
91
|
+
* Get retry statistics.
|
|
92
|
+
*/
|
|
93
|
+
stats(): RetryStats;
|
|
94
|
+
/** Is retry policy enabled? */
|
|
95
|
+
get isEnabled(): boolean;
|
|
96
|
+
/** Current config. */
|
|
97
|
+
get currentConfig(): RetryConfig;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=retry-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../src/retry-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,mFAAmF;IACnF,eAAe,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACxC;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAeD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,YAAY,CAAiF;IAGrG,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAE/B,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC;IAKzC;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW;IAWrD;;;OAGG;IACG,OAAO,CAAC,CAAC,EACb,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GACxC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAgE1B;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAkBzC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,KAAK;IAIb;;OAEG;IACH,KAAK,IAAI,UAAU;IAuBnB,+BAA+B;IAC/B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,sBAAsB;IACtB,IAAI,aAAa,IAAI,WAAW,CAE/B;CACF"}
|