@sriinnu/kosha-discovery 1.2.0 → 1.5.1

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 (164) hide show
  1. package/README.md +125 -52
  2. package/dist/aliases.d.ts +6 -1
  3. package/dist/aliases.d.ts.map +1 -1
  4. package/dist/aliases.js +38 -12
  5. package/dist/aliases.js.map +1 -1
  6. package/dist/cache.d.ts.map +1 -1
  7. package/dist/cache.js +40 -3
  8. package/dist/cache.js.map +1 -1
  9. package/dist/claude-generation.d.ts +59 -0
  10. package/dist/claude-generation.d.ts.map +1 -0
  11. package/dist/claude-generation.js +117 -0
  12. package/dist/claude-generation.js.map +1 -0
  13. package/dist/cli-cmd-doctor.d.ts +17 -0
  14. package/dist/cli-cmd-doctor.d.ts.map +1 -0
  15. package/dist/cli-cmd-doctor.js +199 -0
  16. package/dist/cli-cmd-doctor.js.map +1 -0
  17. package/dist/cli-cmd-model.js +2 -2
  18. package/dist/cli-cmd-model.js.map +1 -1
  19. package/dist/cli-cmd-spend.d.ts +10 -0
  20. package/dist/cli-cmd-spend.d.ts.map +1 -0
  21. package/dist/cli-cmd-spend.js +130 -0
  22. package/dist/cli-cmd-spend.js.map +1 -0
  23. package/dist/cli-commands.d.ts +4 -1
  24. package/dist/cli-commands.d.ts.map +1 -1
  25. package/dist/cli-commands.js +10 -2
  26. package/dist/cli-commands.js.map +1 -1
  27. package/dist/cli-format.js.map +1 -1
  28. package/dist/cli-help.d.ts.map +1 -1
  29. package/dist/cli-help.js +13 -2
  30. package/dist/cli-help.js.map +1 -1
  31. package/dist/cli.js +10 -0
  32. package/dist/cli.js.map +1 -1
  33. package/dist/cost.d.ts +152 -0
  34. package/dist/cost.d.ts.map +1 -0
  35. package/dist/cost.js +377 -0
  36. package/dist/cost.js.map +1 -0
  37. package/dist/credentials/resolver.d.ts +10 -0
  38. package/dist/credentials/resolver.d.ts.map +1 -1
  39. package/dist/credentials/resolver.js +64 -31
  40. package/dist/credentials/resolver.js.map +1 -1
  41. package/dist/discovery/anthropic.d.ts +19 -1
  42. package/dist/discovery/anthropic.d.ts.map +1 -1
  43. package/dist/discovery/anthropic.js +112 -8
  44. package/dist/discovery/anthropic.js.map +1 -1
  45. package/dist/discovery/base.d.ts +7 -0
  46. package/dist/discovery/base.d.ts.map +1 -1
  47. package/dist/discovery/base.js +32 -4
  48. package/dist/discovery/base.js.map +1 -1
  49. package/dist/discovery/bedrock.d.ts.map +1 -1
  50. package/dist/discovery/cerebras.d.ts.map +1 -1
  51. package/dist/discovery/cohere.d.ts.map +1 -1
  52. package/dist/discovery/deepinfra.d.ts.map +1 -1
  53. package/dist/discovery/deepseek.d.ts.map +1 -1
  54. package/dist/discovery/fireworks.d.ts.map +1 -1
  55. package/dist/discovery/glm.d.ts.map +1 -1
  56. package/dist/discovery/google.d.ts +3 -1
  57. package/dist/discovery/google.d.ts.map +1 -1
  58. package/dist/discovery/google.js +13 -6
  59. package/dist/discovery/google.js.map +1 -1
  60. package/dist/discovery/groq.d.ts.map +1 -1
  61. package/dist/discovery/index.d.ts +2 -0
  62. package/dist/discovery/index.d.ts.map +1 -1
  63. package/dist/discovery/index.js +6 -0
  64. package/dist/discovery/index.js.map +1 -1
  65. package/dist/discovery/llama-cpp.d.ts.map +1 -1
  66. package/dist/discovery/lmstudio.d.ts +26 -0
  67. package/dist/discovery/lmstudio.d.ts.map +1 -0
  68. package/dist/discovery/lmstudio.js +93 -0
  69. package/dist/discovery/lmstudio.js.map +1 -0
  70. package/dist/discovery/minimax.d.ts.map +1 -1
  71. package/dist/discovery/mistral.d.ts.map +1 -1
  72. package/dist/discovery/moonshot.d.ts.map +1 -1
  73. package/dist/discovery/nvidia.d.ts.map +1 -1
  74. package/dist/discovery/ollama.d.ts.map +1 -1
  75. package/dist/discovery/openai-compatible.d.ts.map +1 -1
  76. package/dist/discovery/openai.d.ts.map +1 -1
  77. package/dist/discovery/openrouter.d.ts +29 -5
  78. package/dist/discovery/openrouter.d.ts.map +1 -1
  79. package/dist/discovery/openrouter.js +56 -18
  80. package/dist/discovery/openrouter.js.map +1 -1
  81. package/dist/discovery/perplexity.d.ts.map +1 -1
  82. package/dist/discovery/promo-overrides.js.map +1 -1
  83. package/dist/discovery/static-direct.d.ts +9 -1
  84. package/dist/discovery/static-direct.d.ts.map +1 -1
  85. package/dist/discovery/static-direct.js +68 -7
  86. package/dist/discovery/static-direct.js.map +1 -1
  87. package/dist/discovery/together.d.ts.map +1 -1
  88. package/dist/discovery/vercel.d.ts.map +1 -1
  89. package/dist/discovery/vertex.d.ts.map +1 -1
  90. package/dist/discovery/vllm.d.ts +26 -0
  91. package/dist/discovery/vllm.d.ts.map +1 -0
  92. package/dist/discovery/vllm.js +93 -0
  93. package/dist/discovery/vllm.js.map +1 -0
  94. package/dist/discovery/zai.d.ts.map +1 -1
  95. package/dist/discovery-contract.d.ts +7 -0
  96. package/dist/discovery-contract.d.ts.map +1 -1
  97. package/dist/discovery-contract.js.map +1 -1
  98. package/dist/discovery-routes.d.ts +9 -0
  99. package/dist/discovery-routes.d.ts.map +1 -1
  100. package/dist/discovery-routes.js +106 -18
  101. package/dist/discovery-routes.js.map +1 -1
  102. package/dist/enrichment/litellm.d.ts +1 -1
  103. package/dist/enrichment/litellm.d.ts.map +1 -1
  104. package/dist/enrichment/litellm.js +3 -3
  105. package/dist/entry.d.ts +14 -0
  106. package/dist/entry.d.ts.map +1 -0
  107. package/dist/entry.js +26 -0
  108. package/dist/entry.js.map +1 -0
  109. package/dist/index.d.ts +10 -0
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +5 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/mcp-server.d.ts +207 -2
  114. package/dist/mcp-server.d.ts.map +1 -1
  115. package/dist/mcp-server.js +203 -51
  116. package/dist/mcp-server.js.map +1 -1
  117. package/dist/model-features.d.ts.map +1 -1
  118. package/dist/model-features.js +11 -2
  119. package/dist/model-features.js.map +1 -1
  120. package/dist/normalize.d.ts +7 -7
  121. package/dist/normalize.js +8 -8
  122. package/dist/provider-catalog.d.ts.map +1 -1
  123. package/dist/provider-catalog.js +26 -0
  124. package/dist/provider-catalog.js.map +1 -1
  125. package/dist/proxy.d.ts +49 -7
  126. package/dist/proxy.d.ts.map +1 -1
  127. package/dist/proxy.js +754 -89
  128. package/dist/proxy.js.map +1 -1
  129. package/dist/registry-query.js +2 -2
  130. package/dist/registry-query.js.map +1 -1
  131. package/dist/registry-routing.d.ts +65 -0
  132. package/dist/registry-routing.d.ts.map +1 -0
  133. package/dist/registry-routing.js +165 -0
  134. package/dist/registry-routing.js.map +1 -0
  135. package/dist/registry-runtime.d.ts +2 -0
  136. package/dist/registry-runtime.d.ts.map +1 -1
  137. package/dist/registry-runtime.js +177 -23
  138. package/dist/registry-runtime.js.map +1 -1
  139. package/dist/registry-selection.js +6 -0
  140. package/dist/registry-selection.js.map +1 -1
  141. package/dist/registry.d.ts +69 -0
  142. package/dist/registry.d.ts.map +1 -1
  143. package/dist/registry.js +133 -1
  144. package/dist/registry.js.map +1 -1
  145. package/dist/resilience.d.ts +15 -0
  146. package/dist/resilience.d.ts.map +1 -1
  147. package/dist/resilience.js +23 -1
  148. package/dist/resilience.js.map +1 -1
  149. package/dist/server.d.ts +44 -2
  150. package/dist/server.d.ts.map +1 -1
  151. package/dist/server.js +328 -33
  152. package/dist/server.js.map +1 -1
  153. package/dist/tally.d.ts +80 -0
  154. package/dist/tally.d.ts.map +1 -0
  155. package/dist/tally.js +176 -0
  156. package/dist/tally.js.map +1 -0
  157. package/dist/types.d.ts +22 -1
  158. package/dist/types.d.ts.map +1 -1
  159. package/dist/wire-anthropic.d.ts +264 -0
  160. package/dist/wire-anthropic.d.ts.map +1 -0
  161. package/dist/wire-anthropic.js +960 -0
  162. package/dist/wire-anthropic.js.map +1 -0
  163. package/package.json +14 -10
  164. package/logo.png +0 -0
