paygate-mcp 6.4.0 → 6.6.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 +79 -0
- package/dist/credit-ledger.d.ts +15 -0
- package/dist/credit-ledger.d.ts.map +1 -1
- package/dist/credit-ledger.js +67 -0
- package/dist/credit-ledger.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +144 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,6 +91,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
91
91
|
- **Rate Limit Status** — `GET /keys/rate-limit-status?key=...` returns the current rate limit window state for any key — global calls used/remaining/reset time, per-tool rate limits with individual usage, read-only (doesn't consume a call)
|
|
92
92
|
- **Quota Status** — `GET /keys/quota-status?key=...` returns daily/monthly quota usage for any key — calls and credits used/remaining/limits, reset periods, quota source (per-key vs global vs none)
|
|
93
93
|
- **Credit History** — `GET /keys/credit-history?key=...` returns per-key credit mutation log — tracks initial allocation, topups, transfers (in/out), auto-topups, with type/limit/since filters, balance-before/after on every entry, newest-first ordering, capped at 100 entries per key
|
|
94
|
+
- **Spending Velocity** — `GET /keys/spending-velocity?key=...` returns credit burn rate and depletion forecast — credits/calls per hour/day, estimated depletion date, top tools by spend, configurable analysis window (1h–30d)
|
|
95
|
+
- **Key Comparison** — `GET /keys/compare?keys=pg_a,pg_b` returns side-by-side comparison of 2–10 keys — credits, usage, velocity, rate limits, status, metadata (namespace/group/tags) — with not-found key reporting
|
|
94
96
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
95
97
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
96
98
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -1758,6 +1760,83 @@ curl "http://localhost:3402/keys/credit-history?key=pg_...&type=topup&limit=10"
|
|
|
1758
1760
|
|
|
1759
1761
|
Entry types: `initial`, `topup`, `transfer_in`, `transfer_out`, `auto_topup`, `deduction`, `refund`, `bulk_topup`. Entries are newest-first, capped at 100 per key. Transfers include a `memo` field when provided.
|
|
1760
1762
|
|
|
1763
|
+
### Spending Velocity
|
|
1764
|
+
|
|
1765
|
+
`GET /keys/spending-velocity?key=...` returns credit burn rate and depletion forecast:
|
|
1766
|
+
|
|
1767
|
+
```bash
|
|
1768
|
+
curl "http://localhost:3402/keys/spending-velocity?key=pg_..." -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1769
|
+
|
|
1770
|
+
# Custom analysis window (default 24h, max 720h/30d)
|
|
1771
|
+
curl "http://localhost:3402/keys/spending-velocity?key=pg_...&window=48" -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1772
|
+
```
|
|
1773
|
+
|
|
1774
|
+
**Response:**
|
|
1775
|
+
|
|
1776
|
+
```json
|
|
1777
|
+
{
|
|
1778
|
+
"key": "pg_abc123...",
|
|
1779
|
+
"name": "my-key",
|
|
1780
|
+
"currentBalance": 750,
|
|
1781
|
+
"velocity": {
|
|
1782
|
+
"creditsPerHour": 12.5,
|
|
1783
|
+
"creditsPerDay": 300,
|
|
1784
|
+
"callsPerHour": 2.5,
|
|
1785
|
+
"callsPerDay": 60,
|
|
1786
|
+
"estimatedDepletionDate": "2026-03-01T18:00:00.000Z",
|
|
1787
|
+
"estimatedHoursRemaining": 60,
|
|
1788
|
+
"windowHours": 24,
|
|
1789
|
+
"dataPoints": 45
|
|
1790
|
+
},
|
|
1791
|
+
"topTools": [
|
|
1792
|
+
{ "tool": "search", "calls": 30, "credits": 150 },
|
|
1793
|
+
{ "tool": "generate", "calls": 15, "credits": 120 }
|
|
1794
|
+
]
|
|
1795
|
+
}
|
|
1796
|
+
```
|
|
1797
|
+
|
|
1798
|
+
`estimatedDepletionDate` and `estimatedHoursRemaining` are `null` when there's no spending activity. `topTools` shows the 5 highest-spend tools from usage data.
|
|
1799
|
+
|
|
1800
|
+
### Key Comparison
|
|
1801
|
+
|
|
1802
|
+
`GET /keys/compare?keys=pg_a,pg_b,pg_c` returns side-by-side comparison of 2–10 keys:
|
|
1803
|
+
|
|
1804
|
+
```bash
|
|
1805
|
+
curl "http://localhost:3402/keys/compare?keys=pg_abc,pg_xyz" -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1806
|
+
```
|
|
1807
|
+
|
|
1808
|
+
**Response:**
|
|
1809
|
+
|
|
1810
|
+
```json
|
|
1811
|
+
{
|
|
1812
|
+
"compared": 2,
|
|
1813
|
+
"keys": [
|
|
1814
|
+
{
|
|
1815
|
+
"key": "pg_abc123...",
|
|
1816
|
+
"name": "prod-agent",
|
|
1817
|
+
"status": "active",
|
|
1818
|
+
"credits": { "current": 750, "totalSpent": 250 },
|
|
1819
|
+
"usage": { "totalCalls": 50, "totalAllowed": 48, "totalDenied": 2 },
|
|
1820
|
+
"velocity": { "creditsPerHour": 12.5, "creditsPerDay": 300, "estimatedHoursRemaining": 60 },
|
|
1821
|
+
"rateLimit": { "used": 3, "limit": 60, "remaining": 57 },
|
|
1822
|
+
"metadata": { "namespace": "prod", "group": "team-a", "createdAt": "2026-02-01T00:00:00Z", "tags": { "env": "prod" } }
|
|
1823
|
+
},
|
|
1824
|
+
{
|
|
1825
|
+
"key": "pg_xyz789...",
|
|
1826
|
+
"name": "staging-agent",
|
|
1827
|
+
"status": "active",
|
|
1828
|
+
"credits": { "current": 200, "totalSpent": 800 },
|
|
1829
|
+
"usage": { "totalCalls": 120, "totalAllowed": 120, "totalDenied": 0 },
|
|
1830
|
+
"velocity": { "creditsPerHour": 8.3, "creditsPerDay": 200, "estimatedHoursRemaining": 24 },
|
|
1831
|
+
"rateLimit": { "used": 0, "limit": 60, "remaining": 60 },
|
|
1832
|
+
"metadata": { "namespace": "staging", "group": null, "createdAt": "2026-02-15T00:00:00Z", "tags": {} }
|
|
1833
|
+
}
|
|
1834
|
+
]
|
|
1835
|
+
}
|
|
1836
|
+
```
|
|
1837
|
+
|
|
1838
|
+
Keys not found are reported in a `notFound` array. Supports aliases. Maximum 10 keys per comparison.
|
|
1839
|
+
|
|
1761
1840
|
### IP Allowlisting
|
|
1762
1841
|
|
|
1763
1842
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/credit-ledger.d.ts
CHANGED
|
@@ -38,5 +38,20 @@ export declare class CreditLedger {
|
|
|
38
38
|
* Clear all entries for a key.
|
|
39
39
|
*/
|
|
40
40
|
clear(key: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Compute spending velocity and depletion forecast for a key.
|
|
43
|
+
* Analyzes credit debit entries (deduction, transfer_out) over a rolling window.
|
|
44
|
+
*/
|
|
45
|
+
getSpendingVelocity(key: string, currentBalance: number, windowHours?: number): SpendingVelocity;
|
|
46
|
+
}
|
|
47
|
+
export interface SpendingVelocity {
|
|
48
|
+
creditsPerHour: number;
|
|
49
|
+
creditsPerDay: number;
|
|
50
|
+
callsPerHour: number;
|
|
51
|
+
callsPerDay: number;
|
|
52
|
+
estimatedDepletionDate: string | null;
|
|
53
|
+
estimatedHoursRemaining: number | null;
|
|
54
|
+
windowHours: number;
|
|
55
|
+
dataPoints: number;
|
|
41
56
|
}
|
|
42
57
|
//# sourceMappingURL=credit-ledger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credit-ledger.d.ts","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;IAClH,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,gBAAgB,CAAS;gBAErB,gBAAgB,SAAM;IAIlC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI;IAehE;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW,EAAE;IAmBhG;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAI1B;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"credit-ledger.d.ts","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;IAClH,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,gBAAgB,CAAS;gBAErB,gBAAgB,SAAM;IAIlC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI;IAehE;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW,EAAE;IAmBhG;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAI1B;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,gBAAgB;CAmE7F;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
package/dist/credit-ledger.js
CHANGED
|
@@ -62,6 +62,73 @@ class CreditLedger {
|
|
|
62
62
|
clear(key) {
|
|
63
63
|
this.entries.delete(key);
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Compute spending velocity and depletion forecast for a key.
|
|
67
|
+
* Analyzes credit debit entries (deduction, transfer_out) over a rolling window.
|
|
68
|
+
*/
|
|
69
|
+
getSpendingVelocity(key, currentBalance, windowHours = 24) {
|
|
70
|
+
const list = this.entries.get(key);
|
|
71
|
+
if (!list || list.length === 0) {
|
|
72
|
+
return {
|
|
73
|
+
creditsPerHour: 0,
|
|
74
|
+
creditsPerDay: 0,
|
|
75
|
+
callsPerHour: 0,
|
|
76
|
+
callsPerDay: 0,
|
|
77
|
+
estimatedDepletionDate: null,
|
|
78
|
+
estimatedHoursRemaining: null,
|
|
79
|
+
windowHours,
|
|
80
|
+
dataPoints: 0,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const now = Date.now();
|
|
84
|
+
const cutoff = new Date(now - windowHours * 3_600_000).toISOString();
|
|
85
|
+
// Debit types reduce balance
|
|
86
|
+
const debitTypes = new Set(['deduction', 'transfer_out']);
|
|
87
|
+
const debits = list.filter(e => debitTypes.has(e.type) && e.timestamp >= cutoff);
|
|
88
|
+
const totalDebited = debits.reduce((sum, e) => sum + e.amount, 0);
|
|
89
|
+
const debitCount = debits.length;
|
|
90
|
+
// Compute the actual time span of debits (if any)
|
|
91
|
+
let spanHours = windowHours;
|
|
92
|
+
if (debits.length >= 2) {
|
|
93
|
+
const oldest = new Date(debits[0].timestamp).getTime();
|
|
94
|
+
const newest = new Date(debits[debits.length - 1].timestamp).getTime();
|
|
95
|
+
const span = (newest - oldest) / 3_600_000;
|
|
96
|
+
if (span > 0)
|
|
97
|
+
spanHours = span;
|
|
98
|
+
}
|
|
99
|
+
else if (debits.length === 1) {
|
|
100
|
+
// Single debit — use time from debit to now as span
|
|
101
|
+
const debitTime = new Date(debits[0].timestamp).getTime();
|
|
102
|
+
const span = (now - debitTime) / 3_600_000;
|
|
103
|
+
if (span > 0.01)
|
|
104
|
+
spanHours = span; // At least ~36 seconds
|
|
105
|
+
}
|
|
106
|
+
const creditsPerHour = debits.length > 0 ? totalDebited / spanHours : 0;
|
|
107
|
+
const creditsPerDay = creditsPerHour * 24;
|
|
108
|
+
const callsPerHour = debits.length > 0 ? debitCount / spanHours : 0;
|
|
109
|
+
const callsPerDay = callsPerHour * 24;
|
|
110
|
+
let estimatedDepletionDate = null;
|
|
111
|
+
let estimatedHoursRemaining = null;
|
|
112
|
+
if (creditsPerHour > 0 && currentBalance > 0) {
|
|
113
|
+
estimatedHoursRemaining = Math.round((currentBalance / creditsPerHour) * 100) / 100;
|
|
114
|
+
const depletionMs = now + estimatedHoursRemaining * 3_600_000;
|
|
115
|
+
estimatedDepletionDate = new Date(depletionMs).toISOString();
|
|
116
|
+
}
|
|
117
|
+
else if (currentBalance <= 0) {
|
|
118
|
+
estimatedHoursRemaining = 0;
|
|
119
|
+
estimatedDepletionDate = new Date(now).toISOString();
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
creditsPerHour: Math.round(creditsPerHour * 100) / 100,
|
|
123
|
+
creditsPerDay: Math.round(creditsPerDay * 100) / 100,
|
|
124
|
+
callsPerHour: Math.round(callsPerHour * 100) / 100,
|
|
125
|
+
callsPerDay: Math.round(callsPerDay * 100) / 100,
|
|
126
|
+
estimatedDepletionDate,
|
|
127
|
+
estimatedHoursRemaining,
|
|
128
|
+
windowHours,
|
|
129
|
+
dataPoints: debits.length,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
65
132
|
}
|
|
66
133
|
exports.CreditLedger = CreditLedger;
|
|
67
134
|
//# sourceMappingURL=credit-ledger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credit-ledger.js","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAYH,MAAa,YAAY;IACf,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC3C,gBAAgB,CAAS;IAEjC,YAAY,gBAAgB,GAAG,GAAG;QAChC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW,EAAE,KAAqC;QACvD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC;YACR,GAAG,KAAK;YACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,qBAAqB;QACrB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAW,EAAE,IAAwD;QAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAE1C,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,eAAe;QAEjD,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;YACf,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YAChB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,KAAM,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAW;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAW;QACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"credit-ledger.js","sourceRoot":"","sources":["../src/credit-ledger.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export { SessionManager, writeSseHeaders, writeSseEvent, writeSseKeepAlive } fro
|
|
|
33
33
|
export { AuditLogger, maskKeyForAudit } from './audit';
|
|
34
34
|
export type { AuditEvent, AuditEventType, AuditLogConfig, AuditQuery, AuditQueryResult } from './audit';
|
|
35
35
|
export { CreditLedger } from './credit-ledger';
|
|
36
|
-
export type { CreditEntry } from './credit-ledger';
|
|
36
|
+
export type { CreditEntry, SpendingVelocity } from './credit-ledger';
|
|
37
37
|
export { ToolRegistry } from './registry';
|
|
38
38
|
export { MetricsCollector } from './metrics';
|
|
39
39
|
export type { MetricLabels } from './metrics';
|
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,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,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -182,6 +182,8 @@ export declare class PayGateServer {
|
|
|
182
182
|
private handleRateLimitStatus;
|
|
183
183
|
private handleQuotaStatus;
|
|
184
184
|
private handleCreditHistory;
|
|
185
|
+
private handleSpendingVelocity;
|
|
186
|
+
private handleKeyComparison;
|
|
185
187
|
private handleSetAutoTopup;
|
|
186
188
|
private handleBalance;
|
|
187
189
|
private handleLimits;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -538,6 +538,10 @@ class PayGateServer {
|
|
|
538
538
|
return this.handleQuotaStatus(req, res);
|
|
539
539
|
case '/keys/credit-history':
|
|
540
540
|
return this.handleCreditHistory(req, res);
|
|
541
|
+
case '/keys/spending-velocity':
|
|
542
|
+
return this.handleSpendingVelocity(req, res);
|
|
543
|
+
case '/keys/compare':
|
|
544
|
+
return this.handleKeyComparison(req, res);
|
|
541
545
|
case '/keys/templates':
|
|
542
546
|
if (req.method === 'GET')
|
|
543
547
|
return this.handleListTemplates(req, res);
|
|
@@ -1084,6 +1088,8 @@ class PayGateServer {
|
|
|
1084
1088
|
rateLimitStatus: 'GET /keys/rate-limit-status?key=... — Current rate limit window state (requires X-Admin-Key)',
|
|
1085
1089
|
quotaStatus: 'GET /keys/quota-status?key=... — Current daily/monthly quota usage (requires X-Admin-Key)',
|
|
1086
1090
|
creditHistory: 'GET /keys/credit-history?key=... — Per-key credit mutation history (requires X-Admin-Key)',
|
|
1091
|
+
spendingVelocity: 'GET /keys/spending-velocity?key=... — Spending rate and depletion forecast (requires X-Admin-Key)',
|
|
1092
|
+
keyComparison: 'GET /keys/compare?keys=pg_a,pg_b — Side-by-side key comparison (requires X-Admin-Key)',
|
|
1087
1093
|
keyTemplates: 'GET /keys/templates — List key templates + POST to create/update (requires X-Admin-Key)',
|
|
1088
1094
|
deleteTemplate: 'POST /keys/templates/delete — Delete a key template (requires X-Admin-Key)',
|
|
1089
1095
|
pricing: 'GET /pricing — Tool pricing breakdown (public)',
|
|
@@ -2778,6 +2784,144 @@ class PayGateServer {
|
|
|
2778
2784
|
entries,
|
|
2779
2785
|
}));
|
|
2780
2786
|
}
|
|
2787
|
+
// ─── /keys/spending-velocity — Spending rate + depletion forecast ────────────
|
|
2788
|
+
handleSpendingVelocity(req, res) {
|
|
2789
|
+
if (req.method !== 'GET') {
|
|
2790
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
2791
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
2792
|
+
return;
|
|
2793
|
+
}
|
|
2794
|
+
if (!this.checkAdmin(req, res))
|
|
2795
|
+
return;
|
|
2796
|
+
const urlParts = req.url?.split('?') || [];
|
|
2797
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
2798
|
+
const key = params.get('key');
|
|
2799
|
+
if (!key) {
|
|
2800
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2801
|
+
res.end(JSON.stringify({ error: 'Missing required query parameter: key' }));
|
|
2802
|
+
return;
|
|
2803
|
+
}
|
|
2804
|
+
// Resolve alias
|
|
2805
|
+
const resolved = this.gate.store.resolveKey(key);
|
|
2806
|
+
const actualKey = resolved ? resolved.key : key;
|
|
2807
|
+
const keyRecord = this.gate.store.getKey(actualKey);
|
|
2808
|
+
if (!keyRecord) {
|
|
2809
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
2810
|
+
res.end(JSON.stringify({ error: 'Key not found' }));
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
const windowParam = params.get('window');
|
|
2814
|
+
const windowHours = Math.min(Math.max(1, windowParam !== null ? (Number(windowParam) || 1) : 24), 720); // 1h to 30 days
|
|
2815
|
+
const velocity = this.creditLedger.getSpendingVelocity(actualKey, keyRecord.credits, windowHours);
|
|
2816
|
+
// Get top tools from usage meter (per-key usage)
|
|
2817
|
+
const keyUsage = this.gate.meter.getKeyUsage(actualKey);
|
|
2818
|
+
const topTools = [];
|
|
2819
|
+
if (keyUsage && keyUsage.perTool) {
|
|
2820
|
+
const toolEntries = Object.entries(keyUsage.perTool)
|
|
2821
|
+
.map(([tool, stats]) => ({ tool, calls: stats.calls, credits: stats.credits }))
|
|
2822
|
+
.sort((a, b) => b.credits - a.credits)
|
|
2823
|
+
.slice(0, 5);
|
|
2824
|
+
topTools.push(...toolEntries);
|
|
2825
|
+
}
|
|
2826
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2827
|
+
res.end(JSON.stringify({
|
|
2828
|
+
key: actualKey.slice(0, 10) + '...',
|
|
2829
|
+
name: keyRecord.name,
|
|
2830
|
+
currentBalance: keyRecord.credits,
|
|
2831
|
+
velocity,
|
|
2832
|
+
topTools,
|
|
2833
|
+
}));
|
|
2834
|
+
}
|
|
2835
|
+
// ─── /keys/compare — Side-by-side key comparison ────────────────────────────
|
|
2836
|
+
handleKeyComparison(req, res) {
|
|
2837
|
+
if (req.method !== 'GET') {
|
|
2838
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
2839
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
2840
|
+
return;
|
|
2841
|
+
}
|
|
2842
|
+
if (!this.checkAdmin(req, res))
|
|
2843
|
+
return;
|
|
2844
|
+
const urlParts = req.url?.split('?') || [];
|
|
2845
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
2846
|
+
const keysParam = params.get('keys');
|
|
2847
|
+
if (!keysParam) {
|
|
2848
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2849
|
+
res.end(JSON.stringify({ error: 'Missing required query parameter: keys (comma-separated)' }));
|
|
2850
|
+
return;
|
|
2851
|
+
}
|
|
2852
|
+
const keyIds = keysParam.split(',').map(k => k.trim()).filter(Boolean);
|
|
2853
|
+
if (keyIds.length < 2) {
|
|
2854
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2855
|
+
res.end(JSON.stringify({ error: 'At least 2 keys required for comparison' }));
|
|
2856
|
+
return;
|
|
2857
|
+
}
|
|
2858
|
+
if (keyIds.length > 10) {
|
|
2859
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
2860
|
+
res.end(JSON.stringify({ error: 'Maximum 10 keys per comparison' }));
|
|
2861
|
+
return;
|
|
2862
|
+
}
|
|
2863
|
+
const comparisons = [];
|
|
2864
|
+
const notFound = [];
|
|
2865
|
+
for (const keyId of keyIds) {
|
|
2866
|
+
const resolved = this.gate.store.resolveKey(keyId);
|
|
2867
|
+
const actualKey = resolved ? resolved.key : keyId;
|
|
2868
|
+
const record = this.gate.store.getKey(actualKey);
|
|
2869
|
+
if (!record) {
|
|
2870
|
+
notFound.push(keyId);
|
|
2871
|
+
continue;
|
|
2872
|
+
}
|
|
2873
|
+
// Get usage stats
|
|
2874
|
+
const keyUsage = this.gate.meter.getKeyUsage(actualKey);
|
|
2875
|
+
// Get velocity (24h window)
|
|
2876
|
+
const velocity = this.creditLedger.getSpendingVelocity(actualKey, record.credits, 24);
|
|
2877
|
+
// Get rate limit status
|
|
2878
|
+
const rateStatus = this.gate.rateLimiter.getStatus(actualKey);
|
|
2879
|
+
// Determine key status
|
|
2880
|
+
let status = 'active';
|
|
2881
|
+
if (!record.active)
|
|
2882
|
+
status = 'revoked';
|
|
2883
|
+
else if (record.suspended)
|
|
2884
|
+
status = 'suspended';
|
|
2885
|
+
else if (record.expiresAt && new Date(record.expiresAt).getTime() < Date.now())
|
|
2886
|
+
status = 'expired';
|
|
2887
|
+
comparisons.push({
|
|
2888
|
+
key: actualKey.slice(0, 10) + '...',
|
|
2889
|
+
name: record.name,
|
|
2890
|
+
status,
|
|
2891
|
+
credits: {
|
|
2892
|
+
current: record.credits,
|
|
2893
|
+
totalSpent: keyUsage.totalCreditsSpent,
|
|
2894
|
+
},
|
|
2895
|
+
usage: {
|
|
2896
|
+
totalCalls: keyUsage.totalCalls,
|
|
2897
|
+
totalAllowed: keyUsage.totalAllowed,
|
|
2898
|
+
totalDenied: keyUsage.totalDenied,
|
|
2899
|
+
},
|
|
2900
|
+
velocity: {
|
|
2901
|
+
creditsPerHour: velocity.creditsPerHour,
|
|
2902
|
+
creditsPerDay: velocity.creditsPerDay,
|
|
2903
|
+
estimatedHoursRemaining: velocity.estimatedHoursRemaining,
|
|
2904
|
+
},
|
|
2905
|
+
rateLimit: {
|
|
2906
|
+
used: rateStatus.used,
|
|
2907
|
+
limit: rateStatus.limit,
|
|
2908
|
+
remaining: rateStatus.remaining,
|
|
2909
|
+
},
|
|
2910
|
+
metadata: {
|
|
2911
|
+
namespace: record.namespace || null,
|
|
2912
|
+
group: record.group || null,
|
|
2913
|
+
createdAt: record.createdAt,
|
|
2914
|
+
tags: record.tags || {},
|
|
2915
|
+
},
|
|
2916
|
+
});
|
|
2917
|
+
}
|
|
2918
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
2919
|
+
res.end(JSON.stringify({
|
|
2920
|
+
compared: comparisons.length,
|
|
2921
|
+
notFound: notFound.length > 0 ? notFound : undefined,
|
|
2922
|
+
keys: comparisons,
|
|
2923
|
+
}));
|
|
2924
|
+
}
|
|
2781
2925
|
// ─── /keys/auto-topup — Configure auto-topup ────────────────────────────────
|
|
2782
2926
|
async handleSetAutoTopup(req, res) {
|
|
2783
2927
|
if (req.method !== 'POST') {
|