aigetwey 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +65 -4
  2. package/README.md +32 -11
  3. package/config.example.yaml +6 -6
  4. package/dashboard/next.config.ts +6 -0
  5. package/dashboard/src/app/(console)/quota/page.tsx +2 -2
  6. package/dashboard/src/app/globals.css +47 -0
  7. package/dashboard/src/components/BudgetForm.tsx +256 -0
  8. package/dashboard/src/components/BudgetTracker.tsx +181 -0
  9. package/dashboard/src/components/CooldownTimer.tsx +1 -1
  10. package/dashboard/src/components/EndpointView.tsx +285 -47
  11. package/dashboard/src/components/LogTable.tsx +97 -25
  12. package/dashboard/src/components/ModelPicker.tsx +15 -7
  13. package/dashboard/src/components/ProviderDetail.tsx +27 -29
  14. package/dashboard/src/components/ProviderManager.tsx +39 -31
  15. package/dashboard/src/components/Rail.tsx +1 -1
  16. package/dashboard/src/components/RoutingView.tsx +8 -4
  17. package/dashboard/src/components/ToolDetail.tsx +5 -3
  18. package/dashboard/src/components/TopBar.tsx +1 -1
  19. package/dashboard/src/components/UsageView.tsx +25 -6
  20. package/dashboard/src/components/ui.tsx +6 -1
  21. package/dashboard/src/lib/cliTools.ts +0 -43
  22. package/dashboard/src/lib/client.ts +14 -7
  23. package/dashboard/src/lib/gateway.ts +33 -15
  24. package/dashboard/src/{middleware.ts → proxy.ts} +8 -6
  25. package/dist/cli.js +43 -8
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config.js +136 -27
  28. package/dist/config.js.map +1 -1
  29. package/dist/core/budget.js +62 -17
  30. package/dist/core/budget.js.map +1 -1
  31. package/dist/core/fallback.js +0 -6
  32. package/dist/core/fallback.js.map +1 -1
  33. package/dist/core/handler.js +24 -9
  34. package/dist/core/handler.js.map +1 -1
  35. package/dist/core/keysUsage.js +15 -0
  36. package/dist/core/keysUsage.js.map +1 -0
  37. package/dist/core/ratelimit.js +15 -0
  38. package/dist/core/ratelimit.js.map +1 -0
  39. package/dist/core/state.js +15 -15
  40. package/dist/core/state.js.map +1 -1
  41. package/dist/core/window.js +35 -0
  42. package/dist/core/window.js.map +1 -0
  43. package/dist/db.js +39 -25
  44. package/dist/db.js.map +1 -1
  45. package/dist/middleware/auth.js +15 -8
  46. package/dist/middleware/auth.js.map +1 -1
  47. package/dist/routes/admin.js +80 -17
  48. package/dist/routes/admin.js.map +1 -1
  49. package/dist/routes/v1.js +28 -11
  50. package/dist/routes/v1.js.map +1 -1
  51. package/dist/server.js +5 -7
  52. package/dist/server.js.map +1 -1
  53. package/dist/stream/openai-stream.js +3 -0
  54. package/dist/stream/openai-stream.js.map +1 -1
  55. package/dist/upstream/client.js +9 -0
  56. package/dist/upstream/client.js.map +1 -1
  57. package/package.json +3 -4
  58. package/src/cli.ts +44 -8
  59. package/src/config.ts +142 -29
  60. package/src/core/budget.ts +78 -25
  61. package/src/core/fallback.ts +0 -9
  62. package/src/core/handler.ts +31 -12
  63. package/src/core/keysUsage.ts +49 -0
  64. package/src/core/ratelimit.ts +25 -0
  65. package/src/core/state.ts +21 -16
  66. package/src/core/window.ts +45 -0
  67. package/src/db.ts +50 -28
  68. package/src/middleware/auth.ts +18 -8
  69. package/src/routes/admin.ts +93 -20
  70. package/src/routes/v1.ts +32 -11
  71. package/src/server.ts +5 -8
  72. package/src/stream/openai-stream.ts +3 -1
  73. package/src/upstream/client.ts +9 -0
  74. package/dashboard/src/components/BudgetEditor.tsx +0 -97
  75. package/dashboard/src/components/QuotaView.tsx +0 -152
  76. package/src/core/quota.ts +0 -253