package/dist/server.js CHANGED
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * Routes:
9
9
  * GET /api/models — List models (query: ?provider, ?originProvider, ?mode, ?capability)
10
+ * GET /api/capabilities — Capability summary across the catalog (?provider)
10
11
  * GET /api/models/cheapest — Cheapest eligible models for a role/capability
11
12
  * GET /api/models/:idOrAlias/routes — All provider routes with preferred/direct metadata
12
13
  * GET /api/models/:idOrAlias — Get a single model by ID or alias (+ baseUrl/version)
@@ -16,19 +17,109 @@
16
17
  * POST /api/refresh — Trigger re-discovery (body: { provider?: string })
17
18
  * GET /api/resolve/:alias — Resolve an alias to its canonical model ID
18
19
  * GET /api/discovery-errors — Errors from last discovery pass
20
+ * GET /api/discovery — Stable v1 discovery snapshot (see discovery-routes.ts)
21
+ * GET /api/discovery/delta — Changes since a cursor
22
+ * GET /api/discovery/watch — SSE stream of discovery changes
23
+ * GET /api/discovery/cheapest — Cheapest candidates (v1 contract)
24
+ * GET /api/discovery/binding — Binding hints for a query (v1 contract)
19
25
  * GET /health — Health check
26
+ * GET /metrics — Prometheus exposition (optional KOSHA_METRICS_TOKEN gate)
20
27
  * GET /proxy/v1/models — OpenAI-compatible model list (forwardable models)
