-
Notifications
You must be signed in to change notification settings - Fork 0
feat: show current file in ingest progress + slow file warnings #183 #184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,14 +45,21 @@ export interface IngestResult { | |
| durationMs: number; | ||
| } | ||
|
|
||
| export interface ProgressUpdate { | ||
| current: number; | ||
| total: number; | ||
| currentFile?: string; | ||
| currentFileSize?: number; | ||
| } | ||
|
|
||
| export interface IngestOptions { | ||
| recursive?: boolean; | ||
| reIndex?: boolean; | ||
| /** Project path for project_hash tagging on documents and symbols. */ | ||
| project?: string; | ||
| /** Called after each file chunk+embed for progress reporting. | ||
| * Receives { current, total } — current is 0-based, total is filesFound. */ | ||
| progressCallback?: (progress: { current: number; total: number }) => void; | ||
| /** Called after each file for progress reporting. | ||
| * Receives { current, total, currentFile?, currentFileSize? }. */ | ||
| progressCallback?: (update: ProgressUpdate) => void; | ||
| } | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
|
|
@@ -66,7 +73,7 @@ const MAX_FILE_SIZE = 2 * 1024 * 1024; // 2 MB | |
| const FILE_TIMEOUT_MS = 30_000; // 30 seconds per file | ||
|
|
||
| /** Files exceeding this duration get logged to app.log as a warning. */ | ||
| const SLOW_FILE_WARN_MS = 30_000; // 30 seconds | ||
| const SLOW_FILE_WARN_MS = 10_000; // 10 seconds | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // Progress event helpers (gated on BRAIN_DEBUG=true) | ||
|
|
@@ -190,12 +197,20 @@ export async function ingestPath( | |
| } | ||
|
|
||
| if (fileStats.size > MAX_FILE_SIZE) { | ||
| result.errors.push( | ||
| `Skipped ${filePath}: file size ${fileStats.size} exceeds 2MB cap`, | ||
| ); | ||
| const msg = `Skipped (too large, ${(fileStats.size / 1024 / 1024).toFixed(1)}MB): ${filePath}`; | ||
| log("info", "ingest", msg); | ||
| result.errors.push(msg); | ||
| return; | ||
| } | ||
|
|
||
| // Report which file is being processed | ||
| options?.progressCallback?.({ | ||
| current: i + 1, | ||
| total: walkedFiles.length, | ||
| currentFile: filePath, | ||
| currentFileSize: fileStats.size, | ||
| }); | ||
|
Comment on lines
+207
to
+212
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Progress counter inconsistency causes backwards progress reporting. The
When files are skipped (oversized, binary, failed), Example: For 3 files where file 2 is oversized:
🔧 Recommended fixUse options?.progressCallback?.({
- current: i + 1,
+ current: i + 1, // Keep as-is
total: walkedFiles.length,
currentFile: filePath,
currentFileSize: fileStats.size,
});And update lines 251 and 441: - options?.progressCallback?.({ current: result.filesProcessed, total: walkedFiles.length });
+ options?.progressCallback?.({ current: i + 1, total: walkedFiles.length, currentFile: undefined }); options?.progressCallback?.({
- current: result.filesProcessed,
+ current: i + 1,
total: walkedFiles.length,
currentFile: undefined,
});🤖 Prompt for AI Agents |
||
|
|
||
| // Read file as raw buffer — binary-safe hashing (avoids encoding issues) | ||
| let buf: ArrayBuffer; | ||
| try { | ||
|
|
@@ -208,7 +223,7 @@ export async function ingestPath( | |
|
|
||
| // Binary content guard: skip files with null bytes (safety net for misnamed binaries) | ||
| if (isBinaryContent(new Uint8Array(buf))) { | ||
| log("debug", "ingest", `Skipped binary content: ${filePath}`); | ||
| log("info", "ingest", `Skipped (binary content): ${filePath}`); | ||
| result.binarySkipped++; | ||
| return; | ||
| } | ||
|
|
@@ -317,6 +332,12 @@ export async function ingestPath( | |
| return; | ||
| } | ||
|
|
||
| // Slow-file warning after chunking completes | ||
| const fileElapsed = Date.now() - fileStart; | ||
| if (fileElapsed > SLOW_FILE_WARN_MS) { | ||
| log("warn", "ingest", `Slow file (${(fileElapsed / 1000).toFixed(1)}s): ${filePath} (${chunks ? chunks.length : 0} chunks)`); | ||
| } | ||
|
|
||
| // ── 9. Insert chunks (includes token_count) ─────────────────────── | ||
| // Clean up old chunks for this file before inserting new ones | ||
| db.run("DELETE FROM chunks WHERE file_id = ?", [fileId]); | ||
|
|
@@ -416,7 +437,11 @@ export async function ingestPath( | |
|
|
||
| result.filesIndexed++; | ||
| result.filesProcessed++; | ||
| options?.progressCallback?.({ current: result.filesProcessed, total: walkedFiles.length }); | ||
| options?.progressCallback?.({ | ||
| current: result.filesProcessed, | ||
| total: walkedFiles.length, | ||
| currentFile: undefined, | ||
| }); | ||
|
|
||
| // Per-file timing debug (BRAIN_DEBUG only) | ||
| if (process.env.BRAIN_DEBUG === "true") { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Missing progress callback on early return.
When a file is skipped due to size, the progress callback at lines 207-212 reports
currentFile: filePath, but the early return at line 203 never calls the callback withcurrentFile: undefined. Consumers tracking "which file is currently being processed" will incorrectly believe this file is still in progress.The same issue occurs for binary-content skips at line 228.
🔧 Recommended fix
Call the progress callback before returning:
if (fileStats.size > MAX_FILE_SIZE) { const msg = `Skipped (too large, ${(fileStats.size / 1024 / 1024).toFixed(1)}MB): ${filePath}`; log("info", "ingest", msg); result.errors.push(msg); + options?.progressCallback?.({ + current: i + 1, + total: walkedFiles.length, + currentFile: undefined, + }); return; }Apply the same fix at line 228 for binary-content skips.
📝 Committable suggestion
🤖 Prompt for AI Agents