Skip to content

Commit 652183e

Browse files
author
Tim Sinaeve
committed
fix: dynamically reinitialize RAG vector table for different embedding dimensions and revert to 0.8.8
1 parent 99a85b7 commit 652183e

14 files changed

Lines changed: 229 additions & 84 deletions

File tree

App.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,17 @@ export const MainApp: React.FC = () => {
421421
const { logs, addLog } = useLogger();
422422
const lastLogRef = useRef<LogMessage | null>(null);
423423

424+
useEffect(() => {
425+
if (!window.electronAPI?.onAppLog) return;
426+
427+
const unsubscribe = window.electronAPI.onAppLog(({ level, message, timestamp }) => {
428+
// Avoid duplicate logs if they happen too quickly or are identical
429+
addLog(level, `[BACKEND] ${message}`);
430+
});
431+
432+
return unsubscribe;
433+
}, [addLog]);
434+
424435
useEffect(() => {
425436
if (!isElectron || !window.electronAPI?.dbGetPath) {
426437
setDatabaseStatus({ message: 'Database actions unavailable in this environment.', tone: 'info' });

VERSION_LOG.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
## v0.8.9 - The RAG Indexing & Transparency Fix
2-
3-
### 🐛 Fixes
4-
5-
- **RAG Workspace Indexing**:
6-
* Fixed a critical bug where workspace indexing would find documents but fail to process them (showing "0 documents processed").
7-
* Corrected the `rag_vectors` virtual table schema by removing an unsupported `PRIMARY KEY` constraint.
8-
* Added automated schema recovery logic to detect and report missing or broken vector tables.
9-
- **Transparency & Feedback**:
10-
* **Main Process Error Propagation**: Backend indexing errors are now captured and displayed directly in the Chat Panel log, providing clear feedback if document processing fails.
11-
* **Enhanced Status Diagnostics**: The "Build Index" process now performs a pre-flight check of the database schema and reports specific configuration or initialization errors.
12-
* **Detailed Content Logs**: Added diagnostic logging to identify documents that are skipped due to missing content or extraction failures.
13-
141
## v0.8.8 - The Agentic Workspace Update
152

163
### ✨ Features
@@ -30,9 +17,18 @@
3017

3118
### 🐛 Fixes
3219

20+
- **RAG Workspace Indexing**:
21+
* Fixed a critical bug where workspace indexing would find documents but fail to process them (showing "0 documents processed").
22+
* Corrected the `rag_vectors` virtual table schema by removing an unsupported `PRIMARY KEY` constraint.
23+
* Added automated schema recovery logic to detect and report missing or broken vector tables.
24+
- **Transparency & Feedback**:
25+
* **Main Process Error Propagation**: Backend indexing errors are now captured and displayed directly in the Chat Panel log, providing clear feedback if document processing fails.
26+
* **Enhanced Status Diagnostics**: The "Build Index" process now performs a pre-flight check of the database schema and reports specific configuration or initialization errors.
27+
* **Detailed Content Logs**: Added diagnostic logging to identify documents that are skipped due to missing content or extraction failures.
3328
- **Chat Stability**: Fixed several syntax and state synchronization errors in the chat panel that could cause crashes during long-running tool executions.
3429
- **Tag Balance**: Resolved various build-breaking JSX tag mismatches in the Chat UI.
3530

31+
3632
## v0.8.7 - The RAG & Clipboard Image Update
3733

3834
### ✨ Features

components/ChatPanel.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import React, { useState, useEffect, useRef, useCallback } from 'react';
22
import ReactMarkdown from 'react-markdown';
33
import remarkGfm from 'remark-gfm';
44
import rehypeRaw from 'rehype-raw';
5-
import type { Settings, RagChatMessage, RagSearchResult } from '../types';
5+
import type { Settings, RagChatMessage, RagSearchResult, Node } from '../types';
66
import { ragService } from '../services/ragService';
77
import { v4 as uuidv4 } from 'uuid';
88
import { usePythonEnvironments } from '../hooks/usePythonEnvironments';
99
import { pythonService } from '../services/pythonService';
1010
import { scriptService } from '../services/scriptService';
11+
import { SparklesIcon, TerminalIcon, WarningIcon } from './Icons';
1112

1213
interface ChatPanelProps {
1314
isVisible: boolean;
@@ -106,15 +107,13 @@ const ChatPanel: React.FC<ChatPanelProps> = ({
106107
const result = await ragService.indexAll(settings);
107108
if (result.success) {
108109
addLog('INFO', `RAG: Index build complete. Found ${result.totalDocumentsFound || 0} documents. Processed ${result.documentsProcessed} documents, ${result.totalChunks} chunks.`);
110+
109111
if (result.errors && result.errors.length > 0) {
110-
addLog('WARNING', `RAG: Encountered errors while indexing ${result.errors.length} documents:`);
112+
addLog('WARNING', `RAG: Encountered errors while indexing ${result.errors.length} item(s):`);
111113
result.errors.forEach(err => addLog('ERROR', ` - ${err}`));
112-
}
113-
if (result.documentsProcessed === 0) {
114+
} else if (result.documentsProcessed === 0 && (result.totalDocumentsFound || 0) > 0) {
114115
addLog('WARNING', `RAG: No documents were processed into the index. (Found ${result.totalDocumentsFound || 0} document nodes in total).`);
115-
if (!result.errors || result.errors.length === 0) {
116-
addLog('INFO', 'RAG: Tip - Check if Ollama is running and the embedding model is downloaded.');
117-
}
116+
addLog('INFO', 'RAG: Tip - Check if Ollama is running and the embedding model is downloaded.');
118117
}
119118
} else {
120119
addLog('ERROR', `RAG: Index build failed: ${result.error}`);

components/SettingsView.tsx

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { useLogger } from '../hooks/useLogger';
3333
import KeyboardShortcutsSection from './KeyboardShortcutsSection';
3434
import { usePythonEnvironments } from '../hooks/usePythonEnvironments';
3535
import { computeThemePalette, cssColorToHex, THEME_COLOR_TOKENS, type ThemePalette } from '../services/themeCustomization';
36+
import { ragService } from '../services/ragService';
3637

3738
interface SettingsViewProps {
3839
settings: Settings;
@@ -762,20 +763,52 @@ const RagSettingsSection: React.FC<SectionProps & { discoveredServices: Discover
762763
label="Embedding Model"
763764
description="The specific model used for embeddings. 'nomic-embed-text' is highly recommended."
764765
>
765-
<div className="relative w-60">
766-
<select
767-
id="ragModel"
768-
value={settings.ragEmbeddingModelName}
769-
onChange={(e) => setCurrentSettings(prev => ({ ...prev, ragEmbeddingModelName: e.target.value }))}
770-
disabled={availableModels.length === 0}
771-
className="w-full p-2 text-xs rounded-md bg-background text-text-main border border-border-color focus:ring-2 focus:ring-primary focus:border-primary disabled:opacity-50"
766+
<div className="flex flex-col gap-2 w-60">
767+
<div className="relative w-full">
768+
<select
769+
id="ragModel"
770+
value={availableModels.some(m => m.id === settings.ragEmbeddingModelName) ? settings.ragEmbeddingModelName : ""}
771+
onChange={(e) => setCurrentSettings(prev => ({ ...prev, ragEmbeddingModelName: e.target.value }))}
772+
disabled={availableModels.length === 0}
773+
className="w-full p-2 text-xs rounded-md bg-background text-text-main border border-border-color focus:ring-2 focus:ring-primary focus:border-primary disabled:opacity-50"
774+
>
775+
<option value="" disabled>{availableModels.length > 0 ? 'Select a model' : 'No models found'}</option>
776+
{availableModels.map(model => (
777+
<option key={model.id} value={model.id}>{model.name}</option>
778+
))}
779+
</select>
780+
{isFetchingModels && <div className="absolute right-3 top-1/2 -translate-y-1/2"><Spinner /></div>}
781+
</div>
782+
783+
<div className="space-y-1">
784+
<label className="text-[10px] text-text-tertiary font-medium uppercase tracking-wider">Manual Model Name</label>
785+
<input
786+
type="text"
787+
value={settings.ragEmbeddingModelName}
788+
onChange={(e) => setCurrentSettings(prev => ({ ...prev, ragEmbeddingModelName: e.target.value }))}
789+
placeholder="e.g. nomic-embed-text"
790+
className="w-full p-2 text-xs rounded-md bg-background text-text-main border border-border-color focus:ring-2 focus:ring-primary focus:border-primary"
791+
/>
792+
</div>
793+
794+
<Button
795+
onClick={async () => {
796+
const btn = document.activeElement as HTMLButtonElement;
797+
if (btn) btn.disabled = true;
798+
try {
799+
await ragService.search("test connection", settings);
800+
alert("Connection successful! The model is responsive.");
801+
} catch (err: any) {
802+
alert("Connection failed: " + (err.message || String(err)));
803+
} finally {
804+
if (btn) btn.disabled = false;
805+
}
806+
}}
807+
variant="secondary"
808+
className="w-full mt-2"
772809
>
773-
<option value="" disabled>Select a model</option>
774-
{availableModels.map(model => (
775-
<option key={model.id} value={model.id}>{model.name}</option>
776-
))}
777-
</select>
778-
{isFetchingModels && <div className="absolute right-3 top-1/2 -translate-y-1/2"><Spinner /></div>}
810+
Test Connection
811+
</Button>
779812
</div>
780813
<p className="text-[10px] text-text-tertiary mt-2 italic">
781814
Don't see your model? Run <code>ollama pull nomic-embed-text</code> in your terminal.
@@ -2612,7 +2645,8 @@ const ChatSettingsSection: React.FC<SectionProps> = ({ settings, setCurrentSetti
26122645
description="Allows the AI to perform actions like reading/editing documents, creating files, and running scripts. Requires a model that supports tool-calling (Ollama 0.1.34+ or OpenAI)."
26132646
>
26142647
<ToggleSwitch
2615-
enabled={settings.chatEnableAgentMode}
2648+
id="chatEnableAgentMode"
2649+
checked={settings.chatEnableAgentMode}
26162650
onChange={(enabled) => setCurrentSettings(prev => ({ ...prev, chatEnableAgentMode: enabled }))}
26172651
/>
26182652
</SettingRow>
@@ -2624,7 +2658,8 @@ const ChatSettingsSection: React.FC<SectionProps> = ({ settings, setCurrentSetti
26242658
description="When enabled, the AI will ask for your permission before performing any destructive actions (like deleting or moving files) or running scripts."
26252659
>
26262660
<ToggleSwitch
2627-
enabled={settings.chatAgentRequiresApproval}
2661+
id="chatAgentRequiresApproval"
2662+
checked={settings.chatAgentRequiresApproval}
26282663
onChange={(enabled) => setCurrentSettings(prev => ({ ...prev, chatAgentRequiresApproval: enabled }))}
26292664
/>
26302665
</SettingRow>

docs/VERSION_LOG.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
## v0.8.9 - The RAG Indexing & Transparency Fix
2-
3-
### 🐛 Fixes
4-
5-
- **RAG Workspace Indexing**:
6-
* Fixed a critical bug where workspace indexing would find documents but fail to process them (showing "0 documents processed").
7-
* Corrected the `rag_vectors` virtual table schema by removing an unsupported `PRIMARY KEY` constraint.
8-
* Added automated schema recovery logic to detect and report missing or broken vector tables.
9-
- **Transparency & Feedback**:
10-
* **Main Process Error Propagation**: Backend indexing errors are now captured and displayed directly in the Chat Panel log, providing clear feedback if document processing fails.
11-
* **Enhanced Status Diagnostics**: The "Build Index" process now performs a pre-flight check of the database schema and reports specific configuration or initialization errors.
12-
* **Detailed Content Logs**: Added diagnostic logging to identify documents that are skipped due to missing content or extraction failures.
13-
141
## v0.8.8 - The Agentic Workspace Update
152

163
### ✨ Features
@@ -30,9 +17,18 @@
3017

3118
### 🐛 Fixes
3219

20+
- **RAG Workspace Indexing**:
21+
* Fixed a critical bug where workspace indexing would find documents but fail to process them (showing "0 documents processed").
22+
* Corrected the `rag_vectors` virtual table schema by removing an unsupported `PRIMARY KEY` constraint.
23+
* Added automated schema recovery logic to detect and report missing or broken vector tables.
24+
- **Transparency & Feedback**:
25+
* **Main Process Error Propagation**: Backend indexing errors are now captured and displayed directly in the Chat Panel log, providing clear feedback if document processing fails.
26+
* **Enhanced Status Diagnostics**: The "Build Index" process now performs a pre-flight check of the database schema and reports specific configuration or initialization errors.
27+
* **Detailed Content Logs**: Added diagnostic logging to identify documents that are skipped due to missing content or extraction failures.
3328
- **Chat Stability**: Fixed several syntax and state synchronization errors in the chat panel that could cause crashes during long-running tool executions.
3429
- **Tag Balance**: Resolved various build-breaking JSX tag mismatches in the Chat UI.
3530

31+
3632
## v0.8.7 - The RAG & Clipboard Image Update
3733

3834
### ✨ Features

docs/releases/v0.8.8.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,18 @@ This release transforms the chat panel into an active **Workspace Agent** capabl
2424

2525
- **Chat Stability**: Fixed several syntax and state synchronization errors in the chat panel that could cause crashes during long-running tool executions.
2626
- **Tag Balance**: Resolved various build-breaking JSX tag mismatches in the Chat UI.
27+
- **RAG Workspace Indexing Fix**:
28+
- Resolved a bug where the indexing process would successfully discover documents but fail to process any chunks, resulting in an empty index.
29+
- Corrected the `rag_vectors` virtual table schema in the database initialization logic.
30+
- Fixed a silent failure in the SQLite extension loading process that could cause transactions to roll back without user notification.
31+
32+
### ✨ Improvements
33+
34+
#### Error Visibility & Transparency
35+
- **Main Process Error Propagation**: Indexing errors from the main process are now propagated to the renderer and displayed in the **Chat Panel log**.
36+
- **Diagnostic Troubleshooting**: Added clear troubleshooting tips when indexing results in 0 processed documents (e.g., suggestions to check Ollama status).
37+
- **Engine Status Checks**: The application now performs a detailed check of the RAG engine status on startup and when building the index, identifying missing tables or unsupported architectures.
38+
- **Enhanced Logging**: Added document-level logging to track content retrieval and chunking, making it easier to identify why specific documents might be skipped.
39+
40+
---
41+
*For a full history of changes, see the [Version Log](../../VERSION_LOG.md).*

docs/releases/v0.8.9.md

Lines changed: 0 additions & 25 deletions
This file was deleted.

electron/database.ts

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,17 @@ export const databaseService = {
14231423
};
14241424
}
14251425

1426-
const totalRow = db.prepare('SELECT COUNT(*) as count FROM nodes WHERE node_type = \'document\'').get() as { count: number };
1426+
const totalRow = db.prepare(`
1427+
SELECT COUNT(*) as count
1428+
FROM nodes n
1429+
JOIN documents d ON d.node_id = n.node_id
1430+
JOIN doc_versions dv ON dv.version_id = d.current_version_id
1431+
JOIN content_store cs ON cs.content_id = dv.content_id
1432+
WHERE n.node_type = 'document'
1433+
AND cs.text_content IS NOT NULL
1434+
AND cs.text_content != ''
1435+
`).get() as { count: number };
1436+
14271437
const indexedRow = db.prepare('SELECT COUNT(DISTINCT node_id) as count FROM rag_chunks').get() as { count: number };
14281438

14291439
return {
@@ -1445,6 +1455,28 @@ export const databaseService = {
14451455
db.exec('DELETE FROM rag_chunks;');
14461456
},
14471457

1458+
ragEnsureVectorDimension(dimensions: number): void {
1459+
const tableInfo = db.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='rag_vectors'").get() as { sql: string } | undefined;
1460+
1461+
// Check if the table already has the correct dimension
1462+
if (tableInfo && tableInfo.sql.includes(`float[${dimensions}]`)) {
1463+
return;
1464+
}
1465+
1466+
console.log(`[RAG DB] Re-initializing vector table for ${dimensions} dimensions. This clears the current index.`);
1467+
const transaction = db.transaction(() => {
1468+
db.exec('DROP TABLE IF EXISTS rag_vectors;');
1469+
db.exec('DELETE FROM rag_chunks;');
1470+
db.exec(`
1471+
CREATE VIRTUAL TABLE rag_vectors USING vec0(
1472+
chunk_id INTEGER,
1473+
embedding float[${dimensions}]
1474+
);
1475+
`);
1476+
});
1477+
transaction();
1478+
},
1479+
14481480
ragGetDocumentContent(nodeId: string): { title: string; content: string } | null {
14491481
const row = db.prepare(`
14501482
SELECT n.title, cs.text_content
@@ -1468,10 +1500,16 @@ export const databaseService = {
14681500

14691501
ragGetAllDocumentNodeIds(): string[] {
14701502
const rows = db.prepare(`
1471-
SELECT node_id FROM nodes
1472-
WHERE node_type = 'document'
1503+
SELECT n.node_id
1504+
FROM nodes n
1505+
JOIN documents d ON d.node_id = n.node_id
1506+
JOIN doc_versions dv ON dv.version_id = d.current_version_id
1507+
JOIN content_store cs ON cs.content_id = dv.content_id
1508+
WHERE n.node_type = 'document'
1509+
AND cs.text_content IS NOT NULL
1510+
AND cs.text_content != ''
14731511
`).all() as { node_id: string }[];
1474-
console.log(`[RAG DB] Found ${rows.length} document nodes for indexing.`);
1512+
console.log(`[RAG DB] Found ${rows.length} indexable document nodes.`);
14751513
return rows.map(r => r.node_id);
14761514
},
14771515

0 commit comments

Comments
 (0)