@@ -55,20 +55,6 @@ export const CLI_TOOLS: CliTool[] = [
55
55
  "The gateway translates Anthropic ↔ provider format, so any provider works behind it.",
56
56
  ],
57
57
  },
58
- {
59
- id: "codex",
60
- name: "Codex",
61
- icon: "code",
62
- format: "openai",
63
- blurb: "OpenAI-compatible. Use the /v1 base URL.",
64
- install: "npm i -g @openai/codex",
65
- slots: [{ label: "Model", alias: "gpt-5" }],
66
- env: (base, key) => [
67
- { name: "OPENAI_BASE_URL", value: `${base}/v1` },
68
- { name: "OPENAI_API_KEY", value: KEY(key) },
69
- ],
70
- steps: ["Set the base URL to the gateway's /v1 path.", "Create a combo named like the slot above, then use it as the model."],
71
- },
72
58
  {
73
59
  id: "opencode",
74
60
  name: "opencode",
@@ -84,35 +70,6 @@ export const CLI_TOOLS: CliTool[] = [
84
70
  ],
85
71
  steps: ["Add an OpenAI-compatible provider with the gateway /v1 base URL.", "Pick a combo alias as the model."],
86
72
  },
87
- {
88
- id: "cursor",
89
- name: "Cursor",
90
- icon: "edit_square",
91
- format: "openai",
92
- blurb: "OpenAI-compatible. Override the base URL in settings.",
93
- slots: [{ label: "Model", alias: "gpt-5" }],
94
- env: (base, key) => [
95
- { name: "Base URL", value: `${base}/v1` },
96
- { name: "API Key", value: KEY(key) },
97
- ],
98
- steps: [
99
- "Settings → Models → OpenAI API Key → override base URL with the gateway /v1.",
100
- "Add your combo aliases as custom model names.",
101
- ],
102
- },
103
- {
104
- id: "cline",
105
- name: "Cline",
106
- icon: "extension",
107
- format: "openai",
108
- blurb: "OpenAI-compatible VS Code agent.",
109
- slots: [{ label: "Model", alias: "gpt-5" }],
110
- env: (base, key) => [
111
- { name: "Base URL", value: `${base}/v1` },
112
- { name: "API Key", value: KEY(key) },
113
- ],
114
- steps: ["Choose the OpenAI-compatible provider.", "Set the base URL to the gateway /v1 and use a combo alias."],
115
- },
116
73
  ];
117
74
 
118
75
  export function toolById(id: string): CliTool | undefined {
@@ -12,10 +12,11 @@ import type {
12
12
  EndpointPayload,
13
13
  HeadroomStatusReply,
14
14
  InjectLevel,
15
+ KeyUsageRow,
16
+ ModelsPayload,
15
17
  PingResult,
16
18
  PricingPayload,
17
19
  ProviderSnapshot,
18
- QuotaSnapshot,
19
20
  WireFormat,
20
21
  } from "./gateway";
21
22
 
@@ -53,16 +54,20 @@ async function api<T>(method: string, path: string, body?: unknown): Promise<Api
53
54
 
54
55
  export const adminApi = {
55
56
  providers: () => api<{ providers: ProviderSnapshot[] }>("GET", "/admin/providers"),
56
- quota: () => api<{ quota: QuotaSnapshot[]; budget: BudgetStatus | null }>("GET", "/admin/quota"),
57
+ budgets: () => api<{ budgets: BudgetStatus[] }>("GET", "/admin/budgets"),
58
+ models: () => api<ModelsPayload>("GET", "/admin/models"),
59
+ keys: () => api<Array<{ fingerprint: string; name: string; masked: string }>>("GET", "/admin/keys"),
60
+ keysUsage: () => api<{ keys: KeyUsageRow[] }>("GET", "/admin/keys/usage"),
61
+
57
62
  setBudget: (body: {
63
+ scope: { type: "global" } | { type: "provider"; id: string } | { type: "model"; id: string } | { type: "key"; id: string };
58
64
  unit: "usd" | "tokens";
59
65
  limit: number;
60
- window: "5h" | "daily" | "weekly" | "monthly";
61
- reset_at?: string;
62
- timezone?: string;
66
+ window: "5h" | "24h" | "7day" | "30day";
63
67
  alert_at?: number;
64
- }) => api<ConfigReply>("PUT", "/admin/budget", body),
65
- clearBudget: () => api<ConfigReply>("DELETE", "/admin/budget"),
68
+ note?: string;
69
+ }) => api<ConfigReply>("PUT", "/admin/budgets", body),
70
+ clearBudget: (key: string) => api<ConfigReply>("DELETE", `/admin/budgets/${encodeURIComponent(key)}`),
66
71
 
