paygate-mcp 10.3.0 → 10.4.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/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +382 -0
- package/dist/server.js.map +1 -1
- package/dist/spend-caps.d.ts +105 -0
- package/dist/spend-caps.d.ts.map +1 -0
- package/dist/spend-caps.js +225 -0
- package/dist/spend-caps.js.map +1 -0
- package/dist/task-manager.d.ts +158 -0
- package/dist/task-manager.d.ts.map +1 -0
- package/dist/task-manager.js +302 -0
- package/dist/task-manager.js.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SpendCapManager — Server-wide and per-key spend caps with auto-suspend.
|
|
3
|
+
*
|
|
4
|
+
* Prevents runaway agent spending by enforcing hard limits:
|
|
5
|
+
* - Server-wide daily credit/call caps across ALL keys
|
|
6
|
+
* - Per-key hourly credit/call caps (finer-grained than daily)
|
|
7
|
+
* - Auto-suspend: keys that breach caps are automatically suspended
|
|
8
|
+
* - Auto-resume: suspended keys can be auto-resumed after a cooldown period
|
|
9
|
+
*
|
|
10
|
+
* Unlike quotas (which just deny), spend caps can suspend keys to prevent
|
|
11
|
+
* further abuse until an admin reviews.
|
|
12
|
+
*/
|
|
13
|
+
import { QuotaConfig, SpendCapConfig } from './types';
|
|
14
|
+
export type { SpendCapConfig } from './types';
|
|
15
|
+
export interface SpendCapCheckResult {
|
|
16
|
+
allowed: boolean;
|
|
17
|
+
reason?: string;
|
|
18
|
+
/** Whether the key should be auto-suspended (only when breachAction = 'suspend'). */
|
|
19
|
+
shouldSuspend?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare class SpendCapManager {
|
|
22
|
+
private config;
|
|
23
|
+
/** Server-wide daily counters (reset at UTC midnight). */
|
|
24
|
+
private serverDailyCalls;
|
|
25
|
+
private serverDailyCredits;
|
|
26
|
+
private serverDailyResetDay;
|
|
27
|
+
/** Per-key hourly buckets (keyed by API key prefix). */
|
|
28
|
+
private hourlyBuckets;
|
|
29
|
+
/** Auto-suspend timestamps (keyed by API key prefix → Unix ms when suspended). */
|
|
30
|
+
private suspendedAt;
|
|
31
|
+
/** Callback: notified when a key is auto-suspended. */
|
|
32
|
+
onAutoSuspend?: (apiKeyPrefix: string, reason: string) => void;
|
|
33
|
+
/** Callback: notified when a key is auto-resumed. */
|
|
34
|
+
onAutoResume?: (apiKeyPrefix: string) => void;
|
|
35
|
+
constructor(config: SpendCapConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Update spend cap config at runtime (hot-reload).
|
|
38
|
+
*/
|
|
39
|
+
updateConfig(config: SpendCapConfig): void;
|
|
40
|
+
/**
|
|
41
|
+
* Check server-wide spend caps.
|
|
42
|
+
* Call BEFORE per-key checks to fail fast on global limits.
|
|
43
|
+
*/
|
|
44
|
+
checkServerCap(creditsRequired: number): SpendCapCheckResult;
|
|
45
|
+
/**
|
|
46
|
+
* Check per-key hourly spend caps.
|
|
47
|
+
*/
|
|
48
|
+
checkHourlyCap(apiKeyPrefix: string, creditsRequired: number, quota?: QuotaConfig): SpendCapCheckResult;
|
|
49
|
+
/**
|
|
50
|
+
* Check if a key is auto-suspended and whether it should be auto-resumed.
|
|
51
|
+
* Returns true if the key is still suspended (should deny).
|
|
52
|
+
*/
|
|
53
|
+
isAutoSuspended(apiKeyPrefix: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Auto-suspend a key (called when breachAction = 'suspend').
|
|
56
|
+
*/
|
|
57
|
+
autoSuspendKey(apiKeyPrefix: string, reason: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Manually clear auto-suspend for a key (admin action).
|
|
60
|
+
*/
|
|
61
|
+
clearAutoSuspend(apiKeyPrefix: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Record successful call against server-wide and hourly caps.
|
|
64
|
+
*/
|
|
65
|
+
record(apiKeyPrefix: string, creditsCharged: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Record a batch of successful calls.
|
|
68
|
+
*/
|
|
69
|
+
recordBatch(apiKeyPrefix: string, callCount: number, totalCreditsCharged: number): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get server-wide daily stats.
|
|
72
|
+
*/
|
|
73
|
+
getServerStats(): {
|
|
74
|
+
dailyCalls: number;
|
|
75
|
+
dailyCredits: number;
|
|
76
|
+
dailyCallCap: number;
|
|
77
|
+
dailyCreditCap: number;
|
|
78
|
+
resetDay: string;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Get per-key hourly stats.
|
|
82
|
+
*/
|
|
83
|
+
getKeyHourlyStats(apiKeyPrefix: string): {
|
|
84
|
+
hourlyCalls: number;
|
|
85
|
+
hourlyCredits: number;
|
|
86
|
+
hour: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Get auto-suspend status for a key.
|
|
90
|
+
*/
|
|
91
|
+
getAutoSuspendStatus(apiKeyPrefix: string): {
|
|
92
|
+
suspended: boolean;
|
|
93
|
+
suspendedAt?: number;
|
|
94
|
+
autoResumeIn?: number;
|
|
95
|
+
};
|
|
96
|
+
/** Get number of currently auto-suspended keys. */
|
|
97
|
+
get suspendedCount(): number;
|
|
98
|
+
/** Get the current config. */
|
|
99
|
+
get currentConfig(): SpendCapConfig;
|
|
100
|
+
private todayUTC;
|
|
101
|
+
private hourUTC;
|
|
102
|
+
private resetServerIfNeeded;
|
|
103
|
+
private getOrCreateHourlyBucket;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=spend-caps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spend-caps.d.ts","sourceRoot":"","sources":["../src/spend-caps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAgB,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGpE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9C,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAYD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAiB;IAC/B,0DAA0D;IAC1D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,mBAAmB,CAAM;IACjC,wDAAwD;IACxD,OAAO,CAAC,aAAa,CAAmC;IACxD,kFAAkF;IAClF,OAAO,CAAC,WAAW,CAA6B;IAChD,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,qDAAqD;IACrD,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;gBAElC,MAAM,EAAE,cAAc;IAKlC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAI1C;;;OAGG;IACH,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,mBAAmB;IA0B5D;;OAEG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,mBAAmB;IA2BvG;;;OAGG;IACH,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAiB9C;;OAEG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAK1D;;OAEG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAI/C;;OAEG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI;IAU1D;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,IAAI;IAUvF;;OAEG;IACH,cAAc,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAW9H;;OAEG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IASrG;;OAEG;IACH,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;IAiB/G,mDAAmD;IACnD,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,8BAA8B;IAC9B,IAAI,aAAa,IAAI,cAAc,CAElC;IAID,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,uBAAuB;CAahC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SpendCapManager — Server-wide and per-key spend caps with auto-suspend.
|
|
4
|
+
*
|
|
5
|
+
* Prevents runaway agent spending by enforcing hard limits:
|
|
6
|
+
* - Server-wide daily credit/call caps across ALL keys
|
|
7
|
+
* - Per-key hourly credit/call caps (finer-grained than daily)
|
|
8
|
+
* - Auto-suspend: keys that breach caps are automatically suspended
|
|
9
|
+
* - Auto-resume: suspended keys can be auto-resumed after a cooldown period
|
|
10
|
+
*
|
|
11
|
+
* Unlike quotas (which just deny), spend caps can suspend keys to prevent
|
|
12
|
+
* further abuse until an admin reviews.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SpendCapManager = void 0;
|
|
16
|
+
// ─── SpendCapManager ─────────────────────────────────────────────────────────
|
|
17
|
+
class SpendCapManager {
|
|
18
|
+
config;
|
|
19
|
+
/** Server-wide daily counters (reset at UTC midnight). */
|
|
20
|
+
serverDailyCalls = 0;
|
|
21
|
+
serverDailyCredits = 0;
|
|
22
|
+
serverDailyResetDay = '';
|
|
23
|
+
/** Per-key hourly buckets (keyed by API key prefix). */
|
|
24
|
+
hourlyBuckets = new Map();
|
|
25
|
+
/** Auto-suspend timestamps (keyed by API key prefix → Unix ms when suspended). */
|
|
26
|
+
suspendedAt = new Map();
|
|
27
|
+
/** Callback: notified when a key is auto-suspended. */
|
|
28
|
+
onAutoSuspend;
|
|
29
|
+
/** Callback: notified when a key is auto-resumed. */
|
|
30
|
+
onAutoResume;
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.serverDailyResetDay = this.todayUTC();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Update spend cap config at runtime (hot-reload).
|
|
37
|
+
*/
|
|
38
|
+
updateConfig(config) {
|
|
39
|
+
this.config = config;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check server-wide spend caps.
|
|
43
|
+
* Call BEFORE per-key checks to fail fast on global limits.
|
|
44
|
+
*/
|
|
45
|
+
checkServerCap(creditsRequired) {
|
|
46
|
+
this.resetServerIfNeeded();
|
|
47
|
+
// Server-wide daily credit cap
|
|
48
|
+
if (this.config.serverDailyCreditCap > 0) {
|
|
49
|
+
if (this.serverDailyCredits + creditsRequired > this.config.serverDailyCreditCap) {
|
|
50
|
+
return {
|
|
51
|
+
allowed: false,
|
|
52
|
+
reason: `server_daily_credit_cap: ${this.serverDailyCredits}+${creditsRequired} would exceed ${this.config.serverDailyCreditCap} credits/day (server-wide)`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Server-wide daily call cap
|
|
57
|
+
if (this.config.serverDailyCallCap > 0) {
|
|
58
|
+
if (this.serverDailyCalls + 1 > this.config.serverDailyCallCap) {
|
|
59
|
+
return {
|
|
60
|
+
allowed: false,
|
|
61
|
+
reason: `server_daily_call_cap: ${this.serverDailyCalls}+1 would exceed ${this.config.serverDailyCallCap} calls/day (server-wide)`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { allowed: true };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check per-key hourly spend caps.
|
|
69
|
+
*/
|
|
70
|
+
checkHourlyCap(apiKeyPrefix, creditsRequired, quota) {
|
|
71
|
+
if (!quota)
|
|
72
|
+
return { allowed: true };
|
|
73
|
+
const hourlyCallLimit = quota.hourlyCallLimit || 0;
|
|
74
|
+
const hourlyCreditLimit = quota.hourlyCreditLimit || 0;
|
|
75
|
+
if (hourlyCallLimit === 0 && hourlyCreditLimit === 0)
|
|
76
|
+
return { allowed: true };
|
|
77
|
+
const bucket = this.getOrCreateHourlyBucket(apiKeyPrefix);
|
|
78
|
+
if (hourlyCallLimit > 0 && bucket.calls + 1 > hourlyCallLimit) {
|
|
79
|
+
return {
|
|
80
|
+
allowed: false,
|
|
81
|
+
reason: `hourly_call_cap: ${bucket.calls}+1 would exceed ${hourlyCallLimit} calls/hour`,
|
|
82
|
+
shouldSuspend: this.config.breachAction === 'suspend',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (hourlyCreditLimit > 0 && bucket.credits + creditsRequired > hourlyCreditLimit) {
|
|
86
|
+
return {
|
|
87
|
+
allowed: false,
|
|
88
|
+
reason: `hourly_credit_cap: ${bucket.credits}+${creditsRequired} would exceed ${hourlyCreditLimit} credits/hour`,
|
|
89
|
+
shouldSuspend: this.config.breachAction === 'suspend',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { allowed: true };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if a key is auto-suspended and whether it should be auto-resumed.
|
|
96
|
+
* Returns true if the key is still suspended (should deny).
|
|
97
|
+
*/
|
|
98
|
+
isAutoSuspended(apiKeyPrefix) {
|
|
99
|
+
const suspendTime = this.suspendedAt.get(apiKeyPrefix);
|
|
100
|
+
if (!suspendTime)
|
|
101
|
+
return false;
|
|
102
|
+
// Check auto-resume
|
|
103
|
+
if (this.config.autoResumeAfterSeconds > 0) {
|
|
104
|
+
const elapsed = (Date.now() - suspendTime) / 1000;
|
|
105
|
+
if (elapsed >= this.config.autoResumeAfterSeconds) {
|
|
106
|
+
this.suspendedAt.delete(apiKeyPrefix);
|
|
107
|
+
this.onAutoResume?.(apiKeyPrefix);
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Auto-suspend a key (called when breachAction = 'suspend').
|
|
115
|
+
*/
|
|
116
|
+
autoSuspendKey(apiKeyPrefix, reason) {
|
|
117
|
+
this.suspendedAt.set(apiKeyPrefix, Date.now());
|
|
118
|
+
this.onAutoSuspend?.(apiKeyPrefix, reason);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Manually clear auto-suspend for a key (admin action).
|
|
122
|
+
*/
|
|
123
|
+
clearAutoSuspend(apiKeyPrefix) {
|
|
124
|
+
return this.suspendedAt.delete(apiKeyPrefix);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Record successful call against server-wide and hourly caps.
|
|
128
|
+
*/
|
|
129
|
+
record(apiKeyPrefix, creditsCharged) {
|
|
130
|
+
this.resetServerIfNeeded();
|
|
131
|
+
this.serverDailyCalls++;
|
|
132
|
+
this.serverDailyCredits += creditsCharged;
|
|
133
|
+
const bucket = this.getOrCreateHourlyBucket(apiKeyPrefix);
|
|
134
|
+
bucket.calls++;
|
|
135
|
+
bucket.credits += creditsCharged;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Record a batch of successful calls.
|
|
139
|
+
*/
|
|
140
|
+
recordBatch(apiKeyPrefix, callCount, totalCreditsCharged) {
|
|
141
|
+
this.resetServerIfNeeded();
|
|
142
|
+
this.serverDailyCalls += callCount;
|
|
143
|
+
this.serverDailyCredits += totalCreditsCharged;
|
|
144
|
+
const bucket = this.getOrCreateHourlyBucket(apiKeyPrefix);
|
|
145
|
+
bucket.calls += callCount;
|
|
146
|
+
bucket.credits += totalCreditsCharged;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get server-wide daily stats.
|
|
150
|
+
*/
|
|
151
|
+
getServerStats() {
|
|
152
|
+
this.resetServerIfNeeded();
|
|
153
|
+
return {
|
|
154
|
+
dailyCalls: this.serverDailyCalls,
|
|
155
|
+
dailyCredits: this.serverDailyCredits,
|
|
156
|
+
dailyCallCap: this.config.serverDailyCreditCap,
|
|
157
|
+
dailyCreditCap: this.config.serverDailyCreditCap,
|
|
158
|
+
resetDay: this.serverDailyResetDay,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get per-key hourly stats.
|
|
163
|
+
*/
|
|
164
|
+
getKeyHourlyStats(apiKeyPrefix) {
|
|
165
|
+
const bucket = this.getOrCreateHourlyBucket(apiKeyPrefix);
|
|
166
|
+
return {
|
|
167
|
+
hourlyCalls: bucket.calls,
|
|
168
|
+
hourlyCredits: bucket.credits,
|
|
169
|
+
hour: bucket.hour,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get auto-suspend status for a key.
|
|
174
|
+
*/
|
|
175
|
+
getAutoSuspendStatus(apiKeyPrefix) {
|
|
176
|
+
const suspendTime = this.suspendedAt.get(apiKeyPrefix);
|
|
177
|
+
if (!suspendTime)
|
|
178
|
+
return { suspended: false };
|
|
179
|
+
const result = {
|
|
180
|
+
suspended: true,
|
|
181
|
+
suspendedAt: suspendTime,
|
|
182
|
+
};
|
|
183
|
+
if (this.config.autoResumeAfterSeconds > 0) {
|
|
184
|
+
const elapsed = (Date.now() - suspendTime) / 1000;
|
|
185
|
+
result.autoResumeIn = Math.max(0, Math.ceil(this.config.autoResumeAfterSeconds - elapsed));
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
/** Get number of currently auto-suspended keys. */
|
|
190
|
+
get suspendedCount() {
|
|
191
|
+
return this.suspendedAt.size;
|
|
192
|
+
}
|
|
193
|
+
/** Get the current config. */
|
|
194
|
+
get currentConfig() {
|
|
195
|
+
return { ...this.config };
|
|
196
|
+
}
|
|
197
|
+
// ─── Internals ─────────────────────────────────────────────────────────────
|
|
198
|
+
todayUTC() {
|
|
199
|
+
return new Date().toISOString().slice(0, 10);
|
|
200
|
+
}
|
|
201
|
+
hourUTC() {
|
|
202
|
+
return new Date().toISOString().slice(0, 13); // YYYY-MM-DDTHH
|
|
203
|
+
}
|
|
204
|
+
resetServerIfNeeded() {
|
|
205
|
+
const today = this.todayUTC();
|
|
206
|
+
if (this.serverDailyResetDay !== today) {
|
|
207
|
+
this.serverDailyCalls = 0;
|
|
208
|
+
this.serverDailyCredits = 0;
|
|
209
|
+
this.serverDailyResetDay = today;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
getOrCreateHourlyBucket(apiKeyPrefix) {
|
|
213
|
+
const currentHour = this.hourUTC();
|
|
214
|
+
const existing = this.hourlyBuckets.get(apiKeyPrefix);
|
|
215
|
+
if (existing && existing.hour === currentHour) {
|
|
216
|
+
return existing;
|
|
217
|
+
}
|
|
218
|
+
// New hour — reset bucket
|
|
219
|
+
const bucket = { hour: currentHour, calls: 0, credits: 0 };
|
|
220
|
+
this.hourlyBuckets.set(apiKeyPrefix, bucket);
|
|
221
|
+
return bucket;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.SpendCapManager = SpendCapManager;
|
|
225
|
+
//# sourceMappingURL=spend-caps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spend-caps.js","sourceRoot":"","sources":["../src/spend-caps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaskManager — MCP Tasks primitive (MCP 2025-11-25 spec).
|
|
3
|
+
*
|
|
4
|
+
* Manages async task lifecycle for long-running tool calls:
|
|
5
|
+
* - tasks/send — Create a task wrapping a tool call
|
|
6
|
+
* - tasks/get — Get task status and progress
|
|
7
|
+
* - tasks/result — Get task result (completed or error)
|
|
8
|
+
* - tasks/list — List tasks for a session
|
|
9
|
+
* - tasks/cancel — Cancel a running task
|
|
10
|
+
*
|
|
11
|
+
* Task states: pending → running → completed | failed | cancelled
|
|
12
|
+
*
|
|
13
|
+
* Billing integration:
|
|
14
|
+
* - Pre-charge: credits deducted at task creation (tasks/send)
|
|
15
|
+
* - Refund: if task fails and refundOnFailure is enabled
|
|
16
|
+
* - Outcome billing: additional credits charged on completion if output pricing is configured
|
|
17
|
+
*/
|
|
18
|
+
export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
19
|
+
export interface TaskRecord {
|
|
20
|
+
/** Unique task ID. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Current task status. */
|
|
23
|
+
status: TaskStatus;
|
|
24
|
+
/** Tool name being called. */
|
|
25
|
+
toolName: string;
|
|
26
|
+
/** Tool call arguments. */
|
|
27
|
+
arguments?: Record<string, unknown>;
|
|
28
|
+
/** API key that created this task (prefix only). */
|
|
29
|
+
apiKeyPrefix: string;
|
|
30
|
+
/** Session ID this task belongs to. */
|
|
31
|
+
sessionId: string;
|
|
32
|
+
/** ISO timestamp when task was created. */
|
|
33
|
+
createdAt: string;
|
|
34
|
+
/** ISO timestamp when task started running. */
|
|
35
|
+
startedAt?: string;
|
|
36
|
+
/** ISO timestamp when task completed/failed/was cancelled. */
|
|
37
|
+
completedAt?: string;
|
|
38
|
+
/** Progress percentage (0-100). Updated by the backend. */
|
|
39
|
+
progress?: number;
|
|
40
|
+
/** Human-readable progress message. */
|
|
41
|
+
message?: string;
|
|
42
|
+
/** Credits charged at task creation. */
|
|
43
|
+
creditsCharged: number;
|
|
44
|
+
/** Additional credits charged post-completion (outcome billing). */
|
|
45
|
+
outcomeCredits?: number;
|
|
46
|
+
/** Task result (populated on completion). */
|
|
47
|
+
result?: unknown;
|
|
48
|
+
/** Error message (populated on failure). */
|
|
49
|
+
error?: string;
|
|
50
|
+
/** Duration in milliseconds. */
|
|
51
|
+
durationMs?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface TaskListQuery {
|
|
54
|
+
/** Filter by session ID. */
|
|
55
|
+
sessionId?: string;
|
|
56
|
+
/** Filter by status. */
|
|
57
|
+
status?: TaskStatus;
|
|
58
|
+
/** Filter by API key prefix. */
|
|
59
|
+
apiKeyPrefix?: string;
|
|
60
|
+
/** Pagination cursor. */
|
|
61
|
+
cursor?: string;
|
|
62
|
+
/** Page size. Default: 50. Max: 200. */
|
|
63
|
+
pageSize?: number;
|
|
64
|
+
}
|
|
65
|
+
export interface TaskListResult {
|
|
66
|
+
tasks: TaskRecord[];
|
|
67
|
+
total: number;
|
|
68
|
+
nextCursor?: string;
|
|
69
|
+
}
|
|
70
|
+
export declare class TaskManager {
|
|
71
|
+
/** All tasks, keyed by task ID. */
|
|
72
|
+
private tasks;
|
|
73
|
+
/** Max tasks to retain. Oldest completed tasks are evicted first. Default: 10000. */
|
|
74
|
+
private maxTasks;
|
|
75
|
+
/** Task timeout in ms. 0 = no timeout. Default: 300000 (5 min). */
|
|
76
|
+
private taskTimeoutMs;
|
|
77
|
+
/** Cleanup interval handle. */
|
|
78
|
+
private cleanupInterval;
|
|
79
|
+
constructor(options?: {
|
|
80
|
+
maxTasks?: number;
|
|
81
|
+
taskTimeoutMs?: number;
|
|
82
|
+
});
|
|
83
|
+
/**
|
|
84
|
+
* Create a new task (tasks/send).
|
|
85
|
+
* Returns the task record in pending state.
|
|
86
|
+
*/
|
|
87
|
+
createTask(params: {
|
|
88
|
+
toolName: string;
|
|
89
|
+
arguments?: Record<string, unknown>;
|
|
90
|
+
apiKeyPrefix: string;
|
|
91
|
+
sessionId: string;
|
|
92
|
+
creditsCharged: number;
|
|
93
|
+
}): TaskRecord;
|
|
94
|
+
/**
|
|
95
|
+
* Transition task to 'running'.
|
|
96
|
+
*/
|
|
97
|
+
startTask(taskId: string): TaskRecord | null;
|
|
98
|
+
/**
|
|
99
|
+
* Update task progress.
|
|
100
|
+
*/
|
|
101
|
+
updateProgress(taskId: string, progress: number, message?: string): TaskRecord | null;
|
|
102
|
+
/**
|
|
103
|
+
* Complete a task with result.
|
|
104
|
+
*/
|
|
105
|
+
completeTask(taskId: string, result: unknown, outcomeCredits?: number): TaskRecord | null;
|
|
106
|
+
/**
|
|
107
|
+
* Fail a task with error.
|
|
108
|
+
*/
|
|
109
|
+
failTask(taskId: string, error: string): TaskRecord | null;
|
|
110
|
+
/**
|
|
111
|
+
* Cancel a task.
|
|
112
|
+
*/
|
|
113
|
+
cancelTask(taskId: string): TaskRecord | null;
|
|
114
|
+
/**
|
|
115
|
+
* Get a task by ID.
|
|
116
|
+
*/
|
|
117
|
+
getTask(taskId: string): TaskRecord | null;
|
|
118
|
+
/**
|
|
119
|
+
* List tasks with optional filters.
|
|
120
|
+
*/
|
|
121
|
+
listTasks(query?: TaskListQuery): TaskListResult;
|
|
122
|
+
/**
|
|
123
|
+
* Get summary stats.
|
|
124
|
+
*/
|
|
125
|
+
getStats(): {
|
|
126
|
+
total: number;
|
|
127
|
+
pending: number;
|
|
128
|
+
running: number;
|
|
129
|
+
completed: number;
|
|
130
|
+
failed: number;
|
|
131
|
+
cancelled: number;
|
|
132
|
+
};
|
|
133
|
+
/** Get total task count. */
|
|
134
|
+
get taskCount(): number;
|
|
135
|
+
/**
|
|
136
|
+
* Handle a tasks/* JSON-RPC method.
|
|
137
|
+
* Returns the response content or null if not a tasks method.
|
|
138
|
+
*/
|
|
139
|
+
handleTasksMethod(method: string, params: Record<string, unknown>, apiKeyPrefix: string, sessionId: string): {
|
|
140
|
+
content: Array<{
|
|
141
|
+
type: string;
|
|
142
|
+
text: string;
|
|
143
|
+
}>;
|
|
144
|
+
} | null;
|
|
145
|
+
destroy(): void;
|
|
146
|
+
private taskToResponse;
|
|
147
|
+
private jsonResult;
|
|
148
|
+
private errorResult;
|
|
149
|
+
/**
|
|
150
|
+
* Evict oldest completed tasks if at capacity.
|
|
151
|
+
*/
|
|
152
|
+
private evictIfNeeded;
|
|
153
|
+
/**
|
|
154
|
+
* Cleanup timed-out tasks.
|
|
155
|
+
*/
|
|
156
|
+
private cleanup;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=task-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-manager.d.ts","sourceRoot":"","sources":["../src/task-manager.ts"],"names":[],"mappings":"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"}
|