opencode-rag-plugin 1.15.0 → 1.17.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/ReadMe.md +6 -7
- package/dist/api.js +44 -24
- package/dist/chunker/base.d.ts +34 -3
- package/dist/chunker/base.js +70 -21
- package/dist/chunker/factory.d.ts +4 -1
- package/dist/chunker/factory.js +12 -1
- package/dist/chunker/grammar.js +3 -0
- package/dist/chunker/image.js +8 -8
- package/dist/chunker/pdf.js +11 -13
- package/dist/chunker/xml.d.ts +2 -0
- package/dist/chunker/xml.js +2 -0
- package/dist/cli/commands/index-command.js +0 -4
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +1 -1
- package/dist/cli/commands/init-helpers.d.ts +12 -0
- package/dist/cli/commands/init-helpers.js +84 -2
- package/dist/cli/commands/init.js +20 -2
- package/dist/cli/commands/query.js +1 -0
- package/dist/cli/commands/setup.d.ts +2 -0
- package/dist/cli/commands/setup.js +113 -0
- package/dist/cli/commands/status.js +64 -2
- package/dist/cli/index.js +2 -2
- package/dist/content/image.js +24 -3
- package/dist/content/reader.d.ts +6 -1
- package/dist/content/reader.js +49 -4
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.js +34 -4
- package/dist/core/desc-cache.d.ts +31 -0
- package/dist/core/desc-cache.js +124 -0
- package/dist/core/interfaces.d.ts +58 -3
- package/dist/core/manifest.d.ts +24 -1
- package/dist/core/manifest.js +34 -3
- package/dist/core/resolve-api-key.js +4 -2
- package/dist/core/runtime-overrides.js +9 -7
- package/dist/core/setup-runtime.d.ts +23 -0
- package/dist/core/setup-runtime.js +183 -0
- package/dist/core/version-check.d.ts +9 -0
- package/dist/core/version-check.js +49 -0
- package/dist/describer/anthropic.d.ts +2 -2
- package/dist/describer/anthropic.js +5 -7
- package/dist/describer/describer.d.ts +2 -2
- package/dist/describer/describer.js +6 -8
- package/dist/describer/gemini.d.ts +2 -2
- package/dist/describer/gemini.js +5 -7
- package/dist/embedder/factory.d.ts +3 -1
- package/dist/embedder/factory.js +7 -1
- package/dist/embedder/health.js +4 -0
- package/dist/embedder/http.d.ts +1 -1
- package/dist/embedder/http.js +74 -43
- package/dist/eval/compare-merge.d.ts +10 -0
- package/dist/eval/compare-merge.js +537 -0
- package/dist/eval/compare-rankings.d.ts +10 -0
- package/dist/eval/compare-rankings.js +245 -0
- package/dist/eval/dump-descriptions.d.ts +7 -0
- package/dist/eval/dump-descriptions.js +58 -0
- package/dist/eval/fast-index.d.ts +8 -0
- package/dist/eval/fast-index.js +283 -0
- package/dist/eval/run-branch-compare.d.ts +7 -0
- package/dist/eval/run-branch-compare.js +220 -0
- package/dist/eval/run-token-test.js +1 -0
- package/dist/eval/test-kw.d.ts +1 -0
- package/dist/eval/test-kw.js +22 -0
- package/dist/eval/update-descriptions.d.ts +7 -0
- package/dist/eval/update-descriptions.js +84 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/indexer/embed-stage.js +2 -1
- package/dist/indexer/git-diff.js +21 -9
- package/dist/indexer/pipeline.d.ts +6 -0
- package/dist/indexer/pipeline.js +290 -37
- package/dist/indexer/watch.js +1 -3
- package/dist/indexer/worker.d.ts +15 -2
- package/dist/indexer/worker.js +25 -12
- package/dist/mcp/handlers.d.ts +9 -0
- package/dist/mcp/handlers.js +23 -6
- package/dist/mcp/server.js +2 -0
- package/dist/opencode/create-read-tool.d.ts +2 -0
- package/dist/opencode/create-read-tool.js +8 -2
- package/dist/opencode/read-fallback.d.ts +1 -5
- package/dist/opencode/read-fallback.js +1 -18
- package/dist/opencode/read-format.js +5 -3
- package/dist/opencode/tools.js +5 -7
- package/dist/plugin.js +196 -81
- package/dist/retriever/keyword-index.d.ts +3 -2
- package/dist/retriever/keyword-index.js +25 -1
- package/dist/retriever/retriever.d.ts +4 -1
- package/dist/retriever/retriever.js +34 -56
- package/dist/vectorstore/lancedb.d.ts +35 -4
- package/dist/vectorstore/lancedb.js +146 -23
- package/dist/vectorstore/memory.d.ts +6 -1
- package/dist/vectorstore/memory.js +58 -0
- package/dist/watcher.js +3 -0
- package/dist/web/api.js +10 -2
- package/dist/web/server.js +18 -3
- package/package.json +8 -9
- package/scripts/postinstall-setup.js +82 -0
- package/dist/api.js.map +0 -1
- package/dist/chunker/base.js.map +0 -1
- package/dist/chunker/bash.js.map +0 -1
- package/dist/chunker/c.js.map +0 -1
- package/dist/chunker/cpp.js.map +0 -1
- package/dist/chunker/csharp.js.map +0 -1
- package/dist/chunker/css.js.map +0 -1
- package/dist/chunker/doc.js.map +0 -1
- package/dist/chunker/dockerfile.js.map +0 -1
- package/dist/chunker/docx.js.map +0 -1
- package/dist/chunker/excel.js.map +0 -1
- package/dist/chunker/factory.js.map +0 -1
- package/dist/chunker/fallback.js.map +0 -1
- package/dist/chunker/go.js.map +0 -1
- package/dist/chunker/grammar.js.map +0 -1
- package/dist/chunker/html.js.map +0 -1
- package/dist/chunker/image.js.map +0 -1
- package/dist/chunker/ini.js.map +0 -1
- package/dist/chunker/java.js.map +0 -1
- package/dist/chunker/javascript.js.map +0 -1
- package/dist/chunker/json.js.map +0 -1
- package/dist/chunker/kotlin.js.map +0 -1
- package/dist/chunker/loader.js.map +0 -1
- package/dist/chunker/markdown.js.map +0 -1
- package/dist/chunker/pdf.js.map +0 -1
- package/dist/chunker/php.js.map +0 -1
- package/dist/chunker/powershell.js.map +0 -1
- package/dist/chunker/python.js.map +0 -1
- package/dist/chunker/razor.js.map +0 -1
- package/dist/chunker/ruby.js.map +0 -1
- package/dist/chunker/rust.js.map +0 -1
- package/dist/chunker/sln.js.map +0 -1
- package/dist/chunker/sql.js.map +0 -1
- package/dist/chunker/ssl.js.map +0 -1
- package/dist/chunker/swift.js.map +0 -1
- package/dist/chunker/tex.js.map +0 -1
- package/dist/chunker/toml.js.map +0 -1
- package/dist/chunker/typescript.js.map +0 -1
- package/dist/chunker/uuid.js.map +0 -1
- package/dist/chunker/xml.js.map +0 -1
- package/dist/chunker/yaml.js.map +0 -1
- package/dist/cli/commands/clear.js.map +0 -1
- package/dist/cli/commands/describe-image.js.map +0 -1
- package/dist/cli/commands/dump.js.map +0 -1
- package/dist/cli/commands/eval.js.map +0 -1
- package/dist/cli/commands/index-command.js.map +0 -1
- package/dist/cli/commands/index.js.map +0 -1
- package/dist/cli/commands/init-helpers.js.map +0 -1
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/list.js.map +0 -1
- package/dist/cli/commands/mcp.js.map +0 -1
- package/dist/cli/commands/query.js.map +0 -1
- package/dist/cli/commands/show.js.map +0 -1
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/ui.js.map +0 -1
- package/dist/cli/commands/update.d.ts +0 -17
- package/dist/cli/commands/update.js +0 -79
- package/dist/cli/commands/update.js.map +0 -1
- package/dist/cli/format.js.map +0 -1
- package/dist/cli/helpers.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/progress.d.ts +0 -42
- package/dist/cli/progress.js +0 -137
- package/dist/cli/progress.js.map +0 -1
- package/dist/cli/types.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/content/doc.js.map +0 -1
- package/dist/content/docx.js.map +0 -1
- package/dist/content/excel.js.map +0 -1
- package/dist/content/image.js.map +0 -1
- package/dist/content/pdf.js.map +0 -1
- package/dist/content/reader.js.map +0 -1
- package/dist/content/types.js.map +0 -1
- package/dist/core/bootstrap.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/doc-progress.js.map +0 -1
- package/dist/core/fileLogger.js.map +0 -1
- package/dist/core/interfaces.js.map +0 -1
- package/dist/core/manifest.js.map +0 -1
- package/dist/core/provider-defaults.js.map +0 -1
- package/dist/core/rag-injection-flag.js.map +0 -1
- package/dist/core/resolve-api-key.js.map +0 -1
- package/dist/core/runtime-overrides.js.map +0 -1
- package/dist/describer/anthropic.js.map +0 -1
- package/dist/describer/describer.js.map +0 -1
- package/dist/describer/factory.js.map +0 -1
- package/dist/describer/gemini.js.map +0 -1
- package/dist/describer/shared.js.map +0 -1
- package/dist/embedder/cohere.js.map +0 -1
- package/dist/embedder/factory.js.map +0 -1
- package/dist/embedder/health.js.map +0 -1
- package/dist/embedder/http.js.map +0 -1
- package/dist/embedder/ollama.js.map +0 -1
- package/dist/embedder/openai.js.map +0 -1
- package/dist/eval/index.js.map +0 -1
- package/dist/eval/run-token-test.js.map +0 -1
- package/dist/eval/session-logger.js.map +0 -1
- package/dist/eval/storage.js.map +0 -1
- package/dist/eval/token-analysis.js.map +0 -1
- package/dist/eval/token-counter.js.map +0 -1
- package/dist/eval/types.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/indexer/description-stage.js.map +0 -1
- package/dist/indexer/embed-stage.js.map +0 -1
- package/dist/indexer/git-diff.js.map +0 -1
- package/dist/indexer/metadata.js.map +0 -1
- package/dist/indexer/pipeline.js.map +0 -1
- package/dist/indexer/stats.js.map +0 -1
- package/dist/indexer/watch.js.map +0 -1
- package/dist/indexer/worker.js.map +0 -1
- package/dist/indexer.js.map +0 -1
- package/dist/mcp/cli.js.map +0 -1
- package/dist/mcp/handlers.js.map +0 -1
- package/dist/mcp/server.js.map +0 -1
- package/dist/opencode/create-read-tool.js.map +0 -1
- package/dist/opencode/read-fallback.js.map +0 -1
- package/dist/opencode/read-format.js.map +0 -1
- package/dist/opencode/read-query.js.map +0 -1
- package/dist/opencode/tool-args.js.map +0 -1
- package/dist/opencode/tools.js.map +0 -1
- package/dist/plugin-entry.js.map +0 -1
- package/dist/plugin.js.map +0 -1
- package/dist/retriever/context-optimizer.js.map +0 -1
- package/dist/retriever/keyword-index.js.map +0 -1
- package/dist/retriever/retriever.js.map +0 -1
- package/dist/tui.js.map +0 -1
- package/dist/updater.d.ts +0 -45
- package/dist/updater.js +0 -175
- package/dist/updater.js.map +0 -1
- package/dist/vectorstore/factory.js.map +0 -1
- package/dist/vectorstore/lancedb.js.map +0 -1
- package/dist/vectorstore/memory.js.map +0 -1
- package/dist/watcher.js.map +0 -1
- package/dist/web/api.js.map +0 -1
- package/dist/web/server.js.map +0 -1
- package/dist/web/static.js.map +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync, readFileSync, symlinkSync, } from "node:fs";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
const PLUGIN_NAME = "opencode-rag-plugin";
|
|
6
|
+
export function getRuntimeDir() {
|
|
7
|
+
return path.join(os.homedir(), ".opencode");
|
|
8
|
+
}
|
|
9
|
+
export function getNpmGlobalRoot() {
|
|
10
|
+
return execSync("npm root -g", {
|
|
11
|
+
encoding: "utf-8",
|
|
12
|
+
timeout: 10_000,
|
|
13
|
+
}).trim();
|
|
14
|
+
}
|
|
15
|
+
function createJunction(targetPath, linkPath) {
|
|
16
|
+
const type = process.platform === "win32" ? "junction" : "dir";
|
|
17
|
+
symlinkSync(targetPath, linkPath, type);
|
|
18
|
+
}
|
|
19
|
+
function removeIfExists(targetPath) {
|
|
20
|
+
if (existsSync(targetPath)) {
|
|
21
|
+
rmSync(targetPath, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function getVersionFile(runtimeDir) {
|
|
25
|
+
return path.join(runtimeDir, ".bundle-version");
|
|
26
|
+
}
|
|
27
|
+
export function readVersionFile(versionFile) {
|
|
28
|
+
try {
|
|
29
|
+
return readFileSync(versionFile, "utf-8").trim();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Bin name npm generates for this package (without .cmd/.ps1). */
|
|
36
|
+
function getBinName() {
|
|
37
|
+
const pkgJson = path.join(getNpmGlobalRoot(), PLUGIN_NAME, "package.json");
|
|
38
|
+
try {
|
|
39
|
+
const pkg = JSON.parse(readFileSync(pkgJson, "utf-8"));
|
|
40
|
+
if (pkg.bin && typeof pkg.bin === "object") {
|
|
41
|
+
return Object.keys(pkg.bin)[0] ?? PLUGIN_NAME;
|
|
42
|
+
}
|
|
43
|
+
if (typeof pkg.bin === "string") {
|
|
44
|
+
return PLUGIN_NAME;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// fall through
|
|
49
|
+
}
|
|
50
|
+
return PLUGIN_NAME;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* npm-generated .cmd / .ps1 wrappers on Windows invoke `.js` files directly
|
|
54
|
+
* via file association. If the `.js` association points to a text editor
|
|
55
|
+
* (e.g. Notepad++) instead of Node.js, the CLI opens the editor instead of
|
|
56
|
+
* running. This function patches the wrappers to call `node` explicitly.
|
|
57
|
+
*
|
|
58
|
+
* Runs only on Windows. Safe to call on every setup — detects already-patched
|
|
59
|
+
* wrappers by checking for the `node` prefix.
|
|
60
|
+
*/
|
|
61
|
+
export function patchWindowsWrappers(npmGlobalRoot) {
|
|
62
|
+
if (process.platform !== "win32")
|
|
63
|
+
return;
|
|
64
|
+
const binDir = path.resolve(npmGlobalRoot, "..");
|
|
65
|
+
const binName = getBinName();
|
|
66
|
+
// ── .cmd wrapper ──────────────────────────────────────────────
|
|
67
|
+
const cmdFile = path.join(binDir, `${binName}.cmd`);
|
|
68
|
+
if (existsSync(cmdFile)) {
|
|
69
|
+
const content = readFileSync(cmdFile, "utf-8");
|
|
70
|
+
// npm generates: "%dp0%\node_modules\opencode-rag-plugin\dist\cli\index.js" %*
|
|
71
|
+
// We want: node "%dp0%\node_modules\opencode-rag-plugin\dist\cli\index.js" %*
|
|
72
|
+
const cmdJsLine = /^(?!node\s)("[^"]+\.js"\s+%\*)$/m;
|
|
73
|
+
if (cmdJsLine.test(content)) {
|
|
74
|
+
const patched = content.replace(cmdJsLine, "node $1");
|
|
75
|
+
writeFileSync(cmdFile, patched, "utf-8");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ── PowerShell wrapper ────────────────────────────────────────
|
|
79
|
+
const ps1File = path.join(binDir, `${binName}.ps1`);
|
|
80
|
+
if (existsSync(ps1File)) {
|
|
81
|
+
let content = readFileSync(ps1File, "utf-8");
|
|
82
|
+
// Skip if already patched
|
|
83
|
+
if (content.includes('node "$basedir'))
|
|
84
|
+
return;
|
|
85
|
+
// npm generates:
|
|
86
|
+
// $input | & "$basedir/node_modules/.../index.js" $args
|
|
87
|
+
// & "$basedir/node_modules/.../index.js" $args
|
|
88
|
+
// Replace to: & node "$basedir/.../index.js" $args
|
|
89
|
+
const ps1DirectLine = /(&\s+)("\$basedir\/[^"]+\.js"\s+\$args)/g;
|
|
90
|
+
if (ps1DirectLine.test(content)) {
|
|
91
|
+
content = content.replace(ps1DirectLine, "$1node $2");
|
|
92
|
+
writeFileSync(ps1File, content, "utf-8");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export async function setupRuntime(options) {
|
|
97
|
+
const errors = [];
|
|
98
|
+
const pluginVersion = options?.version || process.env.OPCODE_RAG_VERSION || "0.0.0";
|
|
99
|
+
const runtimeDir = getRuntimeDir();
|
|
100
|
+
const versionFile = getVersionFile(runtimeDir);
|
|
101
|
+
const runtimePluginDir = path.join(runtimeDir, "node_modules", PLUGIN_NAME);
|
|
102
|
+
const runtimeSdkDir = path.join(runtimeDir, "node_modules", "@opencode-ai");
|
|
103
|
+
const runtimeSdkPluginDir = path.join(runtimeSdkDir, "plugin");
|
|
104
|
+
const installedVersion = readVersionFile(versionFile);
|
|
105
|
+
const runtimeDist = path.join(runtimePluginDir, "dist");
|
|
106
|
+
const alreadyInstalled = existsSync(runtimeDist);
|
|
107
|
+
if (alreadyInstalled && installedVersion === pluginVersion && !options?.force) {
|
|
108
|
+
return { success: true, errors: [] };
|
|
109
|
+
}
|
|
110
|
+
let npmGlobalRoot;
|
|
111
|
+
try {
|
|
112
|
+
npmGlobalRoot = getNpmGlobalRoot();
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
errors.push("npm is not available on PATH. Cannot determine global package location.");
|
|
116
|
+
return { success: false, errors };
|
|
117
|
+
}
|
|
118
|
+
const globalPluginDir = path.join(npmGlobalRoot, PLUGIN_NAME);
|
|
119
|
+
const globalSdkPluginDir = path.join(npmGlobalRoot, "@opencode-ai", "plugin");
|
|
120
|
+
if (!existsSync(globalPluginDir)) {
|
|
121
|
+
errors.push(`Plugin not found at: ${globalPluginDir}`);
|
|
122
|
+
return { success: false, errors };
|
|
123
|
+
}
|
|
124
|
+
if (!existsSync(path.join(globalPluginDir, "dist", "cli.js"))) {
|
|
125
|
+
errors.push(`Global install seems incomplete: dist/ not found in ${globalPluginDir}`);
|
|
126
|
+
return { success: false, errors };
|
|
127
|
+
}
|
|
128
|
+
mkdirSync(runtimeDir, { recursive: true });
|
|
129
|
+
const runtimePkg = path.join(runtimeDir, "package.json");
|
|
130
|
+
if (!existsSync(runtimePkg)) {
|
|
131
|
+
writeFileSync(runtimePkg, JSON.stringify({ private: true, type: "module" }, null, 2) + "\n", "utf-8");
|
|
132
|
+
}
|
|
133
|
+
removeIfExists(runtimePluginDir);
|
|
134
|
+
mkdirSync(path.dirname(runtimePluginDir), { recursive: true });
|
|
135
|
+
try {
|
|
136
|
+
createJunction(globalPluginDir, runtimePluginDir);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
const { cpSync } = await import("node:fs");
|
|
140
|
+
cpSync(globalPluginDir, runtimePluginDir, { recursive: true });
|
|
141
|
+
}
|
|
142
|
+
if (existsSync(globalSdkPluginDir)) {
|
|
143
|
+
removeIfExists(runtimeSdkPluginDir);
|
|
144
|
+
mkdirSync(runtimeSdkDir, { recursive: true });
|
|
145
|
+
try {
|
|
146
|
+
createJunction(globalSdkPluginDir, runtimeSdkPluginDir);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
const { cpSync } = await import("node:fs");
|
|
150
|
+
cpSync(globalSdkPluginDir, runtimeSdkPluginDir, { recursive: true });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
mkdirSync(runtimeSdkDir, { recursive: true });
|
|
155
|
+
try {
|
|
156
|
+
execSync(`npm install @opencode-ai/plugin --no-save`, {
|
|
157
|
+
cwd: runtimeDir,
|
|
158
|
+
stdio: "pipe",
|
|
159
|
+
timeout: 60_000,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch (cause) {
|
|
163
|
+
errors.push(`Failed to install @opencode-ai/plugin SDK: ${cause.message}`);
|
|
164
|
+
return { success: false, errors };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
writeFileSync(versionFile, pluginVersion, "utf-8");
|
|
168
|
+
patchWindowsWrappers(npmGlobalRoot);
|
|
169
|
+
const cliEntry = path.join(runtimePluginDir, "dist", "cli.js");
|
|
170
|
+
const pluginEntry = path.join(runtimePluginDir, "dist", "plugin-entry.js");
|
|
171
|
+
const sdkPkg = path.join(runtimeSdkPluginDir, "package.json");
|
|
172
|
+
const success = existsSync(cliEntry) && existsSync(pluginEntry) && existsSync(sdkPkg);
|
|
173
|
+
if (!success) {
|
|
174
|
+
if (!existsSync(cliEntry))
|
|
175
|
+
errors.push(`CLI entry missing: ${cliEntry}`);
|
|
176
|
+
if (!existsSync(pluginEntry))
|
|
177
|
+
errors.push(`Plugin entry missing: ${pluginEntry}`);
|
|
178
|
+
if (!existsSync(sdkPkg))
|
|
179
|
+
errors.push(`Plugin SDK missing: ${sdkPkg}`);
|
|
180
|
+
}
|
|
181
|
+
return { success, errors };
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=setup-runtime.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface UpdateInfo {
|
|
2
|
+
currentVersion: string;
|
|
3
|
+
latestVersion: string;
|
|
4
|
+
updateAvailable: boolean;
|
|
5
|
+
releaseUrl: string;
|
|
6
|
+
publishedAt: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
9
|
+
export declare function checkForUpdate(currentVersion: string): Promise<UpdateInfo>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function compareVersions(a, b) {
|
|
2
|
+
const pa = a.split(".").map((s) => parseInt(s, 10));
|
|
3
|
+
const pb = b.split(".").map((s) => parseInt(s, 10));
|
|
4
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
5
|
+
const na = pa[i] ?? 0;
|
|
6
|
+
const nb = pb[i] ?? 0;
|
|
7
|
+
if (na > nb)
|
|
8
|
+
return 1;
|
|
9
|
+
if (na < nb)
|
|
10
|
+
return -1;
|
|
11
|
+
}
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
export async function checkForUpdate(currentVersion) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const timeout = setTimeout(() => controller.abort(), 5_000);
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch("https://api.github.com/repos/MrDoe/OpenCodeRAG/releases/latest", {
|
|
19
|
+
headers: {
|
|
20
|
+
Accept: "application/vnd.github+json",
|
|
21
|
+
"User-Agent": "opencode-rag-updater",
|
|
22
|
+
},
|
|
23
|
+
signal: controller.signal,
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
return { currentVersion, latestVersion: currentVersion, updateAvailable: false, releaseUrl: "", publishedAt: "" };
|
|
27
|
+
}
|
|
28
|
+
const data = (await response.json());
|
|
29
|
+
const tagName = data.tag_name;
|
|
30
|
+
if (!tagName) {
|
|
31
|
+
return { currentVersion, latestVersion: currentVersion, updateAvailable: false, releaseUrl: "", publishedAt: "" };
|
|
32
|
+
}
|
|
33
|
+
const latestVersion = tagName.replace(/^v/i, "");
|
|
34
|
+
return {
|
|
35
|
+
currentVersion,
|
|
36
|
+
latestVersion,
|
|
37
|
+
updateAvailable: compareVersions(latestVersion, currentVersion) > 0,
|
|
38
|
+
releaseUrl: data.html_url ?? "",
|
|
39
|
+
publishedAt: data.published_at ?? "",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { currentVersion, latestVersion: currentVersion, updateAvailable: false, releaseUrl: "", publishedAt: "" };
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
clearTimeout(timeout);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=version-check.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Anthropic Messages API description provider for generating natural-language descriptions of code chunks.
|
|
3
3
|
*/
|
|
4
|
-
import type { Chunk, DescriptionProvider, DescriptionLogger } from "../core/interfaces.js";
|
|
4
|
+
import type { BatchDescriptionOptions, Chunk, DescriptionProvider, DescriptionLogger } from "../core/interfaces.js";
|
|
5
5
|
import type { DescriptionConfig } from "../core/config.js";
|
|
6
6
|
/**
|
|
7
7
|
* Description provider that uses Anthropic's Messages API to generate natural-language descriptions of code chunks.
|
|
@@ -18,7 +18,7 @@ export declare class AnthropicDescriptionProvider implements DescriptionProvider
|
|
|
18
18
|
/** @inheritdoc */
|
|
19
19
|
generateDescription(chunk: Chunk): Promise<string>;
|
|
20
20
|
/** @inheritdoc */
|
|
21
|
-
generateBatchDescriptions(chunks: Chunk[], logger?: DescriptionLogger): Promise<Map<string, string>>;
|
|
21
|
+
generateBatchDescriptions(chunks: Chunk[], logger?: DescriptionLogger, opts?: BatchDescriptionOptions): Promise<Map<string, string>>;
|
|
22
22
|
/**
|
|
23
23
|
* Sends a request to the Anthropic Messages API with retry and exponential backoff.
|
|
24
24
|
* The system prompt is combined with all user messages into a single message payload, and
|
|
@@ -25,11 +25,11 @@ export class AnthropicDescriptionProvider {
|
|
|
25
25
|
return this.chatRequest(messages, this.config.timeoutMs ?? 60000);
|
|
26
26
|
}
|
|
27
27
|
/** @inheritdoc */
|
|
28
|
-
async generateBatchDescriptions(chunks, logger) {
|
|
29
|
-
const log = logger ?? { info: (msg) =>
|
|
28
|
+
async generateBatchDescriptions(chunks, logger, opts) {
|
|
29
|
+
const log = logger ?? { info: (msg) => process.stderr.write(`${msg}\n`), warn: (msg) => process.stderr.write(`${msg}\n`), debug: (msg) => process.stderr.write(`${msg}\n`) };
|
|
30
30
|
const concurrency = this.config.batchConcurrency ?? 3;
|
|
31
31
|
const total = chunks.length;
|
|
32
|
-
log.
|
|
32
|
+
log.debug(`[describer] Generating descriptions for ${total} chunks (concurrency: ${concurrency})`);
|
|
33
33
|
const result = new Map();
|
|
34
34
|
const limit = pLimit(concurrency);
|
|
35
35
|
let completed = 0;
|
|
@@ -45,11 +45,9 @@ export class AnthropicDescriptionProvider {
|
|
|
45
45
|
log.warn(`[describer] Failed to describe chunk ${chunk.id} (${chunk.metadata.filePath}:${chunk.metadata.startLine}): ${err instanceof Error ? err.message : String(err)}`);
|
|
46
46
|
}
|
|
47
47
|
completed++;
|
|
48
|
-
|
|
49
|
-
log.info(`[describer] Progress: ${completed}/${total}`);
|
|
50
|
-
}
|
|
48
|
+
opts?.onProgress?.(chunk, completed, opts.total ?? total);
|
|
51
49
|
})));
|
|
52
|
-
log.
|
|
50
|
+
log.debug(`[describer] Descriptions generated: ${result.size}/${total}`);
|
|
53
51
|
return result;
|
|
54
52
|
}
|
|
55
53
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview OpenAI-compatible LLM description provider for generating natural-language descriptions of code chunks.
|
|
3
3
|
*/
|
|
4
|
-
import type { Chunk, DescriptionProvider, DescriptionLogger } from "../core/interfaces.js";
|
|
4
|
+
import type { BatchDescriptionOptions, Chunk, DescriptionProvider, DescriptionLogger } from "../core/interfaces.js";
|
|
5
5
|
import type { DescriptionConfig } from "../core/config.js";
|
|
6
6
|
/**
|
|
7
7
|
* Description provider that works with any OpenAI-compatible chat API (including Ollama).
|
|
@@ -18,7 +18,7 @@ export declare class LlmDescriptionProvider implements DescriptionProvider {
|
|
|
18
18
|
/** @inheritdoc */
|
|
19
19
|
generateDescription(chunk: Chunk): Promise<string>;
|
|
20
20
|
/** @inheritdoc */
|
|
21
|
-
generateBatchDescriptions(chunks: Chunk[], logger?: DescriptionLogger): Promise<Map<string, string>>;
|
|
21
|
+
generateBatchDescriptions(chunks: Chunk[], logger?: DescriptionLogger, opts?: BatchDescriptionOptions): Promise<Map<string, string>>;
|
|
22
22
|
/**
|
|
23
23
|
* Sends a chat completion request to the LLM API with retry and exponential backoff.
|
|
24
24
|
* For Ollama, uses the `/api/chat` endpoint with streaming disabled; otherwise uses the standard `/v1/chat/completions` endpoint.
|
|
@@ -2,7 +2,7 @@ import { postJson } from "../embedder/http.js";
|
|
|
2
2
|
import { buildUserMessage, sleep } from "./shared.js";
|
|
3
3
|
import pLimit from "p-limit";
|
|
4
4
|
/** HTTP status codes that are safe to retry on. */
|
|
5
|
-
const RETRYABLE_STATUSES = new Set([
|
|
5
|
+
const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
|
|
6
6
|
/**
|
|
7
7
|
* Description provider that works with any OpenAI-compatible chat API (including Ollama).
|
|
8
8
|
*
|
|
@@ -26,11 +26,11 @@ export class LlmDescriptionProvider {
|
|
|
26
26
|
return this.chatRequest(messages, this.config.timeoutMs ?? 60000);
|
|
27
27
|
}
|
|
28
28
|
/** @inheritdoc */
|
|
29
|
-
async generateBatchDescriptions(chunks, logger) {
|
|
30
|
-
const log = logger ?? { info: (msg) => process.stderr.write(`${msg}\n`), warn: (msg) =>
|
|
29
|
+
async generateBatchDescriptions(chunks, logger, opts) {
|
|
30
|
+
const log = logger ?? { info: (msg) => process.stderr.write(`${msg}\n`), warn: (msg) => process.stderr.write(`${msg}\n`), debug: (msg) => process.stderr.write(`${msg}\n`) };
|
|
31
31
|
const concurrency = this.config.batchConcurrency ?? 3;
|
|
32
32
|
const total = chunks.length;
|
|
33
|
-
log.
|
|
33
|
+
log.debug(`[describer] Generating descriptions for ${total} chunks via ${this.config.provider}/${this.config.model} (concurrency: ${concurrency})`);
|
|
34
34
|
const result = new Map();
|
|
35
35
|
const limit = pLimit(concurrency);
|
|
36
36
|
let completed = 0;
|
|
@@ -46,11 +46,9 @@ export class LlmDescriptionProvider {
|
|
|
46
46
|
log.warn(`[describer] Failed to describe chunk ${chunk.id} (${chunk.metadata.filePath}:${chunk.metadata.startLine}): ${err instanceof Error ? err.message : String(err)}`);
|
|
47
47
|
}
|
|
48
48
|
completed++;
|
|
49
|
-
|
|
50
|
-
log.info(`Descriptions: ${completed}/${total}`);
|
|
51
|
-
}
|
|
49
|
+
opts?.onProgress?.(chunk, completed, opts.total ?? total);
|
|
52
50
|
})));
|
|
53
|
-
log.
|
|
51
|
+
log.debug(`[describer] Descriptions generated: ${result.size}/${total}`);
|
|
54
52
|
return result;
|
|
55
53
|
}
|
|
56
54
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Google Gemini description provider for generating natural-language descriptions of code chunks.
|
|
3
3
|
*/
|
|
4
|
-
import type { Chunk, DescriptionProvider, DescriptionLogger } from "../core/interfaces.js";
|
|
4
|
+
import type { BatchDescriptionOptions, Chunk, DescriptionProvider, DescriptionLogger } from "../core/interfaces.js";
|
|
5
5
|
import type { DescriptionConfig } from "../core/config.js";
|
|
6
6
|
/**
|
|
7
7
|
* Description provider that uses Google Gemini's generateContent API to describe code chunks.
|
|
@@ -12,6 +12,6 @@ export declare class GeminiDescriptionProvider implements DescriptionProvider {
|
|
|
12
12
|
private readonly config;
|
|
13
13
|
constructor(config: DescriptionConfig);
|
|
14
14
|
generateDescription(chunk: Chunk): Promise<string>;
|
|
15
|
-
generateBatchDescriptions(chunks: Chunk[], logger?: DescriptionLogger): Promise<Map<string, string>>;
|
|
15
|
+
generateBatchDescriptions(chunks: Chunk[], logger?: DescriptionLogger, opts?: BatchDescriptionOptions): Promise<Map<string, string>>;
|
|
16
16
|
private chatRequest;
|
|
17
17
|
}
|
package/dist/describer/gemini.js
CHANGED
|
@@ -21,11 +21,11 @@ export class GeminiDescriptionProvider {
|
|
|
21
21
|
];
|
|
22
22
|
return this.chatRequest(contents, this.config.timeoutMs ?? 60000);
|
|
23
23
|
}
|
|
24
|
-
async generateBatchDescriptions(chunks, logger) {
|
|
25
|
-
const log = logger ?? { info: (msg) =>
|
|
24
|
+
async generateBatchDescriptions(chunks, logger, opts) {
|
|
25
|
+
const log = logger ?? { info: (msg) => process.stderr.write(`${msg}\n`), warn: (msg) => process.stderr.write(`${msg}\n`), debug: (msg) => process.stderr.write(`${msg}\n`) };
|
|
26
26
|
const concurrency = this.config.batchConcurrency ?? 3;
|
|
27
27
|
const total = chunks.length;
|
|
28
|
-
log.
|
|
28
|
+
log.debug(`[describer] Generating descriptions for ${total} chunks (concurrency: ${concurrency})`);
|
|
29
29
|
const result = new Map();
|
|
30
30
|
const limit = pLimit(concurrency);
|
|
31
31
|
let completed = 0;
|
|
@@ -41,11 +41,9 @@ export class GeminiDescriptionProvider {
|
|
|
41
41
|
log.warn(`[describer] Failed to describe chunk ${chunk.id} (${chunk.metadata.filePath}:${chunk.metadata.startLine}): ${err instanceof Error ? err.message : String(err)}`);
|
|
42
42
|
}
|
|
43
43
|
completed++;
|
|
44
|
-
|
|
45
|
-
log.info(`[describer] Progress: ${completed}/${total}`);
|
|
46
|
-
}
|
|
44
|
+
opts?.onProgress?.(chunk, completed, opts.total ?? total);
|
|
47
45
|
})));
|
|
48
|
-
log.
|
|
46
|
+
log.debug(`[describer] Descriptions generated: ${result.size}/${total}`);
|
|
49
47
|
return result;
|
|
50
48
|
}
|
|
51
49
|
async chatRequest(contents, timeoutMs) {
|
|
@@ -27,6 +27,8 @@ export declare function createEmbedder(config: RagConfig): EmbeddingProvider;
|
|
|
27
27
|
* @param batchSize - Number of texts per batch (default 10)
|
|
28
28
|
* @param purpose - Optional hint for query vs. document embedding
|
|
29
29
|
* @param concurrency - Maximum number of concurrent batch requests (default 1)
|
|
30
|
+
* @param onProgress - Optional callback invoked after each batch with the running
|
|
31
|
+
* completed count and total; per-text granularity when `concurrency <= 1`.
|
|
30
32
|
* @returns A promise resolving to a flat array of embedding vectors (one per input text)
|
|
31
33
|
*/
|
|
32
|
-
export declare function embedBatch(embedder: EmbeddingProvider, texts: string[], batchSize?: number, purpose?: "query" | "document", concurrency?: number): Promise<number[][]>;
|
|
34
|
+
export declare function embedBatch(embedder: EmbeddingProvider, texts: string[], batchSize?: number, purpose?: "query" | "document", concurrency?: number, onProgress?: (completed: number, total: number) => void): Promise<number[][]>;
|
package/dist/embedder/factory.js
CHANGED
|
@@ -46,9 +46,11 @@ export function createEmbedder(config) {
|
|
|
46
46
|
* @param batchSize - Number of texts per batch (default 10)
|
|
47
47
|
* @param purpose - Optional hint for query vs. document embedding
|
|
48
48
|
* @param concurrency - Maximum number of concurrent batch requests (default 1)
|
|
49
|
+
* @param onProgress - Optional callback invoked after each batch with the running
|
|
50
|
+
* completed count and total; per-text granularity when `concurrency <= 1`.
|
|
49
51
|
* @returns A promise resolving to a flat array of embedding vectors (one per input text)
|
|
50
52
|
*/
|
|
51
|
-
export async function embedBatch(embedder, texts, batchSize = 10, purpose, concurrency = 1) {
|
|
53
|
+
export async function embedBatch(embedder, texts, batchSize = 10, purpose, concurrency = 1, onProgress) {
|
|
52
54
|
if (texts.length === 0)
|
|
53
55
|
return [];
|
|
54
56
|
const batches = [];
|
|
@@ -60,12 +62,16 @@ export async function embedBatch(embedder, texts, batchSize = 10, purpose, concu
|
|
|
60
62
|
for (const batch of batches) {
|
|
61
63
|
const embeddings = await embedder.embed(batch.texts, purpose);
|
|
62
64
|
results.push(...embeddings);
|
|
65
|
+
onProgress?.(results.length, texts.length);
|
|
63
66
|
}
|
|
64
67
|
return results;
|
|
65
68
|
}
|
|
66
69
|
const limit = pLimit(concurrency);
|
|
70
|
+
let completedCount = 0;
|
|
67
71
|
const batchResults = await Promise.all(batches.map((batch) => limit(async () => {
|
|
68
72
|
const embeddings = await embedder.embed(batch.texts, purpose);
|
|
73
|
+
completedCount += embeddings.length;
|
|
74
|
+
onProgress?.(completedCount, texts.length);
|
|
69
75
|
return { index: batch.index, embeddings };
|
|
70
76
|
})));
|
|
71
77
|
batchResults.sort((a, b) => a.index - b.index);
|
package/dist/embedder/health.js
CHANGED
package/dist/embedder/http.d.ts
CHANGED
|
@@ -58,4 +58,4 @@ export declare function directRequest(url: URL, body: unknown, headers: Record<s
|
|
|
58
58
|
* @param proxy - Optional proxy configuration
|
|
59
59
|
* @returns A promise resolving to an HttpResponseLike
|
|
60
60
|
*/
|
|
61
|
-
export declare function postJson(urlString: string, body: unknown, headers: Record<string, string>, timeoutMs: number, proxy?: ProxyConfig): Promise<HttpResponseLike>;
|
|
61
|
+
export declare function postJson(urlString: string, body: unknown, headers: Record<string, string>, timeoutMs: number, proxy?: ProxyConfig, signal?: AbortSignal): Promise<HttpResponseLike>;
|
package/dist/embedder/http.js
CHANGED
|
@@ -6,6 +6,10 @@ import tls from "node:tls";
|
|
|
6
6
|
const MAX_POOL_SIZE = 4;
|
|
7
7
|
const IDLE_TIMEOUT_MS = 30000;
|
|
8
8
|
const connectionPool = new Map();
|
|
9
|
+
// Serialize proxied fetch requests that mutate process.env,
|
|
10
|
+
// preventing races when concurrent requests interleave
|
|
11
|
+
// set/restore of HTTP_PROXY/HTTPS_PROXY.
|
|
12
|
+
let proxyRequestQueue = Promise.resolve(undefined);
|
|
9
13
|
function poolKey(host, port, isHttps) {
|
|
10
14
|
return `${isHttps ? "tls" : "tcp"}:${host}:${port}`;
|
|
11
15
|
}
|
|
@@ -43,7 +47,13 @@ function releaseConnection(socket, host, port, isHttps) {
|
|
|
43
47
|
pool.splice(idx, 1);
|
|
44
48
|
socket.destroy();
|
|
45
49
|
}, IDLE_TIMEOUT_MS);
|
|
46
|
-
|
|
50
|
+
// Avoid removeAllListeners — that would strip the error handler
|
|
51
|
+
// and cause an unhandled crash on ECONNRESET/TLS alert.
|
|
52
|
+
socket.removeAllListeners("data");
|
|
53
|
+
socket.removeAllListeners("end");
|
|
54
|
+
socket.removeAllListeners("drain");
|
|
55
|
+
socket.removeAllListeners("error");
|
|
56
|
+
socket.on("error", () => socket.destroy());
|
|
47
57
|
pool.push({ socket, idleTimer });
|
|
48
58
|
}
|
|
49
59
|
/** Destroy all pooled TCP/TLS sockets and clear the connection pool. */
|
|
@@ -307,9 +317,9 @@ async function sendRawHttpRequest(url, body, headers, timeoutMs, redirectCount)
|
|
|
307
317
|
return;
|
|
308
318
|
}
|
|
309
319
|
if (isChunked) {
|
|
310
|
-
if (bodyBuffer.length >=
|
|
311
|
-
const
|
|
312
|
-
if (
|
|
320
|
+
if (bodyBuffer.length >= 7) {
|
|
321
|
+
const ascii = bodyBuffer.toString("ascii");
|
|
322
|
+
if (/0(?:;[^\n]*)?\r\n(?:[^\n]+:[^\n]*\r\n)*\r\n$/.test(ascii)) {
|
|
313
323
|
settle(() => {
|
|
314
324
|
releaseOrDestroy();
|
|
315
325
|
resolve(assembled);
|
|
@@ -371,7 +381,15 @@ async function sendRawHttpRequest(url, body, headers, timeoutMs, redirectCount)
|
|
|
371
381
|
},
|
|
372
382
|
};
|
|
373
383
|
}
|
|
374
|
-
|
|
384
|
+
const redirectUrl = new URL(location, url);
|
|
385
|
+
const sameOrigin = url.protocol === redirectUrl.protocol &&
|
|
386
|
+
url.hostname === redirectUrl.hostname &&
|
|
387
|
+
(url.port || (url.protocol === "https:" ? "443" : "80")) ===
|
|
388
|
+
(redirectUrl.port || (redirectUrl.protocol === "https:" ? "443" : "80"));
|
|
389
|
+
const safeHeaders = sameOrigin
|
|
390
|
+
? headers
|
|
391
|
+
: Object.fromEntries(Object.entries(headers).filter(([key]) => key.toLowerCase() !== "authorization"));
|
|
392
|
+
return sendRawHttpRequest(redirectUrl, body, safeHeaders, timeoutMs, redirectCount + 1);
|
|
375
393
|
}
|
|
376
394
|
const text = response.body.toString("utf8");
|
|
377
395
|
return {
|
|
@@ -399,52 +417,65 @@ async function sendRawHttpRequest(url, body, headers, timeoutMs, redirectCount)
|
|
|
399
417
|
* @param proxy - Optional proxy configuration
|
|
400
418
|
* @returns A promise resolving to an HttpResponseLike
|
|
401
419
|
*/
|
|
402
|
-
export async function postJson(urlString, body, headers, timeoutMs, proxy) {
|
|
420
|
+
export async function postJson(urlString, body, headers, timeoutMs, proxy, signal) {
|
|
403
421
|
const url = new URL(urlString);
|
|
404
422
|
const bypassProxy = isLocalhost(url.hostname) || matchesNoProxy(url.hostname, proxy?.noProxy);
|
|
405
423
|
if (bypassProxy || !proxy?.url) {
|
|
406
424
|
return directRequest(url, body, headers, timeoutMs);
|
|
407
425
|
}
|
|
408
|
-
return postJsonViaFetch(urlString, body, headers, timeoutMs, proxy);
|
|
426
|
+
return postJsonViaFetch(urlString, body, headers, timeoutMs, proxy, signal);
|
|
409
427
|
}
|
|
410
428
|
/** Send JSON via the global `fetch` API with proxy environment variable overrides. */
|
|
411
|
-
async function postJsonViaFetch(urlString, body, headers, timeoutMs, proxy) {
|
|
429
|
+
async function postJsonViaFetch(urlString, body, headers, timeoutMs, proxy, signal) {
|
|
412
430
|
const authHeader = buildProxyAuthHeader(proxy);
|
|
413
431
|
const envOverride = applyProxyEnv(proxy);
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
432
|
+
// Serialize fetch requests that mutate process.env to prevent
|
|
433
|
+
// concurrent requests from interleaving set/restore of proxy vars.
|
|
434
|
+
const [savedHttpProxy, savedHttpsProxy] = [process.env.HTTP_PROXY, process.env.HTTPS_PROXY];
|
|
435
|
+
return new Promise((resolve, reject) => {
|
|
436
|
+
proxyRequestQueue = proxyRequestQueue.then(async () => {
|
|
437
|
+
try {
|
|
438
|
+
if (envOverride) {
|
|
439
|
+
process.env.HTTP_PROXY = envOverride.httpProxy;
|
|
440
|
+
process.env.HTTPS_PROXY = envOverride.httpsProxy;
|
|
441
|
+
}
|
|
442
|
+
const requestHeaders = {
|
|
443
|
+
"Content-Type": "application/json",
|
|
444
|
+
...headers,
|
|
445
|
+
};
|
|
446
|
+
if (authHeader) {
|
|
447
|
+
requestHeaders["Proxy-Authorization"] = authHeader;
|
|
448
|
+
}
|
|
449
|
+
const controller = new AbortController();
|
|
450
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
451
|
+
const onAbort = () => { controller.abort(); clearTimeout(timeout); };
|
|
452
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
453
|
+
try {
|
|
454
|
+
const response = await fetch(urlString, {
|
|
455
|
+
method: "POST",
|
|
456
|
+
headers: requestHeaders,
|
|
457
|
+
body: JSON.stringify(body),
|
|
458
|
+
signal: controller.signal,
|
|
459
|
+
});
|
|
460
|
+
resolve(response);
|
|
461
|
+
}
|
|
462
|
+
finally {
|
|
463
|
+
clearTimeout(timeout);
|
|
464
|
+
signal?.removeEventListener("abort", onAbort);
|
|
465
|
+
if (envOverride) {
|
|
466
|
+
process.env.HTTP_PROXY = savedHttpProxy;
|
|
467
|
+
process.env.HTTPS_PROXY = savedHttpsProxy;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
catch (err) {
|
|
472
|
+
if (envOverride) {
|
|
473
|
+
process.env.HTTP_PROXY = savedHttpProxy;
|
|
474
|
+
process.env.HTTPS_PROXY = savedHttpsProxy;
|
|
475
|
+
}
|
|
476
|
+
reject(err);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
});
|
|
449
480
|
}
|
|
450
481
|
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Compare two branch benchmark JSON outputs and produce a side-by-side
|
|
3
|
+
* analysis report (console table + markdown file).
|
|
4
|
+
*
|
|
5
|
+
* Usage: node --import tsx src/eval/compare-merge.ts
|
|
6
|
+
* --main .opencode/rag_db/eval-results/main.json
|
|
7
|
+
* --branch .opencode/rag_db/eval-results/t1-cosine-l2.json
|
|
8
|
+
* --output .opencode/rag_db/eval-results/branch-compare-report.md
|
|
9
|
+
*/
|
|
10
|
+
export {};
|