21
28
  * POST /proxy/v1/chat/completions — OpenAI-compatible proxy with model routing
29
+ *
30
+ * Security defaults:
31
+ * - The standalone server binds to 127.0.0.1 unless `--host` / `KOSHA_HOST`
32
+ * says otherwise. The proxy spends the operator's provider credentials, so
33
+ * it must never be reachable from the network by accident.
34
+ * - When `KOSHA_PROXY_TOKEN` is set, every `/proxy/*` route and
35
+ * `POST /api/refresh` require `Authorization: Bearer <token>` (or an
36
+ * `x-kosha-token` header). Unset → open, which is only safe on loopback.
22
37
  * @module
23
38
  */
39
+ import { timingSafeEqual } from "node:crypto";
24
40
  import { Hono } from "hono";
25
41
  import { serve } from "@hono/node-server";
42
+ import { readMonthlyBudgetUsd, readSpendForMonth } from "./cost.js";
26
43
  import { registerDiscoveryRoutes } from "./discovery-routes.js";
27
- import { registerProxyRoutes } from "./proxy.js";
44
+ import { registerProxyRoutes, snapshotProxyMetrics } from "./proxy.js";
28
45
  import { ModelRegistry } from "./registry.js";
46
+ import { isMainModule } from "./entry.js";
29
47
  import { extractModelVersion, normalizeModelId } from "./normalize.js";
30
48
  const MODEL_MODES = ["chat", "embedding", "image", "video", "audio", "moderation", "rerank"];
31
49
  const PRICE_METRICS = ["input", "output", "blended"];
