@data-club/ai-hub-server 0.0.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.
- package/dist/auth/argon2.d.ts +72 -0
- package/dist/auth/argon2.d.ts.map +1 -0
- package/dist/auth/argon2.js +145 -0
- package/dist/auth/argon2.js.map +1 -0
- package/dist/auth/encryption.d.ts +52 -0
- package/dist/auth/encryption.d.ts.map +1 -0
- package/dist/auth/encryption.js +98 -0
- package/dist/auth/encryption.js.map +1 -0
- package/dist/auth/jwt.d.ts +133 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +147 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/middleware.d.ts +101 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +161 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/passwordPolicy.d.ts +72 -0
- package/dist/auth/passwordPolicy.d.ts.map +1 -0
- package/dist/auth/passwordPolicy.js +88 -0
- package/dist/auth/passwordPolicy.js.map +1 -0
- package/dist/auth/roleRules.d.ts +200 -0
- package/dist/auth/roleRules.d.ts.map +1 -0
- package/dist/auth/roleRules.js +365 -0
- package/dist/auth/roleRules.js.map +1 -0
- package/dist/auth/userView.d.ts +55 -0
- package/dist/auth/userView.d.ts.map +1 -0
- package/dist/auth/userView.js +77 -0
- package/dist/auth/userView.js.map +1 -0
- package/dist/bootstrap.d.ts +104 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +160 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/db/connection.d.ts +39 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +62 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/migrate.d.ts +31 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +197 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/schema.d.ts +1902 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +662 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/seed.d.ts +92 -0
- package/dist/db/seed.d.ts.map +1 -0
- package/dist/db/seed.js +160 -0
- package/dist/db/seed.js.map +1 -0
- package/dist/handlers/fetch.d.ts +89 -0
- package/dist/handlers/fetch.d.ts.map +1 -0
- package/dist/handlers/fetch.js +173 -0
- package/dist/handlers/fetch.js.map +1 -0
- package/dist/handlers/nextjs.d.ts +40 -0
- package/dist/handlers/nextjs.d.ts.map +1 -0
- package/dist/handlers/nextjs.js +42 -0
- package/dist/handlers/nextjs.js.map +1 -0
- package/dist/handlers/responses.d.ts +46 -0
- package/dist/handlers/responses.d.ts.map +1 -0
- package/dist/handlers/responses.js +74 -0
- package/dist/handlers/responses.js.map +1 -0
- package/dist/handlers/routeTable.d.ts +21 -0
- package/dist/handlers/routeTable.d.ts.map +1 -0
- package/dist/handlers/routeTable.js +133 -0
- package/dist/handlers/routeTable.js.map +1 -0
- package/dist/handlers/router.d.ts +37 -0
- package/dist/handlers/router.d.ts.map +1 -0
- package/dist/handlers/router.js +82 -0
- package/dist/handlers/router.js.map +1 -0
- package/dist/handlers/sse.d.ts +38 -0
- package/dist/handlers/sse.d.ts.map +1 -0
- package/dist/handlers/sse.js +52 -0
- package/dist/handlers/sse.js.map +1 -0
- package/dist/handlers/types.d.ts +96 -0
- package/dist/handlers/types.d.ts.map +1 -0
- package/dist/handlers/types.js +14 -0
- package/dist/handlers/types.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/letta/client.d.ts +355 -0
- package/dist/letta/client.d.ts.map +1 -0
- package/dist/letta/client.js +529 -0
- package/dist/letta/client.js.map +1 -0
- package/dist/letta/eventTranslator.d.ts +166 -0
- package/dist/letta/eventTranslator.d.ts.map +1 -0
- package/dist/letta/eventTranslator.js +532 -0
- package/dist/letta/eventTranslator.js.map +1 -0
- package/dist/letta/index.d.ts +13 -0
- package/dist/letta/index.d.ts.map +1 -0
- package/dist/letta/index.js +12 -0
- package/dist/letta/index.js.map +1 -0
- package/dist/letta/modelSettings.d.ts +176 -0
- package/dist/letta/modelSettings.d.ts.map +1 -0
- package/dist/letta/modelSettings.js +314 -0
- package/dist/letta/modelSettings.js.map +1 -0
- package/dist/letta/promptWrapping.d.ts +141 -0
- package/dist/letta/promptWrapping.d.ts.map +1 -0
- package/dist/letta/promptWrapping.js +213 -0
- package/dist/letta/promptWrapping.js.map +1 -0
- package/dist/letta/sandbox.d.ts +100 -0
- package/dist/letta/sandbox.d.ts.map +1 -0
- package/dist/letta/sandbox.js +151 -0
- package/dist/letta/sandbox.js.map +1 -0
- package/dist/letta/settingsFileSeed.d.ts +146 -0
- package/dist/letta/settingsFileSeed.d.ts.map +1 -0
- package/dist/letta/settingsFileSeed.js +177 -0
- package/dist/letta/settingsFileSeed.js.map +1 -0
- package/dist/letta/subprocessThrottle.d.ts +151 -0
- package/dist/letta/subprocessThrottle.d.ts.map +1 -0
- package/dist/letta/subprocessThrottle.js +195 -0
- package/dist/letta/subprocessThrottle.js.map +1 -0
- package/dist/letta/tpmRecovery.d.ts +202 -0
- package/dist/letta/tpmRecovery.d.ts.map +1 -0
- package/dist/letta/tpmRecovery.js +314 -0
- package/dist/letta/tpmRecovery.js.map +1 -0
- package/dist/letta/types.d.ts +54 -0
- package/dist/letta/types.d.ts.map +1 -0
- package/dist/letta/types.js +16 -0
- package/dist/letta/types.js.map +1 -0
- package/dist/observability/logger.d.ts +48 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +81 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +53 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +92 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/routes/admin/agents.d.ts +63 -0
- package/dist/routes/admin/agents.d.ts.map +1 -0
- package/dist/routes/admin/agents.js +461 -0
- package/dist/routes/admin/agents.js.map +1 -0
- package/dist/routes/admin/rotatingMessages.d.ts +51 -0
- package/dist/routes/admin/rotatingMessages.d.ts.map +1 -0
- package/dist/routes/admin/rotatingMessages.js +292 -0
- package/dist/routes/admin/rotatingMessages.js.map +1 -0
- package/dist/routes/admin/sessions.d.ts +61 -0
- package/dist/routes/admin/sessions.d.ts.map +1 -0
- package/dist/routes/admin/sessions.js +232 -0
- package/dist/routes/admin/sessions.js.map +1 -0
- package/dist/routes/admin/settings.d.ts +110 -0
- package/dist/routes/admin/settings.d.ts.map +1 -0
- package/dist/routes/admin/settings.js +401 -0
- package/dist/routes/admin/settings.js.map +1 -0
- package/dist/routes/admin/users.d.ts +115 -0
- package/dist/routes/admin/users.d.ts.map +1 -0
- package/dist/routes/admin/users.js +374 -0
- package/dist/routes/admin/users.js.map +1 -0
- package/dist/routes/agents.d.ts +30 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +55 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/auth.d.ts +121 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +422 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/chat.d.ts +97 -0
- package/dist/routes/chat.d.ts.map +1 -0
- package/dist/routes/chat.js +484 -0
- package/dist/routes/chat.js.map +1 -0
- package/dist/routes/featureToggles.d.ts +34 -0
- package/dist/routes/featureToggles.d.ts.map +1 -0
- package/dist/routes/featureToggles.js +47 -0
- package/dist/routes/featureToggles.js.map +1 -0
- package/dist/routes/health.d.ts +24 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +37 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/metrics.d.ts +35 -0
- package/dist/routes/metrics.d.ts.map +1 -0
- package/dist/routes/metrics.js +106 -0
- package/dist/routes/metrics.js.map +1 -0
- package/dist/routes/sessions.d.ts +161 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +1501 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/stubs.d.ts +25 -0
- package/dist/routes/stubs.d.ts.map +1 -0
- package/dist/routes/stubs.js +25 -0
- package/dist/routes/stubs.js.map +1 -0
- package/dist/state/cron.d.ts +58 -0
- package/dist/state/cron.d.ts.map +1 -0
- package/dist/state/cron.js +160 -0
- package/dist/state/cron.js.map +1 -0
- package/dist/state/rotationRunner.d.ts +96 -0
- package/dist/state/rotationRunner.d.ts.map +1 -0
- package/dist/state/rotationRunner.js +246 -0
- package/dist/state/rotationRunner.js.map +1 -0
- package/dist/state/rotationScheduler.d.ts +76 -0
- package/dist/state/rotationScheduler.d.ts.map +1 -0
- package/dist/state/rotationScheduler.js +124 -0
- package/dist/state/rotationScheduler.js.map +1 -0
- package/dist/state/turnRegistry.d.ts +95 -0
- package/dist/state/turnRegistry.d.ts.map +1 -0
- package/dist/state/turnRegistry.js +149 -0
- package/dist/state/turnRegistry.js.map +1 -0
- package/dist/state/turnRunner.d.ts +134 -0
- package/dist/state/turnRunner.d.ts.map +1 -0
- package/dist/state/turnRunner.js +476 -0
- package/dist/state/turnRunner.js.map +1 -0
- package/package.json +47 -0
- package/src/auth/argon2.ts +152 -0
- package/src/auth/encryption.ts +110 -0
- package/src/auth/jwt.ts +217 -0
- package/src/auth/middleware.ts +250 -0
- package/src/auth/passwordPolicy.ts +99 -0
- package/src/auth/roleRules.ts +497 -0
- package/src/auth/userView.ts +88 -0
- package/src/bootstrap.ts +254 -0
- package/src/db/connection.ts +75 -0
- package/src/db/migrate.ts +212 -0
- package/src/db/schema.ts +750 -0
- package/src/db/seed.ts +236 -0
- package/src/handlers/fetch.ts +251 -0
- package/src/handlers/nextjs.ts +49 -0
- package/src/handlers/responses.ts +95 -0
- package/src/handlers/routeTable.ts +188 -0
- package/src/handlers/router.ts +96 -0
- package/src/handlers/sse.ts +55 -0
- package/src/handlers/types.ts +104 -0
- package/src/index.ts +60 -0
- package/src/letta/client.ts +860 -0
- package/src/letta/eventTranslator.ts +667 -0
- package/src/letta/index.ts +46 -0
- package/src/letta/lettaCliShim.mjs +40 -0
- package/src/letta/sandbox.ts +167 -0
- package/src/letta/settingsFileSeed.ts +254 -0
- package/src/letta/subprocessThrottle.ts +251 -0
- package/src/letta/types.ts +65 -0
- package/src/observability/logger.ts +103 -0
- package/src/observability/metrics.ts +114 -0
- package/src/routes/admin/agents.ts +574 -0
- package/src/routes/admin/rotatingMessages.ts +351 -0
- package/src/routes/admin/sessions.ts +283 -0
- package/src/routes/admin/settings.ts +463 -0
- package/src/routes/admin/users.ts +455 -0
- package/src/routes/agents.ts +66 -0
- package/src/routes/auth.ts +513 -0
- package/src/routes/chat.ts +534 -0
- package/src/routes/featureToggles.ts +52 -0
- package/src/routes/health.ts +44 -0
- package/src/routes/metrics.ts +111 -0
- package/src/routes/sessions.ts +1878 -0
- package/src/state/cron.ts +179 -0
- package/src/state/rotationRunner.ts +326 -0
- package/src/state/rotationScheduler.ts +164 -0
- package/src/state/turnRegistry.ts +210 -0
- package/src/state/turnRunner.ts +588 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGvE,sDAAsD;AACtD,MAAM,CAAC,MAAM,YAAY,GAAiB,KAAK,IAAI,EAAE,CACnD,YAAY,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAiB,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACjE,IAAI,CAAC;QACH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,EAAE,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,KAAK,CACd,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,EACzC,yCAAyC,CAC1C,CAAC;QACF,OAAO,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,sBAAsB,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,YAAY,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,2DAA2D;AAC3D,SAAS,UAAU,CAAC,GAAY;IAC9B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `GET /metrics` — Prometheus-text endpoint with a bearer-token gate.
|
|
3
|
+
*
|
|
4
|
+
* Unlike every other protected endpoint, `/metrics` does **not** speak the JWT
|
|
5
|
+
* + role pipeline: Prometheus / Alloy scrapers don't speak our login flow.
|
|
6
|
+
* Instead, the request must carry `Authorization: Bearer <token>` whose value
|
|
7
|
+
* **constant-time-matches** `admin_setting.metrics_scrape_token` (§6.10).
|
|
8
|
+
*
|
|
9
|
+
* Series exposed (Step 4 — these start at 0 and become live in Steps 5/6):
|
|
10
|
+
*
|
|
11
|
+
* - `chat_requests_total` — counter, total `/chat` requests received.
|
|
12
|
+
* - `tpm_recovery_attempts_total` — counter, TPM recovery attempts started.
|
|
13
|
+
* - `tpm_exhausted_total` — counter, TPM recovery exhausted (turn → failed).
|
|
14
|
+
* - `chat_duration_ms` — histogram-like (rendered as a Gauge in v1; Step 6
|
|
15
|
+
* may upgrade to a proper Prometheus histogram).
|
|
16
|
+
* - `letta_request_duration_ms` — same shape as above for Letta calls.
|
|
17
|
+
*
|
|
18
|
+
* Step 4 ships the auth gate + the series scaffolding with all counters at
|
|
19
|
+
* zero; Steps 5 + 6 wire them up as the chat path is implemented.
|
|
20
|
+
*
|
|
21
|
+
* @see SPECIFICATIONS.md §6.10 — observability / metrics token
|
|
22
|
+
* @see SPECIFICATIONS.md §6.3.5 — /metrics in the API surface
|
|
23
|
+
*/
|
|
24
|
+
import type { RouteHandler } from "../handlers/types.js";
|
|
25
|
+
/**
|
|
26
|
+
* `GET /metrics` — bearer-token-gated Prometheus exposition.
|
|
27
|
+
*
|
|
28
|
+
* Not behind `protectedRoute` — the auth is the bearer token, not the JWT
|
|
29
|
+
* pipeline. Returns 401 on missing / wrong token (with the same generic
|
|
30
|
+
* `unauthorized` envelope as the JWT paths, no scope leakage).
|
|
31
|
+
*
|
|
32
|
+
* @see SPECIFICATIONS.md §6.10
|
|
33
|
+
*/
|
|
34
|
+
export declare const handleMetrics: RouteHandler;
|
|
35
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/routes/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA6CzD;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,EAAE,YA0B3B,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `GET /metrics` — Prometheus-text endpoint with a bearer-token gate.
|
|
3
|
+
*
|
|
4
|
+
* Unlike every other protected endpoint, `/metrics` does **not** speak the JWT
|
|
5
|
+
* + role pipeline: Prometheus / Alloy scrapers don't speak our login flow.
|
|
6
|
+
* Instead, the request must carry `Authorization: Bearer <token>` whose value
|
|
7
|
+
* **constant-time-matches** `admin_setting.metrics_scrape_token` (§6.10).
|
|
8
|
+
*
|
|
9
|
+
* Series exposed (Step 4 — these start at 0 and become live in Steps 5/6):
|
|
10
|
+
*
|
|
11
|
+
* - `chat_requests_total` — counter, total `/chat` requests received.
|
|
12
|
+
* - `tpm_recovery_attempts_total` — counter, TPM recovery attempts started.
|
|
13
|
+
* - `tpm_exhausted_total` — counter, TPM recovery exhausted (turn → failed).
|
|
14
|
+
* - `chat_duration_ms` — histogram-like (rendered as a Gauge in v1; Step 6
|
|
15
|
+
* may upgrade to a proper Prometheus histogram).
|
|
16
|
+
* - `letta_request_duration_ms` — same shape as above for Letta calls.
|
|
17
|
+
*
|
|
18
|
+
* Step 4 ships the auth gate + the series scaffolding with all counters at
|
|
19
|
+
* zero; Steps 5 + 6 wire them up as the chat path is implemented.
|
|
20
|
+
*
|
|
21
|
+
* @see SPECIFICATIONS.md §6.10 — observability / metrics token
|
|
22
|
+
* @see SPECIFICATIONS.md §6.3.5 — /metrics in the API surface
|
|
23
|
+
*/
|
|
24
|
+
import { timingSafeEqual } from "node:crypto";
|
|
25
|
+
import { eq } from "drizzle-orm";
|
|
26
|
+
import { adminSetting } from "../db/schema.js";
|
|
27
|
+
import { unauthorized } from "../handlers/responses.js";
|
|
28
|
+
import { renderMetrics } from "../observability/metrics.js";
|
|
29
|
+
/**
|
|
30
|
+
* Constant-time-compares the supplied bearer token against the stored
|
|
31
|
+
* scrape token. Returns `false` for any malformed input (no length leak).
|
|
32
|
+
*
|
|
33
|
+
* @param supplied - the bearer token from the request header.
|
|
34
|
+
* @param stored - the token from `admin_setting.metrics_scrape_token`.
|
|
35
|
+
* @returns `true` if the tokens match.
|
|
36
|
+
*/
|
|
37
|
+
function tokensEqual(supplied, stored) {
|
|
38
|
+
// Buffers must be the same length for timingSafeEqual. Pad the shorter one
|
|
39
|
+
// and compare lengths separately so we still don't reveal "supplied was
|
|
40
|
+
// shorter" via timing.
|
|
41
|
+
const a = Buffer.from(supplied, "utf8");
|
|
42
|
+
const b = Buffer.from(stored, "utf8");
|
|
43
|
+
if (a.length !== b.length) {
|
|
44
|
+
// Burn an equal-length compare so the timing of the rejection doesn't
|
|
45
|
+
// distinguish "wrong length" from "wrong value."
|
|
46
|
+
const dummy = Buffer.alloc(b.length, 0);
|
|
47
|
+
try {
|
|
48
|
+
timingSafeEqual(dummy, b);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
/* ignored */
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return timingSafeEqual(a, b);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Extracts the bearer token from the `Authorization` header value.
|
|
59
|
+
*
|
|
60
|
+
* @param value - the raw header value (or `null`).
|
|
61
|
+
* @returns the token or `null`.
|
|
62
|
+
*/
|
|
63
|
+
function extractBearer(value) {
|
|
64
|
+
if (!value)
|
|
65
|
+
return null;
|
|
66
|
+
const m = value.match(/^Bearer\s+(.+)$/i);
|
|
67
|
+
if (!m)
|
|
68
|
+
return null;
|
|
69
|
+
const token = m[1]?.trim() ?? "";
|
|
70
|
+
return token.length > 0 ? token : null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* `GET /metrics` — bearer-token-gated Prometheus exposition.
|
|
74
|
+
*
|
|
75
|
+
* Not behind `protectedRoute` — the auth is the bearer token, not the JWT
|
|
76
|
+
* pipeline. Returns 401 on missing / wrong token (with the same generic
|
|
77
|
+
* `unauthorized` envelope as the JWT paths, no scope leakage).
|
|
78
|
+
*
|
|
79
|
+
* @see SPECIFICATIONS.md §6.10
|
|
80
|
+
*/
|
|
81
|
+
export const handleMetrics = async (req, ctx) => {
|
|
82
|
+
const supplied = extractBearer(req.headers.get("authorization"));
|
|
83
|
+
if (!supplied)
|
|
84
|
+
return unauthorized();
|
|
85
|
+
const settings = ctx.db
|
|
86
|
+
.select({ token: adminSetting.metricsScrapeToken })
|
|
87
|
+
.from(adminSetting)
|
|
88
|
+
.where(eq(adminSetting.id, 1))
|
|
89
|
+
.get();
|
|
90
|
+
const stored = settings?.token;
|
|
91
|
+
if (!stored || !tokensEqual(supplied, stored)) {
|
|
92
|
+
return unauthorized();
|
|
93
|
+
}
|
|
94
|
+
// Step 5 wires `chat_requests_total`, `chat_duration_ms`, and
|
|
95
|
+
// `letta_request_duration_ms` to live values. Step 6 fills in the
|
|
96
|
+
// TPM-recovery counters. The registry lives in
|
|
97
|
+
// `observability/metrics.ts`.
|
|
98
|
+
const body = renderMetrics();
|
|
99
|
+
return new Response(body, {
|
|
100
|
+
status: 200,
|
|
101
|
+
headers: {
|
|
102
|
+
"Content-Type": "text/plain; version=0.0.4; charset=utf-8",
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/routes/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,MAAc;IACnD,2EAA2E;IAC3E,wEAAwE;IACxE,uBAAuB;IACvB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,sEAAsE;QACtE,iDAAiD;QACjD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC;YACH,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,KAAoB;IACzC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAiB,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,QAAQ;QAAE,OAAO,YAAY,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE;SACpB,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,kBAAkB,EAAE,CAAC;SAClD,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAC7B,GAAG,EAAE,CAAC;IACT,MAAM,MAAM,GAAG,QAAQ,EAAE,KAAK,CAAC;IAC/B,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QAC9C,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC;IAED,8DAA8D;IAC9D,kEAAkE;IAClE,+CAA+C;IAC/C,8BAA8B;IAC9B,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAE7B,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;QACxB,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACP,cAAc,EAAE,0CAA0C;SAC3D;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-facing `/sessions/*` — the caller's own sessions (never cross-user).
|
|
3
|
+
*
|
|
4
|
+
* Step 4 ships the four CRUD endpoints minus DELETE (sessions are archive-only
|
|
5
|
+
* in v1 — §6.3.1). The Letta-conversation-create call on `POST /sessions` is
|
|
6
|
+
* stubbed; Step 5 replaces the placeholder with `client.conversations.create`.
|
|
7
|
+
*
|
|
8
|
+
* - `POST /sessions` — body `{ agent_id, title }`; title required (1..80
|
|
9
|
+
* chars). Creates a session owned by the caller against `agent_id`. The
|
|
10
|
+
* server snapshots `agent.letta_agent_id` into `session.letta_agent_id` and
|
|
11
|
+
* stores a placeholder `letta_conversation_id` (Step 5 fills the real one).
|
|
12
|
+
* Rejects when the agent is archived (`agent_archived`).
|
|
13
|
+
* - `GET /sessions?agent_id=...&include_archived=false` — caller-scoped list.
|
|
14
|
+
* `agent_id` is required; `include_archived` defaults to false.
|
|
15
|
+
* - `GET /sessions/:id` — single session if the caller owns it; 404 with no
|
|
16
|
+
* enumeration leakage otherwise.
|
|
17
|
+
* - `PATCH /sessions/:id` — body `{ title?, is_archived? }`. Rename and / or
|
|
18
|
+
* archive / unarchive. An empty patch is a 200 no-op.
|
|
19
|
+
* - `GET /sessions/:id/messages` — 501 stub; Step 5 wires
|
|
20
|
+
* `client.conversations.messages.list`.
|
|
21
|
+
*
|
|
22
|
+
* @see SPECIFICATIONS.md §6.3.1 — Sessions
|
|
23
|
+
* @see SPECIFICATIONS.md §11 — `session` table
|
|
24
|
+
* @see SPECIFICATIONS.md §13.2 — user isolation
|
|
25
|
+
*/
|
|
26
|
+
import type { RouteHandler } from "../handlers/types.js";
|
|
27
|
+
/**
|
|
28
|
+
* `POST /sessions` — create a new session for the caller against `agent_id`.
|
|
29
|
+
*
|
|
30
|
+
* Validates that the referenced ai-hub agent exists and is not archived.
|
|
31
|
+
* Snapshots `agent.letta_agent_id` so a future re-point of the catalog entry
|
|
32
|
+
* does not migrate existing conversations.
|
|
33
|
+
*
|
|
34
|
+
* Step 5 replaces the placeholder `letta_conversation_id` with a real SDK
|
|
35
|
+
* call to `client.conversations.create`.
|
|
36
|
+
*
|
|
37
|
+
* @see SPECIFICATIONS.md §6.3.1
|
|
38
|
+
*/
|
|
39
|
+
export declare const handleCreateSession: RouteHandler;
|
|
40
|
+
/**
|
|
41
|
+
* `GET /sessions` — list the caller's sessions for a given agent.
|
|
42
|
+
*
|
|
43
|
+
* Query parameters:
|
|
44
|
+
*
|
|
45
|
+
* - `agent_id` — required. The ai-hub agent (catalog entry) to scope the list
|
|
46
|
+
* to. Sessions for other agents are not returned (a single GET is
|
|
47
|
+
* per-agent, mirroring how the React sessions panel mounts inside an
|
|
48
|
+
* opened agent — see [03-chat.md](../../../../docs/ui-sketches/03-chat.md)).
|
|
49
|
+
* - `include_archived` — optional, default `false`. When `true`, archived
|
|
50
|
+
* rows are surfaced alongside active ones with their `is_archived` flag
|
|
51
|
+
* set; the client distinguishes them visually (`--archived` modifier).
|
|
52
|
+
*
|
|
53
|
+
* Order: newest first by `updated_at`.
|
|
54
|
+
*
|
|
55
|
+
* @see SPECIFICATIONS.md §6.3.1
|
|
56
|
+
*/
|
|
57
|
+
export declare const handleListSessions: RouteHandler;
|
|
58
|
+
/**
|
|
59
|
+
* `GET /sessions/:id` — single session, owner-scoped.
|
|
60
|
+
*
|
|
61
|
+
* Returns 404 with `not_found` for both "no such session" and "exists but
|
|
62
|
+
* belongs to another user" — no enumeration leakage (§13.1).
|
|
63
|
+
*
|
|
64
|
+
* @see SPECIFICATIONS.md §6.3.1
|
|
65
|
+
*/
|
|
66
|
+
export declare const handleGetSession: RouteHandler;
|
|
67
|
+
/**
|
|
68
|
+
* `PATCH /sessions/:id` — rename and / or archive / unarchive, owner-scoped.
|
|
69
|
+
*
|
|
70
|
+
* Accepts either field independently — the React UI sends just `title` for
|
|
71
|
+
* rename and just `is_archived` for archive/unarchive. An empty body
|
|
72
|
+
* (`{}`) is a 200 no-op that echoes the row unchanged.
|
|
73
|
+
*
|
|
74
|
+
* @see SPECIFICATIONS.md §6.3.1
|
|
75
|
+
*/
|
|
76
|
+
export declare const handlePatchSession: RouteHandler;
|
|
77
|
+
/**
|
|
78
|
+
* `PATCH /sessions/:id/reasoning` — update the user's per-session reasoning
|
|
79
|
+
* settings. Applied to the agent's `model_settings` automatically before
|
|
80
|
+
* the next chat turn.
|
|
81
|
+
*
|
|
82
|
+
* Owner-scoped: returns 404 for sessions the caller doesn't own.
|
|
83
|
+
*
|
|
84
|
+
* @see SPECIFICATIONS.md §6.3.1
|
|
85
|
+
*/
|
|
86
|
+
export declare const handlePatchSessionReasoning: RouteHandler;
|
|
87
|
+
/**
|
|
88
|
+
* `GET /sessions/:id/messages` — paginated history pulled from Letta.
|
|
89
|
+
*
|
|
90
|
+
* Calls `client.conversations.messages.list(conversation_id)` per §6.4 and
|
|
91
|
+
* projects the result into the wire-shaped `AIHubMessage` array the
|
|
92
|
+
* React client consumes. Letta is the source of truth for message
|
|
93
|
+
* history (§6.8); ai-hub does not duplicate it in its SQLite.
|
|
94
|
+
*
|
|
95
|
+
* Owner-scoped: returns 404 for sessions not owned by the caller. The
|
|
96
|
+
* `power_user`+ "all-sessions overview" lives at `/admin/sessions`, not
|
|
97
|
+
* here.
|
|
98
|
+
*
|
|
99
|
+
* @see SPECIFICATIONS.md §6.3.1 — sessions
|
|
100
|
+
* @see SPECIFICATIONS.md §6.4 — SDK-only rule
|
|
101
|
+
* @see SPECIFICATIONS.md §6.8 — Letta owns message history
|
|
102
|
+
*/
|
|
103
|
+
export declare const handleGetSessionMessages: RouteHandler;
|
|
104
|
+
/**
|
|
105
|
+
* `GET /admin/sessions/:id/messages` — read-only session detail for the
|
|
106
|
+
* admin sessions overview (§8.2, [07-admin-sessions-overview.md]).
|
|
107
|
+
*
|
|
108
|
+
* Mirrors `handleGetSessionMessages` but skips the owner check — power_user+
|
|
109
|
+
* can view any session in the deployment (no write surface; the React side
|
|
110
|
+
* mounts the same `<MessageBubble />`s without input controls).
|
|
111
|
+
*
|
|
112
|
+
* @see SPECIFICATIONS.md §6.3.4 — admin sessions overview
|
|
113
|
+
* @see ui-sketches/07-admin-sessions-overview.md
|
|
114
|
+
*/
|
|
115
|
+
export declare const handleAdminGetSessionMessages: RouteHandler;
|
|
116
|
+
/**
|
|
117
|
+
* `GET /sessions/:id/message-overrides` — list the caller's overrides for
|
|
118
|
+
* the session's underlying Letta conversation.
|
|
119
|
+
*
|
|
120
|
+
* Returns the rows sorted by `ordinal_position` ascending so consumers
|
|
121
|
+
* can render them alongside the message list at the matching index. An
|
|
122
|
+
* empty list (no overrides set) returns `{ overrides: [] }` with 200.
|
|
123
|
+
*
|
|
124
|
+
* Owner-scoped: 404 for sessions the caller doesn't own.
|
|
125
|
+
*/
|
|
126
|
+
export declare const handleListMessageOverrides: RouteHandler;
|
|
127
|
+
/**
|
|
128
|
+
* `PUT /sessions/:id/message-overrides/:position` — upsert one or both
|
|
129
|
+
* override layers for the message at `position`.
|
|
130
|
+
*
|
|
131
|
+
* **Validation gates** (in order):
|
|
132
|
+
* - `404` — session not owned by caller (or doesn't exist).
|
|
133
|
+
* - `400 invalid_position` — path segment doesn't parse as a non-negative
|
|
134
|
+
* integer.
|
|
135
|
+
* - `400 validation` — body missing both fields.
|
|
136
|
+
* - `409 turn_in_progress` — a `turn` row exists with `status = "running"`
|
|
137
|
+
* for this session. Honoring writes while a turn is in flight would
|
|
138
|
+
* race the post-turn writer, so we reject up front.
|
|
139
|
+
* - `409 message_not_found` — `position` is out of range for the current
|
|
140
|
+
* Letta message list. The override would point at a message that
|
|
141
|
+
* doesn't exist; callers must wait for the message to land before
|
|
142
|
+
* overriding it.
|
|
143
|
+
*
|
|
144
|
+
* **Merge semantics.** Only the layers the body provides are written; an
|
|
145
|
+
* existing value on the other layer is preserved by reading the row,
|
|
146
|
+
* computing the merged tuple, and upserting the result. This lets the
|
|
147
|
+
* `/chat` post-turn writer set `user_override` (leaving `system_override`
|
|
148
|
+
* null) and a later operator PUT set `system_override` without
|
|
149
|
+
* clobbering the post-turn-written `user_override`.
|
|
150
|
+
*
|
|
151
|
+
* Idempotent: same body → same result. Returns 200 with the resulting view.
|
|
152
|
+
*/
|
|
153
|
+
export declare const handlePutMessageOverride: RouteHandler;
|
|
154
|
+
/**
|
|
155
|
+
* `DELETE /sessions/:id/message-overrides/:position` — remove an override.
|
|
156
|
+
*
|
|
157
|
+
* Idempotent: returns 204 whether or not the row existed. Owner-scoped:
|
|
158
|
+
* 404 for sessions the caller doesn't own.
|
|
159
|
+
*/
|
|
160
|
+
export declare const handleDeleteMessageOverride: RouteHandler;
|
|
161
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AA2BH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAmIzD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAkMjC,CAAC;AAMF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAgChC,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAiB9B,CAAC;AAcF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAoDhC,CAAC;AA0BF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,EAAE,YA8CzC,CAAC;AAMF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,EAAE,YAStC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6BAA6B,EAAE,YAS3C,CAAC;AAsRF;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,EAAE,YAgBxC,CAAC;AA6BF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,wBAAwB,EAAE,YA+ItC,CAAC;AAMF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,EAAE,YA4BzC,CAAC"}
|