@agentlensai/server 0.9.0 → 0.11.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 (209) hide show
  1. package/dist/cloud/auth/api-key-middleware.d.ts +66 -0
  2. package/dist/cloud/auth/api-key-middleware.d.ts.map +1 -0
  3. package/dist/cloud/auth/api-key-middleware.js +147 -0
  4. package/dist/cloud/auth/api-key-middleware.js.map +1 -0
  5. package/dist/cloud/auth/api-keys.d.ts +90 -0
  6. package/dist/cloud/auth/api-keys.d.ts.map +1 -0
  7. package/dist/cloud/auth/api-keys.js +162 -0
  8. package/dist/cloud/auth/api-keys.js.map +1 -0
  9. package/dist/cloud/auth/audit-log.d.ts +66 -0
  10. package/dist/cloud/auth/audit-log.d.ts.map +1 -0
  11. package/dist/cloud/auth/audit-log.js +92 -0
  12. package/dist/cloud/auth/audit-log.js.map +1 -0
  13. package/dist/cloud/auth/auth-service.d.ts +77 -0
  14. package/dist/cloud/auth/auth-service.d.ts.map +1 -0
  15. package/dist/cloud/auth/auth-service.js +229 -0
  16. package/dist/cloud/auth/auth-service.js.map +1 -0
  17. package/dist/cloud/auth/brute-force.d.ts +36 -0
  18. package/dist/cloud/auth/brute-force.d.ts.map +1 -0
  19. package/dist/cloud/auth/brute-force.js +67 -0
  20. package/dist/cloud/auth/brute-force.js.map +1 -0
  21. package/dist/cloud/auth/index.d.ts +11 -0
  22. package/dist/cloud/auth/index.d.ts.map +1 -0
  23. package/dist/cloud/auth/index.js +11 -0
  24. package/dist/cloud/auth/index.js.map +1 -0
  25. package/dist/cloud/auth/jwt.d.ts +34 -0
  26. package/dist/cloud/auth/jwt.d.ts.map +1 -0
  27. package/dist/cloud/auth/jwt.js +68 -0
  28. package/dist/cloud/auth/jwt.js.map +1 -0
  29. package/dist/cloud/auth/oauth.d.ts +37 -0
  30. package/dist/cloud/auth/oauth.d.ts.map +1 -0
  31. package/dist/cloud/auth/oauth.js +120 -0
  32. package/dist/cloud/auth/oauth.js.map +1 -0
  33. package/dist/cloud/auth/passwords.d.ts +25 -0
  34. package/dist/cloud/auth/passwords.d.ts.map +1 -0
  35. package/dist/cloud/auth/passwords.js +50 -0
  36. package/dist/cloud/auth/passwords.js.map +1 -0
  37. package/dist/cloud/auth/rbac.d.ts +51 -0
  38. package/dist/cloud/auth/rbac.d.ts.map +1 -0
  39. package/dist/cloud/auth/rbac.js +89 -0
  40. package/dist/cloud/auth/rbac.js.map +1 -0
  41. package/dist/cloud/auth/tokens.d.ts +18 -0
  42. package/dist/cloud/auth/tokens.d.ts.map +1 -0
  43. package/dist/cloud/auth/tokens.js +29 -0
  44. package/dist/cloud/auth/tokens.js.map +1 -0
  45. package/dist/cloud/billing/billing-service.d.ts +44 -0
  46. package/dist/cloud/billing/billing-service.d.ts.map +1 -0
  47. package/dist/cloud/billing/billing-service.js +153 -0
  48. package/dist/cloud/billing/billing-service.js.map +1 -0
  49. package/dist/cloud/billing/index.d.ts +11 -0
  50. package/dist/cloud/billing/index.d.ts.map +1 -0
  51. package/dist/cloud/billing/index.js +11 -0
  52. package/dist/cloud/billing/index.js.map +1 -0
  53. package/dist/cloud/billing/invoice-service.d.ts +57 -0
  54. package/dist/cloud/billing/invoice-service.d.ts.map +1 -0
  55. package/dist/cloud/billing/invoice-service.js +123 -0
  56. package/dist/cloud/billing/invoice-service.js.map +1 -0
  57. package/dist/cloud/billing/plan-management.d.ts +46 -0
  58. package/dist/cloud/billing/plan-management.d.ts.map +1 -0
  59. package/dist/cloud/billing/plan-management.js +157 -0
  60. package/dist/cloud/billing/plan-management.js.map +1 -0
  61. package/dist/cloud/billing/quota-enforcement.d.ts +53 -0
  62. package/dist/cloud/billing/quota-enforcement.d.ts.map +1 -0
  63. package/dist/cloud/billing/quota-enforcement.js +143 -0
  64. package/dist/cloud/billing/quota-enforcement.js.map +1 -0
  65. package/dist/cloud/billing/stripe-client.d.ts +142 -0
  66. package/dist/cloud/billing/stripe-client.d.ts.map +1 -0
  67. package/dist/cloud/billing/stripe-client.js +169 -0
  68. package/dist/cloud/billing/stripe-client.js.map +1 -0
  69. package/dist/cloud/billing/trial-service.d.ts +47 -0
  70. package/dist/cloud/billing/trial-service.d.ts.map +1 -0
  71. package/dist/cloud/billing/trial-service.js +104 -0
  72. package/dist/cloud/billing/trial-service.js.map +1 -0
  73. package/dist/cloud/billing/usage-metering.d.ts +83 -0
  74. package/dist/cloud/billing/usage-metering.d.ts.map +1 -0
  75. package/dist/cloud/billing/usage-metering.js +174 -0
  76. package/dist/cloud/billing/usage-metering.js.map +1 -0
  77. package/dist/cloud/ingestion/backpressure.d.ts +107 -0
  78. package/dist/cloud/ingestion/backpressure.d.ts.map +1 -0
  79. package/dist/cloud/ingestion/backpressure.js +134 -0
  80. package/dist/cloud/ingestion/backpressure.js.map +1 -0
  81. package/dist/cloud/ingestion/batch-writer.d.ts +115 -0
  82. package/dist/cloud/ingestion/batch-writer.d.ts.map +1 -0
  83. package/dist/cloud/ingestion/batch-writer.js +319 -0
  84. package/dist/cloud/ingestion/batch-writer.js.map +1 -0
  85. package/dist/cloud/ingestion/dlq-manager.d.ts +116 -0
  86. package/dist/cloud/ingestion/dlq-manager.d.ts.map +1 -0
  87. package/dist/cloud/ingestion/dlq-manager.js +244 -0
  88. package/dist/cloud/ingestion/dlq-manager.js.map +1 -0
  89. package/dist/cloud/ingestion/event-queue.d.ts +105 -0
  90. package/dist/cloud/ingestion/event-queue.d.ts.map +1 -0
  91. package/dist/cloud/ingestion/event-queue.js +185 -0
  92. package/dist/cloud/ingestion/event-queue.js.map +1 -0
  93. package/dist/cloud/ingestion/gateway.d.ts +68 -0
  94. package/dist/cloud/ingestion/gateway.d.ts.map +1 -0
  95. package/dist/cloud/ingestion/gateway.js +198 -0
  96. package/dist/cloud/ingestion/gateway.js.map +1 -0
  97. package/dist/cloud/ingestion/index.d.ts +7 -0
  98. package/dist/cloud/ingestion/index.d.ts.map +1 -0
  99. package/dist/cloud/ingestion/index.js +7 -0
  100. package/dist/cloud/ingestion/index.js.map +1 -0
  101. package/dist/cloud/ingestion/rate-limiter.d.ts +73 -0
  102. package/dist/cloud/ingestion/rate-limiter.d.ts.map +1 -0
  103. package/dist/cloud/ingestion/rate-limiter.js +153 -0
  104. package/dist/cloud/ingestion/rate-limiter.js.map +1 -0
  105. package/dist/cloud/migrate.d.ts +45 -0
  106. package/dist/cloud/migrate.d.ts.map +1 -0
  107. package/dist/cloud/migrate.js +147 -0
  108. package/dist/cloud/migrate.js.map +1 -0
  109. package/dist/cloud/migration/export-import.d.ts +56 -0
  110. package/dist/cloud/migration/export-import.d.ts.map +1 -0
  111. package/dist/cloud/migration/export-import.js +289 -0
  112. package/dist/cloud/migration/export-import.js.map +1 -0
  113. package/dist/cloud/migration/index.d.ts +5 -0
  114. package/dist/cloud/migration/index.d.ts.map +1 -0
  115. package/dist/cloud/migration/index.js +5 -0
  116. package/dist/cloud/migration/index.js.map +1 -0
  117. package/dist/cloud/org-service.d.ts +68 -0
  118. package/dist/cloud/org-service.d.ts.map +1 -0
  119. package/dist/cloud/org-service.js +169 -0
  120. package/dist/cloud/org-service.js.map +1 -0
  121. package/dist/cloud/partition-maintenance.d.ts +29 -0
  122. package/dist/cloud/partition-maintenance.d.ts.map +1 -0
  123. package/dist/cloud/partition-maintenance.js +96 -0
  124. package/dist/cloud/partition-maintenance.js.map +1 -0
  125. package/dist/cloud/retention/index.d.ts +7 -0
  126. package/dist/cloud/retention/index.d.ts.map +1 -0
  127. package/dist/cloud/retention/index.js +7 -0
  128. package/dist/cloud/retention/index.js.map +1 -0
  129. package/dist/cloud/retention/partition-management.d.ts +61 -0
  130. package/dist/cloud/retention/partition-management.d.ts.map +1 -0
  131. package/dist/cloud/retention/partition-management.js +167 -0
  132. package/dist/cloud/retention/partition-management.js.map +1 -0
  133. package/dist/cloud/retention/retention-job.d.ts +70 -0
  134. package/dist/cloud/retention/retention-job.d.ts.map +1 -0
  135. package/dist/cloud/retention/retention-job.js +160 -0
  136. package/dist/cloud/retention/retention-job.js.map +1 -0
  137. package/dist/cloud/retention/retention-policy.d.ts +27 -0
  138. package/dist/cloud/retention/retention-policy.d.ts.map +1 -0
  139. package/dist/cloud/retention/retention-policy.js +36 -0
  140. package/dist/cloud/retention/retention-policy.js.map +1 -0
  141. package/dist/cloud/routes/api-key-routes.d.ts +38 -0
  142. package/dist/cloud/routes/api-key-routes.d.ts.map +1 -0
  143. package/dist/cloud/routes/api-key-routes.js +84 -0
  144. package/dist/cloud/routes/api-key-routes.js.map +1 -0
  145. package/dist/cloud/routes/audit-routes.d.ts +36 -0
  146. package/dist/cloud/routes/audit-routes.d.ts.map +1 -0
  147. package/dist/cloud/routes/audit-routes.js +47 -0
  148. package/dist/cloud/routes/audit-routes.js.map +1 -0
  149. package/dist/cloud/routes/billing-routes.d.ts +51 -0
  150. package/dist/cloud/routes/billing-routes.d.ts.map +1 -0
  151. package/dist/cloud/routes/billing-routes.js +114 -0
  152. package/dist/cloud/routes/billing-routes.js.map +1 -0
  153. package/dist/cloud/routes/onboarding-routes.d.ts +34 -0
  154. package/dist/cloud/routes/onboarding-routes.d.ts.map +1 -0
  155. package/dist/cloud/routes/onboarding-routes.js +58 -0
  156. package/dist/cloud/routes/onboarding-routes.js.map +1 -0
  157. package/dist/cloud/routes/org-routes.d.ts +80 -0
  158. package/dist/cloud/routes/org-routes.d.ts.map +1 -0
  159. package/dist/cloud/routes/org-routes.js +153 -0
  160. package/dist/cloud/routes/org-routes.js.map +1 -0
  161. package/dist/cloud/routes/usage-routes.d.ts +18 -0
  162. package/dist/cloud/routes/usage-routes.d.ts.map +1 -0
  163. package/dist/cloud/routes/usage-routes.js +66 -0
  164. package/dist/cloud/routes/usage-routes.js.map +1 -0
  165. package/dist/cloud/storage/adapter.d.ts +102 -0
  166. package/dist/cloud/storage/adapter.d.ts.map +1 -0
  167. package/dist/cloud/storage/adapter.js +21 -0
  168. package/dist/cloud/storage/adapter.js.map +1 -0
  169. package/dist/cloud/storage/index.d.ts +8 -0
  170. package/dist/cloud/storage/index.d.ts.map +1 -0
  171. package/dist/cloud/storage/index.js +7 -0
  172. package/dist/cloud/storage/index.js.map +1 -0
  173. package/dist/cloud/storage/postgres-adapter.d.ts +34 -0
  174. package/dist/cloud/storage/postgres-adapter.d.ts.map +1 -0
  175. package/dist/cloud/storage/postgres-adapter.js +544 -0
  176. package/dist/cloud/storage/postgres-adapter.js.map +1 -0
  177. package/dist/cloud/storage/sqlite-adapter.d.ts +29 -0
  178. package/dist/cloud/storage/sqlite-adapter.d.ts.map +1 -0
  179. package/dist/cloud/storage/sqlite-adapter.js +176 -0
  180. package/dist/cloud/storage/sqlite-adapter.js.map +1 -0
  181. package/dist/cloud/tenant-pool.d.ts +49 -0
  182. package/dist/cloud/tenant-pool.d.ts.map +1 -0
  183. package/dist/cloud/tenant-pool.js +61 -0
  184. package/dist/cloud/tenant-pool.js.map +1 -0
  185. package/dist/db/capability-store.d.ts +4 -0
  186. package/dist/db/capability-store.d.ts.map +1 -1
  187. package/dist/db/capability-store.js +20 -0
  188. package/dist/db/capability-store.js.map +1 -1
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +16 -0
  191. package/dist/index.js.map +1 -1
  192. package/dist/routes/audit.js +3 -3
  193. package/dist/routes/audit.js.map +1 -1
  194. package/dist/routes/capabilities-top.d.ts +15 -0
  195. package/dist/routes/capabilities-top.d.ts.map +1 -0
  196. package/dist/routes/capabilities-top.js +77 -0
  197. package/dist/routes/capabilities-top.js.map +1 -0
  198. package/dist/routes/community.d.ts.map +1 -1
  199. package/dist/routes/community.js +85 -3
  200. package/dist/routes/community.js.map +1 -1
  201. package/dist/routes/delegations-top.d.ts +12 -0
  202. package/dist/routes/delegations-top.d.ts.map +1 -0
  203. package/dist/routes/delegations-top.js +43 -0
  204. package/dist/routes/delegations-top.js.map +1 -0
  205. package/dist/services/community-service.d.ts +6 -0
  206. package/dist/services/community-service.d.ts.map +1 -1
  207. package/dist/services/community-service.js +31 -0
  208. package/dist/services/community-service.js.map +1 -1
  209. package/package.json +1 -1