50
+ /**
51
+ * Set to true when the boot-time discovery pass threw and the server bound on
52
+ * cached/partial state instead. Surfaced via /health and the
53
+ * `kosha_discovery_degraded` /metrics gauge so an operator knows the catalog
54
+ * is stale and a /api/refresh is needed.
55
+ */
56
+ let registryBootDegraded = false;
57
+ /** Loopback addresses the standalone server treats as "safe without a token". */
58
+ const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1", "[::1]"]);
59
+ /**
60
+ * Resolve the interface the standalone server binds to.
61
+ *
62
+ * Precedence: explicit argument → `KOSHA_HOST` env → `127.0.0.1`. The default
63
+ * is loopback on purpose: `kosha serve` fronts an unauthenticated (unless
64
+ * `KOSHA_PROXY_TOKEN` is set) proxy that forwards requests using the
65
+ * operator's own provider API keys. Binding every interface by default would
66
+ * let anyone on the same network spend those keys.
67
+ */
68
+ export function resolveBindHost(explicit) {
69
+ const candidate = (explicit ?? process.env.KOSHA_HOST ?? "").trim();
70
+ return candidate.length > 0 ? candidate : "127.0.0.1";
71
+ }
72
+ /** True when `host` is a loopback-only bind. */
73
+ export function isLoopbackHost(host) {
74
+ return LOOPBACK_HOSTS.has(host.trim().toLowerCase());
75
+ }
76
+ /**
77
+ * Constant-time bearer/token comparison. Length mismatch is an early false,
78
+ * which leaks only the token length — acceptable for an operator-set secret
79
+ * and far better than a `===` that leaks the matching prefix length.
80
+ */
81
+ function tokenMatches(provided, expected) {
82
+ if (!provided)
83
+ return false;
84
+ const a = Buffer.from(provided, "utf8");
85
+ const b = Buffer.from(expected, "utf8");
86
+ if (a.length !== b.length)
87
+ return false;
88
+ return timingSafeEqual(a, b);
89
+ }
90
+ /**
91
+ * Extract the bearer credential from an `Authorization` header, if any.
92
+ * Deliberately regex-free: this runs on every unauthenticated request to a
93
+ * gated route, and a lazy-quantifier regex here was measurably quadratic on
94
+ * a 16 KB header.
95
+ */
96
+ function bearerFrom(authHeader) {
97
+ if (!authHeader)
98
+ return undefined;
99
+ const trimmed = authHeader.trim();
100
+ if (trimmed.length < 7 || trimmed.slice(0, 6).toLowerCase() !== "bearer")
101
+ return undefined;
102
+ if (trimmed[6] !== " " && trimmed[6] !== "\t")
103
+ return undefined;
104
+ const token = trimmed.slice(7).trim();
105
+ return token.length > 0 ? token : undefined;
106
+ }
107
+ /**
108
+ * Check a request against the operator token in `KOSHA_PROXY_TOKEN`.
109
+ * Accepts the token either as `Authorization: Bearer <token>` or in an
110
+ * `x-kosha-token` header (the latter leaves `Authorization` free for the
111
+ * `kosha-tenant-<name>` bucketing tag). Returns true when no token is
112
+ * configured — the gate is opt-in.
113
+ */
114
+ export function proxyRequestAuthorized(headers) {
115
+ const expected = process.env.KOSHA_PROXY_TOKEN;
116
+ if (!expected)
117
+ return true;
118
+ const viaHeader = headers.get("x-kosha-token") ?? undefined;
119
+ if (tokenMatches(viaHeader, expected))
120
+ return true;
121
+ return tokenMatches(bearerFrom(headers.get("authorization") ?? undefined), expected);
122
+ }
32
123
  function parseMode(value) {
33
124
  if (!value)
34
125
  return undefined;
@@ -65,10 +156,28 @@ function parsePriceMetric(value) {
65
156
  * @param registry - A pre-populated (or lazy) ModelRegistry instance.
66
157
  * @returns A configured Hono app with all kosha REST routes.
67
158
  */
68
- export function createServer(registry) {
159
+ export function createServer(registry, shutdownSignal) {
69
160
  const app = new Hono();
161
+ // ── Operator token gate (opt-in via KOSHA_PROXY_TOKEN) ──────────────
162
+ // Registered before the routes it protects so it runs first. Covers the
163
+ // two surfaces that spend money or trigger outbound work on the
164
+ // operator's behalf: the OpenAI-compatible proxy and manual re-discovery.
165
+ const requireOperatorToken = async (ctx, next) => {
166
+ if (!proxyRequestAuthorized({ get: (name) => ctx.req.header(name) })) {
167
+ return ctx.json({
168
+ error: {
169
+ message: "kosha proxy requires a valid operator token (Authorization: Bearer <KOSHA_PROXY_TOKEN> or x-kosha-token header)",
170
+ type: "authentication_error",
171
+ code: "401",
172
+ },
173
+ }, 401);
174
+ }
175
+ await next();
176
+ };
177
+ app.use("/proxy/*", requireOperatorToken);
178
+ app.use("/api/refresh", requireOperatorToken);
70
179
  registerDiscoveryRoutes(app, registry);
71
- registerProxyRoutes(app, registry);
180
+ registerProxyRoutes(app, registry, shutdownSignal);
72
181
  // ── Model listing & lookup routes ────────────────────────────────
73
182
  //
74
183
  // GET /api/models supports four optional query parameters:
@@ -79,7 +188,14 @@ export function createServer(registry) {
79
188
  app.get("/api/models", (ctx) => {
80
189
  const provider = ctx.req.query("provider") ?? undefined;
81
190
  const originProvider = ctx.req.query("originProvider") ?? undefined;
82
- const mode = parseMode(ctx.req.query("mode"));
191
+ // Distinguish "absent" (no filter) from "present-but-invalid" (400):
192
+ // a typo'd ?mode=chat2 used to silently return the unfiltered catalog,
193
+ // which is the worst failure mode for a discovery tool.
194
+ const modeRaw = ctx.req.query("mode");
195
+ const mode = parseMode(modeRaw);
196
+ if (modeRaw !== undefined && mode === undefined) {
197
+ return ctx.json({ error: "invalid query parameter", param: "mode", received: modeRaw, allowedValues: MODEL_MODES }, 400);
198
+ }
83
199
  const capability = ctx.req.query("capability") ?? undefined;
84
200
  const models = registry.models({ provider, originProvider, mode, capability });
85
201
  return ctx.json({
@@ -90,17 +206,49 @@ export function createServer(registry) {
90
206
  // Ranked cheapest model lookup for routing decisions. Route must be
91
207
  // registered before dynamic /api/models/:idOrAlias.
92
208
  app.get("/api/models/cheapest", (ctx) => {
209
+ // Validate each typed query param up front: present-but-invalid → 400
210
+ // with the allowed values, so a typo can't silently select the wrong
211
+ // (or unfiltered) result set. Absent params stay no-ops as before.
212
+ const modeRaw = ctx.req.query("mode");
213
+ const mode = parseMode(modeRaw);
214
+ if (modeRaw !== undefined && mode === undefined) {
215
+ return ctx.json({ error: "invalid query parameter", param: "mode", received: modeRaw, allowedValues: MODEL_MODES }, 400);
216
+ }
217
+ const limitRaw = ctx.req.query("limit");
218
+ const limit = parseNumber(limitRaw);
219
+ if (limitRaw !== undefined && limit === undefined) {
220
+ return ctx.json({ error: "invalid query parameter", param: "limit", received: limitRaw }, 400);
221
+ }
222
+ const priceMetricRaw = ctx.req.query("priceMetric");
223
+ const priceMetric = parsePriceMetric(priceMetricRaw);
224
+ if (priceMetricRaw !== undefined && priceMetric === undefined) {
225
+ return ctx.json({ error: "invalid query parameter", param: "priceMetric", received: priceMetricRaw, allowedValues: PRICE_METRICS }, 400);
226
+ }
227
+ const inputWeightRaw = ctx.req.query("inputWeight");
228
+ const inputWeight = parseNumber(inputWeightRaw);
229
+ if (inputWeightRaw !== undefined && inputWeight === undefined) {
230
+ return ctx.json({ error: "invalid query parameter", param: "inputWeight", received: inputWeightRaw }, 400);
231
+ }
232
+ const outputWeightRaw = ctx.req.query("outputWeight");
233
+ const outputWeight = parseNumber(outputWeightRaw);
234
+ if (outputWeightRaw !== undefined && outputWeight === undefined) {
235
+ return ctx.json({ error: "invalid query parameter", param: "outputWeight", received: outputWeightRaw }, 400);
236
+ }
237
+ const includeUnpricedRaw = ctx.req.query("includeUnpriced");
238
+ if (includeUnpricedRaw !== undefined && includeUnpricedRaw !== "true" && includeUnpricedRaw !== "false") {
239
+ return ctx.json({ error: "invalid query parameter", param: "includeUnpriced", received: includeUnpricedRaw, allowedValues: ["true", "false"] }, 400);
240
+ }
93
241
  const options = {
94
242
  role: ctx.req.query("role") ?? undefined,
95
243
  capability: ctx.req.query("capability") ?? undefined,
96
244
  provider: ctx.req.query("provider") ?? undefined,
97
245
  originProvider: ctx.req.query("originProvider") ?? undefined,
98
- mode: parseMode(ctx.req.query("mode")),
99
- limit: parseNumber(ctx.req.query("limit")),
100
- priceMetric: parsePriceMetric(ctx.req.query("priceMetric")),
101
- inputWeight: parseNumber(ctx.req.query("inputWeight")),
102
- outputWeight: parseNumber(ctx.req.query("outputWeight")),
103
- includeUnpriced: ctx.req.query("includeUnpriced") === "true",
246
+ mode,
247
+ limit,
248
+ priceMetric,
249
+ inputWeight,
250
+ outputWeight,
251
+ includeUnpriced: includeUnpricedRaw === "true",
104
252
  };
105
253
  const result = registry.cheapestModels(options);
106
254
  const message = result.matches.length > 0
@@ -275,12 +423,118 @@ export function createServer(registry) {
275
423
  app.get("/health", (ctx) => {
276
424
  const providers = registry.providers_list();
277
425
  return ctx.json({
278
- status: "ok",
426
+ // "degraded" when boot discovery threw and we bound on cached/partial
427
+ // state — load-balancer liveness/readiness probes need to see this
428
+ // so they stop routing to a node whose catalog went stale at boot.
429
+ status: registryBootDegraded ? "degraded" : "ok",
430
+ degraded: registryBootDegraded,
279
431
  models: registry.models().length,
280
432
  providers: providers.length,
281
433
  uptime: process.uptime(),
282
434
  });
283
435
  });
436
+ // Provider ids come from a JSON-loaded registry; per the Prometheus
437
+ // exposition spec, label values need '\\', '\"', and '\n' escaped — a
438
+ // plain quote-strip is not sufficient and could let a crafted id break
439
+ // the exposition format. https://prometheus.io/docs/instrumenting/exposition_formats/
440
+ const escapePrometheusLabel = (value) => value
441
+ .replace(/\\/g, "\\\\")
442
+ .replace(/"/g, '\\"')
443
+ .replace(/\n/g, "\\n")
444
+ .replace(/\r/g, "");
445
+ // ── Prometheus metrics ───────────────────────────────────────────
446
+ // Plain-text exposition format. Operators can scrape this directly with
447
+ // Prometheus / Grafana Agent / VictoriaMetrics; no extra dependency.
448
+ app.get("/metrics", async (ctx) => {
449
+ // Optional bearer-token gate. Unset → open (default, single-process dev);
450
+ // set → required, so a shared/multi-tenant deployment doesn't leak
451
+ // per-provider breaker state, reliability scores, and p95 latencies.
452
+ const metricsToken = process.env.KOSHA_METRICS_TOKEN;
453
+ if (metricsToken) {
454
+ if (!tokenMatches(bearerFrom(ctx.req.header("authorization")), metricsToken)) {
455
+ return ctx.text("metrics endpoint requires a valid bearer token\n", 403);
456
+ }
457
+ }
458
+ const lines = [];
459
+ const providers = registry.providers_list();
460
+ lines.push("# HELP kosha_models_total Total models known to the registry.");
461
+ lines.push("# TYPE kosha_models_total gauge");
462
+ lines.push(`kosha_models_total ${registry.models().length}`);
463
+ lines.push("# HELP kosha_providers_total Total providers known to the registry.");
464
+ lines.push("# TYPE kosha_providers_total gauge");
465
+ lines.push(`kosha_providers_total ${providers.length}`);
466
+ lines.push("# HELP kosha_discovery_degraded 1 when boot discovery failed and the server is serving cached/partial state.");
467
+ lines.push("# TYPE kosha_discovery_degraded gauge");
468
+ lines.push(`kosha_discovery_degraded ${registryBootDegraded ? 1 : 0}`);
469
+ lines.push("# HELP kosha_provider_reliability Reliability score per provider in [0,1].");
470
+ lines.push("# TYPE kosha_provider_reliability gauge");
471
+ lines.push("# HELP kosha_provider_p95_latency_ms Observed p95 latency per provider in ms.");
472
+ lines.push("# TYPE kosha_provider_p95_latency_ms gauge");
473
+ lines.push("# HELP kosha_provider_breaker_open Whether the per-provider breaker is open (1) or available (0).");
474
+ lines.push("# TYPE kosha_provider_breaker_open gauge");
475
+ for (const provider of providers) {
476
+ const health = registry.providerRouteHealth(provider.id);
477
+ const safeId = escapePrometheusLabel(provider.id);
478
+ lines.push(`kosha_provider_reliability{provider="${safeId}"} ${health.reliabilityScore}`);
479
+ if (typeof health.p95LatencyMs === "number") {
480
+ lines.push(`kosha_provider_p95_latency_ms{provider="${safeId}"} ${health.p95LatencyMs}`);
481
+ }
482
+ lines.push(`kosha_provider_breaker_open{provider="${safeId}"} ${health.available ? 0 : 1}`);
483
+ }
484
+ lines.push("# HELP kosha_discovery_errors_total Discovery errors captured during the most recent pass.");
485
+ lines.push("# TYPE kosha_discovery_errors_total gauge");
486
+ lines.push(`kosha_discovery_errors_total ${registry.discoveryErrors().length}`);
487
+ // ── Proxy hot-path counters (real inference traffic) ────────────
488
+ const proxy = snapshotProxyMetrics();
489
+ lines.push("# HELP kosha_proxy_requests_total Total requests forwarded by the proxy.");
490
+ lines.push("# TYPE kosha_proxy_requests_total counter");
491
+ lines.push(`kosha_proxy_requests_total ${proxy.requestsTotal}`);
492
+ lines.push("# HELP kosha_proxy_errors_total Total proxy requests that failed upstream.");
493
+ lines.push("# TYPE kosha_proxy_errors_total counter");
494
+ lines.push(`kosha_proxy_errors_total ${proxy.errorsTotal}`);
495
+ lines.push("# HELP kosha_proxy_provider_requests Proxy requests per provider.");
496
+ lines.push("# TYPE kosha_proxy_provider_requests counter");
497
+ lines.push("# HELP kosha_proxy_provider_errors Proxy errors per provider.");
498
+ lines.push("# TYPE kosha_proxy_provider_errors counter");
499
+ lines.push("# HELP kosha_proxy_provider_avg_latency_ms Rolling average proxy latency per provider in ms.");
500
+ lines.push("# TYPE kosha_proxy_provider_avg_latency_ms gauge");
501
+ for (const [providerId, c] of Object.entries(proxy.byProvider)) {
502
+ const safeId = escapePrometheusLabel(providerId);
503
+ lines.push(`kosha_proxy_provider_requests{provider="${safeId}"} ${c.requests}`);
504
+ lines.push(`kosha_proxy_provider_errors{provider="${safeId}"} ${c.errors}`);
505
+ lines.push(`kosha_proxy_provider_avg_latency_ms{provider="${safeId}"} ${c.avgLatencyMs}`);
506
+ }
507
+ // ── Spend / budget ──────────────────────────────────────────────
508
+ lines.push("# HELP kosha_spend_usd_month Estimated spend for the current month in USD.");
509
+ lines.push("# TYPE kosha_spend_usd_month gauge");
510
+ let monthSpend = 0;
511
+ try {
512
+ monthSpend = await readSpendForMonth(Date.now());
513
+ }
514
+ catch {
515
+ // Unreadable ledger → omit the spend gauge rather than fail /metrics.
516
+ }
517
+ lines.push(`kosha_spend_usd_month ${monthSpend.toFixed(6)}`);
518
+ const budget = readMonthlyBudgetUsd();
519
+ if (budget !== null) {
520
+ lines.push("# HELP kosha_budget_remaining_usd Remaining monthly budget in USD.");
521
+ lines.push("# TYPE kosha_budget_remaining_usd gauge");
522
+ lines.push(`kosha_budget_remaining_usd ${Math.max(0, budget - monthSpend).toFixed(6)}`);
523
+ lines.push(`kosha_budget_usd ${budget.toFixed(2)}`);
524
+ }
525
+ // ── Pricing-provenance coverage ────────────────────────────────
526
+ // Fraction of priced models whose price came from a live provider API
527
+ // or LiteLLM (not a static seed / unknown). A drop signals that the
528
+ // pricing source is unreachable/stale — the registry's headline value
529
+ // (pricing) is silently degrading.
530
+ const priced = registry.models().filter((m) => m.pricing);
531
+ const livePriced = priced.filter((m) => m.pricingSource === "provider-live" || m.pricingSource === "litellm").length;
532
+ const coverage = priced.length > 0 ? livePriced / priced.length : 0;
533
+ lines.push("# HELP kosha_pricing_coverage Fraction of priced models with provider-live or litellm pricing.");
534
+ lines.push("# TYPE kosha_pricing_coverage gauge");
535
+ lines.push(`kosha_pricing_coverage ${coverage.toFixed(4)}`);
536
+ return ctx.text(`${lines.join("\n")}\n`, 200, { "content-type": "text/plain; version=0.0.4" });
537
+ });
284
538
  return app;
285
539
  }
286
540
  // ---------------------------------------------------------------------------
@@ -291,36 +545,77 @@ export function createServer(registry) {
291
545
  *
292
546
  * Runs full discovery, then starts an HTTP listener on the given port.
293
547
  * @param port - TCP port to bind (default `3000`, overridable via `PORT` env var).
548
+ * @param host - Interface to bind (default `127.0.0.1`, overridable via
549
+ * `KOSHA_HOST` or `kosha serve --host`). Binding a non-loopback
550
+ * address without `KOSHA_PROXY_TOKEN` logs a loud warning: the
551
+ * proxy would be spending your provider keys for anyone who can
552
+ * reach the port.
294
553
  */
295
- export async function startServer(port = 3000) {
554
+ export async function startServer(port = 3000, host) {
555
+ const bindHost = resolveBindHost(host);
556
+ if (!isLoopbackHost(bindHost) && !process.env.KOSHA_PROXY_TOKEN) {
557
+ console.error(`Warning: binding ${bindHost} with no KOSHA_PROXY_TOKEN set — the /proxy routes forward requests using ` +
558
+ "your provider API keys and are open to anyone who can reach this port. Set KOSHA_PROXY_TOKEN or bind 127.0.0.1.");
559
+ }
296
560
  const registry = new ModelRegistry();
297
561
  console.log("Discovering providers and models...");
298
- await registry.discover();
299
- const providers = registry.providers_list();
562
+ // Boot is fault-tolerant: if discovery throws (network outage on this host,
563
+ // every provider erroring at once, a corrupt cache) we still bind on
564
+ // whatever the registry cached and mark ourselves degraded. The worst time
565
+ // for the service to be down is during the outage it exists to observe.
566
+ let providers = registry.providers_list();
567
+ try {
568
+ await registry.discover();
569
+ providers = registry.providers_list();
570
+ }
571
+ catch (err) {
572
+ registryBootDegraded = true;
573
+ const message = err instanceof Error ? err.message : String(err);
574
+ console.error(`Warning: boot discovery failed (${message}); serving cached/partial state. POST /api/refresh to recover.`);
575
+ providers = registry.providers_list();
576
+ }
300
577
  const totalModels = registry.models().length;
301
- console.log(`Found ${totalModels} models from ${providers.length} providers`);
302
- const app = createServer(registry);
303
- console.log(`\nKosha API server listening on http://localhost:${port}`);
304
- console.log(` GET http://localhost:${port}/api/models`);
305
- console.log(` GET http://localhost:${port}/api/models/cheapest`);
306
- console.log(` GET http://localhost:${port}/api/models/:id/routes`);
307
- console.log(` GET http://localhost:${port}/api/capabilities`);
308
- console.log(` GET http://localhost:${port}/api/roles`);
309
- console.log(` GET http://localhost:${port}/api/providers`);
310
- console.log(` GET http://localhost:${port}/api/discovery`);
311
- console.log(` GET http://localhost:${port}/api/discovery/delta`);
312
- console.log(` GET http://localhost:${port}/api/discovery/watch`);
313
- console.log(` GET http://localhost:${port}/health`);
314
- console.log(` GET http://localhost:${port}/proxy/v1/models`);
315
- console.log(` POST http://localhost:${port}/proxy/v1/chat/completions`);
316
- serve({ fetch: app.fetch, port });
578
+ console.log(`Found ${totalModels} models from ${providers.length} providers${registryBootDegraded ? " (degraded)" : ""}`);
579
+ // Abort in-flight proxy fetches on shutdown so the server drains instead of
580
+ // dropping streams mid-response; the proxy threads this signal into every
581
+ // upstream fetch alongside its per-request timeout.
582
+ const shutdownController = new AbortController();
583
+ const app = createServer(registry, shutdownController.signal);
584
+ // IPv6 literals need brackets in a URL; everything else prints as-is.
585
+ const urlHost = bindHost.includes(":") && !bindHost.startsWith("[") ? `[${bindHost}]` : bindHost;
586
+ const base = `http://${urlHost}:${port}`;
587
+ console.log(`\nKosha API server listening on ${base}${process.env.KOSHA_PROXY_TOKEN ? " (proxy token required)" : ""}`);
588
+ console.log(` GET ${base}/api/models`);
589
+ console.log(` GET ${base}/api/models/cheapest`);
590
+ console.log(` GET ${base}/api/models/:id/routes`);
591
+ console.log(` GET ${base}/api/capabilities`);
592
+ console.log(` GET ${base}/api/roles`);
593
+ console.log(` GET ${base}/api/providers`);
594
+ console.log(` GET ${base}/api/discovery`);
595
+ console.log(` GET ${base}/api/discovery/delta`);
596
+ console.log(` GET ${base}/api/discovery/watch`);
597
+ console.log(` GET ${base}/health`);
598
+ console.log(` GET ${base}/metrics`);
599
+ console.log(` GET ${base}/proxy/v1/models`);
600
+ console.log(` POST ${base}/proxy/v1/chat/completions`);
601
+ const server = serve({ fetch: app.fetch, port, hostname: bindHost });
602
+ // Graceful shutdown: stop accepting new connections, abort in-flight
603
+ // upstream fetches (so SSE streams drain / bill correctly), then exit.
604
+ // A hard timeout guards against a hung keep-alive stalling close().
605
+ const shutdown = (signal) => {
606
+ console.log(`\n${signal} received — draining in-flight requests and shutting down.`);
607
+ shutdownController.abort();
608
+ server.close(() => process.exit(0));
609
+ setTimeout(() => process.exit(0), 5_000).unref();
610
+ };
611
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
612
+ process.on("SIGINT", () => shutdown("SIGINT"));
317
613
  }
318
614
  // ---------------------------------------------------------------------------
319
615
  // Auto-start when executed directly (e.g. `node dist/server.js`)
320
616
  // ---------------------------------------------------------------------------
321
- const isEntryPoint = import.meta.url === `file://${process.argv[1]}`;
322
- if (isEntryPoint) {
617
+ if (isMainModule(import.meta.url)) {
323
618
  const port = parseInt(process.env.PORT || "3000", 10);
324
- startServer(port);
619
+ startServer(port, process.env.KOSHA_HOST);
325
620
  }
326
621
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * kosha-discovery — Zero-dependency token usage + cost tally primitives.
3
+ *
4
+ * Pure functions only: no fs/network/process imports, so this module is
5
+ * safe to import in a browser, a Workers/edge runtime, or any bundle that
6
+ * cares about staying isomorphic. Node-only concerns (ledger I/O, budget
7
+ * gates) live in ./cost.js instead — import that separately if you need them.
8
+ *
9
+ * Mirrors the normalize → resolve pricing → estimate → tally shape so
10
+ * consumers (tokmeter, Runic, a browser cost calculator) don't each
11
+ * reinvent cross-provider usage normalization or rate math.
12
+ * @module
13
+ */
14
+ import type { ModelPricing } from "./types.js";
15
+ /** Canonical, provider-agnostic token usage shape. */
16
+ export interface TokenUsage {
17
+ inputTokens: number;
18
+ outputTokens: number;
19
+ /** Cache-read ("hit") input tokens, if the provider reports them separately. */
20
+ cachedInputTokens?: number;
21
+ /** Cache-write input tokens (Anthropic-style cache creation), if reported. */
22
+ cacheWriteTokens?: number;
23
+ /** Reasoning/thinking output tokens, if the provider bills or reports them separately. */
24
+ reasoningTokens?: number;
25
+ }
26
+ /** `TokenUsage` plus a derived total. Returned by `normalizeTokenUsage`. */
27
+ export interface NormalizedTokenUsage extends TokenUsage {
28
+ totalTokens: number;
29
+ }
30
+ /**
31
+ * Normalize a raw, provider-shaped usage object (OpenAI `prompt_tokens` /
32
+ * `completion_tokens`, Anthropic `input_tokens` / `output_tokens` /
33
+ * `cache_read_input_tokens`, etc.) into the canonical `TokenUsage` shape.
34
+ *
35
+ * Returns `null` when neither an input nor output token count can be found —
36
+ * that's "not a usage object," not "zero usage."
37
+ */
38
+ export declare function normalizeTokenUsage(raw: Record<string, unknown> | null | undefined): NormalizedTokenUsage | null;
39
+ /** USD breakdown returned by `estimateUsdCost`. */
40
+ export interface UsdCostBreakdown {
41
+ inputUsd: number;
42
+ outputUsd: number;
43
+ cachedInputUsd: number;
44
+ cacheWriteUsd: number;
45
+ reasoningUsd: number;
46
+ totalUsd: number;
47
+ }
48
+ /**
49
+ * Estimate USD cost for one usage record against one model's pricing.
50
+ * Reasoning tokens price against `reasoningOutputPerMillion` when the model
51
+ * has it, falling back to the plain output rate otherwise — most providers
52
+ * that report reasoning tokens separately still bill them at the output rate.
53
+ */
54
+ export declare function estimateUsdCost(usage: TokenUsage, pricing: ModelPricing): UsdCostBreakdown;
55
+ /** One call record as consumed by `tallyCosts`. */
56
+ export interface TallyCall {
57
+ modelId: string;
58
+ usage: TokenUsage;
59
+ }
60
+ /** Per-model subtotal within a `tallyCosts` result. */
61
+ export interface TallyModelSubtotal extends UsdCostBreakdown {
62
+ modelId: string;
63
+ calls: number;
64
+ usage: TokenUsage;
65
+ }
66
+ /** Aggregate result of `tallyCosts`. */
67
+ export interface TallyResult extends UsdCostBreakdown {
68
+ calls: number;
69
+ byModel: TallyModelSubtotal[];
70
+ /** modelIds `resolvePricing` returned `null` for — cost for these is excluded from the totals. */
71
+ unpriced: string[];
72
+ }
73
+ /**
74
+ * Aggregate USD cost and token totals across heterogeneous calls, grouped by
75
+ * model. Pricing is resolved per model via the injected `resolvePricing`
76
+ * callback so the caller decides the source (kosha's live registry, a
77
+ * static map, a cached snapshot) — this function does no I/O of its own.
78
+ */
79
+ export declare function tallyCosts(calls: readonly TallyCall[], resolvePricing: (modelId: string) => ModelPricing | null | undefined): TallyResult;
80
+ //# sourceMappingURL=tally.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tally.d.ts","sourceRoot":"","sources":["../src/tally.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,sDAAsD;AACtD,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0FAA0F;IAC1F,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACvD,WAAW,EAAE,MAAM,CAAC;CACpB;AAsCD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,oBAAoB,GAAG,IAAI,CA2BhH;AAOD,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,gBAAgB,CAqB1F;AAED,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;CAClB;AAED,uDAAuD;AACvD,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,CAAC;CAClB;AAED,wCAAwC;AACxC,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,kGAAkG;IAClG,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,GAAG,SAAS,GAClE,WAAW,CA6Cb"}