@nxuss/lemma 0.2.1 → 0.3.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 (113) hide show
  1. package/README.md +50 -5
  2. package/dist/cjs/api/dashboardRoutes.d.ts +28 -0
  3. package/dist/cjs/api/dashboardRoutes.d.ts.map +1 -0
  4. package/dist/cjs/api/dashboardRoutes.js +239 -0
  5. package/dist/cjs/api/dashboardRoutes.js.map +1 -0
  6. package/dist/cjs/api/server.d.ts +51 -0
  7. package/dist/cjs/api/server.d.ts.map +1 -0
  8. package/dist/cjs/api/server.js +166 -0
  9. package/dist/cjs/api/server.js.map +1 -0
  10. package/dist/cjs/core/AgentRegistry.d.ts +4 -0
  11. package/dist/cjs/core/AgentRegistry.d.ts.map +1 -1
  12. package/dist/cjs/core/AgentRegistry.js +6 -0
  13. package/dist/cjs/core/AgentRegistry.js.map +1 -1
  14. package/dist/cjs/core/DashboardWebSocketServer.d.ts +70 -0
  15. package/dist/cjs/core/DashboardWebSocketServer.d.ts.map +1 -0
  16. package/dist/cjs/core/DashboardWebSocketServer.js +211 -0
  17. package/dist/cjs/core/DashboardWebSocketServer.js.map +1 -0
  18. package/dist/cjs/core/OrchestrationEngine.d.ts +22 -0
  19. package/dist/cjs/core/OrchestrationEngine.d.ts.map +1 -1
  20. package/dist/cjs/core/OrchestrationEngine.js +98 -0
  21. package/dist/cjs/core/OrchestrationEngine.js.map +1 -1
  22. package/dist/cjs/core/SubconsciousEngine.d.ts +24 -0
  23. package/dist/cjs/core/SubconsciousEngine.d.ts.map +1 -1
  24. package/dist/cjs/core/SubconsciousEngine.js +110 -0
  25. package/dist/cjs/core/SubconsciousEngine.js.map +1 -1
  26. package/dist/cjs/core/WebSocketServer.d.ts.map +1 -1
  27. package/dist/cjs/core/WebSocketServer.js +4 -0
  28. package/dist/cjs/core/WebSocketServer.js.map +1 -1
  29. package/dist/cjs/db/database.d.ts +60 -0
  30. package/dist/cjs/db/database.d.ts.map +1 -0
  31. package/dist/cjs/db/database.js +297 -0
  32. package/dist/cjs/db/database.js.map +1 -0
  33. package/dist/cjs/db/migrations/001-dashboard-schema.d.ts +18 -0
  34. package/dist/cjs/db/migrations/001-dashboard-schema.d.ts.map +1 -0
  35. package/dist/cjs/db/migrations/001-dashboard-schema.js +175 -0
  36. package/dist/cjs/db/migrations/001-dashboard-schema.js.map +1 -0
  37. package/dist/cjs/embed/index.d.ts +1 -1
  38. package/dist/cjs/embed/index.d.ts.map +1 -1
  39. package/dist/cjs/embed/index.js +17 -9
  40. package/dist/cjs/embed/index.js.map +1 -1
  41. package/dist/cjs/proxy/Gatekeeper.d.ts +43 -0
  42. package/dist/cjs/proxy/Gatekeeper.d.ts.map +1 -0
  43. package/dist/cjs/proxy/Gatekeeper.js +202 -0
  44. package/dist/cjs/proxy/Gatekeeper.js.map +1 -0
  45. package/dist/cjs/proxy/KeyManager.d.ts +56 -0
  46. package/dist/cjs/proxy/KeyManager.d.ts.map +1 -0
  47. package/dist/cjs/proxy/KeyManager.js +220 -0
  48. package/dist/cjs/proxy/KeyManager.js.map +1 -0
  49. package/dist/cjs/proxy/ProjectStore.d.ts +84 -0
  50. package/dist/cjs/proxy/ProjectStore.d.ts.map +1 -0
  51. package/dist/cjs/proxy/ProjectStore.js +214 -0
  52. package/dist/cjs/proxy/ProjectStore.js.map +1 -0
  53. package/dist/cjs/proxy/SseRelay.d.ts +41 -0
  54. package/dist/cjs/proxy/SseRelay.d.ts.map +1 -0
  55. package/dist/cjs/proxy/SseRelay.js +176 -0
  56. package/dist/cjs/proxy/SseRelay.js.map +1 -0
  57. package/dist/esm/api/dashboardRoutes.d.ts +28 -0
  58. package/dist/esm/api/dashboardRoutes.d.ts.map +1 -0
  59. package/dist/esm/api/dashboardRoutes.js +236 -0
  60. package/dist/esm/api/dashboardRoutes.js.map +1 -0
  61. package/dist/esm/api/server.d.ts +51 -0
  62. package/dist/esm/api/server.d.ts.map +1 -0
  63. package/dist/esm/api/server.js +159 -0
  64. package/dist/esm/api/server.js.map +1 -0
  65. package/dist/esm/core/AgentRegistry.d.ts +4 -0
  66. package/dist/esm/core/AgentRegistry.d.ts.map +1 -1
  67. package/dist/esm/core/AgentRegistry.js +6 -0
  68. package/dist/esm/core/AgentRegistry.js.map +1 -1
  69. package/dist/esm/core/DashboardWebSocketServer.d.ts +70 -0
  70. package/dist/esm/core/DashboardWebSocketServer.d.ts.map +1 -0
  71. package/dist/esm/core/DashboardWebSocketServer.js +207 -0
  72. package/dist/esm/core/DashboardWebSocketServer.js.map +1 -0
  73. package/dist/esm/core/OrchestrationEngine.d.ts +22 -0
  74. package/dist/esm/core/OrchestrationEngine.d.ts.map +1 -1
  75. package/dist/esm/core/OrchestrationEngine.js +98 -0
  76. package/dist/esm/core/OrchestrationEngine.js.map +1 -1
  77. package/dist/esm/core/SubconsciousEngine.d.ts +24 -0
  78. package/dist/esm/core/SubconsciousEngine.d.ts.map +1 -1
  79. package/dist/esm/core/SubconsciousEngine.js +110 -0
  80. package/dist/esm/core/SubconsciousEngine.js.map +1 -1
  81. package/dist/esm/core/WebSocketServer.d.ts.map +1 -1
  82. package/dist/esm/core/WebSocketServer.js +4 -0
  83. package/dist/esm/core/WebSocketServer.js.map +1 -1
  84. package/dist/esm/db/database.d.ts +60 -0
  85. package/dist/esm/db/database.d.ts.map +1 -0
  86. package/dist/esm/db/database.js +293 -0
  87. package/dist/esm/db/database.js.map +1 -0
  88. package/dist/esm/db/migrations/001-dashboard-schema.d.ts +18 -0
  89. package/dist/esm/db/migrations/001-dashboard-schema.d.ts.map +1 -0
  90. package/dist/esm/db/migrations/001-dashboard-schema.js +172 -0
  91. package/dist/esm/db/migrations/001-dashboard-schema.js.map +1 -0
  92. package/dist/esm/embed/index.d.ts +1 -1
  93. package/dist/esm/embed/index.d.ts.map +1 -1
  94. package/dist/esm/embed/index.js +17 -9
  95. package/dist/esm/embed/index.js.map +1 -1
  96. package/dist/esm/proxy/Gatekeeper.d.ts +43 -0
  97. package/dist/esm/proxy/Gatekeeper.d.ts.map +1 -0
  98. package/dist/esm/proxy/Gatekeeper.js +165 -0
  99. package/dist/esm/proxy/Gatekeeper.js.map +1 -0
  100. package/dist/esm/proxy/KeyManager.d.ts +56 -0
  101. package/dist/esm/proxy/KeyManager.d.ts.map +1 -0
  102. package/dist/esm/proxy/KeyManager.js +213 -0
  103. package/dist/esm/proxy/KeyManager.js.map +1 -0
  104. package/dist/esm/proxy/ProjectStore.d.ts +84 -0
  105. package/dist/esm/proxy/ProjectStore.d.ts.map +1 -0
  106. package/dist/esm/proxy/ProjectStore.js +207 -0
  107. package/dist/esm/proxy/ProjectStore.js.map +1 -0
  108. package/dist/esm/proxy/SseRelay.d.ts +41 -0
  109. package/dist/esm/proxy/SseRelay.d.ts.map +1 -0
  110. package/dist/esm/proxy/SseRelay.js +169 -0
  111. package/dist/esm/proxy/SseRelay.js.map +1 -0
  112. package/lemma-proxy.js +810 -0
  113. package/package.json +17 -3
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * Lemma ProjectStore
4
+ *
5
+ * Project-aware storage resolver:
6
+ * - Detects project identity from package.json → cwd basename fallback
7
+ * - Hashes project name to a 12-char hex prefix for path safety
8
+ * - Provides Stats and Usage persistence helpers
9
+ *
10
+ * Layout:
11
+ * ~/.lemma-cache/
12
+ * proxy.pid
13
+ * proxy.port
14
+ * stats.json (global, cross-project)
15
+ * usage.json (global free-tier counter)
16
+ * license.json (KeyManager)
17
+ * <12-char hash>/ (per-project)
18
+ * cache.db (future SQLite)
19
+ * project-stats.json
20
+ */
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.ProjectStore = exports.WARNING_THRESHOLD = exports.FREE_TIER_LIMIT = exports.USAGE_FILE = exports.STATS_FILE = exports.PORT_FILE = exports.PID_FILE = exports.CACHE_DIR = void 0;
26
+ const fs_1 = __importDefault(require("fs"));
27
+ const path_1 = __importDefault(require("path"));
28
+ const crypto_1 = __importDefault(require("crypto"));
29
+ // ─── Constants ────────────────────────────────────────────────────────────────
30
+ const HOME = process.env.HOME || process.env.USERPROFILE || '~';
31
+ exports.CACHE_DIR = path_1.default.join(HOME, '.lemma-cache');
32
+ exports.PID_FILE = path_1.default.join(exports.CACHE_DIR, 'proxy.pid');
33
+ exports.PORT_FILE = path_1.default.join(exports.CACHE_DIR, 'proxy.port');
34
+ exports.STATS_FILE = path_1.default.join(exports.CACHE_DIR, 'stats.json');
35
+ exports.USAGE_FILE = path_1.default.join(exports.CACHE_DIR, 'usage.json');
36
+ exports.FREE_TIER_LIMIT = 300; // queries per month
37
+ exports.WARNING_THRESHOLD = 0.8; // warn at 80%
38
+ // ─── ProjectStore ─────────────────────────────────────────────────────────────
39
+ class ProjectStore {
40
+ constructor(overrideName) {
41
+ this.ensureCacheDir();
42
+ this.project = this.resolveProject(overrideName);
43
+ this.stats = this.loadStats();
44
+ this.usage = this.loadUsage();
45
+ }
46
+ // ── Project Resolution ──────────────────────────────────────────────────────
47
+ getProject() {
48
+ return this.project;
49
+ }
50
+ resolveProject(overrideName) {
51
+ const name = overrideName || this.detectProjectName();
52
+ const hash = crypto_1.default.createHash('sha1').update(name).digest('hex').slice(0, 12);
53
+ const dir = path_1.default.join(exports.CACHE_DIR, hash);
54
+ if (!fs_1.default.existsSync(dir)) {
55
+ fs_1.default.mkdirSync(dir, { recursive: true });
56
+ }
57
+ // Write a human-readable marker inside the hash dir
58
+ const markerFile = path_1.default.join(dir, 'project-name.txt');
59
+ if (!fs_1.default.existsSync(markerFile)) {
60
+ fs_1.default.writeFileSync(markerFile, name);
61
+ }
62
+ return {
63
+ name,
64
+ hash,
65
+ cacheDir: dir,
66
+ dbFile: path_1.default.join(dir, 'cache.db'),
67
+ statsFile: path_1.default.join(dir, 'project-stats.json'),
68
+ };
69
+ }
70
+ detectProjectName() {
71
+ const cwd = process.cwd();
72
+ const pkgPath = path_1.default.join(cwd, 'package.json');
73
+ if (fs_1.default.existsSync(pkgPath)) {
74
+ try {
75
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
76
+ if (pkg.name)
77
+ return pkg.name;
78
+ }
79
+ catch {
80
+ // Ignore parse errors
81
+ }
82
+ }
83
+ return path_1.default.basename(cwd);
84
+ }
85
+ // ── Stats ───────────────────────────────────────────────────────────────────
86
+ getStats() {
87
+ return this.stats;
88
+ }
89
+ getProjectStats() {
90
+ return this.stats[this.project.name] || this.emptyProjectStats();
91
+ }
92
+ recordRequest(opts) {
93
+ if (!this.stats[this.project.name]) {
94
+ this.stats[this.project.name] = this.emptyProjectStats();
95
+ }
96
+ const s = this.stats[this.project.name];
97
+ s.total++;
98
+ s.totalLatency += opts.latencyMs;
99
+ if (opts.fromCache) {
100
+ s.hits++;
101
+ s.totalTokensSaved += opts.tokensSaved || 0;
102
+ }
103
+ else {
104
+ s.misses++;
105
+ }
106
+ if (!s.providers[opts.provider]) {
107
+ s.providers[opts.provider] = { hits: 0, misses: 0 };
108
+ }
109
+ if (opts.fromCache) {
110
+ s.providers[opts.provider].hits++;
111
+ }
112
+ else {
113
+ s.providers[opts.provider].misses++;
114
+ }
115
+ this.saveStats();
116
+ }
117
+ emptyProjectStats() {
118
+ return { total: 0, hits: 0, misses: 0, totalLatency: 0, totalTokensSaved: 0, providers: {} };
119
+ }
120
+ loadStats() {
121
+ try {
122
+ if (fs_1.default.existsSync(exports.STATS_FILE)) {
123
+ return JSON.parse(fs_1.default.readFileSync(exports.STATS_FILE, 'utf8'));
124
+ }
125
+ }
126
+ catch {
127
+ // Ignore
128
+ }
129
+ return {};
130
+ }
131
+ saveStats() {
132
+ try {
133
+ fs_1.default.writeFileSync(exports.STATS_FILE, JSON.stringify(this.stats, null, 2));
134
+ }
135
+ catch {
136
+ // Ignore
137
+ }
138
+ }
139
+ // ── Usage (Free Tier) ───────────────────────────────────────────────────────
140
+ getUsage() {
141
+ return this.usage;
142
+ }
143
+ incrementUsage() {
144
+ this.usage.count++;
145
+ this.saveUsage();
146
+ if (this.usage.count === Math.floor(exports.FREE_TIER_LIMIT * exports.WARNING_THRESHOLD)) {
147
+ console.log(`\n⚠️ Free tier: ${this.usage.count}/${exports.FREE_TIER_LIMIT} queries used this month`);
148
+ console.log(`💡 Upgrade to Pro: https://lemma.nxus.studio/upgrade\n`);
149
+ }
150
+ }
151
+ checkUsageLimit() {
152
+ const remaining = exports.FREE_TIER_LIMIT - this.usage.count;
153
+ if (remaining <= 0) {
154
+ return {
155
+ allowed: false,
156
+ remaining: 0,
157
+ warning: `Free tier limit reached (${exports.FREE_TIER_LIMIT}/month). Upgrade: https://lemma.nxus.studio/upgrade`,
158
+ };
159
+ }
160
+ const percentUsed = this.usage.count / exports.FREE_TIER_LIMIT;
161
+ if (percentUsed >= exports.WARNING_THRESHOLD) {
162
+ return {
163
+ allowed: true,
164
+ remaining,
165
+ warning: `Approaching free tier limit: ${remaining} queries remaining.`,
166
+ };
167
+ }
168
+ return { allowed: true, remaining };
169
+ }
170
+ getNextResetDate() {
171
+ const now = new Date();
172
+ return new Date(now.getFullYear(), now.getMonth() + 1, 1).toISOString();
173
+ }
174
+ loadUsage() {
175
+ try {
176
+ if (fs_1.default.existsSync(exports.USAGE_FILE)) {
177
+ const u = JSON.parse(fs_1.default.readFileSync(exports.USAGE_FILE, 'utf8'));
178
+ // Check if we need to reset (new month)
179
+ const now = new Date();
180
+ const lastReset = new Date(u.lastReset || 0);
181
+ if (now.getMonth() !== lastReset.getMonth() || now.getFullYear() !== lastReset.getFullYear()) {
182
+ const newRecord = {
183
+ count: 0,
184
+ lastReset: now.toISOString(),
185
+ history: [...(u.history || []), { month: lastReset.toISOString().slice(0, 7), count: u.count }],
186
+ };
187
+ this.saveUsage(newRecord);
188
+ return newRecord;
189
+ }
190
+ return u;
191
+ }
192
+ }
193
+ catch {
194
+ // Ignore
195
+ }
196
+ return { count: 0, lastReset: new Date().toISOString(), history: [] };
197
+ }
198
+ saveUsage(override) {
199
+ try {
200
+ fs_1.default.writeFileSync(exports.USAGE_FILE, JSON.stringify(override || this.usage, null, 2));
201
+ }
202
+ catch {
203
+ // Ignore
204
+ }
205
+ }
206
+ // ── Utilities ───────────────────────────────────────────────────────────────
207
+ ensureCacheDir() {
208
+ if (!fs_1.default.existsSync(exports.CACHE_DIR)) {
209
+ fs_1.default.mkdirSync(exports.CACHE_DIR, { recursive: true });
210
+ }
211
+ }
212
+ }
213
+ exports.ProjectStore = ProjectStore;
214
+ //# sourceMappingURL=ProjectStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectStore.js","sourceRoot":"","sources":["../../../src/proxy/ProjectStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Lemma SseRelay
3
+ *
4
+ * Handles Server-Sent Events (SSE) streaming in two modes:
5
+ *
6
+ * MISS mode: Pipes upstream SSE response from OpenAI/Anthropic to the client
7
+ * in real-time (transparent relay).
8
+ *
9
+ * HIT mode: Simulates an SSE stream from a cached response by chunking the
10
+ * text into ~5-word pieces and emitting them with a small delay.
11
+ * Visually identical to a real stream for IDEs like Cursor.
12
+ *
13
+ * Both modes:
14
+ * - Set correct SSE headers (text/event-stream, no-cache)
15
+ * - Inject X-Lemma-Cache, X-Lemma-Similarity, X-Lemma-Tier headers
16
+ * - Append the `data: [DONE]` sentinel
17
+ * - Support both OpenAI and Anthropic SSE envelope formats
18
+ */
19
+ import { Request, Response } from 'express';
20
+ export type Provider = 'openai' | 'anthropic';
21
+ export interface SseRelayOptions {
22
+ provider: Provider;
23
+ tier: 'standard' | 'pro';
24
+ similarity?: number;
25
+ latencyMs?: number;
26
+ }
27
+ export declare class SseRelay {
28
+ /**
29
+ * Simulate an SSE stream from a cached response.
30
+ */
31
+ static simulateHit(res: Response, cachedResponse: any, opts: SseRelayOptions): Promise<void>;
32
+ /**
33
+ * Relay a live upstream SSE stream transparently.
34
+ */
35
+ static relayMiss(req: Request, res: Response, upstreamBody: any, provider: Provider, opts: SseRelayOptions): Promise<void>;
36
+ private static setSseHeaders;
37
+ private static buildUpstreamRequest;
38
+ private static buildChunkEvent;
39
+ private static extractTextFromResponse;
40
+ }
41
+ //# sourceMappingURL=SseRelay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SseRelay.d.ts","sourceRoot":"","sources":["../../../src/proxy/SseRelay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAS5C,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,QAAQ;IACnB;;OAEG;WACU,WAAW,CACtB,GAAG,EAAE,QAAQ,EACb,cAAc,EAAE,GAAG,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC;IAuBhB;;OAEG;WACU,SAAS,CACpB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,YAAY,EAAE,GAAG,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC;IA0DhB,OAAO,CAAC,MAAM,CAAC,aAAa;IAa5B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAmBnC,OAAO,CAAC,MAAM,CAAC,eAAe;IA+B9B,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAevC"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Lemma SseRelay
4
+ *
5
+ * Handles Server-Sent Events (SSE) streaming in two modes:
6
+ *
7
+ * MISS mode: Pipes upstream SSE response from OpenAI/Anthropic to the client
8
+ * in real-time (transparent relay).
9
+ *
10
+ * HIT mode: Simulates an SSE stream from a cached response by chunking the
11
+ * text into ~5-word pieces and emitting them with a small delay.
12
+ * Visually identical to a real stream for IDEs like Cursor.
13
+ *
14
+ * Both modes:
15
+ * - Set correct SSE headers (text/event-stream, no-cache)
16
+ * - Inject X-Lemma-Cache, X-Lemma-Similarity, X-Lemma-Tier headers
17
+ * - Append the `data: [DONE]` sentinel
18
+ * - Support both OpenAI and Anthropic SSE envelope formats
19
+ */
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.SseRelay = void 0;
25
+ const http_1 = __importDefault(require("http"));
26
+ const https_1 = __importDefault(require("https"));
27
+ // ─── Constants ────────────────────────────────────────────────────────────────
28
+ const CHUNK_WORDS = 5; // words per simulated chunk
29
+ const CHUNK_DELAY_MS = 15; // ms between simulated chunks
30
+ // ─── SseRelay ─────────────────────────────────────────────────────────────────
31
+ class SseRelay {
32
+ /**
33
+ * Simulate an SSE stream from a cached response.
34
+ */
35
+ static async simulateHit(res, cachedResponse, opts) {
36
+ SseRelay.setSseHeaders(res, opts);
37
+ const text = SseRelay.extractTextFromResponse(cachedResponse, opts.provider);
38
+ const model = cachedResponse?.model || (opts.provider === 'openai' ? 'gpt-4' : 'claude-3-5-sonnet-20241022');
39
+ const id = `lemma-hit-${Date.now()}`;
40
+ const words = text.split(' ');
41
+ // Emit chunks
42
+ for (let i = 0; i < words.length; i += CHUNK_WORDS) {
43
+ const chunk = words.slice(i, i + CHUNK_WORDS).join(' ');
44
+ const sseData = SseRelay.buildChunkEvent(chunk, id, model, opts.provider, false);
45
+ res.write(`data: ${JSON.stringify(sseData)}\n\n`);
46
+ await sleep(CHUNK_DELAY_MS);
47
+ }
48
+ // Emit final chunk (finish_reason: stop)
49
+ const stopEvent = SseRelay.buildChunkEvent('', id, model, opts.provider, true);
50
+ res.write(`data: ${JSON.stringify(stopEvent)}\n\n`);
51
+ res.write('data: [DONE]\n\n');
52
+ res.end();
53
+ }
54
+ /**
55
+ * Relay a live upstream SSE stream transparently.
56
+ */
57
+ static async relayMiss(req, res, upstreamBody, provider, opts) {
58
+ SseRelay.setSseHeaders(res, opts);
59
+ const apiKey = provider === 'openai'
60
+ ? process.env.OPENAI_API_KEY
61
+ : process.env.ANTHROPIC_API_KEY;
62
+ if (!apiKey) {
63
+ res.write(`data: ${JSON.stringify({ error: `${provider.toUpperCase()}_API_KEY not set` })}\n\n`);
64
+ res.write('data: [DONE]\n\n');
65
+ res.end();
66
+ return;
67
+ }
68
+ const { hostname, path, headers } = SseRelay.buildUpstreamRequest(provider, apiKey);
69
+ const body = JSON.stringify({ ...upstreamBody, stream: true });
70
+ await new Promise((resolve, reject) => {
71
+ const lib = hostname.startsWith('localhost') ? http_1.default : https_1.default;
72
+ const reqOpts = {
73
+ hostname,
74
+ port: hostname.startsWith('localhost') ? 80 : 443,
75
+ path,
76
+ method: 'POST',
77
+ headers: {
78
+ ...headers,
79
+ 'Content-Type': 'application/json',
80
+ 'Content-Length': Buffer.byteLength(body),
81
+ },
82
+ };
83
+ const upstreamReq = lib.request(reqOpts, (upstreamRes) => {
84
+ upstreamRes.on('data', (chunk) => {
85
+ res.write(chunk);
86
+ });
87
+ upstreamRes.on('end', () => {
88
+ res.write('data: [DONE]\n\n');
89
+ res.end();
90
+ resolve();
91
+ });
92
+ upstreamRes.on('error', reject);
93
+ });
94
+ upstreamReq.on('error', (err) => {
95
+ res.write(`data: ${JSON.stringify({ error: err.message })}\n\n`);
96
+ res.write('data: [DONE]\n\n');
97
+ res.end();
98
+ resolve();
99
+ });
100
+ upstreamReq.write(body);
101
+ upstreamReq.end();
102
+ });
103
+ }
104
+ // ── Private helpers ─────────────────────────────────────────────────────────
105
+ static setSseHeaders(res, opts) {
106
+ res.setHeader('Content-Type', 'text/event-stream');
107
+ res.setHeader('Cache-Control', 'no-cache');
108
+ res.setHeader('Connection', 'keep-alive');
109
+ res.setHeader('X-Accel-Buffering', 'no');
110
+ res.setHeader('X-Lemma-Cache', 'HIT');
111
+ res.setHeader('X-Lemma-Similarity', (opts.similarity ?? 1.0).toFixed(3));
112
+ res.setHeader('X-Lemma-Tier', opts.tier);
113
+ if (opts.latencyMs !== undefined) {
114
+ res.setHeader('X-Lemma-Latency', `${opts.latencyMs}ms`);
115
+ }
116
+ }
117
+ static buildUpstreamRequest(provider, apiKey) {
118
+ if (provider === 'openai') {
119
+ return {
120
+ hostname: 'api.openai.com',
121
+ path: '/v1/chat/completions',
122
+ headers: { Authorization: `Bearer ${apiKey}` },
123
+ };
124
+ }
125
+ return {
126
+ hostname: 'api.anthropic.com',
127
+ path: '/v1/messages',
128
+ headers: { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' },
129
+ };
130
+ }
131
+ static buildChunkEvent(text, id, model, provider, isStop) {
132
+ if (provider === 'openai') {
133
+ return {
134
+ id,
135
+ object: 'chat.completion.chunk',
136
+ created: Math.floor(Date.now() / 1000),
137
+ model,
138
+ choices: [{
139
+ index: 0,
140
+ delta: isStop ? {} : { content: text },
141
+ finish_reason: isStop ? 'stop' : null,
142
+ }],
143
+ };
144
+ }
145
+ // Anthropic format
146
+ if (isStop) {
147
+ return { type: 'message_stop' };
148
+ }
149
+ return {
150
+ type: 'content_block_delta',
151
+ index: 0,
152
+ delta: { type: 'text_delta', text },
153
+ };
154
+ }
155
+ static extractTextFromResponse(response, provider) {
156
+ try {
157
+ if (provider === 'openai') {
158
+ return response?.choices?.[0]?.message?.content || '';
159
+ }
160
+ // Anthropic
161
+ const content = response?.content;
162
+ if (Array.isArray(content)) {
163
+ return content.map((c) => c.text || '').join('');
164
+ }
165
+ return String(content || '');
166
+ }
167
+ catch {
168
+ return '';
169
+ }
170
+ }
171
+ }
172
+ exports.SseRelay = SseRelay;
173
+ function sleep(ms) {
174
+ return new Promise((resolve) => setTimeout(resolve, ms));
175
+ }
176
+ //# sourceMappingURL=SseRelay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SseRelay.js","sourceRoot":"","sources":["../../../src/proxy/SseRelay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Dashboard REST API Routes
3
+ * Provides real-time metrics and analytics endpoints for the Phase 2 dashboard
4
+ *
5
+ * Endpoints:
6
+ * GET /api/metrics - System-wide metrics
7
+ * GET /api/agents - Active agents with capabilities
8
+ * GET /api/events - Paginated event log
9
+ * GET /api/cache-stats - Cache statistics and top queries
10
+ * POST /api/cache/clear - Clear cache (admin)
11
+ * POST /api/debugger/pause - Pause all agents
12
+ * POST /api/debugger/resume - Resume agents
13
+ * POST /api/debugger/rewind - Rewind to event state
14
+ */
15
+ import { Router } from 'express';
16
+ import { OrchestrationEngine } from '../core/OrchestrationEngine';
17
+ import { AgentRegistry } from '../core/AgentRegistry';
18
+ import { SubconsciousEngine } from '../core/SubconsciousEngine';
19
+ interface DashboardAPIContext {
20
+ eventLog: any[];
21
+ orchestrationEngine: OrchestrationEngine;
22
+ agentRegistry: AgentRegistry;
23
+ eventSource: any;
24
+ cacheStore: SubconsciousEngine;
25
+ }
26
+ export declare function createDashboardRouter(context: DashboardAPIContext): Router;
27
+ export {};
28
+ //# sourceMappingURL=dashboardRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardRoutes.d.ts","sourceRoot":"","sources":["../../../src/api/dashboardRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAKhE,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,GAAG,CAAC;IACjB,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA8O1E"}