@@ -0,0 +1,544 @@
1
+ /**
2
+ * PostgreSQL Storage Adapter (S-4.2, S-4.3, S-4.4)
3
+ *
4
+ * Implements StorageAdapter for the cloud Postgres backend.
5
+ * Uses the tenant pool from B2A for automatic org scoping via
6
+ * SET LOCAL app.current_org within transactions.
7
+ *
8
+ * All queries use org_id composite indexes. RLS provides automatic
9
+ * tenant scoping as defense-in-depth (queries also filter by org_id
10
+ * explicitly for index usage).
11
+ *
12
+ * S-4.3: Analytics queries use date_trunc + window functions for Postgres.
13
+ * S-4.4: Full-text search uses tsvector/to_tsquery with GIN indexes.
14
+ */
15
+ import { withTenantTransaction } from '../tenant-pool.js';
16
+ // ─── Helpers ────────────────────────────────────────────────
17
+ function safeJson(val, fallback) {
18
+ if (val === null || val === undefined)
19
+ return fallback;
20
+ if (typeof val === 'object')
21
+ return val;
22
+ if (typeof val === 'string') {
23
+ try {
24
+ return JSON.parse(val);
25
+ }
26
+ catch {
27
+ return fallback;
28
+ }
29
+ }
30
+ return fallback;
31
+ }
32
+ function mapEventRow(row) {
33
+ return {
34
+ id: row.id,
35
+ timestamp: row.timestamp,
36
+ sessionId: (row.session_id ?? row.sessionId),
37
+ agentId: (row.agent_id ?? row.agentId),
38
+ eventType: (row.event_type ?? row.eventType),
39
+ severity: row.severity,
40
+ payload: safeJson(row.payload, {}),
41
+ metadata: safeJson(row.metadata, {}),
42
+ prevHash: (row.prev_hash ?? row.prevHash),
43
+ hash: row.hash,
44
+ tenantId: (row.tenant_id ?? row.tenantId ?? row.org_id ?? row.orgId),
45
+ };
46
+ }
47
+ function mapSessionRow(row) {
48
+ return {
49
+ id: row.id,
50
+ agentId: (row.agent_id ?? row.agentId),
51
+ agentName: (row.agent_name ?? row.agentName),
52
+ startedAt: (row.started_at ?? row.startedAt),
53
+ endedAt: (row.ended_at ?? row.endedAt),
54
+ status: row.status,
55
+ eventCount: Number(row.event_count ?? row.eventCount ?? 0),
56
+ toolCallCount: Number(row.tool_call_count ?? row.toolCallCount ?? 0),
57
+ errorCount: Number(row.error_count ?? row.errorCount ?? 0),
58
+ totalCostUsd: Number(row.total_cost_usd ?? row.totalCostUsd ?? 0),
59
+ llmCallCount: Number(row.llm_call_count ?? row.llmCallCount ?? 0),
60
+ totalInputTokens: Number(row.total_input_tokens ?? row.totalInputTokens ?? 0),
61
+ totalOutputTokens: Number(row.total_output_tokens ?? row.totalOutputTokens ?? 0),
62
+ tags: safeJson(row.tags, []),
63
+ tenantId: (row.tenant_id ?? row.tenantId ?? row.org_id ?? row.orgId),
64
+ };
65
+ }
66
+ function mapAgentRow(row) {
67
+ return {
68
+ id: row.id,
69
+ name: row.name,
70
+ description: row.description,
71
+ firstSeenAt: (row.first_seen_at ?? row.firstSeenAt),
72
+ lastSeenAt: (row.last_seen_at ?? row.lastSeenAt),
73
+ sessionCount: Number(row.session_count ?? row.sessionCount ?? 0),
74
+ tenantId: (row.tenant_id ?? row.tenantId ?? row.org_id ?? row.orgId),
75
+ modelOverride: (row.model_override ?? row.modelOverride),
76
+ pausedAt: (row.paused_at ?? row.pausedAt),
77
+ pauseReason: (row.pause_reason ?? row.pauseReason),
78
+ };
79
+ }
80
+ function buildEventWhere(orgId, query) {
81
+ const where = [`org_id = $1`];
82
+ const params = [orgId];
83
+ let idx = 2;
84
+ if (query.sessionId) {
85
+ where.push(`session_id = $${idx}`);
86
+ params.push(query.sessionId);
87
+ idx++;
88
+ }
89
+ if (query.agentId) {
90
+ where.push(`agent_id = $${idx}`);
91
+ params.push(query.agentId);
92
+ idx++;
93
+ }
94
+ if (query.eventType) {
95
+ const types = Array.isArray(query.eventType) ? query.eventType : [query.eventType];
96
+ where.push(`event_type = ANY($${idx})`);
97
+ params.push(types);
98
+ idx++;
99
+ }
100
+ if (query.severity) {
101
+ const sevs = Array.isArray(query.severity) ? query.severity : [query.severity];
102
+ where.push(`severity = ANY($${idx})`);
103
+ params.push(sevs);
104
+ idx++;
105
+ }
106
+ if (query.from) {
107
+ where.push(`timestamp >= $${idx}`);
108
+ params.push(query.from);
109
+ idx++;
110
+ }
111
+ if (query.to) {
112
+ where.push(`timestamp <= $${idx}`);
113
+ params.push(query.to);
114
+ idx++;
115
+ }
116
+ if (query.search) {
117
+ where.push(`payload::text ILIKE $${idx}`);
118
+ params.push(`%${query.search}%`);
119
+ idx++;
120
+ }
121
+ return { where, params, paramIdx: idx };
122
+ }
123
+ function buildSessionWhere(orgId, query) {
124
+ const where = [`org_id = $1`];
125
+ const params = [orgId];
126
+ let idx = 2;
127
+ if (query.agentId) {
128
+ where.push(`agent_id = $${idx}`);
129
+ params.push(query.agentId);
130
+ idx++;
131
+ }
132
+ if (query.status) {
133
+ const statuses = Array.isArray(query.status) ? query.status : [query.status];
134
+ where.push(`status = ANY($${idx})`);
135
+ params.push(statuses);
136
+ idx++;
137
+ }
138
+ if (query.from) {
139
+ where.push(`started_at >= $${idx}`);
140
+ params.push(query.from);
141
+ idx++;
142
+ }
143
+ if (query.to) {
144
+ where.push(`started_at <= $${idx}`);
145
+ params.push(query.to);
146
+ idx++;
147
+ }
148
+ if (query.tags && query.tags.length > 0) {
149
+ where.push(`tags ?| $${idx}`);
150
+ params.push(query.tags);
151
+ idx++;
152
+ }
153
+ return { where, params, paramIdx: idx };
154
+ }
155
+ // ─── Analytics Helpers (S-4.3) ──────────────────────────────
156
+ const ALLOWED_GRANULARITY = { hour: 'hour', day: 'day', week: 'week' };
157
+ function pgDateTrunc(granularity) {
158
+ const val = ALLOWED_GRANULARITY[granularity];
159
+ if (!val)
160
+ throw new Error(`Invalid granularity: ${granularity}`);
161
+ return val;
162
+ }
163
+ // ─── PostgreSQL Storage Adapter ─────────────────────────────
164
+ export class PostgresStorageAdapter {
165
+ pool;
166
+ constructor(pool) {
167
+ this.pool = pool;
168
+ }
169
+ async queryEvents(orgId, query) {
170
+ return withTenantTransaction(this.pool, orgId, async (client) => {
171
+ const { where, params, paramIdx } = buildEventWhere(orgId, query);
172
+ const whereClause = where.join(' AND ');
173
+ const orderDir = query.order === 'asc' ? 'ASC' : 'DESC';
174
+ const limit = Math.min(query.limit ?? 50, 500);
175
+ const offset = query.offset ?? 0;
176
+ const countResult = await client.query(`SELECT COUNT(*)::int AS total FROM events WHERE ${whereClause}`, params);
177
+ const total = countResult.rows[0]?.total ?? 0;
178
+ const dataResult = await client.query(`SELECT * FROM events WHERE ${whereClause} ORDER BY timestamp ${orderDir} LIMIT $${paramIdx} OFFSET $${paramIdx + 1}`, [...params, limit, offset]);
179
+ const events = dataResult.rows.map(mapEventRow);
180
+ return { events, total, hasMore: offset + events.length < total };
181
+ });
182
+ }
183
+ async getEventsBySession(orgId, sessionId) {
184
+ return withTenantTransaction(this.pool, orgId, async (client) => {
185
+ const result = await client.query(`SELECT * FROM events WHERE org_id = $1 AND session_id = $2 ORDER BY timestamp ASC`, [orgId, sessionId]);
186
+ return result.rows.map(mapEventRow);
187
+ });
188
+ }
189
+ async getSessions(orgId, query) {
190
+ return withTenantTransaction(this.pool, orgId, async (client) => {
191
+ const { where, params, paramIdx } = buildSessionWhere(orgId, query);
192
+ const whereClause = where.join(' AND ');
193
+ const limit = Math.min(query.limit ?? 50, 500);
194
+ const offset = query.offset ?? 0;
195
+ const countResult = await client.query(`SELECT COUNT(*)::int AS total FROM sessions WHERE ${whereClause}`, params);
196
+ const total = countResult.rows[0]?.total ?? 0;
197
+ const dataResult = await client.query(`SELECT * FROM sessions WHERE ${whereClause} ORDER BY started_at DESC LIMIT $${paramIdx} OFFSET $${paramIdx + 1}`, [...params, limit, offset]);
198
+ const items = dataResult.rows.map(mapSessionRow);
199
+ return { items, total, hasMore: offset + items.length < total };
200
+ });
201
+ }
202
+ async getSession(orgId, sessionId) {
203
+ return withTenantTransaction(this.pool, orgId, async (client) => {
204
+ const result = await client.query(`SELECT * FROM sessions WHERE org_id = $1 AND id = $2 LIMIT 1`, [orgId, sessionId]);
205
+ if (result.rows.length === 0)
206
+ return null;
207
+ return mapSessionRow(result.rows[0]);
208
+ });
209
+ }
210
+ async getAgents(orgId) {
211
+ return withTenantTransaction(this.pool, orgId, async (client) => {
212
+ const result = await client.query(`SELECT * FROM agents WHERE org_id = $1 ORDER BY last_seen_at DESC`, [orgId]);
213
+ return result.rows.map(mapAgentRow);
214
+ });
215
+ }
216
+ async getStats(orgId) {
217
+ return withTenantTransaction(this.pool, orgId, async (client) => {
218
+ const eventCount = await client.query(`SELECT COUNT(*)::int AS c FROM events WHERE org_id = $1`, [orgId]);
219
+ const sessionCount = await client.query(`SELECT COUNT(*)::int AS c FROM sessions WHERE org_id = $1`, [orgId]);
220
+ const agentCount = await client.query(`SELECT COUNT(*)::int AS c FROM agents WHERE org_id = $1`, [orgId]);
221
+ const oldest = await client.query(`SELECT timestamp FROM events WHERE org_id = $1 ORDER BY timestamp ASC LIMIT 1`, [orgId]);
222
+ const newest = await client.query(`SELECT timestamp FROM events WHERE org_id = $1 ORDER BY timestamp DESC LIMIT 1`, [orgId]);
223
+ const sizeResult = await client.query(`SELECT pg_total_relation_size('events') AS size_bytes`);
224
+ return {
225
+ totalEvents: eventCount.rows[0]?.c ?? 0,
226
+ totalSessions: sessionCount.rows[0]?.c ?? 0,
227
+ totalAgents: agentCount.rows[0]?.c ?? 0,
228
+ oldestEvent: oldest.rows[0]?.timestamp,
229
+ newestEvent: newest.rows[0]?.timestamp,
230
+ storageSizeBytes: Number(sizeResult.rows[0]?.size_bytes ?? 0),
231
+ };
232
+ });
233
+ }
234
+ // ═══════════════════════════════════════════════════════════
235
+ // S-4.3: Analytics Queries (Postgres-optimized)
236
+ // ═══════════════════════════════════════════════════════════
237
+ async getCostAnalytics(orgId, query) {
238
+ return withTenantTransaction(this.pool, orgId, async (client) => {
239
+ const trunc = pgDateTrunc(query.granularity);
240
+ const params = [orgId, query.from, query.to];
241
+ let agentFilter = '';
242
+ if (query.agentId) {
243
+ agentFilter = `AND agent_id = $4`;
244
+ params.push(query.agentId);
245
+ }
246
+ const result = await client.query(`SELECT
247
+ date_trunc('${trunc}', timestamp) AS bucket,
248
+ COALESCE(SUM((payload->>'costUsd')::numeric), 0)::float AS total_cost,
249
+ COUNT(*)::int AS event_count
250
+ FROM events
251
+ WHERE org_id = $1
252
+ AND timestamp >= $2
253
+ AND timestamp <= $3
254
+ AND event_type = 'cost_tracked'
255
+ ${agentFilter}
256
+ GROUP BY bucket
257
+ ORDER BY bucket ASC`, params);
258
+ const buckets = result.rows.map((row) => ({
259
+ timestamp: String(row.bucket),
260
+ totalCostUsd: Number(row.total_cost ?? 0),
261
+ eventCount: Number(row.event_count ?? 0),
262
+ }));
263
+ const totalCostUsd = buckets.reduce((sum, b) => sum + b.totalCostUsd, 0);
264
+ const totalEvents = buckets.reduce((sum, b) => sum + b.eventCount, 0);
265
+ return { buckets, totalCostUsd, totalEvents };
266
+ });
267
+ }
268
+ async getHealthAnalytics(orgId, query) {
269
+ return withTenantTransaction(this.pool, orgId, async (client) => {
270
+ const params = [orgId, query.from, query.to];
271
+ let agentFilter = '';
272
+ if (query.agentId) {
273
+ agentFilter = `AND agent_id = $4`;
274
+ params.push(query.agentId);
275
+ }
276
+ const result = await client.query(`SELECT
277
+ agent_id,
278
+ date::text AS date,
279
+ overall_score,
280
+ error_rate_score,
281
+ cost_efficiency_score,
282
+ tool_success_score,
283
+ latency_score,
284
+ completion_rate_score,
285
+ session_count
286
+ FROM health_snapshots
287
+ WHERE org_id = $1
288
+ AND date >= $2::date
289
+ AND date <= $3::date
290
+ ${agentFilter}
291
+ ORDER BY date ASC, agent_id ASC`, params);
292
+ const snapshots = result.rows.map((row) => ({
293
+ agentId: row.agent_id,
294
+ date: row.date,
295
+ overallScore: Number(row.overall_score ?? 0),
296
+ errorRateScore: Number(row.error_rate_score ?? 0),
297
+ costEfficiencyScore: Number(row.cost_efficiency_score ?? 0),
298
+ toolSuccessScore: Number(row.tool_success_score ?? 0),
299
+ latencyScore: Number(row.latency_score ?? 0),
300
+ completionRateScore: Number(row.completion_rate_score ?? 0),
301
+ sessionCount: Number(row.session_count ?? 0),
302
+ }));
303
+ return { snapshots };
304
+ });
305
+ }
306
+ async getTokenUsage(orgId, query) {
307
+ return withTenantTransaction(this.pool, orgId, async (client) => {
308
+ const trunc = pgDateTrunc(query.granularity);
309
+ const params = [orgId, query.from, query.to];
310
+ let agentFilter = '';
311
+ if (query.agentId) {
312
+ agentFilter = `AND agent_id = $4`;
313
+ params.push(query.agentId);
314
+ }
315
+ const result = await client.query(`SELECT
316
+ date_trunc('${trunc}', timestamp) AS bucket,
317
+ COALESCE(SUM((payload->>'inputTokens')::int), 0)::int AS input_tokens,
318
+ COALESCE(SUM((payload->>'outputTokens')::int), 0)::int AS output_tokens,
319
+ COALESCE(SUM((payload->>'inputTokens')::int + (payload->>'outputTokens')::int), 0)::int AS total_tokens,
320
+ COUNT(*)::int AS llm_call_count
321
+ FROM events
322
+ WHERE org_id = $1
323
+ AND timestamp >= $2
324
+ AND timestamp <= $3
325
+ AND event_type = 'llm_response'
326
+ ${agentFilter}
327
+ GROUP BY bucket
328
+ ORDER BY bucket ASC`, params);
329
+ const buckets = result.rows.map((row) => ({
330
+ timestamp: String(row.bucket),
331
+ inputTokens: Number(row.input_tokens ?? 0),
332
+ outputTokens: Number(row.output_tokens ?? 0),
333
+ totalTokens: Number(row.total_tokens ?? 0),
334
+ llmCallCount: Number(row.llm_call_count ?? 0),
335
+ }));
336
+ const totals = buckets.reduce((acc, b) => ({
337
+ inputTokens: acc.inputTokens + b.inputTokens,
338
+ outputTokens: acc.outputTokens + b.outputTokens,
339
+ totalTokens: acc.totalTokens + b.totalTokens,
340
+ llmCallCount: acc.llmCallCount + b.llmCallCount,
341
+ }), { inputTokens: 0, outputTokens: 0, totalTokens: 0, llmCallCount: 0 });
342
+ return { buckets, totals };
343
+ });
344
+ }
345
+ async getAnalytics(orgId, query) {
346
+ return withTenantTransaction(this.pool, orgId, async (client) => {
347
+ const trunc = pgDateTrunc(query.granularity);
348
+ const params = [orgId, query.from, query.to];
349
+ let agentFilter = '';
350
+ if (query.agentId) {
351
+ agentFilter = `AND agent_id = $4`;
352
+ params.push(query.agentId);
353
+ }
354
+ // Bucketed query using date_trunc (Postgres-optimized)
355
+ const bucketResult = await client.query(`SELECT
356
+ date_trunc('${trunc}', timestamp) AS bucket,
357
+ COUNT(*)::int AS event_count,
358
+ SUM(CASE WHEN event_type = 'tool_call' THEN 1 ELSE 0 END)::int AS tool_call_count,
359
+ SUM(CASE WHEN severity IN ('error', 'critical') OR event_type = 'tool_error' THEN 1 ELSE 0 END)::int AS error_count,
360
+ COUNT(DISTINCT session_id)::int AS unique_sessions,
361
+ COALESCE(AVG(CASE WHEN event_type = 'tool_response' THEN (payload->>'durationMs')::numeric ELSE NULL END), 0)::float AS avg_latency_ms,
362
+ COALESCE(SUM(CASE WHEN event_type = 'cost_tracked' THEN (payload->>'costUsd')::numeric ELSE 0 END), 0)::float AS total_cost_usd
363
+ FROM events
364
+ WHERE org_id = $1 AND timestamp >= $2 AND timestamp <= $3
365
+ ${agentFilter}
366
+ GROUP BY bucket
367
+ ORDER BY bucket ASC`, params);
368
+ // Totals query
369
+ const totalsResult = await client.query(`SELECT
370
+ COUNT(*)::int AS event_count,
371
+ SUM(CASE WHEN event_type = 'tool_call' THEN 1 ELSE 0 END)::int AS tool_call_count,
372
+ SUM(CASE WHEN severity IN ('error', 'critical') OR event_type = 'tool_error' THEN 1 ELSE 0 END)::int AS error_count,
373
+ COUNT(DISTINCT session_id)::int AS unique_sessions,
374
+ COUNT(DISTINCT agent_id)::int AS unique_agents,
375
+ COALESCE(AVG(CASE WHEN event_type = 'tool_response' THEN (payload->>'durationMs')::numeric ELSE NULL END), 0)::float AS avg_latency_ms,
376
+ COALESCE(SUM(CASE WHEN event_type = 'cost_tracked' THEN (payload->>'costUsd')::numeric ELSE 0 END), 0)::float AS total_cost_usd
377
+ FROM events
378
+ WHERE org_id = $1 AND timestamp >= $2 AND timestamp <= $3
379
+ ${agentFilter}`, params);
380
+ const totalsRow = totalsResult.rows[0];
381
+ return {
382
+ buckets: bucketResult.rows.map((row) => ({
383
+ timestamp: String(row.bucket),
384
+ eventCount: Number(row.event_count ?? 0),
385
+ toolCallCount: Number(row.tool_call_count ?? 0),
386
+ errorCount: Number(row.error_count ?? 0),
387
+ avgLatencyMs: Number(row.avg_latency_ms ?? 0),
388
+ totalCostUsd: Number(row.total_cost_usd ?? 0),
389
+ uniqueSessions: Number(row.unique_sessions ?? 0),
390
+ })),
391
+ totals: {
392
+ eventCount: Number(totalsRow?.event_count ?? 0),
393
+ toolCallCount: Number(totalsRow?.tool_call_count ?? 0),
394
+ errorCount: Number(totalsRow?.error_count ?? 0),
395
+ avgLatencyMs: Number(totalsRow?.avg_latency_ms ?? 0),
396
+ totalCostUsd: Number(totalsRow?.total_cost_usd ?? 0),
397
+ uniqueSessions: Number(totalsRow?.unique_sessions ?? 0),
398
+ uniqueAgents: Number(totalsRow?.unique_agents ?? 0),
399
+ },
400
+ };
401
+ });
402
+ }
403
+ // ═══════════════════════════════════════════════════════════
404
+ // S-4.4: Full-Text Search (Postgres tsvector/to_tsquery)
405
+ // ═══════════════════════════════════════════════════════════
406
+ async search(orgId, query) {
407
+ return withTenantTransaction(this.pool, orgId, async (client) => {
408
+ const limit = Math.min(query.limit ?? 20, 100);
409
+ const offset = query.offset ?? 0;
410
+ const scope = query.scope ?? 'all';
411
+ // Sanitize query for to_tsquery: replace spaces with & for AND semantics
412
+ const tsQuery = query.query
413
+ .trim()
414
+ .split(/\s+/)
415
+ .filter(Boolean)
416
+ .map((w) => w.replace(/[^\w]/g, ''))
417
+ .filter(Boolean)
418
+ .join(' & ');
419
+ if (!tsQuery) {
420
+ return { items: [], total: 0, hasMore: false };
421
+ }
422
+ const items = [];
423
+ let total = 0;
424
+ // Search events
425
+ if (scope === 'events' || scope === 'all') {
426
+ const timeFilters = [];
427
+ const params = [orgId, tsQuery];
428
+ let idx = 3;
429
+ if (query.from) {
430
+ timeFilters.push(`AND e.timestamp >= $${idx}`);
431
+ params.push(query.from);
432
+ idx++;
433
+ }
434
+ if (query.to) {
435
+ timeFilters.push(`AND e.timestamp <= $${idx}`);
436
+ params.push(query.to);
437
+ idx++;
438
+ }
439
+ const timeFilterStr = timeFilters.join(' ');
440
+ // Use to_tsvector on payload::text + event_type for full-text search
441
+ // ts_rank for scoring, ts_headline for highlighted snippets
442
+ const eventResult = await client.query(`WITH matched AS (
443
+ SELECT
444
+ e.id,
445
+ e.session_id,
446
+ e.timestamp,
447
+ ts_rank(
448
+ to_tsvector('english', COALESCE(e.event_type, '') || ' ' || COALESCE(e.payload::text, '')),
449
+ to_tsquery('english', $2)
450
+ ) AS score,
451
+ ts_headline('english',
452
+ COALESCE(e.event_type, '') || ' ' || COALESCE(e.payload::text, ''),
453
+ to_tsquery('english', $2),
454
+ 'MaxWords=30, MinWords=10, StartSel=<<, StopSel=>>'
455
+ ) AS headline
456
+ FROM events e
457
+ WHERE e.org_id = $1
458
+ AND to_tsvector('english', COALESCE(e.event_type, '') || ' ' || COALESCE(e.payload::text, ''))
459
+ @@ to_tsquery('english', $2)
460
+ ${timeFilterStr}
461
+ )
462
+ SELECT *, (SELECT COUNT(*)::int FROM matched) AS total_count
463
+ FROM matched
464
+ ORDER BY score DESC
465
+ LIMIT $${idx} OFFSET $${idx + 1}`, [...params, limit, offset]);
466
+ for (const row of eventResult.rows) {
467
+ items.push({
468
+ type: 'event',
469
+ id: row.id,
470
+ score: Number(row.score ?? 0),
471
+ headline: row.headline,
472
+ timestamp: row.timestamp,
473
+ sessionId: row.session_id,
474
+ });
475
+ total = Number(row.total_count ?? 0);
476
+ }
477
+ }
478
+ // Search sessions
479
+ if (scope === 'sessions' || scope === 'all') {
480
+ const timeFilters = [];
481
+ const params = [orgId, tsQuery];
482
+ let idx = 3;
483
+ if (query.from) {
484
+ timeFilters.push(`AND s.started_at >= $${idx}`);
485
+ params.push(query.from);
486
+ idx++;
487
+ }
488
+ if (query.to) {
489
+ timeFilters.push(`AND s.started_at <= $${idx}`);
490
+ params.push(query.to);
491
+ idx++;
492
+ }
493
+ const timeFilterStr = timeFilters.join(' ');
494
+ const sessionResult = await client.query(`WITH matched AS (
495
+ SELECT
496
+ s.id,
497
+ s.started_at AS timestamp,
498
+ ts_rank(
499
+ to_tsvector('english', COALESCE(s.agent_name, '') || ' ' || COALESCE(s.tags::text, '')),
500
+ to_tsquery('english', $2)
501
+ ) AS score,
502
+ ts_headline('english',
503
+ COALESCE(s.agent_name, '') || ' ' || COALESCE(s.tags::text, ''),
504
+ to_tsquery('english', $2),
505
+ 'MaxWords=30, MinWords=10, StartSel=<<, StopSel=>>'
506
+ ) AS headline
507
+ FROM sessions s
508
+ WHERE s.org_id = $1
509
+ AND to_tsvector('english', COALESCE(s.agent_name, '') || ' ' || COALESCE(s.tags::text, ''))
510
+ @@ to_tsquery('english', $2)
511
+ ${timeFilterStr}
512
+ )
513
+ SELECT *, (SELECT COUNT(*)::int FROM matched) AS total_count
514
+ FROM matched
515
+ ORDER BY score DESC
516
+ LIMIT $${idx} OFFSET $${idx + 1}`, [...params, limit, offset]);
517
+ const sessionTotal = Number(sessionResult.rows[0]?.total_count ?? 0);
518
+ for (const row of sessionResult.rows) {
519
+ items.push({
520
+ type: 'session',
521
+ id: row.id,
522
+ score: Number(row.score ?? 0),
523
+ headline: row.headline,
524
+ timestamp: row.timestamp,
525
+ });
526
+ }
527
+ if (scope === 'all') {
528
+ total += sessionTotal;
529
+ }
530
+ else {
531
+ total = sessionTotal;
532
+ }
533
+ }
534
+ // Sort combined results by score descending
535
+ items.sort((a, b) => b.score - a.score);
536
+ return {
537
+ items: items.slice(0, limit),
538
+ total,
539
+ hasMore: offset + items.length < total,
540
+ };
541
+ });
542
+ }
543
+ }
544
+ //# sourceMappingURL=postgres-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-adapter.js","sourceRoot":"","sources":["../../../src/cloud/storage/postgres-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * SQLite Storage Adapter (S-4.1, S-4.3, S-4.4)
3
+ *
4
+ * Wraps the existing SqliteEventStore to implement the StorageAdapter interface.
5
+ * orgId is mapped to tenantId for multi-tenant SQLite (self-hosted).
6
+ *
7
+ * S-4.3: Analytics use SQLite strftime for time bucketing.
8
+ * S-4.4: Full-text search uses LIKE (SQLite lacks tsvector; FTS5 optional).
9
+ */
10
+ import type { AgentLensEvent, EventQuery, EventQueryResult, Session, SessionQuery, Agent } from '@agentlensai/core';
11
+ import type { AnalyticsResult, StorageStats } from '@agentlensai/core';
12
+ import type { StorageAdapter, PaginatedResult, AnalyticsQuery, CostAnalyticsResult, HealthAnalyticsResult, TokenUsageResult, SearchQuery, SearchResult } from './adapter.js';
13
+ import type { SqliteEventStore } from '../../db/sqlite-store.js';
14
+ export declare class SqliteStorageAdapter implements StorageAdapter {
15
+ private readonly store;
16
+ constructor(store: SqliteEventStore);
17
+ queryEvents(orgId: string, query: EventQuery): Promise<EventQueryResult>;
18
+ getEventsBySession(orgId: string, sessionId: string): Promise<AgentLensEvent[]>;
19
+ getSessions(orgId: string, query: SessionQuery): Promise<PaginatedResult<Session>>;
20
+ getSession(orgId: string, sessionId: string): Promise<Session | null>;
21
+ getAgents(orgId: string): Promise<Agent[]>;
22
+ getStats(orgId: string): Promise<StorageStats>;
23
+ getCostAnalytics(orgId: string, query: AnalyticsQuery): Promise<CostAnalyticsResult>;
24
+ getHealthAnalytics(_orgId: string, _query: AnalyticsQuery): Promise<HealthAnalyticsResult>;
25
+ getTokenUsage(orgId: string, query: AnalyticsQuery): Promise<TokenUsageResult>;
26
+ getAnalytics(orgId: string, query: AnalyticsQuery): Promise<AnalyticsResult>;
27
+ search(orgId: string, query: SearchQuery): Promise<SearchResult>;
28
+ }
29
+ //# sourceMappingURL=sqlite-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../../src/cloud/storage/sqlite-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,KAAK,EAEN,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACb,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,qBAAa,oBAAqB,YAAW,cAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,gBAAgB;IAE9C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIxE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAI/E,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAWlF,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIrE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAI1C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ9C,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsBpF,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAO1F,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4B9E,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAc5E,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA+EvE"}