agent-knowledge 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/LICENSE +21 -0
- package/README.md +191 -0
- package/dist/dashboard.d.ts +4 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +434 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/embeddings/claude.d.ts +21 -0
- package/dist/embeddings/claude.d.ts.map +1 -0
- package/dist/embeddings/claude.js +84 -0
- package/dist/embeddings/claude.js.map +1 -0
- package/dist/embeddings/factory.d.ts +9 -0
- package/dist/embeddings/factory.d.ts.map +1 -0
- package/dist/embeddings/factory.js +60 -0
- package/dist/embeddings/factory.js.map +1 -0
- package/dist/embeddings/gemini.d.ts +21 -0
- package/dist/embeddings/gemini.d.ts.map +1 -0
- package/dist/embeddings/gemini.js +86 -0
- package/dist/embeddings/gemini.js.map +1 -0
- package/dist/embeddings/index.d.ts +4 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +3 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/local.d.ts +20 -0
- package/dist/embeddings/local.d.ts.map +1 -0
- package/dist/embeddings/local.js +73 -0
- package/dist/embeddings/local.js.map +1 -0
- package/dist/embeddings/openai.d.ts +20 -0
- package/dist/embeddings/openai.d.ts.map +1 -0
- package/dist/embeddings/openai.js +84 -0
- package/dist/embeddings/openai.js.map +1 -0
- package/dist/embeddings/types.d.ts +39 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +12 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/distill.d.ts +27 -0
- package/dist/knowledge/distill.d.ts.map +1 -0
- package/dist/knowledge/distill.js +407 -0
- package/dist/knowledge/distill.js.map +1 -0
- package/dist/knowledge/git.d.ts +30 -0
- package/dist/knowledge/git.d.ts.map +1 -0
- package/dist/knowledge/git.js +228 -0
- package/dist/knowledge/git.js.map +1 -0
- package/dist/knowledge/search.d.ts +20 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +72 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/store.d.ts +47 -0
- package/dist/knowledge/store.d.ts.map +1 -0
- package/dist/knowledge/store.js +173 -0
- package/dist/knowledge/store.js.map +1 -0
- package/dist/search/excerpt.d.ts +12 -0
- package/dist/search/excerpt.d.ts.map +1 -0
- package/dist/search/excerpt.js +28 -0
- package/dist/search/excerpt.js.map +1 -0
- package/dist/search/fuzzy.d.ts +15 -0
- package/dist/search/fuzzy.d.ts.map +1 -0
- package/dist/search/fuzzy.js +81 -0
- package/dist/search/fuzzy.js.map +1 -0
- package/dist/search/tfidf.d.ts +19 -0
- package/dist/search/tfidf.d.ts.map +1 -0
- package/dist/search/tfidf.js +200 -0
- package/dist/search/tfidf.js.map +1 -0
- package/dist/search/types.d.ts +19 -0
- package/dist/search/types.d.ts.map +1 -0
- package/dist/search/types.js +2 -0
- package/dist/search/types.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +518 -0
- package/dist/server.js.map +1 -0
- package/dist/sessions/indexer.d.ts +15 -0
- package/dist/sessions/indexer.d.ts.map +1 -0
- package/dist/sessions/indexer.js +182 -0
- package/dist/sessions/indexer.js.map +1 -0
- package/dist/sessions/parser.d.ts +58 -0
- package/dist/sessions/parser.d.ts.map +1 -0
- package/dist/sessions/parser.js +142 -0
- package/dist/sessions/parser.js.map +1 -0
- package/dist/sessions/scopes.d.ts +16 -0
- package/dist/sessions/scopes.d.ts.map +1 -0
- package/dist/sessions/scopes.js +153 -0
- package/dist/sessions/scopes.js.map +1 -0
- package/dist/sessions/search.d.ts +26 -0
- package/dist/sessions/search.d.ts.map +1 -0
- package/dist/sessions/search.js +256 -0
- package/dist/sessions/search.js.map +1 -0
- package/dist/sessions/summary.d.ts +28 -0
- package/dist/sessions/summary.d.ts.map +1 -0
- package/dist/sessions/summary.js +135 -0
- package/dist/sessions/summary.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +109 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/app.js +1029 -0
- package/dist/ui/index.html +373 -0
- package/dist/ui/styles.css +1508 -0
- package/dist/ui/ui/app.js +811 -0
- package/dist/ui/ui/index.html +300 -0
- package/dist/ui/ui/styles.css +1154 -0
- package/dist/validate.d.ts +21 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +86 -0
- package/dist/validate.js.map +1 -0
- package/dist/vectorstore/chunker.d.ts +48 -0
- package/dist/vectorstore/chunker.d.ts.map +1 -0
- package/dist/vectorstore/chunker.js +165 -0
- package/dist/vectorstore/chunker.js.map +1 -0
- package/dist/vectorstore/index.d.ts +5 -0
- package/dist/vectorstore/index.d.ts.map +1 -0
- package/dist/vectorstore/index.js +3 -0
- package/dist/vectorstore/index.js.map +1 -0
- package/dist/vectorstore/store.d.ts +139 -0
- package/dist/vectorstore/store.d.ts.map +1 -0
- package/dist/vectorstore/store.js +500 -0
- package/dist/vectorstore/store.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docs/ARCHITECTURE.md +244 -0
- package/docs/DASHBOARD.md +133 -0
- package/docs/SETUP.md +178 -0
- package/package.json +92 -0
- package/scripts/copy-ui.js +6 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import http from 'http';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
5
|
+
import { listEntries, readEntry } from './knowledge/store.js';
|
|
6
|
+
import { searchKnowledge } from './knowledge/search.js';
|
|
7
|
+
import { getProjectDirs, getSessionFiles, parseSessionFile, extractMessages, getSessionMeta, } from './sessions/parser.js';
|
|
8
|
+
import { searchSessions } from './sessions/search.js';
|
|
9
|
+
import { listSessions, getSessionSummary } from './sessions/summary.js';
|
|
10
|
+
import { scopedSearch } from './sessions/scopes.js';
|
|
11
|
+
import { VectorStore } from './vectorstore/index.js';
|
|
12
|
+
import { getConfig } from './types.js';
|
|
13
|
+
import { getVersion } from './version.js';
|
|
14
|
+
const VERSION = getVersion();
|
|
15
|
+
const DEFAULT_PORT = 3423;
|
|
16
|
+
const HEARTBEAT_INTERVAL = 30_000;
|
|
17
|
+
const MAX_WS_CONNECTIONS = 50;
|
|
18
|
+
const MAX_WS_MESSAGE_SIZE = 4096;
|
|
19
|
+
const MIME_TYPES = {
|
|
20
|
+
'.html': 'text/html; charset=utf-8',
|
|
21
|
+
'.css': 'text/css; charset=utf-8',
|
|
22
|
+
'.js': 'application/javascript; charset=utf-8',
|
|
23
|
+
'.json': 'application/json; charset=utf-8',
|
|
24
|
+
'.png': 'image/png',
|
|
25
|
+
'.svg': 'image/svg+xml',
|
|
26
|
+
'.ico': 'image/x-icon',
|
|
27
|
+
};
|
|
28
|
+
function resolveUiDir() {
|
|
29
|
+
const moduleUrl = new URL(import.meta.url);
|
|
30
|
+
let moduleDir;
|
|
31
|
+
if (process.platform === 'win32') {
|
|
32
|
+
moduleDir = moduleUrl.pathname.replace(/^\/([a-zA-Z]:)/, '$1');
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
moduleDir = moduleUrl.pathname;
|
|
36
|
+
}
|
|
37
|
+
moduleDir = path.dirname(moduleDir);
|
|
38
|
+
const srcUi = path.resolve(moduleDir, 'ui');
|
|
39
|
+
if (fs.existsSync(srcUi))
|
|
40
|
+
return srcUi;
|
|
41
|
+
const distUi = path.resolve(moduleDir, '..', 'dist', 'ui');
|
|
42
|
+
if (fs.existsSync(distUi))
|
|
43
|
+
return distUi;
|
|
44
|
+
return srcUi;
|
|
45
|
+
}
|
|
46
|
+
function jsonResponse(res, data, status = 200) {
|
|
47
|
+
const body = JSON.stringify(data, null, 2);
|
|
48
|
+
res.writeHead(status, {
|
|
49
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
50
|
+
'Access-Control-Allow-Origin': '*',
|
|
51
|
+
'X-Content-Type-Options': 'nosniff',
|
|
52
|
+
});
|
|
53
|
+
res.end(body);
|
|
54
|
+
}
|
|
55
|
+
function errorResponse(res, message, status = 500) {
|
|
56
|
+
jsonResponse(res, { error: message }, status);
|
|
57
|
+
}
|
|
58
|
+
function serveStatic(uiDir, reqPath, res) {
|
|
59
|
+
const filePath = reqPath === '/' ? '/index.html' : reqPath;
|
|
60
|
+
// Decode and reject path traversal attempts
|
|
61
|
+
let decoded;
|
|
62
|
+
try {
|
|
63
|
+
decoded = decodeURIComponent(filePath);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
errorResponse(res, 'Bad request', 400);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (decoded.includes('\0') || /(?:^|[\\/])\.\.(?:[\\/]|$)/.test(decoded)) {
|
|
70
|
+
errorResponse(res, 'Forbidden', 403);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const resolved = path.resolve(uiDir, '.' + decoded);
|
|
74
|
+
// Use realpathSync to resolve symlinks for robust traversal check
|
|
75
|
+
let realBase;
|
|
76
|
+
try {
|
|
77
|
+
realBase = fs.realpathSync(uiDir);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
errorResponse(res, 'Not found', 404);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!resolved.startsWith(realBase)) {
|
|
84
|
+
errorResponse(res, 'Forbidden', 403);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Also verify the actual resolved file (after symlink resolution)
|
|
88
|
+
let realFilePath;
|
|
89
|
+
try {
|
|
90
|
+
realFilePath = fs.realpathSync(resolved);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
realFilePath = resolved;
|
|
94
|
+
}
|
|
95
|
+
if (!realFilePath.startsWith(realBase)) {
|
|
96
|
+
errorResponse(res, 'Forbidden', 403);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const ext = path.extname(resolved).toLowerCase();
|
|
100
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
101
|
+
fs.readFile(resolved, (err, data) => {
|
|
102
|
+
if (err) {
|
|
103
|
+
if (err.code === 'ENOENT') {
|
|
104
|
+
errorResponse(res, 'Not found', 404);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
errorResponse(res, 'Internal server error', 500);
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
res.writeHead(200, {
|
|
112
|
+
'Content-Type': contentType,
|
|
113
|
+
'Access-Control-Allow-Origin': '*',
|
|
114
|
+
'X-Content-Type-Options': 'nosniff',
|
|
115
|
+
'Content-Security-Policy': [
|
|
116
|
+
"default-src 'self'",
|
|
117
|
+
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net",
|
|
118
|
+
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net",
|
|
119
|
+
"font-src 'self' https://fonts.gstatic.com https://cdn.jsdelivr.net",
|
|
120
|
+
"connect-src 'self' ws: wss:",
|
|
121
|
+
"img-src 'self' data:",
|
|
122
|
+
].join('; '),
|
|
123
|
+
});
|
|
124
|
+
res.end(data);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async function handleApi(pathname, url, res) {
|
|
128
|
+
const config = getConfig();
|
|
129
|
+
const memoryDir = config.memoryDir;
|
|
130
|
+
try {
|
|
131
|
+
if (pathname === '/health') {
|
|
132
|
+
const entries = listEntries(memoryDir);
|
|
133
|
+
const sessions = listSessions();
|
|
134
|
+
jsonResponse(res, {
|
|
135
|
+
status: 'ok',
|
|
136
|
+
version: VERSION,
|
|
137
|
+
uptime: process.uptime(),
|
|
138
|
+
knowledge_entries: entries.length,
|
|
139
|
+
sessions: sessions.length,
|
|
140
|
+
});
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
if (pathname === '/api/index-status') {
|
|
144
|
+
try {
|
|
145
|
+
const store = new VectorStore();
|
|
146
|
+
const stats = store.stats();
|
|
147
|
+
jsonResponse(res, stats);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
jsonResponse(res, {
|
|
151
|
+
totalEntries: 0,
|
|
152
|
+
knowledgeEntries: 0,
|
|
153
|
+
sessionEntries: 0,
|
|
154
|
+
dbSizeMB: 0,
|
|
155
|
+
provider: null,
|
|
156
|
+
dimensions: 0,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
if (pathname === '/api/knowledge/search') {
|
|
162
|
+
const q = url.searchParams.get('q') || '';
|
|
163
|
+
const category = url.searchParams.get('category') || undefined;
|
|
164
|
+
const maxResults = url.searchParams.get('max_results');
|
|
165
|
+
const results = searchKnowledge(memoryDir, q, {
|
|
166
|
+
category,
|
|
167
|
+
maxResults: maxResults ? parseInt(maxResults, 10) : undefined,
|
|
168
|
+
});
|
|
169
|
+
jsonResponse(res, results);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
if (pathname === '/api/knowledge') {
|
|
173
|
+
const category = url.searchParams.get('category') || undefined;
|
|
174
|
+
const tag = url.searchParams.get('tag') || undefined;
|
|
175
|
+
const entries = listEntries(memoryDir, category, tag);
|
|
176
|
+
jsonResponse(res, entries);
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
if (pathname.startsWith('/api/knowledge/')) {
|
|
180
|
+
const entryPath = decodeURIComponent(pathname.slice('/api/knowledge/'.length));
|
|
181
|
+
if (entryPath) {
|
|
182
|
+
const entry = readEntry(memoryDir, entryPath);
|
|
183
|
+
jsonResponse(res, entry);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (pathname === '/api/sessions/search') {
|
|
188
|
+
const q = url.searchParams.get('q') || '';
|
|
189
|
+
const role = url.searchParams.get('role') || 'all';
|
|
190
|
+
const maxResults = url.searchParams.get('max_results');
|
|
191
|
+
const ranked = url.searchParams.get('ranked') !== 'false';
|
|
192
|
+
const project = url.searchParams.get('project') || undefined;
|
|
193
|
+
const results = await searchSessions(q, {
|
|
194
|
+
role: role,
|
|
195
|
+
maxResults: maxResults ? parseInt(maxResults, 10) : 20,
|
|
196
|
+
ranked,
|
|
197
|
+
project,
|
|
198
|
+
});
|
|
199
|
+
jsonResponse(res, results);
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
if (pathname === '/api/sessions/recall') {
|
|
203
|
+
const scope = (url.searchParams.get('scope') || 'all');
|
|
204
|
+
const q = url.searchParams.get('q') || '';
|
|
205
|
+
const maxResults = url.searchParams.get('max_results');
|
|
206
|
+
const project = url.searchParams.get('project') || undefined;
|
|
207
|
+
const results = await scopedSearch(scope, q, {
|
|
208
|
+
maxResults: maxResults ? parseInt(maxResults, 10) : 20,
|
|
209
|
+
project,
|
|
210
|
+
});
|
|
211
|
+
jsonResponse(res, results);
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
if (pathname === '/api/sessions') {
|
|
215
|
+
const project = url.searchParams.get('project') || undefined;
|
|
216
|
+
const sessions = listSessions(project);
|
|
217
|
+
jsonResponse(res, sessions);
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
const sessionSummaryMatch = pathname.match(/^\/api\/sessions\/([^/]+)\/summary$/);
|
|
221
|
+
if (sessionSummaryMatch) {
|
|
222
|
+
const sessionId = decodeURIComponent(sessionSummaryMatch[1]);
|
|
223
|
+
const project = url.searchParams.get('project') || undefined;
|
|
224
|
+
const summary = getSessionSummary(sessionId, project);
|
|
225
|
+
if (!summary) {
|
|
226
|
+
errorResponse(res, `Session ${sessionId} not found`, 404);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
jsonResponse(res, summary);
|
|
230
|
+
}
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
const sessionMatch = pathname.match(/^\/api\/sessions\/([^/]+)$/);
|
|
234
|
+
if (sessionMatch) {
|
|
235
|
+
const sessionId = decodeURIComponent(sessionMatch[1]);
|
|
236
|
+
const project = url.searchParams.get('project') || undefined;
|
|
237
|
+
const includeTools = url.searchParams.get('include_tools') === 'true';
|
|
238
|
+
const tailParam = url.searchParams.get('tail');
|
|
239
|
+
const tail = tailParam ? parseInt(tailParam, 10) : undefined;
|
|
240
|
+
const projects = getProjectDirs().filter((p) => !project || p.name.toLowerCase().includes(project.toLowerCase()));
|
|
241
|
+
for (const proj of projects) {
|
|
242
|
+
const sessions = getSessionFiles(proj.path);
|
|
243
|
+
const match = sessions.find((s) => s.id === sessionId);
|
|
244
|
+
if (match) {
|
|
245
|
+
const entries = parseSessionFile(match.file);
|
|
246
|
+
let messages = extractMessages(entries);
|
|
247
|
+
if (!includeTools) {
|
|
248
|
+
messages = messages.filter((m) => m.role === 'user' || m.role === 'assistant');
|
|
249
|
+
}
|
|
250
|
+
if (tail && tail > 0) {
|
|
251
|
+
messages = messages.slice(-tail);
|
|
252
|
+
}
|
|
253
|
+
const meta = getSessionMeta(entries);
|
|
254
|
+
jsonResponse(res, { meta, messages });
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
errorResponse(res, `Session ${sessionId} not found`, 404);
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
const message = err instanceof Error ? err.message : 'Internal server error';
|
|
265
|
+
errorResponse(res, message, 500);
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const wsClients = new Set();
|
|
270
|
+
function wsBroadcast(data) {
|
|
271
|
+
const payload = JSON.stringify(data);
|
|
272
|
+
for (const client of wsClients) {
|
|
273
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
274
|
+
client.send(payload);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async function buildStateSnapshot() {
|
|
279
|
+
const config = getConfig();
|
|
280
|
+
try {
|
|
281
|
+
const knowledge = listEntries(config.memoryDir);
|
|
282
|
+
const sessions = listSessions();
|
|
283
|
+
return {
|
|
284
|
+
type: 'state',
|
|
285
|
+
knowledge: knowledge || [],
|
|
286
|
+
sessions: sessions || [],
|
|
287
|
+
stats: {
|
|
288
|
+
knowledge_entries: knowledge.length,
|
|
289
|
+
session_count: sessions.length,
|
|
290
|
+
uptime: process.uptime(),
|
|
291
|
+
version: VERSION,
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
return {
|
|
297
|
+
type: 'state',
|
|
298
|
+
knowledge: [],
|
|
299
|
+
sessions: [],
|
|
300
|
+
stats: { knowledge_entries: 0, session_count: 0, uptime: process.uptime(), version: VERSION },
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
export async function notifyUpdate() {
|
|
305
|
+
if (wsClients.size === 0)
|
|
306
|
+
return;
|
|
307
|
+
const state = await buildStateSnapshot();
|
|
308
|
+
wsBroadcast(state);
|
|
309
|
+
}
|
|
310
|
+
export function startDashboard(port) {
|
|
311
|
+
const listenPort = port ?? DEFAULT_PORT;
|
|
312
|
+
const uiDir = resolveUiDir();
|
|
313
|
+
return new Promise((resolve, reject) => {
|
|
314
|
+
const server = http.createServer(async (req, res) => {
|
|
315
|
+
const reqUrl = req.url || '/';
|
|
316
|
+
if (req.method === 'OPTIONS') {
|
|
317
|
+
res.writeHead(204, {
|
|
318
|
+
'Access-Control-Allow-Origin': '*',
|
|
319
|
+
'X-Content-Type-Options': 'nosniff',
|
|
320
|
+
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
|
321
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
322
|
+
});
|
|
323
|
+
res.end();
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (req.method !== 'GET') {
|
|
327
|
+
errorResponse(res, 'Method not allowed', 405);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
let url;
|
|
331
|
+
try {
|
|
332
|
+
url = new URL(reqUrl, `http://${req.headers.host || 'localhost'}`);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
errorResponse(res, 'Bad request', 400);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const pathname = url.pathname;
|
|
339
|
+
if (pathname.startsWith('/api/') || pathname === '/health') {
|
|
340
|
+
const handled = await handleApi(pathname, url, res);
|
|
341
|
+
if (handled)
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (!pathname.startsWith('/api/')) {
|
|
345
|
+
serveStatic(uiDir, pathname, res);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
errorResponse(res, 'Not found', 404);
|
|
349
|
+
});
|
|
350
|
+
const wss = new WebSocketServer({ noServer: true, maxPayload: MAX_WS_MESSAGE_SIZE });
|
|
351
|
+
server.on('upgrade', (request, socket, head) => {
|
|
352
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
353
|
+
wss.emit('connection', ws, request);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
wss.on('connection', async (ws) => {
|
|
357
|
+
if (wsClients.size >= MAX_WS_CONNECTIONS) {
|
|
358
|
+
ws.close(1013, 'Too many connections');
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
ws.isAlive = true;
|
|
362
|
+
wsClients.add(ws);
|
|
363
|
+
ws.on('pong', () => {
|
|
364
|
+
ws.isAlive = true;
|
|
365
|
+
});
|
|
366
|
+
ws.on('close', () => {
|
|
367
|
+
wsClients.delete(ws);
|
|
368
|
+
});
|
|
369
|
+
ws.on('error', () => {
|
|
370
|
+
wsClients.delete(ws);
|
|
371
|
+
});
|
|
372
|
+
try {
|
|
373
|
+
const state = await buildStateSnapshot();
|
|
374
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
375
|
+
ws.send(JSON.stringify(state));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// non-fatal
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
const heartbeat = setInterval(() => {
|
|
383
|
+
for (const ws of wsClients) {
|
|
384
|
+
if (ws.isAlive === false) {
|
|
385
|
+
wsClients.delete(ws);
|
|
386
|
+
ws.terminate();
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
ws.isAlive = false;
|
|
390
|
+
ws.ping();
|
|
391
|
+
}
|
|
392
|
+
}, HEARTBEAT_INTERVAL);
|
|
393
|
+
// ── File Watcher (live reload) ──────────────────────────────────────
|
|
394
|
+
let reloadDebounce = null;
|
|
395
|
+
let fileWatcher = null;
|
|
396
|
+
function broadcastReload() {
|
|
397
|
+
if (reloadDebounce)
|
|
398
|
+
clearTimeout(reloadDebounce);
|
|
399
|
+
reloadDebounce = setTimeout(() => {
|
|
400
|
+
wsBroadcast({ type: 'reload' });
|
|
401
|
+
}, 200);
|
|
402
|
+
}
|
|
403
|
+
try {
|
|
404
|
+
if (fs.existsSync(uiDir)) {
|
|
405
|
+
fileWatcher = fs.watch(uiDir, { recursive: true }, (eventType, filename) => {
|
|
406
|
+
if (filename && /\.(html|css|js)$/.test(filename)) {
|
|
407
|
+
broadcastReload();
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
// file watching not available on this platform — non-fatal
|
|
414
|
+
}
|
|
415
|
+
server.on('close', () => {
|
|
416
|
+
clearInterval(heartbeat);
|
|
417
|
+
if (fileWatcher)
|
|
418
|
+
fileWatcher.close();
|
|
419
|
+
wss.close();
|
|
420
|
+
});
|
|
421
|
+
server.on('error', (err) => {
|
|
422
|
+
if (err.code === 'EADDRINUSE') {
|
|
423
|
+
reject(new Error(`Port ${listenPort} already in use`));
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
reject(err);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
server.listen(listenPort, () => {
|
|
430
|
+
resolve(server);
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { EmbeddingProvider } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Anthropic/Voyage AI embedding provider.
|
|
4
|
+
* Uses the Voyage AI API (Anthropic's embedding partner).
|
|
5
|
+
* Accepts an Anthropic API key but prefers VOYAGE_API_KEY if set.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ClaudeEmbeddingProvider implements EmbeddingProvider {
|
|
8
|
+
readonly name = "claude";
|
|
9
|
+
readonly dimensions: number;
|
|
10
|
+
readonly model: string;
|
|
11
|
+
private readonly apiKey;
|
|
12
|
+
constructor(apiKey: string, modelOverride?: string);
|
|
13
|
+
/** Embed one or more texts, batching internally at 128 texts per request. */
|
|
14
|
+
embed(texts: string[]): Promise<number[][]>;
|
|
15
|
+
/** Embed a single text. */
|
|
16
|
+
embedOne(text: string): Promise<number[]>;
|
|
17
|
+
/** Check availability by making a test embedding request. */
|
|
18
|
+
isAvailable(): Promise<boolean>;
|
|
19
|
+
private requestEmbeddings;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/embeddings/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAQpD;;;;GAIG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM;IAMlD,6EAA6E;IACvE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAYjD,2BAA2B;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAK/C,6DAA6D;IACvD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YASvB,iBAAiB;CAqChC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const DEFAULT_MODEL = 'voyage-3-lite';
|
|
2
|
+
const DEFAULT_DIMENSIONS = 512;
|
|
3
|
+
const MAX_BATCH_SIZE = 128;
|
|
4
|
+
const TIMEOUT_MS = 30_000;
|
|
5
|
+
const ENDPOINT = 'https://api.voyageai.com/v1/embeddings';
|
|
6
|
+
/**
|
|
7
|
+
* Anthropic/Voyage AI embedding provider.
|
|
8
|
+
* Uses the Voyage AI API (Anthropic's embedding partner).
|
|
9
|
+
* Accepts an Anthropic API key but prefers VOYAGE_API_KEY if set.
|
|
10
|
+
*/
|
|
11
|
+
export class ClaudeEmbeddingProvider {
|
|
12
|
+
name = 'claude';
|
|
13
|
+
dimensions;
|
|
14
|
+
model;
|
|
15
|
+
apiKey;
|
|
16
|
+
constructor(apiKey, modelOverride) {
|
|
17
|
+
this.apiKey = process.env.VOYAGE_API_KEY || apiKey;
|
|
18
|
+
this.model = modelOverride || DEFAULT_MODEL;
|
|
19
|
+
this.dimensions = DEFAULT_DIMENSIONS;
|
|
20
|
+
}
|
|
21
|
+
/** Embed one or more texts, batching internally at 128 texts per request. */
|
|
22
|
+
async embed(texts) {
|
|
23
|
+
if (texts.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
const results = [];
|
|
26
|
+
for (let i = 0; i < texts.length; i += MAX_BATCH_SIZE) {
|
|
27
|
+
const batch = texts.slice(i, i + MAX_BATCH_SIZE);
|
|
28
|
+
const vectors = await this.requestEmbeddings(batch);
|
|
29
|
+
results.push(...vectors);
|
|
30
|
+
}
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
/** Embed a single text. */
|
|
34
|
+
async embedOne(text) {
|
|
35
|
+
const results = await this.embed([text]);
|
|
36
|
+
return results[0] ?? [];
|
|
37
|
+
}
|
|
38
|
+
/** Check availability by making a test embedding request. */
|
|
39
|
+
async isAvailable() {
|
|
40
|
+
try {
|
|
41
|
+
const result = await this.embed(['test']);
|
|
42
|
+
return result.length === 1 && result[0].length > 0;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async requestEmbeddings(texts, retry = true) {
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(ENDPOINT, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: {
|
|
53
|
+
'Content-Type': 'application/json',
|
|
54
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify({ model: this.model, input: texts }),
|
|
57
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
58
|
+
});
|
|
59
|
+
if (response.status === 429 && retry) {
|
|
60
|
+
const retryAfter = parseInt(response.headers.get('retry-after') || '1', 10);
|
|
61
|
+
const delayMs = Math.max(retryAfter, 1) * 1000;
|
|
62
|
+
console.error(`[knowledge] Voyage rate limited, retrying in ${delayMs}ms`);
|
|
63
|
+
await sleep(delayMs);
|
|
64
|
+
return this.requestEmbeddings(texts, false);
|
|
65
|
+
}
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const body = await response.text().catch(() => '');
|
|
68
|
+
console.error(`[knowledge] Voyage embedding request failed (${response.status}): ${body}`);
|
|
69
|
+
return texts.map(() => []);
|
|
70
|
+
}
|
|
71
|
+
const json = (await response.json());
|
|
72
|
+
const sorted = json.data.sort((a, b) => a.index - b.index);
|
|
73
|
+
return sorted.map((d) => d.embedding);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
console.error('[knowledge] Voyage embedding request error:', err);
|
|
77
|
+
return texts.map(() => []);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function sleep(ms) {
|
|
82
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/embeddings/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EmbeddingProvider, EmbeddingConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get or create the embedding provider based on config.
|
|
4
|
+
* Returns null if the requested provider is unavailable.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getEmbeddingProvider(config?: EmbeddingConfig): Promise<EmbeddingProvider | null>;
|
|
7
|
+
/** Reset cached instance (used when switching providers). */
|
|
8
|
+
export declare function resetProvider(): void;
|
|
9
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/embeddings/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMrE;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAQnC;AAyCD,6DAA6D;AAC7D,wBAAgB,aAAa,IAAI,IAAI,CAGpC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getEmbeddingConfig } from './types.js';
|
|
2
|
+
let _instance = null;
|
|
3
|
+
let _instanceProvider = null;
|
|
4
|
+
/**
|
|
5
|
+
* Get or create the embedding provider based on config.
|
|
6
|
+
* Returns null if the requested provider is unavailable.
|
|
7
|
+
*/
|
|
8
|
+
export async function getEmbeddingProvider(config) {
|
|
9
|
+
const cfg = config ?? getEmbeddingConfig();
|
|
10
|
+
if (_instance && _instanceProvider === cfg.provider)
|
|
11
|
+
return _instance;
|
|
12
|
+
_instance = await createProvider(cfg);
|
|
13
|
+
_instanceProvider = cfg.provider;
|
|
14
|
+
return _instance;
|
|
15
|
+
}
|
|
16
|
+
async function createProvider(cfg) {
|
|
17
|
+
switch (cfg.provider) {
|
|
18
|
+
case 'local': {
|
|
19
|
+
const { LocalEmbeddingProvider } = await import('./local.js');
|
|
20
|
+
const provider = new LocalEmbeddingProvider(cfg.modelOverride);
|
|
21
|
+
if (await provider.isAvailable())
|
|
22
|
+
return provider;
|
|
23
|
+
console.error('[knowledge] Local embedding model unavailable');
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
case 'openai': {
|
|
27
|
+
if (!cfg.openaiApiKey) {
|
|
28
|
+
console.error('[knowledge] KNOWLEDGE_OPENAI_API_KEY not set');
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const { OpenAIEmbeddingProvider } = await import('./openai.js');
|
|
32
|
+
return new OpenAIEmbeddingProvider(cfg.openaiApiKey, cfg.modelOverride);
|
|
33
|
+
}
|
|
34
|
+
case 'claude': {
|
|
35
|
+
if (!cfg.claudeApiKey) {
|
|
36
|
+
console.error('[knowledge] KNOWLEDGE_CLAUDE_API_KEY not set');
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const { ClaudeEmbeddingProvider } = await import('./claude.js');
|
|
40
|
+
return new ClaudeEmbeddingProvider(cfg.claudeApiKey, cfg.modelOverride);
|
|
41
|
+
}
|
|
42
|
+
case 'gemini': {
|
|
43
|
+
if (!cfg.geminiApiKey) {
|
|
44
|
+
console.error('[knowledge] KNOWLEDGE_GEMINI_API_KEY not set');
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const { GeminiEmbeddingProvider } = await import('./gemini.js');
|
|
48
|
+
return new GeminiEmbeddingProvider(cfg.geminiApiKey, cfg.modelOverride);
|
|
49
|
+
}
|
|
50
|
+
default:
|
|
51
|
+
console.error(`[knowledge] Unknown provider: ${cfg.provider}`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Reset cached instance (used when switching providers). */
|
|
56
|
+
export function resetProvider() {
|
|
57
|
+
_instance = null;
|
|
58
|
+
_instanceProvider = null;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/embeddings/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,IAAI,SAAS,GAA6B,IAAI,CAAC;AAC/C,IAAI,iBAAiB,GAAkB,IAAI,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAwB;IAExB,MAAM,GAAG,GAAG,MAAM,IAAI,kBAAkB,EAAE,CAAC;IAE3C,IAAI,SAAS,IAAI,iBAAiB,KAAK,GAAG,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEtE,SAAS,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IACtC,iBAAiB,GAAG,GAAG,CAAC,QAAQ,CAAC;IACjC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAoB;IAChD,QAAQ,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9D,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC/D,IAAI,MAAM,QAAQ,CAAC,WAAW,EAAE;gBAAE,OAAO,QAAQ,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBAC9D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAChE,OAAO,IAAI,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;QAC1E,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBAC9D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAChE,OAAO,IAAI,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;QAC1E,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBAC9D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAChE,OAAO,IAAI,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;QAC1E,CAAC;QACD;YACE,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,aAAa;IAC3B,SAAS,GAAG,IAAI,CAAC;IACjB,iBAAiB,GAAG,IAAI,CAAC;AAC3B,CAAC"}
|