@agentlensai/server 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/db/embedding-store.d.ts +74 -0
- package/dist/db/embedding-store.d.ts.map +1 -0
- package/dist/db/embedding-store.js +177 -0
- package/dist/db/embedding-store.js.map +1 -0
- package/dist/db/lesson-store.d.ts +57 -0
- package/dist/db/lesson-store.d.ts.map +1 -0
- package/dist/db/lesson-store.js +217 -0
- package/dist/db/lesson-store.js.map +1 -0
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +250 -4
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.sqlite.d.ts +881 -55
- package/dist/db/schema.sqlite.d.ts.map +1 -1
- package/dist/db/schema.sqlite.js +82 -4
- package/dist/db/schema.sqlite.js.map +1 -1
- package/dist/db/session-summary-store.d.ts +45 -0
- package/dist/db/session-summary-store.d.ts.map +1 -0
- package/dist/db/session-summary-store.js +112 -0
- package/dist/db/session-summary-store.js.map +1 -0
- package/dist/db/sqlite-store.d.ts +25 -13
- package/dist/db/sqlite-store.d.ts.map +1 -1
- package/dist/db/sqlite-store.js +224 -47
- package/dist/db/sqlite-store.js.map +1 -1
- package/dist/db/tenant-scoped-store.d.ts +61 -0
- package/dist/db/tenant-scoped-store.d.ts.map +1 -0
- package/dist/db/tenant-scoped-store.js +94 -0
- package/dist/db/tenant-scoped-store.js.map +1 -0
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +99 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/alert-engine.d.ts +72 -0
- package/dist/lib/alert-engine.d.ts.map +1 -0
- package/dist/lib/alert-engine.js +318 -0
- package/dist/lib/alert-engine.js.map +1 -0
- package/dist/lib/analysis/cost-analysis.d.ts +20 -0
- package/dist/lib/analysis/cost-analysis.d.ts.map +1 -0
- package/dist/lib/analysis/cost-analysis.js +158 -0
- package/dist/lib/analysis/cost-analysis.js.map +1 -0
- package/dist/lib/analysis/error-patterns.d.ts +26 -0
- package/dist/lib/analysis/error-patterns.d.ts.map +1 -0
- package/dist/lib/analysis/error-patterns.js +155 -0
- package/dist/lib/analysis/error-patterns.js.map +1 -0
- package/dist/lib/analysis/index.d.ts +23 -0
- package/dist/lib/analysis/index.d.ts.map +1 -0
- package/dist/lib/analysis/index.js +144 -0
- package/dist/lib/analysis/index.js.map +1 -0
- package/dist/lib/analysis/performance-trends.d.ts +19 -0
- package/dist/lib/analysis/performance-trends.d.ts.map +1 -0
- package/dist/lib/analysis/performance-trends.js +118 -0
- package/dist/lib/analysis/performance-trends.js.map +1 -0
- package/dist/lib/analysis/tool-sequences.d.ts +19 -0
- package/dist/lib/analysis/tool-sequences.d.ts.map +1 -0
- package/dist/lib/analysis/tool-sequences.js +145 -0
- package/dist/lib/analysis/tool-sequences.js.map +1 -0
- package/dist/lib/context/index.d.ts +5 -0
- package/dist/lib/context/index.d.ts.map +1 -0
- package/dist/lib/context/index.js +5 -0
- package/dist/lib/context/index.js.map +1 -0
- package/dist/lib/context/retrieval.d.ts +56 -0
- package/dist/lib/context/retrieval.d.ts.map +1 -0
- package/dist/lib/context/retrieval.js +229 -0
- package/dist/lib/context/retrieval.js.map +1 -0
- package/dist/lib/embeddings/index.d.ts +31 -0
- package/dist/lib/embeddings/index.d.ts.map +1 -0
- package/dist/lib/embeddings/index.js +31 -0
- package/dist/lib/embeddings/index.js.map +1 -0
- package/dist/lib/embeddings/local.d.ts +15 -0
- package/dist/lib/embeddings/local.d.ts.map +1 -0
- package/dist/lib/embeddings/local.js +65 -0
- package/dist/lib/embeddings/local.js.map +1 -0
- package/dist/lib/embeddings/math.d.ts +13 -0
- package/dist/lib/embeddings/math.d.ts.map +1 -0
- package/dist/lib/embeddings/math.js +35 -0
- package/dist/lib/embeddings/math.js.map +1 -0
- package/dist/lib/embeddings/openai.d.ts +15 -0
- package/dist/lib/embeddings/openai.d.ts.map +1 -0
- package/dist/lib/embeddings/openai.js +58 -0
- package/dist/lib/embeddings/openai.js.map +1 -0
- package/dist/lib/embeddings/summarizer.d.ts +26 -0
- package/dist/lib/embeddings/summarizer.d.ts.map +1 -0
- package/dist/lib/embeddings/summarizer.js +181 -0
- package/dist/lib/embeddings/summarizer.js.map +1 -0
- package/dist/lib/embeddings/types.d.ts +17 -0
- package/dist/lib/embeddings/types.d.ts.map +1 -0
- package/dist/lib/embeddings/types.js +5 -0
- package/dist/lib/embeddings/types.js.map +1 -0
- package/dist/lib/embeddings/worker.d.ts +56 -0
- package/dist/lib/embeddings/worker.d.ts.map +1 -0
- package/dist/lib/embeddings/worker.js +109 -0
- package/dist/lib/embeddings/worker.js.map +1 -0
- package/dist/lib/event-bus.d.ts +48 -0
- package/dist/lib/event-bus.d.ts.map +1 -0
- package/dist/lib/event-bus.js +34 -0
- package/dist/lib/event-bus.js.map +1 -0
- package/dist/lib/retention.d.ts +1 -1
- package/dist/lib/retention.d.ts.map +1 -1
- package/dist/lib/sse.d.ts +22 -0
- package/dist/lib/sse.d.ts.map +1 -0
- package/dist/lib/sse.js +121 -0
- package/dist/lib/sse.js.map +1 -0
- package/dist/middleware/auth.d.ts +1 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +2 -1
- package/dist/middleware/auth.js.map +1 -1
- package/dist/routes/agents.d.ts +1 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +6 -3
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/alerts.d.ts +17 -0
- package/dist/routes/alerts.d.ts.map +1 -0
- package/dist/routes/alerts.js +141 -0
- package/dist/routes/alerts.js.map +1 -0
- package/dist/routes/analytics.d.ts +16 -0
- package/dist/routes/analytics.d.ts.map +1 -0
- package/dist/routes/analytics.js +307 -0
- package/dist/routes/analytics.js.map +1 -0
- package/dist/routes/api-keys.d.ts.map +1 -1
- package/dist/routes/api-keys.js +30 -5
- package/dist/routes/api-keys.js.map +1 -1
- package/dist/routes/config.d.ts +5 -0
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +27 -7
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/context.d.ts +23 -0
- package/dist/routes/context.d.ts.map +1 -0
- package/dist/routes/context.js +52 -0
- package/dist/routes/context.js.map +1 -0
- package/dist/routes/events.d.ts +7 -2
- package/dist/routes/events.d.ts.map +1 -1
- package/dist/routes/events.js +76 -8
- package/dist/routes/events.js.map +1 -1
- package/dist/routes/ingest.d.ts +36 -0
- package/dist/routes/ingest.d.ts.map +1 -0
- package/dist/routes/ingest.js +280 -0
- package/dist/routes/ingest.js.map +1 -0
- package/dist/routes/lessons.d.ts +19 -0
- package/dist/routes/lessons.d.ts.map +1 -0
- package/dist/routes/lessons.js +164 -0
- package/dist/routes/lessons.js.map +1 -0
- package/dist/routes/recall.d.ts +20 -0
- package/dist/routes/recall.d.ts.map +1 -0
- package/dist/routes/recall.js +71 -0
- package/dist/routes/recall.js.map +1 -0
- package/dist/routes/reflect.d.ts +15 -0
- package/dist/routes/reflect.d.ts.map +1 -0
- package/dist/routes/reflect.js +55 -0
- package/dist/routes/reflect.js.map +1 -0
- package/dist/routes/sessions.d.ts +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +9 -7
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/stats.d.ts +1 -1
- package/dist/routes/stats.d.ts.map +1 -1
- package/dist/routes/stats.js +3 -1
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/stream.d.ts +23 -0
- package/dist/routes/stream.d.ts.map +1 -0
- package/dist/routes/stream.js +94 -0
- package/dist/routes/stream.js.map +1 -0
- package/dist/routes/tenant-helper.d.ts +20 -0
- package/dist/routes/tenant-helper.d.ts.map +1 -0
- package/dist/routes/tenant-helper.js +23 -0
- package/dist/routes/tenant-helper.js.map +1 -0
- package/package.json +11 -11
- package/LICENSE +0 -21
- package/dist/__tests__/agents-stats.test.d.ts +0 -5
- package/dist/__tests__/agents-stats.test.d.ts.map +0 -1
- package/dist/__tests__/agents-stats.test.js +0 -134
- package/dist/__tests__/agents-stats.test.js.map +0 -1
- package/dist/__tests__/api-keys.test.d.ts +0 -5
- package/dist/__tests__/api-keys.test.d.ts.map +0 -1
- package/dist/__tests__/api-keys.test.js +0 -118
- package/dist/__tests__/api-keys.test.js.map +0 -1
- package/dist/__tests__/auth-no-db.test.d.ts +0 -2
- package/dist/__tests__/auth-no-db.test.d.ts.map +0 -1
- package/dist/__tests__/auth-no-db.test.js +0 -43
- package/dist/__tests__/auth-no-db.test.js.map +0 -1
- package/dist/__tests__/auth.test.d.ts +0 -5
- package/dist/__tests__/auth.test.d.ts.map +0 -1
- package/dist/__tests__/auth.test.js +0 -86
- package/dist/__tests__/auth.test.js.map +0 -1
- package/dist/__tests__/config.test.d.ts +0 -2
- package/dist/__tests__/config.test.d.ts.map +0 -1
- package/dist/__tests__/config.test.js +0 -37
- package/dist/__tests__/config.test.js.map +0 -1
- package/dist/__tests__/events-ingest.test.d.ts +0 -5
- package/dist/__tests__/events-ingest.test.d.ts.map +0 -1
- package/dist/__tests__/events-ingest.test.js +0 -248
- package/dist/__tests__/events-ingest.test.js.map +0 -1
- package/dist/__tests__/events-query.test.d.ts +0 -5
- package/dist/__tests__/events-query.test.d.ts.map +0 -1
- package/dist/__tests__/events-query.test.js +0 -205
- package/dist/__tests__/events-query.test.js.map +0 -1
- package/dist/__tests__/health.test.d.ts +0 -5
- package/dist/__tests__/health.test.d.ts.map +0 -1
- package/dist/__tests__/health.test.js +0 -40
- package/dist/__tests__/health.test.js.map +0 -1
- package/dist/__tests__/sessions.test.d.ts +0 -5
- package/dist/__tests__/sessions.test.d.ts.map +0 -1
- package/dist/__tests__/sessions.test.js +0 -176
- package/dist/__tests__/sessions.test.js.map +0 -1
- package/dist/__tests__/test-helpers.d.ts +0 -24
- package/dist/__tests__/test-helpers.d.ts.map +0 -1
- package/dist/__tests__/test-helpers.js +0 -45
- package/dist/__tests__/test-helpers.js.map +0 -1
- package/dist/db/__tests__/init.test.d.ts +0 -2
- package/dist/db/__tests__/init.test.d.ts.map +0 -1
- package/dist/db/__tests__/init.test.js +0 -73
- package/dist/db/__tests__/init.test.js.map +0 -1
- package/dist/db/__tests__/sqlite-store-read.test.d.ts +0 -2
- package/dist/db/__tests__/sqlite-store-read.test.d.ts.map +0 -1
- package/dist/db/__tests__/sqlite-store-read.test.js +0 -749
- package/dist/db/__tests__/sqlite-store-read.test.js.map +0 -1
- package/dist/db/__tests__/sqlite-store-write.test.d.ts +0 -2
- package/dist/db/__tests__/sqlite-store-write.test.d.ts.map +0 -1
- package/dist/db/__tests__/sqlite-store-write.test.js +0 -418
- package/dist/db/__tests__/sqlite-store-write.test.js.map +0 -1
- package/dist/lib/__tests__/retention.test.d.ts +0 -2
- package/dist/lib/__tests__/retention.test.d.ts.map +0 -1
- package/dist/lib/__tests__/retention.test.js +0 -238
- package/dist/lib/__tests__/retention.test.js.map +0 -1
package/dist/routes/events.d.ts
CHANGED
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
* GET /api/events/:id — get single event
|
|
7
7
|
*/
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
|
-
import type { IEventStore } from '@
|
|
9
|
+
import type { IEventStore } from '@agentlensai/core';
|
|
10
10
|
import type { AuthVariables } from '../middleware/auth.js';
|
|
11
|
-
|
|
11
|
+
import type { EmbeddingWorker } from '../lib/embeddings/worker.js';
|
|
12
|
+
import type { SessionSummaryStore } from '../db/session-summary-store.js';
|
|
13
|
+
export declare function eventsRoutes(store: IEventStore, deps?: {
|
|
14
|
+
embeddingWorker: EmbeddingWorker | null;
|
|
15
|
+
sessionSummaryStore?: SessionSummaryStore | null;
|
|
16
|
+
}): Hono<{
|
|
12
17
|
Variables: AuthVariables;
|
|
13
18
|
}, import("hono/types").BlankSchema, "/">;
|
|
14
19
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAO1E,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,EAClB,IAAI,CAAC,EAAE;IACL,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAClD;eAEiC,aAAa;0CA0PhD"}
|
package/dist/routes/events.js
CHANGED
|
@@ -8,15 +8,19 @@
|
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
9
|
import { ulid } from 'ulid';
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import { ingestEventSchema, computeEventHash, truncatePayload, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, } from '@
|
|
11
|
+
import { ingestEventSchema, computeEventHash, truncatePayload, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, } from '@agentlensai/core';
|
|
12
|
+
import { eventBus } from '../lib/event-bus.js';
|
|
13
|
+
import { getTenantStore } from './tenant-helper.js';
|
|
14
|
+
import { summarizeEvent, summarizeSession } from '../lib/embeddings/summarizer.js';
|
|
12
15
|
/** Schema for the batch ingestion request body */
|
|
13
16
|
const ingestBatchSchema = z.object({
|
|
14
17
|
events: z.array(ingestEventSchema).min(1).max(1000),
|
|
15
18
|
});
|
|
16
|
-
export function eventsRoutes(store) {
|
|
19
|
+
export function eventsRoutes(store, deps) {
|
|
17
20
|
const app = new Hono();
|
|
18
21
|
// POST /api/events — ingest events
|
|
19
22
|
app.post('/', async (c) => {
|
|
23
|
+
const tenantStore = getTenantStore(store, c);
|
|
20
24
|
const rawBody = await c.req.json().catch(() => null);
|
|
21
25
|
if (!rawBody) {
|
|
22
26
|
return c.json({ error: 'Invalid JSON body', status: 400 }, 400);
|
|
@@ -43,9 +47,8 @@ export function eventsRoutes(store) {
|
|
|
43
47
|
const allProcessed = [];
|
|
44
48
|
// Phase 1: Build all events (validate and compute hashes) without writing
|
|
45
49
|
for (const [sessionId, sessionEvents] of bySession) {
|
|
46
|
-
// Get the last event hash for this session to chain from
|
|
47
|
-
|
|
48
|
-
let prevHash = timeline.length > 0 ? timeline[timeline.length - 1].hash : null;
|
|
50
|
+
// Get the last event hash for this session to chain from (optimized)
|
|
51
|
+
let prevHash = await tenantStore.getLastEventHash(sessionId);
|
|
49
52
|
for (const input of sessionEvents) {
|
|
50
53
|
const id = ulid();
|
|
51
54
|
const timestamp = input.timestamp ?? new Date().toISOString();
|
|
@@ -74,6 +77,7 @@ export function eventsRoutes(store) {
|
|
|
74
77
|
metadata,
|
|
75
78
|
prevHash,
|
|
76
79
|
hash,
|
|
80
|
+
tenantId: 'default',
|
|
77
81
|
};
|
|
78
82
|
allProcessed.push(event);
|
|
79
83
|
prevHash = hash;
|
|
@@ -91,7 +95,7 @@ export function eventsRoutes(store) {
|
|
|
91
95
|
}
|
|
92
96
|
try {
|
|
93
97
|
for (const [, sessionProcessed] of sessionGroups) {
|
|
94
|
-
await
|
|
98
|
+
await tenantStore.insertEvents(sessionProcessed);
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
catch (error) {
|
|
@@ -99,6 +103,68 @@ export function eventsRoutes(store) {
|
|
|
99
103
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
100
104
|
return c.json({ error: `Batch insert failed: ${message}`, status: 500 }, 500);
|
|
101
105
|
}
|
|
106
|
+
// Emit events to EventBus for SSE fan-out (async, non-blocking)
|
|
107
|
+
const now = new Date().toISOString();
|
|
108
|
+
for (const event of allProcessed) {
|
|
109
|
+
eventBus.emit({ type: 'event_ingested', event, timestamp: now });
|
|
110
|
+
}
|
|
111
|
+
// Enqueue embeddable events for background embedding
|
|
112
|
+
const worker = deps?.embeddingWorker;
|
|
113
|
+
if (worker) {
|
|
114
|
+
const tenantId = allProcessed[0]?.tenantId ?? 'default';
|
|
115
|
+
for (const event of allProcessed) {
|
|
116
|
+
try {
|
|
117
|
+
const text = summarizeEvent(event);
|
|
118
|
+
if (text) {
|
|
119
|
+
worker.enqueue({
|
|
120
|
+
tenantId,
|
|
121
|
+
sourceType: 'event',
|
|
122
|
+
sourceId: event.id,
|
|
123
|
+
textContent: text,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Never crash on embedding failures
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Emit session updates for affected sessions
|
|
133
|
+
const affectedSessionIds = new Set(allProcessed.map((e) => e.sessionId));
|
|
134
|
+
for (const sessionId of affectedSessionIds) {
|
|
135
|
+
const session = await tenantStore.getSession(sessionId);
|
|
136
|
+
if (session) {
|
|
137
|
+
eventBus.emit({ type: 'session_updated', session, timestamp: now });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Generate session summaries for sessions that just ended (fail-safe)
|
|
141
|
+
const summaryStore = deps?.sessionSummaryStore;
|
|
142
|
+
if (summaryStore) {
|
|
143
|
+
const endedEvents = allProcessed.filter((e) => e.eventType === 'session_ended');
|
|
144
|
+
for (const endedEvent of endedEvents) {
|
|
145
|
+
try {
|
|
146
|
+
const session = await tenantStore.getSession(endedEvent.sessionId);
|
|
147
|
+
if (!session)
|
|
148
|
+
continue;
|
|
149
|
+
const timeline = await tenantStore.getSessionTimeline(endedEvent.sessionId);
|
|
150
|
+
const summaryResult = summarizeSession(session, timeline);
|
|
151
|
+
summaryStore.save(endedEvent.tenantId, endedEvent.sessionId, summaryResult.summary, summaryResult.topics, summaryResult.toolSequence, summaryResult.errorSummary || null, summaryResult.outcome);
|
|
152
|
+
// Enqueue the summary for embedding
|
|
153
|
+
if (worker) {
|
|
154
|
+
worker.enqueue({
|
|
155
|
+
tenantId: endedEvent.tenantId,
|
|
156
|
+
sourceType: 'session',
|
|
157
|
+
sourceId: endedEvent.sessionId,
|
|
158
|
+
textContent: summaryResult.summary,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Fail-safe: log and continue — never block event ingest
|
|
164
|
+
console.error(`[events] Failed to generate session summary for ${endedEvent.sessionId}:`, err instanceof Error ? err.message : err);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
102
168
|
return c.json({
|
|
103
169
|
ingested: allProcessed.length,
|
|
104
170
|
events: allProcessed.map((e) => ({ id: e.id, hash: e.hash })),
|
|
@@ -106,6 +172,7 @@ export function eventsRoutes(store) {
|
|
|
106
172
|
});
|
|
107
173
|
// GET /api/events — query events
|
|
108
174
|
app.get('/', async (c) => {
|
|
175
|
+
const tenantStore = getTenantStore(store, c);
|
|
109
176
|
const query = {};
|
|
110
177
|
const sessionId = c.req.query('sessionId');
|
|
111
178
|
if (sessionId)
|
|
@@ -143,7 +210,7 @@ export function eventsRoutes(store) {
|
|
|
143
210
|
const order = c.req.query('order');
|
|
144
211
|
if (order === 'asc' || order === 'desc')
|
|
145
212
|
query.order = order;
|
|
146
|
-
const result = await
|
|
213
|
+
const result = await tenantStore.queryEvents(query);
|
|
147
214
|
return c.json({
|
|
148
215
|
events: result.events,
|
|
149
216
|
total: result.total,
|
|
@@ -152,8 +219,9 @@ export function eventsRoutes(store) {
|
|
|
152
219
|
});
|
|
153
220
|
// GET /api/events/:id — single event
|
|
154
221
|
app.get('/:id', async (c) => {
|
|
222
|
+
const tenantStore = getTenantStore(store, c);
|
|
155
223
|
const id = c.req.param('id');
|
|
156
|
-
const event = await
|
|
224
|
+
const event = await tenantStore.getEvent(id);
|
|
157
225
|
if (!event) {
|
|
158
226
|
return c.json({ error: 'Event not found', status: 404 }, 404);
|
|
159
227
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/routes/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Ingestion Endpoint (Stories 9.1, 10.1, 10.2, 10.3)
|
|
3
|
+
*
|
|
4
|
+
* POST /api/events/ingest — receives webhooks from AgentGate, FormBridge, or generic sources.
|
|
5
|
+
*
|
|
6
|
+
* Each source is verified using HMAC-SHA256 with a per-source secret.
|
|
7
|
+
* Events are mapped to AgentLens event types and persisted via the standard pipeline.
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from 'hono';
|
|
10
|
+
import type { IEventStore } from '@agentlensai/core';
|
|
11
|
+
export type WebhookSource = 'agentgate' | 'formbridge' | 'generic';
|
|
12
|
+
export interface WebhookPayload {
|
|
13
|
+
source: WebhookSource;
|
|
14
|
+
event: string;
|
|
15
|
+
data: Record<string, unknown>;
|
|
16
|
+
timestamp?: string;
|
|
17
|
+
context?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface IngestConfig {
|
|
20
|
+
/** HMAC secret for AgentGate webhooks */
|
|
21
|
+
agentgateWebhookSecret?: string;
|
|
22
|
+
/** HMAC secret for FormBridge webhooks */
|
|
23
|
+
formbridgeWebhookSecret?: string;
|
|
24
|
+
/** Tenant ID for AgentGate webhooks (defaults to 'default') */
|
|
25
|
+
agentgateTenantId?: string;
|
|
26
|
+
/** Tenant ID for FormBridge webhooks (defaults to 'default') */
|
|
27
|
+
formbridgeTenantId?: string;
|
|
28
|
+
/** Tenant ID for generic webhooks (defaults to 'default') */
|
|
29
|
+
genericTenantId?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Verify HMAC-SHA256 webhook signature using timing-safe comparison.
|
|
33
|
+
*/
|
|
34
|
+
export declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
|
|
35
|
+
export declare function ingestRoutes(store: IEventStore, config: IngestConfig): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
36
|
+
//# sourceMappingURL=ingest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/routes/ingest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAc5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0CAA0C;IAC1C,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAWT;AA4JD,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,8EA0JpE"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Ingestion Endpoint (Stories 9.1, 10.1, 10.2, 10.3)
|
|
3
|
+
*
|
|
4
|
+
* POST /api/events/ingest — receives webhooks from AgentGate, FormBridge, or generic sources.
|
|
5
|
+
*
|
|
6
|
+
* Each source is verified using HMAC-SHA256 with a per-source secret.
|
|
7
|
+
* Events are mapped to AgentLens event types and persisted via the standard pipeline.
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from 'hono';
|
|
10
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
11
|
+
import { ulid } from 'ulid';
|
|
12
|
+
import { computeEventHash, truncatePayload } from '@agentlensai/core';
|
|
13
|
+
import { TenantScopedStore } from '../db/tenant-scoped-store.js';
|
|
14
|
+
import { eventBus } from '../lib/event-bus.js';
|
|
15
|
+
// ─── Signature Verification ─────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* Verify HMAC-SHA256 webhook signature using timing-safe comparison.
|
|
18
|
+
*/
|
|
19
|
+
export function verifyWebhookSignature(payload, signature, secret) {
|
|
20
|
+
if (!signature || !secret)
|
|
21
|
+
return false;
|
|
22
|
+
const expected = createHmac('sha256', secret).update(payload).digest('hex');
|
|
23
|
+
// Ensure buffers are equal length for timingSafeEqual
|
|
24
|
+
const sigBuf = Buffer.from(signature, 'utf8');
|
|
25
|
+
const expBuf = Buffer.from(expected, 'utf8');
|
|
26
|
+
if (sigBuf.length !== expBuf.length)
|
|
27
|
+
return false;
|
|
28
|
+
return timingSafeEqual(sigBuf, expBuf);
|
|
29
|
+
}
|
|
30
|
+
// ─── AgentGate Event Mapping ────────────────────────────────────────
|
|
31
|
+
const AGENTGATE_EVENT_MAP = {
|
|
32
|
+
'request.created': 'approval_requested',
|
|
33
|
+
'request.approved': 'approval_granted',
|
|
34
|
+
'request.denied': 'approval_denied',
|
|
35
|
+
'request.expired': 'approval_expired',
|
|
36
|
+
};
|
|
37
|
+
function mapAgentGateEvent(webhookEvent, data) {
|
|
38
|
+
const eventType = AGENTGATE_EVENT_MAP[webhookEvent];
|
|
39
|
+
if (!eventType)
|
|
40
|
+
return null;
|
|
41
|
+
if (eventType === 'approval_requested') {
|
|
42
|
+
const payload = {
|
|
43
|
+
requestId: String(data['requestId'] ?? data['id'] ?? ''),
|
|
44
|
+
action: String(data['action'] ?? ''),
|
|
45
|
+
params: data['params'] ?? {},
|
|
46
|
+
urgency: String(data['urgency'] ?? 'normal'),
|
|
47
|
+
};
|
|
48
|
+
return { eventType, payload };
|
|
49
|
+
}
|
|
50
|
+
// approval_granted, approval_denied, approval_expired
|
|
51
|
+
const payload = {
|
|
52
|
+
requestId: String(data['requestId'] ?? data['id'] ?? ''),
|
|
53
|
+
action: String(data['action'] ?? ''),
|
|
54
|
+
decidedBy: String(data['decidedBy'] ?? data['approvedBy'] ?? data['deniedBy'] ?? 'system'),
|
|
55
|
+
reason: data['reason'] ? String(data['reason']) : undefined,
|
|
56
|
+
};
|
|
57
|
+
return { eventType, payload };
|
|
58
|
+
}
|
|
59
|
+
// ─── FormBridge Event Mapping (Story 10.2) ──────────────────────────
|
|
60
|
+
const FORMBRIDGE_EVENT_MAP = {
|
|
61
|
+
'submission.created': 'form_submitted',
|
|
62
|
+
'submission.completed': 'form_completed',
|
|
63
|
+
'submission.expired': 'form_expired',
|
|
64
|
+
};
|
|
65
|
+
function mapFormBridgeEvent(webhookEvent, data) {
|
|
66
|
+
const eventType = FORMBRIDGE_EVENT_MAP[webhookEvent];
|
|
67
|
+
if (!eventType)
|
|
68
|
+
return null;
|
|
69
|
+
if (eventType === 'form_submitted') {
|
|
70
|
+
const payload = {
|
|
71
|
+
submissionId: String(data['submissionId'] ?? data['id'] ?? ''),
|
|
72
|
+
formId: String(data['formId'] ?? ''),
|
|
73
|
+
formName: data['formName'] ? String(data['formName']) : undefined,
|
|
74
|
+
fieldCount: typeof data['fieldCount'] === 'number' ? data['fieldCount'] : 0,
|
|
75
|
+
};
|
|
76
|
+
return { eventType, payload };
|
|
77
|
+
}
|
|
78
|
+
if (eventType === 'form_completed') {
|
|
79
|
+
const payload = {
|
|
80
|
+
submissionId: String(data['submissionId'] ?? data['id'] ?? ''),
|
|
81
|
+
formId: String(data['formId'] ?? ''),
|
|
82
|
+
completedBy: String(data['completedBy'] ?? 'unknown'),
|
|
83
|
+
durationMs: typeof data['durationMs'] === 'number' ? data['durationMs'] : 0,
|
|
84
|
+
};
|
|
85
|
+
return { eventType, payload };
|
|
86
|
+
}
|
|
87
|
+
if (eventType === 'form_expired') {
|
|
88
|
+
const payload = {
|
|
89
|
+
submissionId: String(data['submissionId'] ?? data['id'] ?? ''),
|
|
90
|
+
formId: String(data['formId'] ?? ''),
|
|
91
|
+
expiredAfterMs: typeof data['expiredAfterMs'] === 'number' ? data['expiredAfterMs'] : 0,
|
|
92
|
+
};
|
|
93
|
+
return { eventType, payload };
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
// ─── Generic Event Mapping ──────────────────────────────────────────
|
|
98
|
+
function mapGenericEvent(data) {
|
|
99
|
+
return {
|
|
100
|
+
eventType: data['eventType'] ?? 'custom',
|
|
101
|
+
payload: {
|
|
102
|
+
type: String(data['type'] ?? 'generic'),
|
|
103
|
+
data: data['data'] ?? data,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// ─── Session Correlation (Story 10.3) ───────────────────────────────
|
|
108
|
+
/**
|
|
109
|
+
* Extract session ID and agent ID from webhook context.
|
|
110
|
+
* Falls back to generating an unlinked session ID if not present.
|
|
111
|
+
*/
|
|
112
|
+
function extractCorrelation(context) {
|
|
113
|
+
const sessionId = context?.['agentlens_session_id']
|
|
114
|
+
? String(context['agentlens_session_id'])
|
|
115
|
+
: `unlinked_${ulid()}`;
|
|
116
|
+
const agentId = context?.['agentlens_agent_id']
|
|
117
|
+
? String(context['agentlens_agent_id'])
|
|
118
|
+
: context?.['agent_id']
|
|
119
|
+
? String(context['agent_id'])
|
|
120
|
+
: 'external';
|
|
121
|
+
return { sessionId, agentId };
|
|
122
|
+
}
|
|
123
|
+
// ─── Secret Resolver ────────────────────────────────────────────────
|
|
124
|
+
function getSecretForSource(source, config) {
|
|
125
|
+
switch (source) {
|
|
126
|
+
case 'agentgate':
|
|
127
|
+
return config.agentgateWebhookSecret;
|
|
128
|
+
case 'formbridge':
|
|
129
|
+
return config.formbridgeWebhookSecret;
|
|
130
|
+
case 'generic':
|
|
131
|
+
return undefined; // Generic webhooks don't require HMAC
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// ─── Tenant Resolver ────────────────────────────────────────────────
|
|
135
|
+
function getTenantIdForSource(source, config) {
|
|
136
|
+
switch (source) {
|
|
137
|
+
case 'agentgate':
|
|
138
|
+
return config.agentgateTenantId ?? 'default';
|
|
139
|
+
case 'formbridge':
|
|
140
|
+
return config.formbridgeTenantId ?? 'default';
|
|
141
|
+
case 'generic':
|
|
142
|
+
return config.genericTenantId ?? 'default';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// ─── Route Factory ──────────────────────────────────────────────────
|
|
146
|
+
export function ingestRoutes(store, config) {
|
|
147
|
+
const app = new Hono();
|
|
148
|
+
// Cast to SqliteEventStore for TenantScopedStore wrapping.
|
|
149
|
+
// IEventStore is the interface but we need the concrete type for the tenant wrapper.
|
|
150
|
+
const innerStore = store;
|
|
151
|
+
/**
|
|
152
|
+
* POST /api/events/ingest — Webhook ingestion endpoint.
|
|
153
|
+
*
|
|
154
|
+
* Accepts JSON body with:
|
|
155
|
+
* source: 'agentgate' | 'formbridge' | 'generic'
|
|
156
|
+
* event: source-specific event name
|
|
157
|
+
* data: event payload
|
|
158
|
+
* timestamp?: ISO 8601
|
|
159
|
+
* context?: { agentlens_session_id?, agentlens_agent_id?, ... }
|
|
160
|
+
*
|
|
161
|
+
* Signature header: X-Webhook-Signature (HMAC-SHA256 hex)
|
|
162
|
+
*/
|
|
163
|
+
app.post('/', async (c) => {
|
|
164
|
+
// Read raw body for signature verification
|
|
165
|
+
const rawBody = await c.req.text();
|
|
166
|
+
let body;
|
|
167
|
+
try {
|
|
168
|
+
body = JSON.parse(rawBody);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return c.json({ error: 'Invalid JSON body', status: 400 }, 400);
|
|
172
|
+
}
|
|
173
|
+
// Validate source
|
|
174
|
+
const source = body.source;
|
|
175
|
+
if (!source || !['agentgate', 'formbridge', 'generic'].includes(source)) {
|
|
176
|
+
return c.json({
|
|
177
|
+
error: 'Invalid or missing source. Expected: agentgate, formbridge, or generic',
|
|
178
|
+
status: 400,
|
|
179
|
+
}, 400);
|
|
180
|
+
}
|
|
181
|
+
// Verify signature for agentgate/formbridge
|
|
182
|
+
const secret = getSecretForSource(source, config);
|
|
183
|
+
if (source !== 'generic') {
|
|
184
|
+
if (!secret) {
|
|
185
|
+
return c.json({
|
|
186
|
+
error: `Webhook secret not configured for source: ${source}`,
|
|
187
|
+
status: 500,
|
|
188
|
+
}, 500);
|
|
189
|
+
}
|
|
190
|
+
const signature = c.req.header('X-Webhook-Signature') ?? '';
|
|
191
|
+
if (!verifyWebhookSignature(rawBody, signature, secret)) {
|
|
192
|
+
return c.json({ error: 'Invalid webhook signature', status: 401 }, 401);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Validate required fields
|
|
196
|
+
if (!body.event) {
|
|
197
|
+
return c.json({ error: 'Missing event field', status: 400 }, 400);
|
|
198
|
+
}
|
|
199
|
+
if (!body.data || typeof body.data !== 'object') {
|
|
200
|
+
return c.json({ error: 'Missing or invalid data field', status: 400 }, 400);
|
|
201
|
+
}
|
|
202
|
+
// Map webhook event to AgentLens event
|
|
203
|
+
let mapped = null;
|
|
204
|
+
switch (source) {
|
|
205
|
+
case 'agentgate':
|
|
206
|
+
mapped = mapAgentGateEvent(body.event, body.data);
|
|
207
|
+
break;
|
|
208
|
+
case 'formbridge':
|
|
209
|
+
mapped = mapFormBridgeEvent(body.event, body.data);
|
|
210
|
+
break;
|
|
211
|
+
case 'generic':
|
|
212
|
+
mapped = mapGenericEvent(body.data);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
if (!mapped) {
|
|
216
|
+
return c.json({
|
|
217
|
+
error: `Unknown event type '${body.event}' for source '${source}'`,
|
|
218
|
+
status: 400,
|
|
219
|
+
}, 400);
|
|
220
|
+
}
|
|
221
|
+
// Resolve tenant ID from webhook source configuration
|
|
222
|
+
const tenantId = getTenantIdForSource(source, config);
|
|
223
|
+
const tenantStore = new TenantScopedStore(innerStore, tenantId);
|
|
224
|
+
// Extract session/agent correlation
|
|
225
|
+
const { sessionId, agentId } = extractCorrelation(body.context);
|
|
226
|
+
// Build the AgentLens event
|
|
227
|
+
const id = ulid();
|
|
228
|
+
const timestamp = body.timestamp ?? new Date().toISOString();
|
|
229
|
+
const metadata = {
|
|
230
|
+
source,
|
|
231
|
+
webhookEvent: body.event,
|
|
232
|
+
...(body.context ?? {}),
|
|
233
|
+
};
|
|
234
|
+
// Get last hash for session chain (optimized — only fetches last event's hash)
|
|
235
|
+
const prevHash = await tenantStore.getLastEventHash(sessionId);
|
|
236
|
+
const payload = truncatePayload(mapped.payload);
|
|
237
|
+
const hash = computeEventHash({
|
|
238
|
+
id,
|
|
239
|
+
timestamp,
|
|
240
|
+
sessionId,
|
|
241
|
+
agentId,
|
|
242
|
+
eventType: mapped.eventType,
|
|
243
|
+
severity: 'info',
|
|
244
|
+
payload,
|
|
245
|
+
metadata,
|
|
246
|
+
prevHash,
|
|
247
|
+
});
|
|
248
|
+
const event = {
|
|
249
|
+
id,
|
|
250
|
+
timestamp,
|
|
251
|
+
sessionId,
|
|
252
|
+
agentId,
|
|
253
|
+
eventType: mapped.eventType,
|
|
254
|
+
severity: 'info',
|
|
255
|
+
payload,
|
|
256
|
+
metadata,
|
|
257
|
+
prevHash,
|
|
258
|
+
hash,
|
|
259
|
+
tenantId,
|
|
260
|
+
};
|
|
261
|
+
// Persist via tenant-scoped store (stamps tenantId on insert)
|
|
262
|
+
await tenantStore.insertEvents([event]);
|
|
263
|
+
// Emit to EventBus for SSE fan-out (async, non-blocking)
|
|
264
|
+
const emitTimestamp = new Date().toISOString();
|
|
265
|
+
eventBus.emit({ type: 'event_ingested', event, timestamp: emitTimestamp });
|
|
266
|
+
// Emit session update
|
|
267
|
+
const updatedSession = await tenantStore.getSession(sessionId);
|
|
268
|
+
if (updatedSession) {
|
|
269
|
+
eventBus.emit({ type: 'session_updated', session: updatedSession, timestamp: emitTimestamp });
|
|
270
|
+
}
|
|
271
|
+
return c.json({
|
|
272
|
+
ok: true,
|
|
273
|
+
eventId: event.id,
|
|
274
|
+
eventType: event.eventType,
|
|
275
|
+
sessionId,
|
|
276
|
+
}, 201);
|
|
277
|
+
});
|
|
278
|
+
return app;
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/routes/ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lessons REST Endpoints (Story 3.2)
|
|
3
|
+
*
|
|
4
|
+
* POST /api/lessons — Create lesson
|
|
5
|
+
* GET /api/lessons — List lessons with filters
|
|
6
|
+
* GET /api/lessons/:id — Get single lesson (increments access_count)
|
|
7
|
+
* PUT /api/lessons/:id — Update lesson
|
|
8
|
+
* DELETE /api/lessons/:id — Archive (soft delete)
|
|
9
|
+
*/
|
|
10
|
+
import { Hono } from 'hono';
|
|
11
|
+
import type { AuthVariables } from '../middleware/auth.js';
|
|
12
|
+
import type { SqliteDb } from '../db/index.js';
|
|
13
|
+
import type { EmbeddingWorker } from '../lib/embeddings/worker.js';
|
|
14
|
+
export declare function lessonsRoutes(db: SqliteDb, deps?: {
|
|
15
|
+
embeddingWorker: EmbeddingWorker | null;
|
|
16
|
+
}): Hono<{
|
|
17
|
+
Variables: AuthVariables;
|
|
18
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
19
|
+
//# sourceMappingURL=lessons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lessons.d.ts","sourceRoot":"","sources":["../../src/routes/lessons.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,IAAI,CAAC,EAAE;IAAE,eAAe,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE;eAEhB,aAAa;0CA4KhD"}
|