67
72
  addProvider: (p: {
68
73
  id: string;
@@ -136,6 +141,8 @@ export const adminApi = {
136
141
  setPonytail: (level: InjectLevel) => api<ConfigReply>("PUT", "/admin/endpoint/ponytail", { level }),
137
142
  addServerKey: (key: string, name?: string) => api<ConfigReply>("POST", "/admin/endpoint/keys", { key, name }),
138
143
  editServerKey: (index: number, name: string) => api<ConfigReply>("PUT", `/admin/endpoint/keys/${index}`, { name }),
144
+ setServerKeyScope: (index: number, body: { models?: string[]; rpm?: number | null; expires?: number | null }) =>
145
+ api<ConfigReply>("PUT", `/admin/endpoint/keys/${index}/scope`, body),
139
146
  removeServerKey: (index: number) => api<ConfigReply>("DELETE", `/admin/endpoint/keys/${index}`),
140
147
  revealServerKey: (index: number) => api<{ key: string }>("GET", `/admin/endpoint/keys/${index}/reveal`),
141
148
 
@@ -7,7 +7,7 @@ import { currentPassword } from "./session";
7
7
  * a Bearer token so it never reaches the browser.
8
8
  *
9
9
  * Scoped to the admin surface the gateway exposes today (usage, logs, providers,
10
- * quota, whole-config CRUD). Granular provider/combo mutation helpers are added
10
+ * budgets, whole-config CRUD). Granular provider/combo mutation helpers are added
11
11
  * alongside the pages that drive them in phase 11.
12
12
  */
13
13
  function gatewayUrl(): string {
@@ -67,7 +67,7 @@ export async function checkGatewayAuth(password: string): Promise<boolean> {
67
67
 
68
68
  export const gateway = {
69
69
  providers: () => call<{ providers: ProviderSnapshot[] }>("GET", "/admin/providers"),
70
- quota: () => call<{ quota: QuotaSnapshot[]; budget: BudgetStatus | null }>("GET", "/admin/quota"),
70
+ budgets: () => call<{ budgets: BudgetStatus[] }>("GET", "/admin/budgets"),
71
71
  models: () => call<ModelsPayload>("GET", "/admin/models"),
72
72
  logs: (limit = 100) => call<{ logs: UsageLog[] }>("GET", `/admin/logs?limit=${limit}`),
73
73
  usage: (since = 0) => call<UsageSummary>("GET", `/admin/usage?since=${since}`),
@@ -157,7 +157,6 @@ export interface MaskedProvider {
157
157
  auto_models: boolean;
158
158
  service_account?: string;
159
159
  models: Array<{ id: string; price_in?: number; price_out?: number }>;
160
- quota?: { window: "5h" | "daily" | "weekly" | "monthly"; reset_at?: string; timezone: string; limit_tokens?: number };
161
160
  cooldown_base_ms: number;
162
161
  max_retries: number;
163
162
  disabled_keys?: number[];
@@ -178,7 +177,26 @@ export interface EndpointPayload {
178
177
  caveman: InjectLevel;
179
178
  ponytail: InjectLevel;
180
179
  headroom: { enabled: boolean; url: string; compress_user_messages: boolean };
181
- keys: Array<{ key: string; name?: string }>;
180
+ keys: Array<{ key: string; fingerprint: string; name?: string; models?: string[]; rpm?: number; expires?: number }>;
181
+ }
182
+
183
+ export interface KeyUsageRow {
184
+ fingerprint: string;
185
+ name: string;
186
+ masked: string;
187
+ expires?: number;
188
+ spent: number;
189
+ tokens: number;
190
+ budget: {
191
+ unit: "usd" | "tokens";
192
+ limit: number;
193
+ spent: number;
194
+ pct: number;
195
+ window: "5h" | "24h" | "7day" | "30day";
196
+ reset_in_ms: number;
197
+ exhausted: boolean;
198
+ alert: boolean;
199
+ } | null;
182
200
  }
183
201
 
184
202
  export interface HeadroomStatusReply {
@@ -233,27 +251,27 @@ export interface ProviderSnapshot {
233
251
  format: WireFormat;
234
252
  keys: KeySnapshot[];
235
253
  }
236
- export interface QuotaSnapshot {
237
- provider: string;
238
- window: "5h" | "daily" | "weekly" | "monthly";
239
- consumed: number;
240
- limit_tokens?: number;
241
- reset_in_ms: number;
242
- pct?: number;
243
- exhausted: boolean;
244
- alert: boolean;
245
- }
254
+ export type BudgetScope =
255
+ | { type: "global" }
256
+ | { type: "provider"; id: string }
257
+ | { type: "model"; id: string }
258
+ | { type: "key"; id: string };
246
259
 
247
260
  export interface BudgetStatus {
261
+ scope: BudgetScope;
262
+ key: string;
263
+ label: string;
264
+ note?: string;
248
265
  unit: "usd" | "tokens";
249
266
  limit: number;
250
267
  spent: number;
251
268
  pct: number;
252
269
  alert: boolean;
270
+ alert_at: number;
253
271
  exhausted: boolean;
254
272
  est_converse: number | null;
255
273
  reset_in_ms: number;
256
- window: "5h" | "daily" | "weekly" | "monthly";
274
+ window: "5h" | "24h" | "7day" | "30day";
257
275
  }
258
276
  export interface UsageLog {
259
277
  ts: number;
@@ -5,11 +5,11 @@ import { openSession, SESSION_COOKIE } from "@/lib/session";
5
5
  /**
6
6
  * Gate every page and admin-proxy route behind a valid session. The login page
7
7
  * and the auth endpoints stay open; everything else redirects to /login (pages)
8
- * or 401s (api).
8
+ * or 401s (api). This is Next 16's `proxy` convention (formerly `middleware`).
9
9
  */
10
10
  const OPEN = ["/login", "/api/login", "/api/logout"];
11
11
 
12
- export function middleware(req: NextRequest): NextResponse {
12
+ export function proxy(req: NextRequest): NextResponse {
13
13
  const { pathname } = req.nextUrl;
14
14
  if (OPEN.some((p) => pathname === p || pathname.startsWith(p + "/"))) {
15
15
  return NextResponse.next();
@@ -30,8 +30,10 @@ export function middleware(req: NextRequest): NextResponse {
30
30
  }
31
31
 
32
32
  export const config = {
33
- // run on everything except next internals and static assets
34
- matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
35
- // session verification uses node:crypto, unsupported on the Edge runtime
36
- runtime: "nodejs",
33
+ // run on everything except next internals and static assets. icon.svg is the
34
+ // App Router favicon — it must stay public, else the auth gate redirects it to
35
+ // /login and the browser tab shows no icon.
36
+ matcher: ["/((?!_next/static|_next/image|favicon.ico|icon.svg).*)"],
37
+ // note: the proxy convention always runs on the Node.js runtime (no `runtime`
38
+ // key allowed), which is what our node:crypto session check needs anyway.
37
39
  };
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { spawn, execSync } from "node:child_process";
16
16
  import { randomBytes } from "node:crypto";
17
- import { existsSync, copyFileSync } from "node:fs";
17
+ import { existsSync, copyFileSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
18
18
  import { resolve, dirname, join } from "node:path";
19
19
  import { fileURLToPath } from "node:url";
20
20
  import { createInterface } from "node:readline";
@@ -57,21 +57,53 @@ const HELP = `
57
57
  `;
58
58
  const GATEWAY_PORT = opts.port ?? Number(process.env.AIGETWEY_PORT ?? 18080);
59
59
  const DASHBOARD_PORT = Number(process.env.DASHBOARD_PORT ?? 3000);
60
- // reuse env secrets if present, otherwise generate (admin) / random (session).
60
+ // reuse env secrets if present, otherwise generate (admin) / persist (session).
61
61
  const adminPassword = process.env.AIGETWEY_ADMIN_PASSWORD ?? randomBytes(6).toString("hex");
62
- const sessionSecret = process.env.SESSION_SECRET ?? randomBytes(24).toString("hex");
63
62
  const generatedPw = !process.env.AIGETWEY_ADMIN_PASSWORD;
63
+ /**
64
+ * The dashboard session cookie is signed+encrypted with SESSION_SECRET. A fresh
65
+ * random secret each boot would invalidate every cookie on restart — the symptom
66
+ * being "re-enter the password after a relaunch" — so persist a generated one to
67
+ * the data dir (alongside auth.json) and reuse it. An explicit env var wins.
68
+ */
69
+ function loadOrCreateSessionSecret() {
70
+ if (process.env.SESSION_SECRET)
71
+ return process.env.SESSION_SECRET;
72
+ const dataDir = resolve(process.env.AIGETWEY_DATA_DIR ?? join(root, "data"));
73
+ const file = join(dataDir, "session-secret");
74
+ try {
75
+ const existing = readFileSync(file, "utf8").trim();
76
+ if (existing)
77
+ return existing;
78
+ }
79
+ catch {
80
+ // not created yet — fall through and generate.
81
+ }
82
+ const secret = randomBytes(24).toString("hex");
83
+ try {
84
+ mkdirSync(dataDir, { recursive: true });
85
+ writeFileSync(file, secret, { mode: 0o600 });
86
+ }
87
+ catch {
88
+ // unwritable data dir — fall back to an ephemeral secret (cookies won't
89
+ // survive this boot, but the gateway still runs).
90
+ }
91
+ return secret;
92
+ }
93
+ const sessionSecret = loadOrCreateSessionSecret();
64
94
  function openBrowser(url) {
65
95
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
66
96
  spawn(cmd, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
67
97
  }
68
- async function waitForGateway(url, timeoutMs = 20000) {
98
+ async function waitForGateway(url, timeoutMs = 20000, ready = (s) => s > 0) {
69
99
  const deadline = Date.now() + timeoutMs;
70
100
  while (Date.now() < deadline) {
71
101
  try {
72
102
  const res = await fetch(url, { method: "GET" });
73
- // any HTTP answer (even 401/503) means the port is up
74
- if (res.status > 0)
103
+ // default: any HTTP answer (even 401/503) means the port is up. A caller
104
+ // can demand more — e.g. a non-5xx, to wait past a proxy's boot-time 502/500
105
+ // while the upstream it fronts is still coming up.
106
+ if (ready(res.status))
75
107
  return true;
76
108
  }
77
109
  catch {
@@ -331,9 +363,12 @@ async function main() {
331
363
  process.exit(code ?? 1);
332
364
  });
333
365
  // one URL for everything — the gateway reverse-proxies the dashboard. Wait for
334
- // the dashboard to answer THROUGH the proxy before opening the browser.
366
+ // the dashboard to be READY before opening the browser. Probe it directly on
367
+ // its own port (not through the proxy) and require a non-5xx answer: a proxy
368
+ // hit during boot returns 500 (ECONNREFUSED upstream), which a bare "port up"
369
+ // check would mistake for ready and open the browser into a wall of 500s.
335
370
  const appUrl = `http://127.0.0.1:${GATEWAY_PORT}`;
336
- await waitForGateway(`${appUrl}/login`, 30000);
371
+ await waitForGateway(`http://127.0.0.1:${DASHBOARD_PORT}/login`, 30000, (s) => s > 0 && s < 500);
337
372
  console.log(`\n aigetwey ${appUrl} (dashboard + API, one URL)`);
338
373
  if (generatedPw) {
339
374
  console.log(`\n admin password (generated): ${adminPassword}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -2,24 +2,15 @@ import { readFileSync, writeFileSync, renameSync, copyFileSync, existsSync, mkdi
2
2
  import { dirname } from "node:path";
3
3
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
4
4
  import { z } from "zod";
5
+ import { clientKeyFingerprint } from "./middleware/auth.js";
6
+ export { clientKeyFingerprint } from "./middleware/auth.js";
5
7
  // ---- schema (PLAN §8) -------------------------------------------------------
6
8
  //
7
9
  // Shape differs from a flat OpenAI gateway: routing lives in a top-level
8
10
  // `models[]` layer (alias -> provider chain), the endpoint block carries the
9
11
  // token-saver toggles, and providers may be free passthroughs or service-account
10
- // backed. The handler/keypool/quota phases read these fields; defining the full
12
+ // backed. The handler/keypool phases read these fields; defining the full
11
13
  // shape up front avoids reshaping config across later phases.
12
- /** Token quota window for a provider — drives the dashboard reset countdown. */
13
- const QuotaSchema = z.object({
14
- window: z.enum(["5h", "daily", "weekly", "monthly"]),
15
- // daily: "HH:MM" local reset; weekly: weekday name ("monday"); others: ignored.
16
- reset_at: z.string().optional(),
17
- timezone: z.string().default("UTC"),
18
- // optional ceiling for a progress bar; quota tracking works without it.
19
- limit_tokens: z.number().int().positive().optional(),
20
- // soft-alert threshold (0..1); UI flags the quota when pct >= this. Default 0.8.
21
- alert_at: z.number().gt(0).lte(1).optional(),
22
- });
23
14
  const ProviderModelSchema = z.object({
24
15
  id: z.string().min(1),
25
16
  price_in: z.number().nonnegative().optional(),
@@ -45,7 +36,6 @@ const ProviderSchema = z
45
36
  service_account: z.string().optional(),
46
37
  models: z.array(ProviderModelSchema).default([]),
47
38
  headers: z.record(z.string()).optional(),
48
- quota: QuotaSchema.optional(),
49
39
  // when true the provider is skipped in routing (kept in config, like a key's
50
40
  // disabled state but for the whole provider).
51
41
  disabled: z.boolean().optional(),
@@ -102,20 +92,40 @@ const ServerSchema = z
102
92
  // optional friendly label per key, keyed by the key itself. Kept separate so
103
93
  // api_keys stays a plain string[] (auth/masking paths untouched).
104
94
  key_names: z.record(z.string()).optional(),
95
+ // per-key model allowlist (call-strings) + rate limit (req/min), keyed by the
96
+ // raw key like key_names. Absent → unrestricted / unlimited.
97
+ key_models: z.record(z.array(z.string().min(1))).optional(),
98
+ key_rpm: z.record(z.number().int().positive()).optional(),
99
+ // per-key access expiry, epoch ms, keyed by the RAW key. Absent → never expires.
100
+ key_expires: z.record(z.number().int().positive()).optional(),
105
101
  })
106
102
  .default({ host: "127.0.0.1", port: 18080, api_keys: [] });
107
103
  /**
108
- * Gateway-wide spend budget. unit picks what `limit` means USD cost or total
109
- * tokens across every provider. Soft-alert at alert_at (default 0.8), hard-stop
110
- * at 100%. Window math reuses the quota calendar engine. Opt-in: omit to disable.
104
+ * A spend budget scoped to the whole gateway, one provider, or one upstream
105
+ * model. unit picks what `limit` means USD cost or total tokens. Soft-alert at
106
+ * alert_at (default 0.8), hard-stop at 100%. Each window is a rolling tumbling
107
+ * bucket on the epoch grid (window.ts). Opt-in: omit / empty list to disable.
111
108
  */
109
+ const BudgetScopeSchema = z.discriminatedUnion("type", [
110
+ z.object({ type: z.literal("global") }),
111
+ z.object({ type: z.literal("provider"), id: z.string().min(1) }),
112
+ z.object({ type: z.literal("model"), id: z.string().min(1) }),
113
+ z.object({ type: z.literal("key"), id: z.string().min(1) }),
114
+ ]);
115
+ // rolling windows replaced the old calendar windows; coerce any legacy value so
116
+ // existing config.yaml budgets keep loading (daily→24h, weekly→7day, monthly→30day).
117
+ const LEGACY_WINDOW = { daily: "24h", weekly: "7day", monthly: "30day" };
118
+ const WindowSchema = z.preprocess((v) => (typeof v === "string" && v in LEGACY_WINDOW ? LEGACY_WINDOW[v] : v), z.enum(["5h", "24h", "7day", "30day"]));
112
119
  const BudgetSchema = z.object({
120
+ scope: BudgetScopeSchema,
113
121
  unit: z.enum(["usd", "tokens"]),
114
122
  limit: z.number().positive(),
115
- window: z.enum(["5h", "daily", "weekly", "monthly"]),
116
- reset_at: z.string().optional(),
117
- timezone: z.string().default("UTC"),
123
+ window: WindowSchema,
124
+ // epoch ms the recurring cycle is anchored to; stamped by setBudget on create.
125
+ anchor: z.number().int().nonnegative().optional(),
118
126
  alert_at: z.number().gt(0).lte(1).optional(),
127
+ // optional free-text label so an operator remembers what a budget is for.
128
+ note: z.string().max(200).optional(),
119
129
  });
120
130
  const ConfigSchema = z.object({
121
131
  server: ServerSchema,
@@ -123,7 +133,7 @@ const ConfigSchema = z.object({
123
133
  providers: z.array(ProviderSchema).default([]),
124
134
  // the routing layer. Each entry is a "combo": an alias + a provider chain.
125
135
  models: z.array(ModelRouteSchema).default([]),
126
- budget: BudgetSchema.optional(),
136
+ budgets: z.array(BudgetSchema).default([]),
127
137
  });
128
138
  export class GatewayConfig {
129
139
  server;
@@ -236,6 +246,16 @@ export class GatewayConfig {
236
246
  }
237
247
  /** Validate an already-parsed config object. Throws with readable issues. */
238
248
  export function validateConfig(parsed) {
249
+ // migrate the legacy single `budget` (pre-scoped) into a global-scoped entry
250
+ // before zod runs — zod would otherwise strip the unknown `budget` key.
251
+ if (parsed && typeof parsed === "object") {
252
+ const raw = parsed;
253
+ if (raw.budget && !raw.budgets) {
254
+ const legacy = raw.budget;
255
+ raw.budgets = [{ scope: { type: "global" }, ...legacy }];
256
+ }
257
+ delete raw.budget;
258
+ }
239
259
  const result = ConfigSchema.safeParse(parsed ?? {});
240
260
  if (!result.success) {
241
261
  const issues = result.error.issues
@@ -700,17 +720,48 @@ export function setHeadroom(config, patch) {
700
720
  }
701
721
  return next;
702
722
  }
703
- // ---- global budget ---------------------------------------------------------
704
- /** Set (or replace) the gateway-wide spend budget. */
705
- export function setBudget(config, budget) {
723
+ // ---- scoped budgets --------------------------------------------------------
724
+ /** Stable identity key for a budget's scope. */
725
+ export function budgetKey(scope) {
726
+ return scope.type === "global" ? "global" : `${scope.type}:${scope.id}`;
727
+ }
728
+ /** Add a budget, or replace the existing one with the same scope key. */
729
+ export function setBudget(config, budget, now = Date.now()) {
730
+ if (budget.scope.type === "provider") {
731
+ const { id } = budget.scope;
732
+ if (!config.providers.some((p) => p.id === id)) {
733
+ throw new Error(`unknown provider "${id}" for budget scope`);
734
+ }
735
+ }
736
+ if (budget.scope.type === "key") {
737
+ const { id } = budget.scope;
738
+ if (!config.server.api_keys.some((k) => clientKeyFingerprint(k) === id)) {
739
+ throw new Error(`unknown API key fingerprint "${id}" for budget scope`);
740
+ }
741
+ }
706
742
  const next = cloneConfig(config);
707
- next.budget = budget;
743
+ const key = budgetKey(budget.scope);
744
+ const idx = next.budgets.findIndex((b) => budgetKey(b.scope) === key);
745
+ if (idx === -1) {
746
+ next.budgets.push({ ...budget, anchor: budget.anchor ?? now });
747
+ }
748
+ else {
749
+ const prev = next.budgets[idx];
750
+ // keep the running cycle on edit (preserve prev anchor as-is, including a
751
+ // legacy undefined = epoch grid, so editing a limit never resets spend);
752
+ // start a fresh cycle only when the window length actually changed.
753
+ const anchor = budget.anchor ?? (prev.window === budget.window ? prev.anchor : now);
754
+ next.budgets[idx] = { ...budget, anchor };
755
+ }
708
756
  return next;
709
757
  }
710
- /** Remove the gateway-wide budget (turns the feature off). */
711
- export function clearBudget(config) {
758
+ /** Remove a budget by its scope key (global | provider:<id> | model:<id> | key:<fp>). */
759
+ export function clearBudget(config, key) {
712
760
  const next = cloneConfig(config);
713
- delete next.budget;
761
+ const idx = next.budgets.findIndex((b) => budgetKey(b.scope) === key);
762
+ if (idx === -1)
763
+ throw new Error(`no budget with scope "${key}"`);
764
+ next.budgets.splice(idx, 1);
714
765
  return next;
715
766
  }
716
767
  /** Append a gateway-level api key clients must present on /v1/*, with a label. */
@@ -752,6 +803,64 @@ export function removeServerKey(config, index) {
752
803
  if (removed && next.server.key_names && removed in next.server.key_names) {
753
804
  delete next.server.key_names[removed];
754
805
  }
806
+ if (removed && next.server.key_models && removed in next.server.key_models) {
807
+ delete next.server.key_models[removed];
808
+ if (Object.keys(next.server.key_models).length === 0)
809
+ next.server.key_models = undefined;
810
+ }
811
+ if (removed && next.server.key_rpm && removed in next.server.key_rpm) {
812
+ delete next.server.key_rpm[removed];
813
+ if (Object.keys(next.server.key_rpm).length === 0)
814
+ next.server.key_rpm = undefined;
815
+ }
816
+ if (removed && next.server.key_expires && removed in next.server.key_expires) {
817
+ delete next.server.key_expires[removed];
818
+ if (Object.keys(next.server.key_expires).length === 0)
819
+ next.server.key_expires = undefined;
820
+ }
755
821
  return next;
756
822
  }
823
+ /**
824
+ * Set or clear a gateway key's scopes (by index, since keys are masked in the
825
+ * API). `models`/`rpm` are each applied only when present in the patch; an empty
826
+ * list or null/0 clears that scope. Empty maps are pruned to undefined.
827
+ */
828
+ export function setServerKeyScope(config, index, patch) {
829
+ const next = cloneConfig(config);
830
+ const keys = next.server.api_keys;
831
+ if (index < 0 || index >= keys.length)
832
+ throw new Error(`no gateway key at index ${index}`);
833
+ const key = keys[index];
834
+ if (patch.models !== undefined) {
835
+ const models = { ...(next.server.key_models ?? {}) };
836
+ const list = (patch.models ?? []).map((m) => m.trim()).filter(Boolean);
837
+ if (list.length > 0)
838
+ models[key] = list;
839
+ else
840
+ delete models[key];
841
+ next.server.key_models = Object.keys(models).length > 0 ? models : undefined;
842
+ }
843
+ if (patch.rpm !== undefined) {
844
+ const rpm = { ...(next.server.key_rpm ?? {}) };
845
+ if (patch.rpm && patch.rpm > 0)
846
+ rpm[key] = Math.floor(patch.rpm);
847
+ else
848
+ delete rpm[key];
849
+ next.server.key_rpm = Object.keys(rpm).length > 0 ? rpm : undefined;
850
+ }
851
+ if (patch.expires !== undefined) {
852
+ const exp = { ...(next.server.key_expires ?? {}) };
853
+ if (patch.expires && patch.expires > 0)
854
+ exp[key] = Math.floor(patch.expires);
855
+ else
856
+ delete exp[key];
857
+ next.server.key_expires = Object.keys(exp).length > 0 ? exp : undefined;
858
+ }
859
+ return next;
860
+ }
861
+ /** True when `rawKey` has an expiry set and `now` is strictly past it. */
862
+ export function isKeyExpired(server, rawKey, now) {
863
+ const at = server.key_expires?.[rawKey];
864
+ return at !== undefined && now > at;
865
+ }
757
866
  //# sourceMappingURL=config.js.map