@agentlensai/server 0.3.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.
Files changed (231) hide show
  1. package/dist/db/embedding-store.d.ts +74 -0
  2. package/dist/db/embedding-store.d.ts.map +1 -0
  3. package/dist/db/embedding-store.js +177 -0
  4. package/dist/db/embedding-store.js.map +1 -0
  5. package/dist/db/lesson-store.d.ts +57 -0
  6. package/dist/db/lesson-store.d.ts.map +1 -0
  7. package/dist/db/lesson-store.js +217 -0
  8. package/dist/db/lesson-store.js.map +1 -0
  9. package/dist/db/migrate.d.ts.map +1 -1
  10. package/dist/db/migrate.js +237 -8
  11. package/dist/db/migrate.js.map +1 -1
  12. package/dist/db/schema.sqlite.d.ts +822 -47
  13. package/dist/db/schema.sqlite.d.ts.map +1 -1
  14. package/dist/db/schema.sqlite.js +79 -4
  15. package/dist/db/schema.sqlite.js.map +1 -1
  16. package/dist/db/session-summary-store.d.ts +45 -0
  17. package/dist/db/session-summary-store.d.ts.map +1 -0
  18. package/dist/db/session-summary-store.js +112 -0
  19. package/dist/db/session-summary-store.js.map +1 -0
  20. package/dist/db/sqlite-store.d.ts +14 -12
  21. package/dist/db/sqlite-store.d.ts.map +1 -1
  22. package/dist/db/sqlite-store.js +130 -44
  23. package/dist/db/sqlite-store.js.map +1 -1
  24. package/dist/db/tenant-scoped-store.d.ts +61 -0
  25. package/dist/db/tenant-scoped-store.d.ts.map +1 -0
  26. package/dist/db/tenant-scoped-store.js +94 -0
  27. package/dist/db/tenant-scoped-store.js.map +1 -0
  28. package/dist/index.d.ts +16 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +66 -5
  31. package/dist/index.js.map +1 -1
  32. package/dist/lib/alert-engine.d.ts +11 -0
  33. package/dist/lib/alert-engine.d.ts.map +1 -1
  34. package/dist/lib/alert-engine.js +62 -24
  35. package/dist/lib/alert-engine.js.map +1 -1
  36. package/dist/lib/analysis/cost-analysis.d.ts +20 -0
  37. package/dist/lib/analysis/cost-analysis.d.ts.map +1 -0
  38. package/dist/lib/analysis/cost-analysis.js +158 -0
  39. package/dist/lib/analysis/cost-analysis.js.map +1 -0
  40. package/dist/lib/analysis/error-patterns.d.ts +26 -0
  41. package/dist/lib/analysis/error-patterns.d.ts.map +1 -0
  42. package/dist/lib/analysis/error-patterns.js +155 -0
  43. package/dist/lib/analysis/error-patterns.js.map +1 -0
  44. package/dist/lib/analysis/index.d.ts +23 -0
  45. package/dist/lib/analysis/index.d.ts.map +1 -0
  46. package/dist/lib/analysis/index.js +144 -0
  47. package/dist/lib/analysis/index.js.map +1 -0
  48. package/dist/lib/analysis/performance-trends.d.ts +19 -0
  49. package/dist/lib/analysis/performance-trends.d.ts.map +1 -0
  50. package/dist/lib/analysis/performance-trends.js +118 -0
  51. package/dist/lib/analysis/performance-trends.js.map +1 -0
  52. package/dist/lib/analysis/tool-sequences.d.ts +19 -0
  53. package/dist/lib/analysis/tool-sequences.d.ts.map +1 -0
  54. package/dist/lib/analysis/tool-sequences.js +145 -0
  55. package/dist/lib/analysis/tool-sequences.js.map +1 -0
  56. package/dist/lib/context/index.d.ts +5 -0
  57. package/dist/lib/context/index.d.ts.map +1 -0
  58. package/dist/lib/context/index.js +5 -0
  59. package/dist/lib/context/index.js.map +1 -0
  60. package/dist/lib/context/retrieval.d.ts +56 -0
  61. package/dist/lib/context/retrieval.d.ts.map +1 -0
  62. package/dist/lib/context/retrieval.js +229 -0
  63. package/dist/lib/context/retrieval.js.map +1 -0
  64. package/dist/lib/embeddings/index.d.ts +31 -0
  65. package/dist/lib/embeddings/index.d.ts.map +1 -0
  66. package/dist/lib/embeddings/index.js +31 -0
  67. package/dist/lib/embeddings/index.js.map +1 -0
  68. package/dist/lib/embeddings/local.d.ts +15 -0
  69. package/dist/lib/embeddings/local.d.ts.map +1 -0
  70. package/dist/lib/embeddings/local.js +65 -0
  71. package/dist/lib/embeddings/local.js.map +1 -0
  72. package/dist/lib/embeddings/math.d.ts +13 -0
  73. package/dist/lib/embeddings/math.d.ts.map +1 -0
  74. package/dist/lib/embeddings/math.js +35 -0
  75. package/dist/lib/embeddings/math.js.map +1 -0
  76. package/dist/lib/embeddings/openai.d.ts +15 -0
  77. package/dist/lib/embeddings/openai.d.ts.map +1 -0
  78. package/dist/lib/embeddings/openai.js +58 -0
  79. package/dist/lib/embeddings/openai.js.map +1 -0
  80. package/dist/lib/embeddings/summarizer.d.ts +26 -0
  81. package/dist/lib/embeddings/summarizer.d.ts.map +1 -0
  82. package/dist/lib/embeddings/summarizer.js +181 -0
  83. package/dist/lib/embeddings/summarizer.js.map +1 -0
  84. package/dist/lib/embeddings/types.d.ts +17 -0
  85. package/dist/lib/embeddings/types.d.ts.map +1 -0
  86. package/dist/lib/embeddings/types.js +5 -0
  87. package/dist/lib/embeddings/types.js.map +1 -0
  88. package/dist/lib/embeddings/worker.d.ts +56 -0
  89. package/dist/lib/embeddings/worker.d.ts.map +1 -0
  90. package/dist/lib/embeddings/worker.js +109 -0
  91. package/dist/lib/embeddings/worker.js.map +1 -0
  92. package/dist/lib/sse.d.ts +1 -0
  93. package/dist/lib/sse.d.ts.map +1 -1
  94. package/dist/lib/sse.js +8 -1
  95. package/dist/lib/sse.js.map +1 -1
  96. package/dist/middleware/auth.d.ts +1 -0
  97. package/dist/middleware/auth.d.ts.map +1 -1
  98. package/dist/middleware/auth.js +2 -1
  99. package/dist/middleware/auth.js.map +1 -1
  100. package/dist/routes/agents.d.ts.map +1 -1
  101. package/dist/routes/agents.js +6 -3
  102. package/dist/routes/agents.js.map +1 -1
  103. package/dist/routes/alerts.d.ts.map +1 -1
  104. package/dist/routes/alerts.js +15 -7
  105. package/dist/routes/alerts.js.map +1 -1
  106. package/dist/routes/analytics.d.ts.map +1 -1
  107. package/dist/routes/analytics.js +16 -2
  108. package/dist/routes/analytics.js.map +1 -1
  109. package/dist/routes/api-keys.d.ts.map +1 -1
  110. package/dist/routes/api-keys.js +30 -5
  111. package/dist/routes/api-keys.js.map +1 -1
  112. package/dist/routes/context.d.ts +23 -0
  113. package/dist/routes/context.d.ts.map +1 -0
  114. package/dist/routes/context.js +52 -0
  115. package/dist/routes/context.js.map +1 -0
  116. package/dist/routes/events.d.ts +6 -1
  117. package/dist/routes/events.d.ts.map +1 -1
  118. package/dist/routes/events.js +61 -6
  119. package/dist/routes/events.js.map +1 -1
  120. package/dist/routes/ingest.d.ts +6 -0
  121. package/dist/routes/ingest.d.ts.map +1 -1
  122. package/dist/routes/ingest.js +23 -4
  123. package/dist/routes/ingest.js.map +1 -1
  124. package/dist/routes/lessons.d.ts +19 -0
  125. package/dist/routes/lessons.d.ts.map +1 -0
  126. package/dist/routes/lessons.js +164 -0
  127. package/dist/routes/lessons.js.map +1 -0
  128. package/dist/routes/recall.d.ts +20 -0
  129. package/dist/routes/recall.d.ts.map +1 -0
  130. package/dist/routes/recall.js +71 -0
  131. package/dist/routes/recall.js.map +1 -0
  132. package/dist/routes/reflect.d.ts +15 -0
  133. package/dist/routes/reflect.d.ts.map +1 -0
  134. package/dist/routes/reflect.js +55 -0
  135. package/dist/routes/reflect.js.map +1 -0
  136. package/dist/routes/sessions.d.ts.map +1 -1
  137. package/dist/routes/sessions.js +8 -6
  138. package/dist/routes/sessions.js.map +1 -1
  139. package/dist/routes/stats.d.ts.map +1 -1
  140. package/dist/routes/stats.js +3 -1
  141. package/dist/routes/stats.js.map +1 -1
  142. package/dist/routes/stream.d.ts +9 -2
  143. package/dist/routes/stream.d.ts.map +1 -1
  144. package/dist/routes/stream.js +55 -2
  145. package/dist/routes/stream.js.map +1 -1
  146. package/dist/routes/tenant-helper.d.ts +20 -0
  147. package/dist/routes/tenant-helper.d.ts.map +1 -0
  148. package/dist/routes/tenant-helper.js +23 -0
  149. package/dist/routes/tenant-helper.js.map +1 -0
  150. package/package.json +11 -11
  151. package/LICENSE +0 -21
  152. package/dist/__tests__/agents-stats.test.d.ts +0 -5
  153. package/dist/__tests__/agents-stats.test.d.ts.map +0 -1
  154. package/dist/__tests__/agents-stats.test.js +0 -134
  155. package/dist/__tests__/agents-stats.test.js.map +0 -1
  156. package/dist/__tests__/alerts.test.d.ts +0 -5
  157. package/dist/__tests__/alerts.test.d.ts.map +0 -1
  158. package/dist/__tests__/alerts.test.js +0 -245
  159. package/dist/__tests__/alerts.test.js.map +0 -1
  160. package/dist/__tests__/analytics.test.d.ts +0 -5
  161. package/dist/__tests__/analytics.test.d.ts.map +0 -1
  162. package/dist/__tests__/analytics.test.js +0 -218
  163. package/dist/__tests__/analytics.test.js.map +0 -1
  164. package/dist/__tests__/api-keys.test.d.ts +0 -5
  165. package/dist/__tests__/api-keys.test.d.ts.map +0 -1
  166. package/dist/__tests__/api-keys.test.js +0 -118
  167. package/dist/__tests__/api-keys.test.js.map +0 -1
  168. package/dist/__tests__/auth-no-db.test.d.ts +0 -2
  169. package/dist/__tests__/auth-no-db.test.d.ts.map +0 -1
  170. package/dist/__tests__/auth-no-db.test.js +0 -43
  171. package/dist/__tests__/auth-no-db.test.js.map +0 -1
  172. package/dist/__tests__/auth.test.d.ts +0 -5
  173. package/dist/__tests__/auth.test.d.ts.map +0 -1
  174. package/dist/__tests__/auth.test.js +0 -86
  175. package/dist/__tests__/auth.test.js.map +0 -1
  176. package/dist/__tests__/config.test.d.ts +0 -2
  177. package/dist/__tests__/config.test.d.ts.map +0 -1
  178. package/dist/__tests__/config.test.js +0 -37
  179. package/dist/__tests__/config.test.js.map +0 -1
  180. package/dist/__tests__/events-ingest.test.d.ts +0 -5
  181. package/dist/__tests__/events-ingest.test.d.ts.map +0 -1
  182. package/dist/__tests__/events-ingest.test.js +0 -248
  183. package/dist/__tests__/events-ingest.test.js.map +0 -1
  184. package/dist/__tests__/events-query.test.d.ts +0 -5
  185. package/dist/__tests__/events-query.test.d.ts.map +0 -1
  186. package/dist/__tests__/events-query.test.js +0 -205
  187. package/dist/__tests__/events-query.test.js.map +0 -1
  188. package/dist/__tests__/health.test.d.ts +0 -5
  189. package/dist/__tests__/health.test.d.ts.map +0 -1
  190. package/dist/__tests__/health.test.js +0 -40
  191. package/dist/__tests__/health.test.js.map +0 -1
  192. package/dist/__tests__/ingest.test.d.ts +0 -8
  193. package/dist/__tests__/ingest.test.d.ts.map +0 -1
  194. package/dist/__tests__/ingest.test.js +0 -469
  195. package/dist/__tests__/ingest.test.js.map +0 -1
  196. package/dist/__tests__/llm-tracking.test.d.ts +0 -10
  197. package/dist/__tests__/llm-tracking.test.d.ts.map +0 -1
  198. package/dist/__tests__/llm-tracking.test.js +0 -602
  199. package/dist/__tests__/llm-tracking.test.js.map +0 -1
  200. package/dist/__tests__/sessions.test.d.ts +0 -5
  201. package/dist/__tests__/sessions.test.d.ts.map +0 -1
  202. package/dist/__tests__/sessions.test.js +0 -176
  203. package/dist/__tests__/sessions.test.js.map +0 -1
  204. package/dist/__tests__/stream.test.d.ts +0 -5
  205. package/dist/__tests__/stream.test.d.ts.map +0 -1
  206. package/dist/__tests__/stream.test.js +0 -352
  207. package/dist/__tests__/stream.test.js.map +0 -1
  208. package/dist/__tests__/test-helpers.d.ts +0 -24
  209. package/dist/__tests__/test-helpers.d.ts.map +0 -1
  210. package/dist/__tests__/test-helpers.js +0 -45
  211. package/dist/__tests__/test-helpers.js.map +0 -1
  212. package/dist/db/__tests__/init.test.d.ts +0 -2
  213. package/dist/db/__tests__/init.test.d.ts.map +0 -1
  214. package/dist/db/__tests__/init.test.js +0 -73
  215. package/dist/db/__tests__/init.test.js.map +0 -1
  216. package/dist/db/__tests__/sqlite-store-read.test.d.ts +0 -2
  217. package/dist/db/__tests__/sqlite-store-read.test.d.ts.map +0 -1
  218. package/dist/db/__tests__/sqlite-store-read.test.js +0 -749
  219. package/dist/db/__tests__/sqlite-store-read.test.js.map +0 -1
  220. package/dist/db/__tests__/sqlite-store-write.test.d.ts +0 -2
  221. package/dist/db/__tests__/sqlite-store-write.test.d.ts.map +0 -1
  222. package/dist/db/__tests__/sqlite-store-write.test.js +0 -418
  223. package/dist/db/__tests__/sqlite-store-write.test.js.map +0 -1
  224. package/dist/lib/__tests__/alert-engine.test.d.ts +0 -5
  225. package/dist/lib/__tests__/alert-engine.test.d.ts.map +0 -1
  226. package/dist/lib/__tests__/alert-engine.test.js +0 -211
  227. package/dist/lib/__tests__/alert-engine.test.js.map +0 -1
  228. package/dist/lib/__tests__/retention.test.d.ts +0 -2
  229. package/dist/lib/__tests__/retention.test.d.ts.map +0 -1
  230. package/dist/lib/__tests__/retention.test.js +0 -238
  231. package/dist/lib/__tests__/retention.test.js.map +0 -1
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Performance Trends Analysis (Story 4.4)
3
+ *
4
+ * Analyzes sessions over time to calculate success rates, durations,
5
+ * tool call averages, and error averages, with trend detection.
6
+ */
7
+ /**
8
+ * Analyze performance trends across sessions.
9
+ */
10
+ export async function analyzePerformance(store, opts = {}) {
11
+ // Query sessions
12
+ const sessionResult = await store.querySessions({
13
+ agentId: opts.agentId,
14
+ from: opts.from,
15
+ to: opts.to,
16
+ limit: 500,
17
+ });
18
+ const sessions = sessionResult.sessions;
19
+ const sessionsAnalyzed = sessions.length;
20
+ // Count events for metadata
21
+ const eventCount = await store.countEvents({
22
+ agentId: opts.agentId,
23
+ from: opts.from,
24
+ to: opts.to,
25
+ });
26
+ const timeRange = {
27
+ from: sessions.length > 0
28
+ ? sessions.reduce((min, s) => (s.startedAt < min ? s.startedAt : min), sessions[0].startedAt)
29
+ : (opts.from ?? ''),
30
+ to: sessions.length > 0
31
+ ? sessions.reduce((max, s) => (s.startedAt > max ? s.startedAt : max), sessions[0].startedAt)
32
+ : (opts.to ?? ''),
33
+ };
34
+ // Current aggregate metrics
35
+ const successCount = sessions.filter((s) => s.errorCount === 0).length;
36
+ const successRate = sessionsAnalyzed > 0 ? successCount / sessionsAnalyzed : 0;
37
+ const durations = sessions
38
+ .filter((s) => s.endedAt && s.startedAt)
39
+ .map((s) => new Date(s.endedAt).getTime() - new Date(s.startedAt).getTime());
40
+ const avgDuration = durations.length > 0 ? durations.reduce((a, b) => a + b, 0) / durations.length : 0;
41
+ const avgToolCalls = sessionsAnalyzed > 0
42
+ ? sessions.reduce((sum, s) => sum + s.toolCallCount, 0) / sessionsAnalyzed
43
+ : 0;
44
+ const avgErrors = sessionsAnalyzed > 0
45
+ ? sessions.reduce((sum, s) => sum + s.errorCount, 0) / sessionsAnalyzed
46
+ : 0;
47
+ // Bucket by day for trend lines
48
+ const dailyMap = new Map();
49
+ for (const session of sessions) {
50
+ const date = session.startedAt.slice(0, 10); // YYYY-MM-DD
51
+ const entry = dailyMap.get(date) ?? { sessions: [] };
52
+ entry.sessions.push(session);
53
+ dailyMap.set(date, entry);
54
+ }
55
+ const limit = opts.limit ?? 20;
56
+ const allBuckets = Array.from(dailyMap.entries())
57
+ .map(([date, data]) => {
58
+ const daySessions = data.sessions;
59
+ const daySuccess = daySessions.filter((s) => s.errorCount === 0).length;
60
+ const dayDurations = daySessions
61
+ .filter((s) => s.endedAt && s.startedAt)
62
+ .map((s) => new Date(s.endedAt).getTime() - new Date(s.startedAt).getTime());
63
+ return {
64
+ date,
65
+ successRate: daySessions.length > 0 ? daySuccess / daySessions.length : 0,
66
+ duration: dayDurations.length > 0
67
+ ? dayDurations.reduce((a, b) => a + b, 0) / dayDurations.length
68
+ : 0,
69
+ toolCalls: daySessions.length > 0
70
+ ? daySessions.reduce((sum, s) => sum + s.toolCallCount, 0) / daySessions.length
71
+ : 0,
72
+ errors: daySessions.length > 0
73
+ ? daySessions.reduce((sum, s) => sum + s.errorCount, 0) / daySessions.length
74
+ : 0,
75
+ };
76
+ })
77
+ .sort((a, b) => a.date.localeCompare(b.date));
78
+ // Respect limit on trend buckets
79
+ const trends = allBuckets.slice(-limit);
80
+ // Trend assessment: compare recent half vs historical half
81
+ const assessment = detectPerformanceTrend(allBuckets);
82
+ return {
83
+ current: {
84
+ successRate: Math.round(successRate * 10000) / 10000,
85
+ avgDuration: Math.round(avgDuration),
86
+ avgToolCalls: Math.round(avgToolCalls * 100) / 100,
87
+ avgErrors: Math.round(avgErrors * 100) / 100,
88
+ },
89
+ trends,
90
+ assessment,
91
+ metadata: {
92
+ sessionsAnalyzed,
93
+ eventsAnalyzed: eventCount,
94
+ timeRange,
95
+ },
96
+ };
97
+ }
98
+ /**
99
+ * Detect performance trend by comparing recent vs historical success rates.
100
+ */
101
+ function detectPerformanceTrend(buckets) {
102
+ if (buckets.length < 2)
103
+ return 'stable';
104
+ const midpoint = Math.floor(buckets.length / 2);
105
+ const recent = buckets.slice(midpoint);
106
+ const historical = buckets.slice(0, midpoint);
107
+ if (historical.length === 0 || recent.length === 0)
108
+ return 'stable';
109
+ const recentAvgSuccess = recent.reduce((s, b) => s + b.successRate, 0) / recent.length;
110
+ const historicalAvgSuccess = historical.reduce((s, b) => s + b.successRate, 0) / historical.length;
111
+ const diff = recentAvgSuccess - historicalAvgSuccess;
112
+ if (diff > 0.05)
113
+ return 'improving';
114
+ if (diff < -0.05)
115
+ return 'degrading';
116
+ return 'stable';
117
+ }
118
+ //# sourceMappingURL=performance-trends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance-trends.js","sourceRoot":"","sources":["../../../src/lib/analysis/performance-trends.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Tool Sequence Analysis (Story 4.2)
3
+ *
4
+ * Analyzes tool_call events to extract N-grams (2-grams and 3-grams)
5
+ * of tool sequences per session, and identifies error-prone sequences.
6
+ */
7
+ import type { IEventStore } from '@agentlensai/core';
8
+ import type { ToolSequenceResult } from '@agentlensai/core';
9
+ export interface ToolSequenceOpts {
10
+ agentId?: string;
11
+ from?: string;
12
+ to?: string;
13
+ limit?: number;
14
+ }
15
+ /**
16
+ * Analyze tool usage sequences across sessions.
17
+ */
18
+ export declare function analyzeToolSequences(store: IEventStore, opts?: ToolSequenceOpts): Promise<ToolSequenceResult>;
19
+ //# sourceMappingURL=tool-sequences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-sequences.d.ts","sourceRoot":"","sources":["../../../src/lib/analysis/tool-sequences.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,WAAW,EAClB,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CA8J7B"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Tool Sequence Analysis (Story 4.2)
3
+ *
4
+ * Analyzes tool_call events to extract N-grams (2-grams and 3-grams)
5
+ * of tool sequences per session, and identifies error-prone sequences.
6
+ */
7
+ /**
8
+ * Analyze tool usage sequences across sessions.
9
+ */
10
+ export async function analyzeToolSequences(store, opts = {}) {
11
+ const limit = opts.limit ?? 20;
12
+ // Query tool_call events
13
+ const toolCallResult = await store.queryEvents({
14
+ agentId: opts.agentId,
15
+ from: opts.from,
16
+ to: opts.to,
17
+ eventType: 'tool_call',
18
+ limit: 500,
19
+ order: 'asc',
20
+ });
21
+ // Also query tool_error events to identify error-prone sequences
22
+ const toolErrorResult = await store.queryEvents({
23
+ agentId: opts.agentId,
24
+ from: opts.from,
25
+ to: opts.to,
26
+ eventType: 'tool_error',
27
+ limit: 500,
28
+ order: 'asc',
29
+ });
30
+ const allToolCalls = toolCallResult.events;
31
+ const allToolErrors = toolErrorResult.events;
32
+ const eventsAnalyzed = allToolCalls.length + allToolErrors.length;
33
+ const timeRange = {
34
+ from: allToolCalls.length > 0 ? allToolCalls[0].timestamp : (opts.from ?? ''),
35
+ to: allToolCalls.length > 0 ? allToolCalls[allToolCalls.length - 1].timestamp : (opts.to ?? ''),
36
+ };
37
+ // Group tool_call events by session
38
+ const sessionToolCalls = new Map();
39
+ for (const event of allToolCalls) {
40
+ const list = sessionToolCalls.get(event.sessionId) ?? [];
41
+ list.push(event);
42
+ sessionToolCalls.set(event.sessionId, list);
43
+ }
44
+ // Group tool_error events by session for error-prone detection
45
+ const sessionErrors = new Map();
46
+ for (const event of allToolErrors) {
47
+ const list = sessionErrors.get(event.sessionId) ?? [];
48
+ list.push(event);
49
+ sessionErrors.set(event.sessionId, list);
50
+ }
51
+ // Extract tool names per session (ordered by timestamp)
52
+ const uniqueToolsSet = new Set();
53
+ let totalCalls = 0;
54
+ const sessionToolNames = new Map();
55
+ for (const [sessionId, calls] of sessionToolCalls) {
56
+ const names = calls.map((e) => {
57
+ const p = e.payload;
58
+ const name = String(p.toolName ?? 'unknown');
59
+ uniqueToolsSet.add(name);
60
+ return name;
61
+ });
62
+ sessionToolNames.set(sessionId, names);
63
+ totalCalls += names.length;
64
+ }
65
+ // Extract N-grams and count frequencies
66
+ // key = tools joined by "→", value = { frequency across sessions, set of sessions, errorFollowed count }
67
+ const ngramMap = new Map();
68
+ for (const [sessionId, toolNames] of sessionToolNames) {
69
+ const sessionErrorEvents = sessionErrors.get(sessionId) ?? [];
70
+ // Get the full session timeline for error-proximity checks
71
+ const sessionCalls = sessionToolCalls.get(sessionId) ?? [];
72
+ // Extract 2-grams and 3-grams
73
+ const seenInSession = new Set(); // Avoid counting same ngram twice per session
74
+ for (const n of [2, 3]) {
75
+ for (let i = 0; i <= toolNames.length - n; i++) {
76
+ const ngram = toolNames.slice(i, i + n);
77
+ const key = ngram.join('→');
78
+ if (!seenInSession.has(key)) {
79
+ seenInSession.add(key);
80
+ let entry = ngramMap.get(key);
81
+ if (!entry) {
82
+ entry = { tools: ngram, frequency: 0, sessions: new Set(), errorFollowed: 0 };
83
+ ngramMap.set(key, entry);
84
+ }
85
+ entry.frequency++;
86
+ entry.sessions.add(sessionId);
87
+ }
88
+ // Check if this ngram is followed by an error within 2 events
89
+ // The last event of the ngram is at index i + n - 1 in sessionCalls
90
+ const lastCallInNgram = sessionCalls[i + n - 1];
91
+ if (lastCallInNgram) {
92
+ const isErrorFollowed = sessionErrorEvents.some((errEvt) => {
93
+ // Error must be after the last tool call in ngram
94
+ // and within 2 "event positions" (by timestamp)
95
+ if (errEvt.timestamp < lastCallInNgram.timestamp)
96
+ return false;
97
+ // Count how many tool_call events are between the last ngram call and the error
98
+ const callsAfter = sessionCalls.filter((c) => c.timestamp > lastCallInNgram.timestamp && c.timestamp <= errEvt.timestamp);
99
+ return callsAfter.length <= 2;
100
+ });
101
+ if (isErrorFollowed) {
102
+ // We only count this once per session per ngram for error rate calculation
103
+ // But we need to track total occurrences vs error-followed
104
+ let entry = ngramMap.get(key);
105
+ // Track on first occurrence in session
106
+ if (seenInSession.has(`${key}:error-checked`))
107
+ continue;
108
+ seenInSession.add(`${key}:error-checked`);
109
+ entry.errorFollowed++;
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ // Calculate stats
116
+ const sessionLengths = Array.from(sessionToolNames.values()).map((n) => n.length);
117
+ const avgSequenceLength = sessionLengths.length > 0
118
+ ? sessionLengths.reduce((a, b) => a + b, 0) / sessionLengths.length
119
+ : 0;
120
+ // Build sorted results
121
+ const sequences = Array.from(ngramMap.values())
122
+ .map((entry) => ({
123
+ tools: entry.tools,
124
+ frequency: entry.frequency,
125
+ sessions: entry.sessions.size,
126
+ errorRate: entry.sessions.size > 0
127
+ ? entry.errorFollowed / entry.sessions.size
128
+ : 0,
129
+ }))
130
+ .sort((a, b) => b.frequency - a.frequency)
131
+ .slice(0, limit);
132
+ return {
133
+ sequences,
134
+ stats: {
135
+ avgSequenceLength: Math.round(avgSequenceLength * 100) / 100,
136
+ uniqueTools: uniqueToolsSet.size,
137
+ totalCalls,
138
+ },
139
+ metadata: {
140
+ eventsAnalyzed,
141
+ timeRange,
142
+ },
143
+ };
144
+ }
145
+ //# sourceMappingURL=tool-sequences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-sequences.js","sourceRoot":"","sources":["../../../src/lib/analysis/tool-sequences.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Context Retrieval — exports (Epic 5)
3
+ */
4
+ export { ContextRetriever } from './retrieval.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/context/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Context Retrieval — exports (Epic 5)
3
+ */
4
+ export { ContextRetriever } from './retrieval.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/context/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Context Retriever (Story 5.2)
3
+ *
4
+ * Combines semantic search over session summaries, lesson search,
5
+ * and key event retrieval to build cross-session context.
6
+ *
7
+ * Falls back to text search when embeddings are unavailable.
8
+ */
9
+ import type { ContextQuery, ContextResult } from '@agentlensai/core';
10
+ import type { EmbeddingStore } from '../../db/embedding-store.js';
11
+ import type { EmbeddingService } from '../embeddings/index.js';
12
+ import type { SessionSummaryStore } from '../../db/session-summary-store.js';
13
+ import type { LessonStore } from '../../db/lesson-store.js';
14
+ import type { IEventStore } from '@agentlensai/core';
15
+ export declare class ContextRetriever {
16
+ private readonly embeddingStore;
17
+ private readonly embeddingService;
18
+ private readonly sessionSummaryStore;
19
+ private readonly lessonStore;
20
+ private readonly eventStore;
21
+ constructor(embeddingStore: EmbeddingStore | null, embeddingService: EmbeddingService | null, sessionSummaryStore: SessionSummaryStore, lessonStore: LessonStore, eventStore: IEventStore);
22
+ /**
23
+ * Retrieve cross-session context by combining:
24
+ * 1. Semantic search over session summary embeddings
25
+ * 2. Lesson search (semantic or text-based)
26
+ * 3. Key events for matching sessions
27
+ * 4. Ranking by relevance + recency
28
+ */
29
+ retrieve(tenantId: string, query: ContextQuery): Promise<ContextResult>;
30
+ /**
31
+ * Find relevant sessions using semantic search (with text search fallback).
32
+ */
33
+ private findRelevantSessions;
34
+ /**
35
+ * Filter semantic search results by agentId/userId and rank by relevance + recency.
36
+ */
37
+ private filterAndRankSessions;
38
+ /**
39
+ * Text search fallback when embeddings are unavailable.
40
+ */
41
+ private textSearchSessions;
42
+ /**
43
+ * Find relevant lessons using semantic search (with text search fallback).
44
+ */
45
+ private findRelevantLessons;
46
+ /**
47
+ * Enrich a session result with key events from the timeline.
48
+ */
49
+ private enrichSessionWithEvents;
50
+ /**
51
+ * Compute a recency boost (0-1) based on how recent the content is.
52
+ * Items from the last 24h get ~1.0, items from 30+ days ago get ~0.0.
53
+ */
54
+ private computeRecencyBoost;
55
+ }
56
+ //# sourceMappingURL=retrieval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../../src/lib/context/retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAkD,MAAM,mBAAmB,CAAC;AACrH,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,mCAAmC,CAAC;AACnG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAJV,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,EACzC,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,WAAW;IAG1C;;;;;;OAMG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAsB7E;;OAEG;YACW,oBAAoB;IA6BlC;;OAEG;YACW,qBAAqB;IAwCnC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;YACW,mBAAmB;IAwDjC;;OAEG;YACW,uBAAuB;IA+CrC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;CAU5B"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Context Retriever (Story 5.2)
3
+ *
4
+ * Combines semantic search over session summaries, lesson search,
5
+ * and key event retrieval to build cross-session context.
6
+ *
7
+ * Falls back to text search when embeddings are unavailable.
8
+ */
9
+ import { summarizeEvent } from '../embeddings/summarizer.js';
10
+ /** Default maximum results */
11
+ const DEFAULT_LIMIT = 10;
12
+ /** Maximum key events per session in results */
13
+ const MAX_KEY_EVENTS = 5;
14
+ export class ContextRetriever {
15
+ embeddingStore;
16
+ embeddingService;
17
+ sessionSummaryStore;
18
+ lessonStore;
19
+ eventStore;
20
+ constructor(embeddingStore, embeddingService, sessionSummaryStore, lessonStore, eventStore) {
21
+ this.embeddingStore = embeddingStore;
22
+ this.embeddingService = embeddingService;
23
+ this.sessionSummaryStore = sessionSummaryStore;
24
+ this.lessonStore = lessonStore;
25
+ this.eventStore = eventStore;
26
+ }
27
+ /**
28
+ * Retrieve cross-session context by combining:
29
+ * 1. Semantic search over session summary embeddings
30
+ * 2. Lesson search (semantic or text-based)
31
+ * 3. Key events for matching sessions
32
+ * 4. Ranking by relevance + recency
33
+ */
34
+ async retrieve(tenantId, query) {
35
+ const limit = query.limit ?? DEFAULT_LIMIT;
36
+ // Step 1: Find relevant sessions
37
+ const sessionResults = await this.findRelevantSessions(tenantId, query, limit);
38
+ // Step 2: Find relevant lessons
39
+ const lessonResults = await this.findRelevantLessons(tenantId, query, limit);
40
+ // Step 3: For each matching session, get key events
41
+ const sessionsWithEvents = await Promise.all(sessionResults.map((s) => this.enrichSessionWithEvents(tenantId, s)));
42
+ return {
43
+ topic: query.topic,
44
+ sessions: sessionsWithEvents,
45
+ lessons: lessonResults,
46
+ totalSessions: sessionsWithEvents.length,
47
+ };
48
+ }
49
+ /**
50
+ * Find relevant sessions using semantic search (with text search fallback).
51
+ */
52
+ async findRelevantSessions(tenantId, query, limit) {
53
+ // Try semantic search first
54
+ if (this.embeddingService && this.embeddingStore) {
55
+ try {
56
+ const queryVector = await this.embeddingService.embed(query.topic);
57
+ const results = this.embeddingStore.similaritySearch(tenantId, queryVector, {
58
+ sourceType: 'session',
59
+ from: query.from,
60
+ to: query.to,
61
+ limit: limit * 2, // over-fetch for post-filtering
62
+ minScore: 0.3,
63
+ });
64
+ if (results.length > 0) {
65
+ return this.filterAndRankSessions(tenantId, results, query, limit);
66
+ }
67
+ }
68
+ catch {
69
+ // Fall through to text search
70
+ }
71
+ }
72
+ // Fallback: text search on session summaries
73
+ return this.textSearchSessions(tenantId, query, limit);
74
+ }
75
+ /**
76
+ * Filter semantic search results by agentId/userId and rank by relevance + recency.
77
+ */
78
+ async filterAndRankSessions(tenantId, results, query, limit) {
79
+ const sessions = [];
80
+ for (const result of results) {
81
+ // sourceId is the sessionId for session-scope embeddings
82
+ const sessionId = result.sourceId;
83
+ // Filter by agentId if provided
84
+ if (query.agentId) {
85
+ const session = await this.eventStore.getSession(sessionId);
86
+ if (!session || session.agentId !== query.agentId)
87
+ continue;
88
+ }
89
+ // Get the summary text from the store (richer than embedding text)
90
+ const summaryRecord = this.sessionSummaryStore.get(tenantId, sessionId);
91
+ const summary = summaryRecord?.summary ?? result.text;
92
+ // Recency boost: more recent sessions score slightly higher
93
+ const recencyBoost = this.computeRecencyBoost(result.createdAt);
94
+ const adjustedScore = result.score * 0.85 + recencyBoost * 0.15;
95
+ sessions.push({
96
+ sessionId,
97
+ summary,
98
+ relevanceScore: Math.round(adjustedScore * 10000) / 10000,
99
+ });
100
+ if (sessions.length >= limit)
101
+ break;
102
+ }
103
+ // Sort by adjusted score descending
104
+ sessions.sort((a, b) => b.relevanceScore - a.relevanceScore);
105
+ return sessions.slice(0, limit);
106
+ }
107
+ /**
108
+ * Text search fallback when embeddings are unavailable.
109
+ */
110
+ textSearchSessions(tenantId, query, limit) {
111
+ const results = this.sessionSummaryStore.search(tenantId, query.topic, limit * 2);
112
+ let filtered = results;
113
+ // If agentId filter is needed, we need to cross-reference sessions
114
+ // For text search, we can't easily filter by agentId synchronously here,
115
+ // so we'll skip that filter for the text fallback (best effort)
116
+ return filtered.slice(0, limit).map((r, index) => ({
117
+ sessionId: r.sessionId,
118
+ summary: r.summary,
119
+ // Assign a decreasing relevance score for text search results (1.0 → 0.5)
120
+ relevanceScore: Math.round((1.0 - index * (0.5 / Math.max(limit, 1))) * 10000) / 10000,
121
+ }));
122
+ }
123
+ /**
124
+ * Find relevant lessons using semantic search (with text search fallback).
125
+ */
126
+ async findRelevantLessons(tenantId, query, limit) {
127
+ // Try semantic search first
128
+ if (this.embeddingService && this.embeddingStore) {
129
+ try {
130
+ const queryVector = await this.embeddingService.embed(query.topic);
131
+ const results = this.embeddingStore.similaritySearch(tenantId, queryVector, {
132
+ sourceType: 'lesson',
133
+ limit,
134
+ minScore: 0.3,
135
+ });
136
+ if (results.length > 0) {
137
+ const lessons = [];
138
+ for (const result of results) {
139
+ const lesson = this.lessonStore.get(tenantId, result.sourceId);
140
+ if (lesson) {
141
+ lessons.push({
142
+ id: lesson.id,
143
+ title: lesson.title,
144
+ content: lesson.content,
145
+ category: lesson.category,
146
+ importance: lesson.importance,
147
+ relevanceScore: Math.round(result.score * 10000) / 10000,
148
+ });
149
+ }
150
+ }
151
+ return lessons;
152
+ }
153
+ }
154
+ catch {
155
+ // Fall through to text search
156
+ }
157
+ }
158
+ // Fallback: text search on lessons
159
+ const textResults = this.lessonStore.list(tenantId, {
160
+ search: query.topic,
161
+ limit,
162
+ });
163
+ return textResults.map((lesson, index) => ({
164
+ id: lesson.id,
165
+ title: lesson.title,
166
+ content: lesson.content,
167
+ category: lesson.category,
168
+ importance: lesson.importance,
169
+ // Assign decreasing scores for text search results
170
+ relevanceScore: Math.round((1.0 - index * (0.5 / Math.max(limit, 1))) * 10000) / 10000,
171
+ }));
172
+ }
173
+ /**
174
+ * Enrich a session result with key events from the timeline.
175
+ */
176
+ async enrichSessionWithEvents(tenantId, session) {
177
+ // Get session metadata for startedAt/endedAt/agentId
178
+ const sessionRecord = await this.eventStore.getSession(session.sessionId);
179
+ // Get timeline events for key event extraction
180
+ let keyEvents = [];
181
+ try {
182
+ const timeline = await this.eventStore.getSessionTimeline(session.sessionId);
183
+ // Extract key events: errors, tool calls, session boundaries
184
+ const significant = timeline.filter((e) => e.eventType === 'tool_error' ||
185
+ e.eventType === 'tool_call' ||
186
+ e.eventType === 'session_started' ||
187
+ e.eventType === 'session_ended' ||
188
+ e.severity === 'error' ||
189
+ e.severity === 'critical');
190
+ keyEvents = significant.slice(0, MAX_KEY_EVENTS).map((e) => {
191
+ const eventSummary = summarizeEvent(e) ?? `${e.eventType}`;
192
+ return {
193
+ id: e.id,
194
+ eventType: e.eventType,
195
+ summary: eventSummary,
196
+ timestamp: e.timestamp,
197
+ };
198
+ });
199
+ }
200
+ catch {
201
+ // Non-critical — return session without events
202
+ }
203
+ return {
204
+ sessionId: session.sessionId,
205
+ agentId: sessionRecord?.agentId ?? '',
206
+ summary: session.summary,
207
+ relevanceScore: session.relevanceScore,
208
+ startedAt: sessionRecord?.startedAt ?? '',
209
+ endedAt: sessionRecord?.endedAt,
210
+ keyEvents,
211
+ };
212
+ }
213
+ /**
214
+ * Compute a recency boost (0-1) based on how recent the content is.
215
+ * Items from the last 24h get ~1.0, items from 30+ days ago get ~0.0.
216
+ */
217
+ computeRecencyBoost(createdAt) {
218
+ const now = Date.now();
219
+ const created = new Date(createdAt).getTime();
220
+ const ageMs = now - created;
221
+ const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000;
222
+ if (ageMs <= 0)
223
+ return 1.0;
224
+ if (ageMs >= thirtyDaysMs)
225
+ return 0.0;
226
+ return 1.0 - ageMs / thirtyDaysMs;
227
+ }
228
+ }
229
+ //# sourceMappingURL=retrieval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval.js","sourceRoot":"","sources":["../../../src/lib/context/retrieval.ts"],"names":[],"mappings":"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"}