opencode-rag-plugin 1.11.0 → 1.12.1
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 +22 -0
- package/dist/chunker/image.d.ts +14 -0
- package/dist/chunker/image.js +356 -0
- package/dist/chunker/image.js.map +1 -0
- package/dist/chunker/loader.js +5 -0
- package/dist/chunker/loader.js.map +1 -1
- package/dist/cli.js +66 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/config.d.ts +15 -0
- package/dist/core/config.js +27 -3
- package/dist/core/config.js.map +1 -1
- package/dist/core/resolve-api-key.js +3 -0
- package/dist/core/resolve-api-key.js.map +1 -1
- package/dist/core/runtime-overrides.d.ts +5 -0
- package/dist/core/runtime-overrides.js +17 -0
- package/dist/core/runtime-overrides.js.map +1 -1
- package/dist/describer/describer.js +1 -1
- package/dist/describer/describer.js.map +1 -1
- package/dist/embedder/health.d.ts +18 -0
- package/dist/embedder/health.js +291 -0
- package/dist/embedder/health.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/indexer.d.ts +1 -1
- package/dist/indexer.js +65 -13
- package/dist/indexer.js.map +1 -1
- package/dist/web/api.d.ts +8 -0
- package/dist/web/api.js +81 -0
- package/dist/web/api.js.map +1 -1
- package/dist/web/ui/index.html +503 -98
- package/package.json +1 -1
package/ReadMe.md
CHANGED
|
@@ -38,6 +38,7 @@ opencode-rag query "authentication middleware"
|
|
|
38
38
|
| **MCP server** | `opencode-rag mcp` - stdio-based MCP server exposing `search_semantic`, `get_file_skeleton`, `find_usages` tools for any MCP-compatible client |
|
|
39
39
|
| **AST chunking** | 26 languages via tree-sitter (TS, JS, Python, Java, Go, Rust, C/C++, C#, Ruby, Kotlin, Swift, Bash, PHP, PowerShell, SQL, JSON, HTML, CSS, XML, YAML, TOML, INI, Dockerfile, Markdown, LaTeX, Razor) |
|
|
40
40
|
| **Document support** | Markdown, LaTeX, PDF, DOCX, DOC, Excel |
|
|
41
|
+
| **Image indexing** | Describe images via vision LLMs (Ollama, OpenAI, Anthropic, Gemini) and store descriptions as searchable vector chunks |
|
|
41
42
|
| **Hybrid search** | Vector similarity + TF×IDF keyword fusion |
|
|
42
43
|
| **OpenCode plugin** | Auto-inject context, read-tool override, TUI settings, Ctrl+Enter to add RAG context, MCP registration on `init` |
|
|
43
44
|
| **Incremental indexing** | File-hash manifest, background watcher, auto-rebuild on corruption |
|
|
@@ -74,6 +75,27 @@ Launch with `opencode-rag ui`. See [Web UI documentation](doc/webui.md) for deta
|
|
|
74
75
|
| [Troubleshooting](doc/troubleshooting.md) | Common issues, logging, debugging |
|
|
75
76
|
| [Roadmap](doc/roadmap.md) | Completed items, short/mid/long-term plans |
|
|
76
77
|
|
|
78
|
+
## Image Indexing
|
|
79
|
+
|
|
80
|
+
OpenCodeRAG can index image files (PNG, JPEG, WebP, etc.) by sending them to a vision-capable LLM and storing the generated text descriptions as searchable vector chunks. This makes visual assets discoverable via natural language queries (e.g., "login screen screenshot", "architecture diagram").
|
|
81
|
+
|
|
82
|
+
**Supported providers:** Ollama (`llama3.2-vision`, `minicpm-v`, etc.), OpenAI (`gpt-4o-mini`), Anthropic (`claude-3-haiku`), Google Gemini.
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"imageDescription": {
|
|
87
|
+
"enabled": true,
|
|
88
|
+
"provider": "ollama",
|
|
89
|
+
"model": "llama3.2-vision",
|
|
90
|
+
"baseUrl": "http://localhost:11434/api",
|
|
91
|
+
"timeoutMs": 60000,
|
|
92
|
+
"prompt": "Describe this image in detail. Include what it shows, any text content, layout, colors, objects, and the overall purpose or context."
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Disabled by default** — enable in `opencode-rag.json` to opt in.
|
|
98
|
+
|
|
77
99
|
## MCP Server
|
|
78
100
|
|
|
79
101
|
OpenCodeRAG ships a stdio-based [MCP (Model Context Protocol)](https://spec.modelcontextprotocol.io/) server that exposes semantic code tools to any MCP-compatible client (Claude Desktop, OpenCode, Cursor, etc.).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Chunker, Chunk } from "../core/interfaces.js";
|
|
2
|
+
import type { ImageDescriptionConfig } from "../core/config.js";
|
|
3
|
+
export declare const SUPPORTED_IMAGE_EXTENSIONS: Set<string>;
|
|
4
|
+
export declare function getMimeType(ext: string): string;
|
|
5
|
+
export interface ImageVisionProvider {
|
|
6
|
+
describeImage(imageBase64: string, mimeType: string, prompt: string, abort?: AbortSignal): Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createImageVisionProvider(config: ImageDescriptionConfig): ImageVisionProvider;
|
|
9
|
+
export declare class ImageChunker implements Chunker {
|
|
10
|
+
readonly language = "image";
|
|
11
|
+
readonly fileExtensions: string[];
|
|
12
|
+
constructor(extensions: string[]);
|
|
13
|
+
chunk(filePath: string, content: string): Promise<Chunk[]>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { postJson } from "../embedder/http.js";
|
|
2
|
+
import { uuid } from "./uuid.js";
|
|
3
|
+
const MAX_CHUNK_CHARS = 4000;
|
|
4
|
+
const MIN_GROUP_CHARS = 300;
|
|
5
|
+
const PARAGRAPH_SPLIT = /\n\s*\n/;
|
|
6
|
+
const VISION_RETRY_MAX = 2;
|
|
7
|
+
const VISION_RETRY_BASE_DELAY_MS = 1000;
|
|
8
|
+
const VISION_RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
|
|
9
|
+
function visionSleep(ms) {
|
|
10
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
11
|
+
}
|
|
12
|
+
export const SUPPORTED_IMAGE_EXTENSIONS = new Set([
|
|
13
|
+
".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".svg",
|
|
14
|
+
]);
|
|
15
|
+
const MIME_TYPES = {
|
|
16
|
+
png: "image/png",
|
|
17
|
+
jpg: "image/jpeg",
|
|
18
|
+
jpeg: "image/jpeg",
|
|
19
|
+
gif: "image/gif",
|
|
20
|
+
webp: "image/webp",
|
|
21
|
+
bmp: "image/bmp",
|
|
22
|
+
svg: "image/svg+xml",
|
|
23
|
+
};
|
|
24
|
+
export function getMimeType(ext) {
|
|
25
|
+
return MIME_TYPES[ext.toLowerCase().replace(/^\./, "")] || "image/png";
|
|
26
|
+
}
|
|
27
|
+
class OllamaImageVisionProvider {
|
|
28
|
+
baseUrl;
|
|
29
|
+
model;
|
|
30
|
+
timeoutMs;
|
|
31
|
+
think;
|
|
32
|
+
numCtx;
|
|
33
|
+
proxy;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
36
|
+
this.model = config.model;
|
|
37
|
+
this.timeoutMs = config.timeoutMs;
|
|
38
|
+
this.think = config.think ?? false;
|
|
39
|
+
this.numCtx = config.numCtx;
|
|
40
|
+
this.proxy = config.proxy;
|
|
41
|
+
}
|
|
42
|
+
async describeImage(imageBase64, mimeType, prompt, abort) {
|
|
43
|
+
const body = {
|
|
44
|
+
model: this.model,
|
|
45
|
+
messages: [
|
|
46
|
+
{
|
|
47
|
+
role: "user",
|
|
48
|
+
content: prompt,
|
|
49
|
+
images: [imageBase64],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
stream: false,
|
|
53
|
+
think: this.think,
|
|
54
|
+
options: { num_ctx: this.numCtx },
|
|
55
|
+
};
|
|
56
|
+
let lastError;
|
|
57
|
+
for (let attempt = 0; attempt <= VISION_RETRY_MAX; attempt++) {
|
|
58
|
+
const response = await postJson(`${this.baseUrl}/chat`, body, {}, this.timeoutMs, this.proxy);
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
const text = await response.text();
|
|
61
|
+
const error = new Error(`Ollama vision request failed (${response.status}): ${text}`);
|
|
62
|
+
if (VISION_RETRYABLE_STATUSES.has(response.status) && attempt < VISION_RETRY_MAX) {
|
|
63
|
+
lastError = error;
|
|
64
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
const json = (await response.json());
|
|
70
|
+
const content = json.message?.content;
|
|
71
|
+
if (content && content.trim().length > 0) {
|
|
72
|
+
return content.trim();
|
|
73
|
+
}
|
|
74
|
+
lastError = new Error(`Ollama vision returned empty response: ${JSON.stringify(json)}`);
|
|
75
|
+
if (attempt < VISION_RETRY_MAX) {
|
|
76
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
throw lastError;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
class OpenAIImageVisionProvider {
|
|
83
|
+
baseUrl;
|
|
84
|
+
model;
|
|
85
|
+
apiKey;
|
|
86
|
+
timeoutMs;
|
|
87
|
+
proxy;
|
|
88
|
+
constructor(config) {
|
|
89
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
90
|
+
this.model = config.model;
|
|
91
|
+
this.apiKey = config.apiKey ?? "";
|
|
92
|
+
this.timeoutMs = config.timeoutMs;
|
|
93
|
+
this.proxy = config.proxy;
|
|
94
|
+
}
|
|
95
|
+
async describeImage(imageBase64, mimeType, prompt, abort) {
|
|
96
|
+
const url = `${this.baseUrl}${this.baseUrl.endsWith("/v1") ? "" : "/v1"}/chat/completions`;
|
|
97
|
+
const body = {
|
|
98
|
+
model: this.model,
|
|
99
|
+
messages: [
|
|
100
|
+
{
|
|
101
|
+
role: "user",
|
|
102
|
+
content: [
|
|
103
|
+
{ type: "text", text: prompt },
|
|
104
|
+
{
|
|
105
|
+
type: "image_url",
|
|
106
|
+
image_url: { url: `data:${mimeType};base64,${imageBase64}` },
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
max_tokens: 2048,
|
|
112
|
+
};
|
|
113
|
+
const headers = {
|
|
114
|
+
"Content-Type": "application/json",
|
|
115
|
+
};
|
|
116
|
+
if (this.apiKey) {
|
|
117
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
118
|
+
}
|
|
119
|
+
let lastError;
|
|
120
|
+
for (let attempt = 0; attempt <= VISION_RETRY_MAX; attempt++) {
|
|
121
|
+
const response = await postJson(url, body, headers, this.timeoutMs, this.proxy);
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
const text = await response.text();
|
|
124
|
+
const error = new Error(`OpenAI vision request failed (${response.status}): ${text}`);
|
|
125
|
+
if (VISION_RETRYABLE_STATUSES.has(response.status) && attempt < VISION_RETRY_MAX) {
|
|
126
|
+
lastError = error;
|
|
127
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
const json = (await response.json());
|
|
133
|
+
const content = json.choices?.[0]?.message?.content;
|
|
134
|
+
if (content && content.trim().length > 0) {
|
|
135
|
+
return content.trim();
|
|
136
|
+
}
|
|
137
|
+
lastError = new Error(`OpenAI vision returned empty response: ${JSON.stringify(json)}`);
|
|
138
|
+
if (attempt < VISION_RETRY_MAX) {
|
|
139
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
throw lastError;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
class AnthropicImageVisionProvider {
|
|
146
|
+
baseUrl;
|
|
147
|
+
model;
|
|
148
|
+
apiKey;
|
|
149
|
+
timeoutMs;
|
|
150
|
+
proxy;
|
|
151
|
+
constructor(config) {
|
|
152
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
153
|
+
this.model = config.model;
|
|
154
|
+
this.apiKey = config.apiKey ?? "";
|
|
155
|
+
this.timeoutMs = config.timeoutMs;
|
|
156
|
+
this.proxy = config.proxy;
|
|
157
|
+
}
|
|
158
|
+
async describeImage(imageBase64, mimeType, prompt, abort) {
|
|
159
|
+
const body = {
|
|
160
|
+
model: this.model,
|
|
161
|
+
max_tokens: 2048,
|
|
162
|
+
messages: [
|
|
163
|
+
{
|
|
164
|
+
role: "user",
|
|
165
|
+
content: [
|
|
166
|
+
{
|
|
167
|
+
type: "image",
|
|
168
|
+
source: { type: "base64", media_type: mimeType, data: imageBase64 },
|
|
169
|
+
},
|
|
170
|
+
{ type: "text", text: prompt },
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
const headers = {
|
|
176
|
+
"x-api-key": this.apiKey,
|
|
177
|
+
"anthropic-version": "2023-06-01",
|
|
178
|
+
"Content-Type": "application/json",
|
|
179
|
+
};
|
|
180
|
+
let lastError;
|
|
181
|
+
for (let attempt = 0; attempt <= VISION_RETRY_MAX; attempt++) {
|
|
182
|
+
const response = await postJson(`${this.baseUrl}/messages`, body, headers, this.timeoutMs, this.proxy);
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
const text = await response.text();
|
|
185
|
+
const error = new Error(`Anthropic vision request failed (${response.status}): ${text}`);
|
|
186
|
+
if (VISION_RETRYABLE_STATUSES.has(response.status) && attempt < VISION_RETRY_MAX) {
|
|
187
|
+
lastError = error;
|
|
188
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
const json = (await response.json());
|
|
194
|
+
const text = json.content?.find((c) => c.type === "text")?.text;
|
|
195
|
+
if (text && text.trim().length > 0) {
|
|
196
|
+
return text.trim();
|
|
197
|
+
}
|
|
198
|
+
lastError = new Error(`Anthropic vision returned empty response: ${JSON.stringify(json)}`);
|
|
199
|
+
if (attempt < VISION_RETRY_MAX) {
|
|
200
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
throw lastError;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
class GeminiImageVisionProvider {
|
|
207
|
+
baseUrl;
|
|
208
|
+
model;
|
|
209
|
+
apiKey;
|
|
210
|
+
timeoutMs;
|
|
211
|
+
proxy;
|
|
212
|
+
constructor(config) {
|
|
213
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
214
|
+
this.model = config.model;
|
|
215
|
+
this.apiKey = config.apiKey;
|
|
216
|
+
this.timeoutMs = config.timeoutMs;
|
|
217
|
+
this.proxy = config.proxy;
|
|
218
|
+
}
|
|
219
|
+
async describeImage(imageBase64, mimeType, prompt, abort) {
|
|
220
|
+
const body = {
|
|
221
|
+
contents: [
|
|
222
|
+
{
|
|
223
|
+
role: "user",
|
|
224
|
+
parts: [
|
|
225
|
+
{ text: prompt },
|
|
226
|
+
{
|
|
227
|
+
inline_data: {
|
|
228
|
+
mime_type: mimeType,
|
|
229
|
+
data: imageBase64,
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
};
|
|
236
|
+
const headers = {
|
|
237
|
+
"Content-Type": "application/json",
|
|
238
|
+
};
|
|
239
|
+
const url = this.apiKey
|
|
240
|
+
? `${this.baseUrl}/models/${this.model}:generateContent?key=${this.apiKey}`
|
|
241
|
+
: `${this.baseUrl}/models/${this.model}:generateContent`;
|
|
242
|
+
let lastError;
|
|
243
|
+
for (let attempt = 0; attempt <= VISION_RETRY_MAX; attempt++) {
|
|
244
|
+
const response = await postJson(url, body, headers, this.timeoutMs, this.proxy);
|
|
245
|
+
if (!response.ok) {
|
|
246
|
+
const text = await response.text();
|
|
247
|
+
const error = new Error(`Gemini vision request failed (${response.status}): ${text}`);
|
|
248
|
+
if (VISION_RETRYABLE_STATUSES.has(response.status) && attempt < VISION_RETRY_MAX) {
|
|
249
|
+
lastError = error;
|
|
250
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
const json = (await response.json());
|
|
256
|
+
const text = json.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
257
|
+
if (text && text.trim().length > 0) {
|
|
258
|
+
return text.trim();
|
|
259
|
+
}
|
|
260
|
+
lastError = new Error(`Gemini vision returned empty response: ${JSON.stringify(json)}`);
|
|
261
|
+
if (attempt < VISION_RETRY_MAX) {
|
|
262
|
+
await visionSleep(VISION_RETRY_BASE_DELAY_MS * Math.pow(2, attempt));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
throw lastError;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export function createImageVisionProvider(config) {
|
|
269
|
+
if (config.provider === "anthropic") {
|
|
270
|
+
if (!config.apiKey) {
|
|
271
|
+
throw new Error("Anthropic image provider requires an apiKey");
|
|
272
|
+
}
|
|
273
|
+
return new AnthropicImageVisionProvider(config);
|
|
274
|
+
}
|
|
275
|
+
if (config.provider === "google") {
|
|
276
|
+
return new GeminiImageVisionProvider(config);
|
|
277
|
+
}
|
|
278
|
+
if (config.provider === "openai") {
|
|
279
|
+
if (!config.apiKey) {
|
|
280
|
+
throw new Error("OpenAI image provider requires an apiKey");
|
|
281
|
+
}
|
|
282
|
+
return new OpenAIImageVisionProvider(config);
|
|
283
|
+
}
|
|
284
|
+
return new OllamaImageVisionProvider(config);
|
|
285
|
+
}
|
|
286
|
+
export class ImageChunker {
|
|
287
|
+
language = "image";
|
|
288
|
+
fileExtensions;
|
|
289
|
+
constructor(extensions) {
|
|
290
|
+
this.fileExtensions = extensions;
|
|
291
|
+
}
|
|
292
|
+
async chunk(filePath, content) {
|
|
293
|
+
if (content.trim().length === 0)
|
|
294
|
+
return [];
|
|
295
|
+
const paragraphs = content.split(PARAGRAPH_SPLIT).filter((p) => p.trim().length > 0);
|
|
296
|
+
if (paragraphs.length === 0)
|
|
297
|
+
return [];
|
|
298
|
+
const chunks = [];
|
|
299
|
+
let currentGroup = [];
|
|
300
|
+
let currentSize = 0;
|
|
301
|
+
let paragraphIndex = 0;
|
|
302
|
+
function flush() {
|
|
303
|
+
const text = currentGroup.join("\n\n").trim();
|
|
304
|
+
if (text.length === 0)
|
|
305
|
+
return;
|
|
306
|
+
chunks.push({
|
|
307
|
+
id: uuid(),
|
|
308
|
+
content: text,
|
|
309
|
+
metadata: {
|
|
310
|
+
filePath,
|
|
311
|
+
startLine: paragraphIndex - currentGroup.length + 1,
|
|
312
|
+
endLine: paragraphIndex,
|
|
313
|
+
language: "image",
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
currentGroup = [];
|
|
317
|
+
currentSize = 0;
|
|
318
|
+
}
|
|
319
|
+
for (const para of paragraphs) {
|
|
320
|
+
paragraphIndex++;
|
|
321
|
+
const paraLen = para.length;
|
|
322
|
+
if (paraLen > MAX_CHUNK_CHARS) {
|
|
323
|
+
if (currentGroup.length > 0)
|
|
324
|
+
flush();
|
|
325
|
+
chunks.push({
|
|
326
|
+
id: uuid(),
|
|
327
|
+
content: para,
|
|
328
|
+
metadata: {
|
|
329
|
+
filePath,
|
|
330
|
+
startLine: paragraphIndex,
|
|
331
|
+
endLine: paragraphIndex,
|
|
332
|
+
language: "image",
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (currentGroup.length > 0 && currentSize + paraLen > MAX_CHUNK_CHARS) {
|
|
338
|
+
flush();
|
|
339
|
+
}
|
|
340
|
+
currentGroup.push(para);
|
|
341
|
+
currentSize += paraLen;
|
|
342
|
+
if (currentSize >= MIN_GROUP_CHARS && currentGroup.length >= 1) {
|
|
343
|
+
const nextParaStillSmall = paragraphIndex < paragraphs.length &&
|
|
344
|
+
paragraphs[paragraphIndex].length < MIN_GROUP_CHARS;
|
|
345
|
+
if (!nextParaStillSmall) {
|
|
346
|
+
flush();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (currentGroup.length > 0) {
|
|
351
|
+
flush();
|
|
352
|
+
}
|
|
353
|
+
return chunks;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/chunker/image.ts"],"names":[],"mappings":"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"}
|
package/dist/chunker/loader.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { registerChunker } from "./factory.js";
|
|
2
|
+
import { ImageChunker, SUPPORTED_IMAGE_EXTENSIONS } from "./image.js";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { pathToFileURL } from "node:url";
|
|
4
5
|
async function loadSingleChunker(entry, configDir) {
|
|
@@ -18,6 +19,10 @@ async function loadSingleChunker(entry, configDir) {
|
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
export async function loadChunkersFromConfig(config, configDir) {
|
|
22
|
+
if (config.imageDescription?.enabled) {
|
|
23
|
+
const chunker = new ImageChunker([...SUPPORTED_IMAGE_EXTENSIONS]);
|
|
24
|
+
registerChunker(chunker, [...SUPPORTED_IMAGE_EXTENSIONS]);
|
|
25
|
+
}
|
|
21
26
|
if (!config.chunkers || config.chunkers.length === 0)
|
|
22
27
|
return;
|
|
23
28
|
for (const entry of config.chunkers) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/chunker/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,KAAK,UAAU,iBAAiB,CAC9B,KAAoB,EACpB,SAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAEpC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QACnC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CACV,0BAA0B,KAAK,CAAC,MAAM,mEAAmE,CAC1G,CAAC;YACF,OAAO;QACT,CAAC;QAED,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,iDAAiD,KAAK,CAAC,MAAM,IAAI,EAChE,GAAa,CAAC,OAAO,CACvB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAiB,EACjB,SAAiB;IAEjB,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE7D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/chunker/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,KAAK,UAAU,iBAAiB,CAC9B,KAAoB,EACpB,SAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAEpC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QACnC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CACV,0BAA0B,KAAK,CAAC,MAAM,mEAAmE,CAC1G,CAAC;YACF,OAAO;QACT,CAAC;QAED,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,iDAAiD,KAAK,CAAC,MAAM,IAAI,EAChE,GAAa,CAAC,OAAO,CACvB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAiB,EACjB,SAAiB;IAEjB,IAAI,MAAM,CAAC,gBAAgB,EAAE,OAAO,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,0BAA0B,CAAC,CAAC,CAAC;QAClE,eAAe,CAAC,OAAO,EAAE,CAAC,GAAG,0BAA0B,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE7D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ import { appendDebugLog } from "./core/fileLogger.js";
|
|
|
13
13
|
import { loadChunkersFromConfig } from "./chunker/loader.js";
|
|
14
14
|
import { createEmbedder } from "./embedder/factory.js";
|
|
15
15
|
import { createDescriptionProvider } from "./describer/factory.js";
|
|
16
|
+
import { checkProviderHealth, pullOllamaModels } from "./embedder/health.js";
|
|
16
17
|
import { retrieve } from "./retriever/retriever.js";
|
|
17
18
|
import { createWatchPassScheduler, createWatchIgnore, getIndexStatusSummary, runIndexPass, } from "./indexer.js";
|
|
18
19
|
const c = {
|
|
@@ -940,6 +941,24 @@ function generateDefaultConfigJson() {
|
|
|
940
941
|
contentType: DEFAULT_CONFIG.openCode.autoInject.contentType,
|
|
941
942
|
},
|
|
942
943
|
},
|
|
944
|
+
imageDescription: {
|
|
945
|
+
enabled: DEFAULT_CONFIG.imageDescription.enabled,
|
|
946
|
+
provider: DEFAULT_CONFIG.imageDescription.provider,
|
|
947
|
+
model: DEFAULT_CONFIG.imageDescription.model,
|
|
948
|
+
baseUrl: DEFAULT_CONFIG.imageDescription.baseUrl,
|
|
949
|
+
timeoutMs: DEFAULT_CONFIG.imageDescription.timeoutMs,
|
|
950
|
+
think: DEFAULT_CONFIG.imageDescription.think,
|
|
951
|
+
numCtx: DEFAULT_CONFIG.imageDescription.numCtx,
|
|
952
|
+
},
|
|
953
|
+
description: {
|
|
954
|
+
enabled: DEFAULT_CONFIG.description.enabled,
|
|
955
|
+
provider: DEFAULT_CONFIG.description.provider,
|
|
956
|
+
baseUrl: DEFAULT_CONFIG.description.baseUrl,
|
|
957
|
+
model: DEFAULT_CONFIG.description.model,
|
|
958
|
+
think: DEFAULT_CONFIG.description.think,
|
|
959
|
+
numCtx: DEFAULT_CONFIG.description.numCtx,
|
|
960
|
+
timeoutMs: DEFAULT_CONFIG.description.timeoutMs,
|
|
961
|
+
},
|
|
943
962
|
mcp: {
|
|
944
963
|
enabled: DEFAULT_CONFIG.mcp.enabled,
|
|
945
964
|
},
|
|
@@ -957,6 +976,7 @@ program
|
|
|
957
976
|
.description("Configure the current workspace for OpenCodeRAG")
|
|
958
977
|
.option("-f, --force", "overwrite existing files")
|
|
959
978
|
.option("--skip-install", "skip installing workspace-local plugin dependencies")
|
|
979
|
+
.option("--skip-health-check", "skip provider connectivity and model availability check")
|
|
960
980
|
.action(async (options) => {
|
|
961
981
|
const cwd = process.cwd();
|
|
962
982
|
const packageMetadata = getPackageMetadata();
|
|
@@ -1086,6 +1106,52 @@ program
|
|
|
1086
1106
|
else {
|
|
1087
1107
|
console.log(` ${c.exists("Exists:")} opencode-rag.json`);
|
|
1088
1108
|
}
|
|
1109
|
+
// ── Provider health check ──────────────────────────────────
|
|
1110
|
+
if (!options.skipHealthCheck) {
|
|
1111
|
+
console.log(`\n${c.heading("Checking provider connectivity...")}\n`);
|
|
1112
|
+
const logFilePath = path.resolve(cwd, ".opencode", "opencode-rag.log");
|
|
1113
|
+
const ragConfig = loadConfig(configPath);
|
|
1114
|
+
const results = await checkProviderHealth(ragConfig);
|
|
1115
|
+
for (const r of results) {
|
|
1116
|
+
const icon = r.status === "ok" ? c.success("✓") : r.status === "missing" ? c.warn("○") : c.error("✗");
|
|
1117
|
+
const typeLabel = r.type === "image_description" ? "image description" : r.type;
|
|
1118
|
+
const label = `${typeLabel} model`;
|
|
1119
|
+
console.log(` ${icon} ${c.value(r.model)} (${r.provider}) — ${label}: ${r.status}`);
|
|
1120
|
+
if (r.error)
|
|
1121
|
+
console.log(` ${c.dim(r.error)}`);
|
|
1122
|
+
}
|
|
1123
|
+
const missingOllama = results.filter((r) => r.status === "missing" && r.provider === "ollama");
|
|
1124
|
+
if (missingOllama.length > 0) {
|
|
1125
|
+
const modelNames = missingOllama.map((r) => r.model);
|
|
1126
|
+
console.log(`\n ${c.warn("Models not found:")} ${modelNames.join(", ")}`);
|
|
1127
|
+
const readline = await import("node:readline");
|
|
1128
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1129
|
+
const answer = await new Promise((resolve) => {
|
|
1130
|
+
rl.question(` Pull ${modelNames.length === 1 ? "this model" : "these models"} now? (y/n) `, resolve);
|
|
1131
|
+
});
|
|
1132
|
+
rl.close();
|
|
1133
|
+
if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
|
|
1134
|
+
console.log();
|
|
1135
|
+
try {
|
|
1136
|
+
await pullOllamaModels(modelNames, (model, line) => {
|
|
1137
|
+
console.log(` ${c.value(model)}: ${line}`);
|
|
1138
|
+
});
|
|
1139
|
+
console.log(`\n ${c.success("Models pulled successfully.")}`);
|
|
1140
|
+
}
|
|
1141
|
+
catch (err) {
|
|
1142
|
+
console.error(`\n ${c.error("Pull failed:")} ${err.message}`);
|
|
1143
|
+
console.log(` ${c.dim("Pull manually with: ollama pull <model>")}`);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
console.log(` ${c.dim("Skipped. Pull manually with: ollama pull <model>")}`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
const hasErrors = results.some((r) => r.status === "error");
|
|
1151
|
+
if (hasErrors) {
|
|
1152
|
+
console.log(`\n ${c.warn("Some providers are not reachable.")} Check configuration and network, then run ${c.file("'opencode-rag index'")}.`);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1089
1155
|
if (!options.skipInstall) {
|
|
1090
1156
|
console.log(`\n${c.heading("Installing workspace-local plugin dependencies...")}\n`);
|
|
1091
1157
|
installWorkspaceDependencies(opencodeDir);
|