@agentlensai/server 0.6.0 → 0.8.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 (72) hide show
  1. package/dist/db/benchmark-store.d.ts +74 -0
  2. package/dist/db/benchmark-store.d.ts.map +1 -0
  3. package/dist/db/benchmark-store.js +268 -0
  4. package/dist/db/benchmark-store.js.map +1 -0
  5. package/dist/db/guardrail-store.d.ts +34 -0
  6. package/dist/db/guardrail-store.d.ts.map +1 -0
  7. package/dist/db/guardrail-store.js +221 -0
  8. package/dist/db/guardrail-store.js.map +1 -0
  9. package/dist/db/migrate.d.ts.map +1 -1
  10. package/dist/db/migrate.js +112 -0
  11. package/dist/db/migrate.js.map +1 -1
  12. package/dist/db/schema.sqlite.d.ts +58 -1
  13. package/dist/db/schema.sqlite.d.ts.map +1 -1
  14. package/dist/db/schema.sqlite.js +6 -0
  15. package/dist/db/schema.sqlite.js.map +1 -1
  16. package/dist/db/sqlite-store.d.ts +12 -0
  17. package/dist/db/sqlite-store.d.ts.map +1 -1
  18. package/dist/db/sqlite-store.js +47 -0
  19. package/dist/db/sqlite-store.js.map +1 -1
  20. package/dist/db/tenant-scoped-store.d.ts +1 -0
  21. package/dist/db/tenant-scoped-store.d.ts.map +1 -1
  22. package/dist/db/tenant-scoped-store.js +3 -0
  23. package/dist/db/tenant-scoped-store.js.map +1 -1
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +32 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/lib/benchmark/engine.d.ts +24 -0
  29. package/dist/lib/benchmark/engine.d.ts.map +1 -0
  30. package/dist/lib/benchmark/engine.js +159 -0
  31. package/dist/lib/benchmark/engine.js.map +1 -0
  32. package/dist/lib/benchmark/metric-aggregator.d.ts +38 -0
  33. package/dist/lib/benchmark/metric-aggregator.d.ts.map +1 -0
  34. package/dist/lib/benchmark/metric-aggregator.js +159 -0
  35. package/dist/lib/benchmark/metric-aggregator.js.map +1 -0
  36. package/dist/lib/benchmark/statistical.d.ts +51 -0
  37. package/dist/lib/benchmark/statistical.d.ts.map +1 -0
  38. package/dist/lib/benchmark/statistical.js +381 -0
  39. package/dist/lib/benchmark/statistical.js.map +1 -0
  40. package/dist/lib/guardrails/actions.d.ts +28 -0
  41. package/dist/lib/guardrails/actions.d.ts.map +1 -0
  42. package/dist/lib/guardrails/actions.js +126 -0
  43. package/dist/lib/guardrails/actions.js.map +1 -0
  44. package/dist/lib/guardrails/conditions.d.ts +13 -0
  45. package/dist/lib/guardrails/conditions.d.ts.map +1 -0
  46. package/dist/lib/guardrails/conditions.js +188 -0
  47. package/dist/lib/guardrails/conditions.js.map +1 -0
  48. package/dist/lib/guardrails/engine.d.ts +24 -0
  49. package/dist/lib/guardrails/engine.d.ts.map +1 -0
  50. package/dist/lib/guardrails/engine.js +122 -0
  51. package/dist/lib/guardrails/engine.js.map +1 -0
  52. package/dist/lib/replay/builder.d.ts +28 -0
  53. package/dist/lib/replay/builder.d.ts.map +1 -0
  54. package/dist/lib/replay/builder.js +482 -0
  55. package/dist/lib/replay/builder.js.map +1 -0
  56. package/dist/routes/agents.d.ts +4 -3
  57. package/dist/routes/agents.d.ts.map +1 -1
  58. package/dist/routes/agents.js +37 -12
  59. package/dist/routes/agents.js.map +1 -1
  60. package/dist/routes/benchmarks.d.ts +18 -0
  61. package/dist/routes/benchmarks.d.ts.map +1 -0
  62. package/dist/routes/benchmarks.js +312 -0
  63. package/dist/routes/benchmarks.js.map +1 -0
  64. package/dist/routes/guardrails.d.ts +18 -0
  65. package/dist/routes/guardrails.d.ts.map +1 -0
  66. package/dist/routes/guardrails.js +184 -0
  67. package/dist/routes/guardrails.js.map +1 -0
  68. package/dist/routes/replay.d.ts +28 -0
  69. package/dist/routes/replay.d.ts.map +1 -0
  70. package/dist/routes/replay.js +140 -0
  71. package/dist/routes/replay.js.map +1 -0
  72. package/package.json +2 -2
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Benchmark REST Endpoints (Story 3.5)
3
+ *
4
+ * POST /api/benchmarks — Create benchmark
5
+ * GET /api/benchmarks — List benchmarks
6
+ * GET /api/benchmarks/:id — Get benchmark detail
7
+ * PUT /api/benchmarks/:id/status — Transition status
8
+ * GET /api/benchmarks/:id/results — Get comparison results
9
+ * DELETE /api/benchmarks/:id — Delete draft/cancelled
10
+ */
11
+ import { Hono } from 'hono';
12
+ import { BENCHMARK_METRICS } from '@agentlensai/core';
13
+ import { getTenantStore } from './tenant-helper.js';
14
+ import { BenchmarkStore, } from '../db/benchmark-store.js';
15
+ import { BenchmarkEngine } from '../lib/benchmark/engine.js';
16
+ // ─── Validation Helpers ────────────────────────────────────
17
+ const VALID_METRICS = new Set(BENCHMARK_METRICS);
18
+ const VALID_STATUSES = new Set(['draft', 'running', 'completed', 'cancelled']);
19
+ function validateCreateInput(body) {
20
+ if (!body || typeof body !== 'object') {
21
+ return { error: 'Request body is required' };
22
+ }
23
+ // Name required
24
+ if (!body.name || typeof body.name !== 'string' || body.name.trim() === '') {
25
+ return { error: 'name is required and must be a non-empty string' };
26
+ }
27
+ // Variants: 2-10 with name+tag
28
+ if (!Array.isArray(body.variants)) {
29
+ return { error: 'variants must be an array' };
30
+ }
31
+ if (body.variants.length < 2 || body.variants.length > 10) {
32
+ return { error: 'Must have between 2 and 10 variants' };
33
+ }
34
+ for (let i = 0; i < body.variants.length; i++) {
35
+ const v = body.variants[i];
36
+ if (!v || typeof v !== 'object') {
37
+ return { error: `variants[${i}] must be an object` };
38
+ }
39
+ if (!v.name || typeof v.name !== 'string' || v.name.trim() === '') {
40
+ return { error: `variants[${i}].name is required` };
41
+ }
42
+ if (!v.tag || typeof v.tag !== 'string' || v.tag.trim() === '') {
43
+ return { error: `variants[${i}].tag is required` };
44
+ }
45
+ }
46
+ // Metrics: optional array, but if provided must be valid
47
+ let metrics = BENCHMARK_METRICS.filter(m => m !== 'health_score'); // default: all supported
48
+ if (body.metrics !== undefined) {
49
+ if (!Array.isArray(body.metrics) || body.metrics.length === 0) {
50
+ return { error: 'metrics must be a non-empty array' };
51
+ }
52
+ for (const m of body.metrics) {
53
+ if (!VALID_METRICS.has(m)) {
54
+ return { error: `Invalid metric: ${m}` };
55
+ }
56
+ if (m === 'health_score') {
57
+ return { error: `Metric "health_score" is not yet supported for benchmarks. It requires pre-computed health snapshots.` };
58
+ }
59
+ }
60
+ metrics = body.metrics;
61
+ }
62
+ // minSessionsPerVariant: optional, must be ≥ 1
63
+ let minSessions;
64
+ if (body.minSessionsPerVariant !== undefined) {
65
+ const val = Number(body.minSessionsPerVariant);
66
+ if (!Number.isInteger(val) || val < 1) {
67
+ return { error: 'minSessionsPerVariant must be an integer ≥ 1' };
68
+ }
69
+ minSessions = val;
70
+ }
71
+ const input = {
72
+ name: body.name.trim(),
73
+ description: body.description ?? undefined,
74
+ agentId: body.agentId ?? undefined,
75
+ metrics,
76
+ minSessionsPerVariant: minSessions,
77
+ timeRange: body.timeRange,
78
+ variants: body.variants.map((v) => ({
79
+ name: v.name.trim(),
80
+ description: v.description ?? undefined,
81
+ tag: v.tag.trim(),
82
+ agentId: v.agentId ?? undefined,
83
+ })),
84
+ };
85
+ return { input };
86
+ }
87
+ // ─── Route Factory ─────────────────────────────────────────
88
+ export function benchmarkRoutes(store, db) {
89
+ const app = new Hono();
90
+ const engine = new BenchmarkEngine();
91
+ function getBenchmarkStore(c) {
92
+ if (!db)
93
+ return null;
94
+ return new BenchmarkStore(db);
95
+ }
96
+ function getTenantId(c) {
97
+ const apiKey = c.get('apiKey');
98
+ return apiKey?.tenantId ?? 'default';
99
+ }
100
+ // ─── POST / — Create benchmark ─────────────────────────
101
+ app.post('/', async (c) => {
102
+ const benchmarkStore = getBenchmarkStore(c);
103
+ if (!benchmarkStore) {
104
+ return c.json({ error: 'Database not available', status: 500 }, 500);
105
+ }
106
+ const tenantId = getTenantId(c);
107
+ const body = await c.req.json().catch(() => null);
108
+ const { error, input } = validateCreateInput(body);
109
+ if (error || !input) {
110
+ return c.json({ error, status: 400 }, 400);
111
+ }
112
+ try {
113
+ const benchmark = benchmarkStore.create(tenantId, input);
114
+ return c.json(benchmark, 201);
115
+ }
116
+ catch (err) {
117
+ const message = err instanceof Error ? err.message : 'Failed to create benchmark';
118
+ return c.json({ error: message, status: 400 }, 400);
119
+ }
120
+ });
121
+ // ─── GET / — List benchmarks ────────────────────────────
122
+ app.get('/', async (c) => {
123
+ const benchmarkStore = getBenchmarkStore(c);
124
+ if (!benchmarkStore) {
125
+ return c.json({ error: 'Database not available', status: 500 }, 500);
126
+ }
127
+ const tenantId = getTenantId(c);
128
+ // Parse query params
129
+ const statusRaw = c.req.query('status');
130
+ const agentId = c.req.query('agentId') || undefined;
131
+ const limitStr = c.req.query('limit');
132
+ const offsetStr = c.req.query('offset');
133
+ // Validate status
134
+ let status;
135
+ if (statusRaw) {
136
+ if (!VALID_STATUSES.has(statusRaw)) {
137
+ return c.json({ error: `Invalid status: ${statusRaw}`, status: 400 }, 400);
138
+ }
139
+ status = statusRaw;
140
+ }
141
+ // Validate limit (1-100, default 20)
142
+ let limit = 20;
143
+ if (limitStr !== undefined && limitStr !== '') {
144
+ const val = parseInt(limitStr, 10);
145
+ if (isNaN(val) || val < 1 || val > 100) {
146
+ return c.json({ error: 'limit must be an integer between 1 and 100', status: 400 }, 400);
147
+ }
148
+ limit = val;
149
+ }
150
+ // Validate offset
151
+ let offset = 0;
152
+ if (offsetStr !== undefined && offsetStr !== '') {
153
+ const val = parseInt(offsetStr, 10);
154
+ if (isNaN(val) || val < 0) {
155
+ return c.json({ error: 'offset must be a non-negative integer', status: 400 }, 400);
156
+ }
157
+ offset = val;
158
+ }
159
+ const filters = { status, agentId, limit, offset };
160
+ const { benchmarks, total } = benchmarkStore.list(tenantId, filters);
161
+ return c.json({
162
+ benchmarks,
163
+ total,
164
+ hasMore: offset + benchmarks.length < total,
165
+ });
166
+ });
167
+ // ─── GET /:id — Get benchmark detail ────────────────────
168
+ app.get('/:id', async (c) => {
169
+ const benchmarkStore = getBenchmarkStore(c);
170
+ if (!benchmarkStore) {
171
+ return c.json({ error: 'Database not available', status: 500 }, 500);
172
+ }
173
+ const tenantId = getTenantId(c);
174
+ const id = c.req.param('id');
175
+ const benchmark = benchmarkStore.getById(tenantId, id);
176
+ if (!benchmark) {
177
+ return c.json({ error: 'Benchmark not found', status: 404 }, 404);
178
+ }
179
+ // Enrich variants with session counts
180
+ const tenantStore = getTenantStore(store, c);
181
+ const variantsWithCounts = await Promise.all(benchmark.variants.map(async (v) => {
182
+ try {
183
+ const { total } = await tenantStore.querySessions({
184
+ tenantId: v.tenantId,
185
+ agentId: v.agentId,
186
+ tags: [v.tag],
187
+ from: benchmark.timeRange?.from,
188
+ to: benchmark.timeRange?.to,
189
+ limit: 1, // Minimal fetch — we only need the count
190
+ });
191
+ return { ...v, sessionCount: total };
192
+ }
193
+ catch {
194
+ return { ...v, sessionCount: 0 };
195
+ }
196
+ }));
197
+ return c.json({
198
+ ...benchmark,
199
+ variants: variantsWithCounts,
200
+ });
201
+ });
202
+ // ─── PUT /:id/status — Transition status ────────────────
203
+ app.put('/:id/status', async (c) => {
204
+ const benchmarkStore = getBenchmarkStore(c);
205
+ if (!benchmarkStore) {
206
+ return c.json({ error: 'Database not available', status: 500 }, 500);
207
+ }
208
+ const tenantId = getTenantId(c);
209
+ const id = c.req.param('id');
210
+ const body = await c.req.json().catch(() => null);
211
+ if (!body || !body.status) {
212
+ return c.json({ error: 'status is required', status: 400 }, 400);
213
+ }
214
+ if (!VALID_STATUSES.has(body.status)) {
215
+ return c.json({ error: `Invalid status: ${body.status}`, status: 400 }, 400);
216
+ }
217
+ const newStatus = body.status;
218
+ // Get current benchmark
219
+ const current = benchmarkStore.getById(tenantId, id);
220
+ if (!current) {
221
+ return c.json({ error: 'Benchmark not found', status: 404 }, 404);
222
+ }
223
+ // When transitioning to "running": validate ≥1 session per variant
224
+ if (newStatus === 'running') {
225
+ const tenantStore = getTenantStore(store, c);
226
+ for (const v of current.variants) {
227
+ const { sessions } = await tenantStore.querySessions({
228
+ tenantId: v.tenantId,
229
+ agentId: v.agentId,
230
+ tags: [v.tag],
231
+ from: current.timeRange?.from,
232
+ to: current.timeRange?.to,
233
+ limit: 1,
234
+ });
235
+ if (sessions.length === 0) {
236
+ return c.json({
237
+ error: `Variant "${v.name}" has no sessions. Each variant must have at least 1 session to start.`,
238
+ status: 409,
239
+ }, 409);
240
+ }
241
+ }
242
+ }
243
+ try {
244
+ const updated = benchmarkStore.updateStatus(tenantId, id, newStatus);
245
+ // When transitioning to "completed": compute and cache results
246
+ if (newStatus === 'completed') {
247
+ const tenantStore = getTenantStore(store, c);
248
+ await engine.computeResults(updated, tenantStore, benchmarkStore);
249
+ }
250
+ return c.json(updated);
251
+ }
252
+ catch (err) {
253
+ const message = err instanceof Error ? err.message : 'Failed to update status';
254
+ if (message.includes('Invalid status transition')) {
255
+ return c.json({ error: message, status: 409 }, 409);
256
+ }
257
+ return c.json({ error: message, status: 400 }, 400);
258
+ }
259
+ });
260
+ // ─── GET /:id/results — Get comparison results ──────────
261
+ app.get('/:id/results', async (c) => {
262
+ const benchmarkStore = getBenchmarkStore(c);
263
+ if (!benchmarkStore) {
264
+ return c.json({ error: 'Database not available', status: 500 }, 500);
265
+ }
266
+ const tenantId = getTenantId(c);
267
+ const id = c.req.param('id');
268
+ const benchmark = benchmarkStore.getById(tenantId, id);
269
+ if (!benchmark) {
270
+ return c.json({ error: 'Benchmark not found', status: 404 }, 404);
271
+ }
272
+ // Draft benchmarks can't have results
273
+ if (benchmark.status === 'draft') {
274
+ return c.json({ error: 'Cannot get results for a draft benchmark. Start it first.', status: 400 }, 400);
275
+ }
276
+ const tenantStore = getTenantStore(store, c);
277
+ const results = await engine.computeResults(benchmark, tenantStore, benchmarkStore);
278
+ // Strip distributions unless requested
279
+ const includeDistributions = c.req.query('includeDistributions') === 'true';
280
+ if (!includeDistributions) {
281
+ for (const v of results.variants) {
282
+ for (const key of Object.keys(v.metrics)) {
283
+ const stats = v.metrics[key];
284
+ if (stats) {
285
+ delete stats.values;
286
+ }
287
+ }
288
+ }
289
+ }
290
+ return c.json(results);
291
+ });
292
+ // ─── DELETE /:id — Delete benchmark ─────────────────────
293
+ app.delete('/:id', async (c) => {
294
+ const benchmarkStore = getBenchmarkStore(c);
295
+ if (!benchmarkStore) {
296
+ return c.json({ error: 'Database not available', status: 500 }, 500);
297
+ }
298
+ const tenantId = getTenantId(c);
299
+ const id = c.req.param('id');
300
+ const benchmark = benchmarkStore.getById(tenantId, id);
301
+ if (!benchmark) {
302
+ return c.json({ error: 'Benchmark not found', status: 404 }, 404);
303
+ }
304
+ if (benchmark.status === 'running' || benchmark.status === 'completed') {
305
+ return c.json({ error: `Cannot delete a ${benchmark.status} benchmark`, status: 409 }, 409);
306
+ }
307
+ benchmarkStore.delete(tenantId, id);
308
+ return c.body(null, 204);
309
+ });
310
+ return app;
311
+ }
312
+ //# sourceMappingURL=benchmarks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmarks.js","sourceRoot":"","sources":["../../src/routes/benchmarks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Guardrail REST API Routes (v0.8.0 — Stories 2.1, 2.2)
3
+ *
4
+ * POST /api/guardrails — Create rule
5
+ * GET /api/guardrails — List rules
6
+ * GET /api/guardrails/:id — Get rule
7
+ * PUT /api/guardrails/:id — Update rule
8
+ * DELETE /api/guardrails/:id — Delete rule
9
+ * GET /api/guardrails/:id/status — Get rule status + recent triggers
10
+ * GET /api/guardrails/history — List trigger history
11
+ */
12
+ import { Hono } from 'hono';
13
+ import type { AuthVariables } from '../middleware/auth.js';
14
+ import type { GuardrailStore } from '../db/guardrail-store.js';
15
+ export declare function guardrailRoutes(guardrailStore: GuardrailStore): Hono<{
16
+ Variables: AuthVariables;
17
+ }, import("hono/types").BlankSchema, "/">;
18
+ //# sourceMappingURL=guardrails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/routes/guardrails.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAsC/D,wBAAgB,eAAe,CAAC,cAAc,EAAE,cAAc;eAC1B,aAAa;0CA2JhD"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Guardrail REST API Routes (v0.8.0 — Stories 2.1, 2.2)
3
+ *
4
+ * POST /api/guardrails — Create rule
5
+ * GET /api/guardrails — List rules
6
+ * GET /api/guardrails/:id — Get rule
7
+ * PUT /api/guardrails/:id — Update rule
8
+ * DELETE /api/guardrails/:id — Delete rule
9
+ * GET /api/guardrails/:id/status — Get rule status + recent triggers
10
+ * GET /api/guardrails/history — List trigger history
11
+ */
12
+ import { Hono } from 'hono';
13
+ import { ulid } from 'ulid';
14
+ import { CreateGuardrailRuleSchema, UpdateGuardrailRuleSchema } from '@agentlensai/core';
15
+ /**
16
+ * Validate that conditionConfig contains required fields for the given condition type.
17
+ * Returns an error message string if invalid, or null if valid.
18
+ */
19
+ function validateConditionConfig(conditionType, config) {
20
+ switch (conditionType) {
21
+ case 'error_rate_threshold':
22
+ if (config.threshold !== undefined && (typeof config.threshold !== 'number' || config.threshold < 0 || config.threshold > 100)) {
23
+ return 'error_rate_threshold requires threshold to be a number between 0 and 100';
24
+ }
25
+ break;
26
+ case 'cost_limit':
27
+ if (config.maxCostUsd !== undefined && (typeof config.maxCostUsd !== 'number' || config.maxCostUsd < 0)) {
28
+ return 'cost_limit requires maxCostUsd to be a non-negative number';
29
+ }
30
+ if (config.scope !== undefined && config.scope !== 'session' && config.scope !== 'daily') {
31
+ return 'cost_limit scope must be "session" or "daily"';
32
+ }
33
+ break;
34
+ case 'health_score_threshold':
35
+ if (config.minScore !== undefined && (typeof config.minScore !== 'number' || config.minScore < 0 || config.minScore > 100)) {
36
+ return 'health_score_threshold requires minScore to be a number between 0 and 100';
37
+ }
38
+ break;
39
+ case 'custom_metric':
40
+ if (config.operator !== undefined) {
41
+ const validOps = ['gt', 'gte', 'lt', 'lte', 'eq'];
42
+ if (!validOps.includes(config.operator)) {
43
+ return `custom_metric operator must be one of: ${validOps.join(', ')}`;
44
+ }
45
+ }
46
+ break;
47
+ }
48
+ return null;
49
+ }
50
+ export function guardrailRoutes(guardrailStore) {
51
+ const app = new Hono();
52
+ // Helper to get tenant ID from auth
53
+ function getTenantId(c) {
54
+ const apiKeyInfo = c.get('apiKey');
55
+ return apiKeyInfo?.tenantId ?? 'default';
56
+ }
57
+ // POST / — Create guardrail rule
58
+ app.post('/', async (c) => {
59
+ const tenantId = getTenantId(c);
60
+ const rawBody = await c.req.json().catch(() => null);
61
+ if (!rawBody) {
62
+ return c.json({ error: 'Invalid JSON body', status: 400 }, 400);
63
+ }
64
+ const result = CreateGuardrailRuleSchema.safeParse(rawBody);
65
+ if (!result.success) {
66
+ return c.json({
67
+ error: 'Validation failed',
68
+ status: 400,
69
+ details: result.error.issues.map((i) => ({ path: i.path.join('.'), message: i.message })),
70
+ }, 400);
71
+ }
72
+ // H4: Validate that conditionConfig has required fields for the condition type
73
+ const configError = validateConditionConfig(result.data.conditionType, result.data.conditionConfig);
74
+ if (configError) {
75
+ return c.json({ error: 'Validation failed', status: 400, details: [{ path: 'conditionConfig', message: configError }] }, 400);
76
+ }
77
+ // H2: Validate webhook URL if action is notify_webhook
78
+ if (result.data.actionType === 'notify_webhook') {
79
+ const url = result.data.actionConfig?.url;
80
+ if (typeof url === 'string' && !/^https?:\/\//.test(url)) {
81
+ return c.json({ error: 'Validation failed', status: 400, details: [{ path: 'actionConfig.url', message: 'Webhook URL must start with http:// or https://' }] }, 400);
82
+ }
83
+ }
84
+ const now = new Date().toISOString();
85
+ const rule = {
86
+ id: ulid(),
87
+ tenantId,
88
+ ...result.data,
89
+ createdAt: now,
90
+ updatedAt: now,
91
+ };
92
+ guardrailStore.createRule(rule);
93
+ return c.json(rule, 201);
94
+ });
95
+ // GET / — List guardrail rules
96
+ app.get('/', async (c) => {
97
+ const tenantId = getTenantId(c);
98
+ const agentId = c.req.query('agentId');
99
+ const rules = guardrailStore.listRules(tenantId, agentId || undefined);
100
+ return c.json({ rules });
101
+ });
102
+ // GET /history — List trigger history (BEFORE :id routes to avoid route conflict)
103
+ app.get('/history', async (c) => {
104
+ const tenantId = getTenantId(c);
105
+ const ruleId = c.req.query('ruleId');
106
+ const limit = parseInt(c.req.query('limit') ?? '50', 10);
107
+ const offset = parseInt(c.req.query('offset') ?? '0', 10);
108
+ const { triggers, total } = guardrailStore.listTriggerHistory(tenantId, {
109
+ ruleId: ruleId || undefined,
110
+ limit: Math.min(Math.max(1, limit), 200),
111
+ offset: Math.max(0, offset),
112
+ });
113
+ return c.json({ triggers, total });
114
+ });
115
+ // GET /:id — Get single rule
116
+ app.get('/:id', async (c) => {
117
+ const tenantId = getTenantId(c);
118
+ const ruleId = c.req.param('id');
119
+ const rule = guardrailStore.getRule(tenantId, ruleId);
120
+ if (!rule) {
121
+ return c.json({ error: 'Guardrail rule not found', status: 404 }, 404);
122
+ }
123
+ return c.json(rule);
124
+ });
125
+ // PUT /:id — Update rule
126
+ app.put('/:id', async (c) => {
127
+ const tenantId = getTenantId(c);
128
+ const ruleId = c.req.param('id');
129
+ const rawBody = await c.req.json().catch(() => null);
130
+ if (!rawBody) {
131
+ return c.json({ error: 'Invalid JSON body', status: 400 }, 400);
132
+ }
133
+ const result = UpdateGuardrailRuleSchema.safeParse(rawBody);
134
+ if (!result.success) {
135
+ return c.json({
136
+ error: 'Validation failed',
137
+ status: 400,
138
+ details: result.error.issues.map((i) => ({ path: i.path.join('.'), message: i.message })),
139
+ }, 400);
140
+ }
141
+ // H2: Validate webhook URL if action is notify_webhook
142
+ if (result.data.actionType === 'notify_webhook') {
143
+ const url = result.data.actionConfig?.url;
144
+ if (typeof url === 'string' && !/^https?:\/\//.test(url)) {
145
+ return c.json({ error: 'Validation failed', status: 400, details: [{ path: 'actionConfig.url', message: 'Webhook URL must start with http:// or https://' }] }, 400);
146
+ }
147
+ }
148
+ // Handle null agentId (clearing scope)
149
+ const updates = { ...result.data };
150
+ if (updates.agentId === null) {
151
+ updates.agentId = undefined;
152
+ }
153
+ const updated = guardrailStore.updateRule(tenantId, ruleId, updates);
154
+ if (!updated) {
155
+ return c.json({ error: 'Guardrail rule not found', status: 404 }, 404);
156
+ }
157
+ const rule = guardrailStore.getRule(tenantId, ruleId);
158
+ return c.json(rule);
159
+ });
160
+ // DELETE /:id — Delete rule
161
+ app.delete('/:id', async (c) => {
162
+ const tenantId = getTenantId(c);
163
+ const ruleId = c.req.param('id');
164
+ const deleted = guardrailStore.deleteRule(tenantId, ruleId);
165
+ if (!deleted) {
166
+ return c.json({ error: 'Guardrail rule not found', status: 404 }, 404);
167
+ }
168
+ return c.json({ ok: true });
169
+ });
170
+ // GET /:id/status — Get rule status + recent triggers
171
+ app.get('/:id/status', async (c) => {
172
+ const tenantId = getTenantId(c);
173
+ const ruleId = c.req.param('id');
174
+ const rule = guardrailStore.getRule(tenantId, ruleId);
175
+ if (!rule) {
176
+ return c.json({ error: 'Guardrail rule not found', status: 404 }, 404);
177
+ }
178
+ const state = guardrailStore.getState(tenantId, ruleId);
179
+ const recentTriggers = guardrailStore.getRecentTriggers(tenantId, ruleId, 10);
180
+ return c.json({ rule, state, recentTriggers });
181
+ });
182
+ return app;
183
+ }
184
+ //# sourceMappingURL=guardrails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../src/routes/guardrails.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Replay REST Endpoint (Stories 2.2, 2.3)
3
+ *
4
+ * GET /api/sessions/:id/replay — Returns ReplayState for session replay UI.
5
+ *
6
+ * Supports pagination, event type filtering, and server-side LRU caching.
7
+ */
8
+ import { Hono } from 'hono';
9
+ import type { IEventStore, ReplayState } from '@agentlensai/core';
10
+ import type { AuthVariables } from '../middleware/auth.js';
11
+ interface CacheEntry {
12
+ state: ReplayState;
13
+ createdAt: number;
14
+ }
15
+ /** Simple Map-based LRU cache with TTL. Exported for testing. */
16
+ export declare const replayCache: Map<string, CacheEntry>;
17
+ /**
18
+ * Register the replay route directly on the provided Hono app.
19
+ * Path: GET /api/sessions/:id/replay
20
+ *
21
+ * Uses `registerReplayRoutes(app, store)` pattern (like health routes)
22
+ * since the path nests under /api/sessions which already has auth middleware.
23
+ */
24
+ export declare function registerReplayRoutes(app: Hono<{
25
+ Variables: AuthVariables;
26
+ }>, store: IEventStore): void;
27
+ export {};
28
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/routes/replay.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAU3D,UAAU,UAAU;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iEAAiE;AACjE,eAAO,MAAM,WAAW,yBAAgC,CAAC;AAmDzD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,IAAI,CAAC;IAAE,SAAS,EAAE,aAAa,CAAA;CAAE,CAAC,EACvC,KAAK,EAAE,WAAW,GACjB,IAAI,CAgGN"}