opencode-rag-plugin 1.7.1 → 1.8.2

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.
@@ -0,0 +1,197 @@
1
+ import { listSessions, getSession, deleteSession, compareSessions } from "../eval/storage.js";
2
+ function parseQuery(url) {
3
+ const [path, queryString] = url.split("?");
4
+ return {
5
+ path: path ?? "/",
6
+ params: new URLSearchParams(queryString ?? ""),
7
+ };
8
+ }
9
+ function sendJson(res, response) {
10
+ res.writeHead(response.status, {
11
+ "Content-Type": "application/json",
12
+ "Access-Control-Allow-Origin": "*",
13
+ "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
14
+ "Access-Control-Allow-Headers": "Content-Type",
15
+ });
16
+ res.end(JSON.stringify(response.body));
17
+ }
18
+ export function createApiHandler(store, keywordIndex, storePath) {
19
+ return async (req, res) => {
20
+ const url = req.url ?? "/";
21
+ const method = req.method ?? "GET";
22
+ const { path, params } = parseQuery(url);
23
+ // CORS preflight
24
+ if (method === "OPTIONS") {
25
+ res.writeHead(204, {
26
+ "Access-Control-Allow-Origin": "*",
27
+ "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
28
+ "Access-Control-Allow-Headers": "Content-Type",
29
+ });
30
+ res.end();
31
+ return true;
32
+ }
33
+ let response;
34
+ try {
35
+ // Existing endpoints
36
+ if (path === "/api/stats") {
37
+ response = await handleStats(store);
38
+ }
39
+ else if (path === "/api/files") {
40
+ response = await handleFiles(store);
41
+ }
42
+ else if (path === "/api/chunks" && !path.includes("/api/chunks/")) {
43
+ response = await handleChunks(store, params);
44
+ }
45
+ else if (path.startsWith("/api/chunks/")) {
46
+ const id = path.slice("/api/chunks/".length);
47
+ response = await handleChunkById(store, id);
48
+ }
49
+ else if (path === "/api/search") {
50
+ response = await handleSearch(keywordIndex, params);
51
+ }
52
+ else if (path === "/api/compare") {
53
+ response = await handleCompare(store, params);
54
+ }
55
+ // Eval endpoints
56
+ else if (path === "/api/eval/sessions" && method === "GET") {
57
+ response = await handleEvalSessions(storePath);
58
+ }
59
+ else if (path.startsWith("/api/eval/sessions/") && method === "GET") {
60
+ const id = path.slice("/api/eval/sessions/".length);
61
+ response = await handleEvalSession(storePath, id);
62
+ }
63
+ else if (path.startsWith("/api/eval/sessions/") && method === "DELETE") {
64
+ const id = path.slice("/api/eval/sessions/".length);
65
+ response = await handleEvalDeleteSession(storePath, id);
66
+ }
67
+ else if (path === "/api/eval/compare" && method === "GET") {
68
+ response = await handleEvalCompare(storePath, params);
69
+ }
70
+ else {
71
+ return false;
72
+ }
73
+ sendJson(res, response);
74
+ return true;
75
+ }
76
+ catch (err) {
77
+ const message = err instanceof Error ? err.message : String(err);
78
+ sendJson(res, { status: 500, body: { error: message } });
79
+ return true;
80
+ }
81
+ };
82
+ }
83
+ async function handleStats(store) {
84
+ const totalChunks = await store.count();
85
+ const files = await store.listFiles();
86
+ const langMap = new Map();
87
+ for (const file of files) {
88
+ langMap.set(file.language, (langMap.get(file.language) ?? 0) + file.chunkCount);
89
+ }
90
+ const languages = [...langMap.entries()]
91
+ .map(([language, count]) => ({ language, count }))
92
+ .sort((a, b) => b.count - a.count);
93
+ return {
94
+ status: 200,
95
+ body: {
96
+ totalChunks,
97
+ totalFiles: files.length,
98
+ languages,
99
+ },
100
+ };
101
+ }
102
+ async function handleFiles(store) {
103
+ const files = await store.listFiles();
104
+ return { status: 200, body: files };
105
+ }
106
+ async function handleChunks(store, params) {
107
+ const offset = parseInt(params.get("offset") ?? "0", 10);
108
+ const limit = parseInt(params.get("limit") ?? "50", 10);
109
+ const langFilter = params.get("lang");
110
+ const fileFilter = params.get("file");
111
+ const allChunks = await store.getChunks(0, 100000);
112
+ let filtered = allChunks;
113
+ if (langFilter) {
114
+ filtered = filtered.filter((c) => c.language === langFilter);
115
+ }
116
+ if (fileFilter) {
117
+ filtered = filtered.filter((c) => c.filePath.startsWith(fileFilter));
118
+ }
119
+ const total = filtered.length;
120
+ const chunks = filtered.slice(offset, offset + limit);
121
+ return {
122
+ status: 200,
123
+ body: { chunks, total, offset, limit },
124
+ };
125
+ }
126
+ async function handleChunkById(store, id) {
127
+ const chunks = await store.getChunks(0, 100000);
128
+ const chunk = chunks.find((c) => c.id === id);
129
+ if (!chunk) {
130
+ return { status: 404, body: { error: "Chunk not found" } };
131
+ }
132
+ return { status: 200, body: chunk };
133
+ }
134
+ async function handleSearch(keywordIndex, params) {
135
+ const query = params.get("q") ?? "";
136
+ const topK = parseInt(params.get("topK") ?? "20", 10);
137
+ if (!query.trim()) {
138
+ return { status: 200, body: { results: [] } };
139
+ }
140
+ const results = keywordIndex.search(query, topK);
141
+ return {
142
+ status: 200,
143
+ body: {
144
+ results: results.map((r) => ({
145
+ chunk: {
146
+ id: r.chunk.id,
147
+ filePath: r.chunk.metadata.filePath,
148
+ startLine: r.chunk.metadata.startLine,
149
+ endLine: r.chunk.metadata.endLine,
150
+ language: r.chunk.metadata.language,
151
+ content: r.chunk.content,
152
+ description: r.chunk.description,
153
+ },
154
+ score: Math.round(r.score * 1000) / 1000,
155
+ })),
156
+ },
157
+ };
158
+ }
159
+ async function handleCompare(store, params) {
160
+ const idsParam = params.get("ids") ?? "";
161
+ const ids = idsParam.split(",").filter(Boolean);
162
+ if (ids.length === 0) {
163
+ return { status: 400, body: { error: "No chunk IDs provided" } };
164
+ }
165
+ const allChunks = await store.getChunks(0, 100000);
166
+ const chunks = allChunks.filter((c) => ids.includes(c.id ?? ""));
167
+ return { status: 200, body: { chunks } };
168
+ }
169
+ // ── Eval API ──────────────────────────────────────────────────────────
170
+ async function handleEvalSessions(storePath) {
171
+ const sessions = listSessions(storePath);
172
+ return { status: 200, body: { sessions } };
173
+ }
174
+ async function handleEvalSession(storePath, id) {
175
+ const session = getSession(storePath, id);
176
+ if (!session) {
177
+ return { status: 404, body: { error: "Session not found" } };
178
+ }
179
+ return { status: 200, body: session };
180
+ }
181
+ async function handleEvalDeleteSession(storePath, id) {
182
+ deleteSession(storePath, id);
183
+ return { status: 200, body: { deleted: true } };
184
+ }
185
+ async function handleEvalCompare(storePath, params) {
186
+ const idA = params.get("a") ?? "";
187
+ const idB = params.get("b") ?? "";
188
+ if (!idA || !idB) {
189
+ return { status: 400, body: { error: "Both 'a' and 'b' session IDs are required" } };
190
+ }
191
+ const result = compareSessions(storePath, idA, idB);
192
+ if (!result) {
193
+ return { status: 404, body: { error: "One or both sessions not found" } };
194
+ }
195
+ return { status: 200, body: result };
196
+ }
197
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/web/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface WebUiServer {
2
+ port: number;
3
+ close: () => Promise<void>;
4
+ }
5
+ export declare function startWebUi(storePath: string, port: number, vectorDimension?: number): Promise<WebUiServer>;
@@ -0,0 +1,41 @@
1
+ import { createServer } from "node:http";
2
+ import { LanceDBStore } from "../vectorstore/lancedb.js";
3
+ import { KeywordIndex } from "../retriever/keyword-index.js";
4
+ import { createApiHandler } from "./api.js";
5
+ import { getStaticHtml } from "./static.js";
6
+ function serveStatic(res, html) {
7
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
8
+ res.end(html);
9
+ }
10
+ export async function startWebUi(storePath, port, vectorDimension = 384) {
11
+ const store = new LanceDBStore(storePath, vectorDimension);
12
+ const keywordIndex = await KeywordIndex.load(storePath);
13
+ const html = getStaticHtml();
14
+ const apiHandler = createApiHandler(store, keywordIndex, storePath);
15
+ const server = createServer(async (req, res) => {
16
+ const url = req.url ?? "/";
17
+ if (url === "/" || url === "/index.html") {
18
+ serveStatic(res, html);
19
+ return;
20
+ }
21
+ if (url.startsWith("/api/")) {
22
+ const handled = await apiHandler(req, res);
23
+ if (handled)
24
+ return;
25
+ }
26
+ res.writeHead(404, { "Content-Type": "text/plain" });
27
+ res.end("Not Found");
28
+ });
29
+ return new Promise((resolve, reject) => {
30
+ server.on("error", reject);
31
+ server.listen(port, "127.0.0.1", () => {
32
+ resolve({
33
+ port,
34
+ close: () => new Promise((resolveClose) => {
35
+ server.close(() => resolveClose());
36
+ }),
37
+ });
38
+ });
39
+ });
40
+ }
41
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0D,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,SAAS,WAAW,CAAC,GAAmB,EAAE,IAAY;IACpD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;IACnE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,IAAY,EACZ,kBAA0B,GAAG;IAE7B,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAExD,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAW,YAAY,CAAC,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAE,EAAE;QACtF,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAE3B,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;YACzC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3C,IAAI,OAAO;gBAAE,OAAO;QACtB,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;QACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YACpC,OAAO,CAAC;gBACN,IAAI;gBACJ,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE;oBACjC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;gBACrC,CAAC,CAAC;aACL,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function getStaticHtml(): string;
@@ -0,0 +1,13 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ let cachedHtml = null;
5
+ export function getStaticHtml() {
6
+ if (cachedHtml)
7
+ return cachedHtml;
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const htmlPath = join(__dirname, "ui", "index.html");
10
+ cachedHtml = readFileSync(htmlPath, "utf-8");
11
+ return cachedHtml;
12
+ }
13
+ //# sourceMappingURL=static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/web/static.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,UAAU,GAAkB,IAAI,CAAC;AAErC,MAAM,UAAU,aAAa;IAC3B,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACrD,UAAU,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7C,OAAO,UAAU,CAAC;AACpB,CAAC"}