diff --git a/src/main/services/team/TeamDataService.ts b/src/main/services/team/TeamDataService.ts index 6af90ea0..ad4ad92a 100644 --- a/src/main/services/team/TeamDataService.ts +++ b/src/main/services/team/TeamDataService.ts @@ -3247,41 +3247,25 @@ export class TeamDataService { private async readLeadSessionJsonlTailLines(jsonlPath: string): Promise { const MAX_SCAN_BYTES = 8 * 1024 * 1024; - const INITIAL_SCAN_BYTES = 256 * 1024; - - const rawLinesReversed: string[] = []; - const seenRawLines = new Set(); const handle = await fs.promises.open(jsonlPath, 'r'); try { const stat = await handle.stat(); const fileSize = stat.size; + const scanBytes = Math.min(MAX_SCAN_BYTES, fileSize); + const start = Math.max(0, fileSize - scanBytes); + const buffer = Buffer.alloc(scanBytes); + await handle.read(buffer, 0, scanBytes, start); + const chunk = buffer.toString('utf8'); - let scanBytes = Math.min(INITIAL_SCAN_BYTES, fileSize); - while (scanBytes <= MAX_SCAN_BYTES) { - const start = Math.max(0, fileSize - scanBytes); - const buffer = Buffer.alloc(scanBytes); - await handle.read(buffer, 0, scanBytes, start); - const chunk = buffer.toString('utf8'); - - const lines = chunk.split(/\r?\n/); - const fromIndex = start > 0 ? 1 : 0; - - for (let i = lines.length - 1; i >= fromIndex; i--) { - const trimmed = lines[i]?.trim(); - if (!trimmed) continue; - if (seenRawLines.has(trimmed)) continue; - seenRawLines.add(trimmed); - rawLinesReversed.push(trimmed); - } - - if (scanBytes === fileSize) break; - scanBytes = Math.min(fileSize, scanBytes * 2); - } + const lines = chunk.split(/\r?\n/); + const fromIndex = start > 0 ? 1 : 0; + return lines + .slice(fromIndex) + .map((line) => line.trim()) + .filter(Boolean); } finally { await handle.close(); } - - return rawLinesReversed.reverse(); } private async extractLeadAssistantTextsFromJsonlLines( diff --git a/src/main/services/team/leadSessionMessageExtractor.ts b/src/main/services/team/leadSessionMessageExtractor.ts index 6d4a7df1..e90f52f6 100644 --- a/src/main/services/team/leadSessionMessageExtractor.ts +++ b/src/main/services/team/leadSessionMessageExtractor.ts @@ -9,7 +9,6 @@ import type { ParsedMessage } from '@main/types'; import type { CommandOutputMeta, InboxMessage, SlashCommandMeta } from '@shared/types'; const MAX_SCAN_BYTES = 8 * 1024 * 1024; -const INITIAL_SCAN_BYTES = 256 * 1024; interface LeadSessionMessageExtractorOptions { jsonlPath: string; @@ -133,23 +132,17 @@ export async function extractLeadSessionMessagesFromJsonl({ try { const stat = await handle.stat(); const fileSize = stat.size; + const scanBytes = Math.min(MAX_SCAN_BYTES, fileSize); + const start = Math.max(0, fileSize - scanBytes); + const buffer = Buffer.alloc(scanBytes); + await handle.read(buffer, 0, scanBytes, start); + const chunk = buffer.toString('utf8'); - let scanBytes = Math.min(INITIAL_SCAN_BYTES, fileSize); - while (scanBytes <= MAX_SCAN_BYTES) { - const start = Math.max(0, fileSize - scanBytes); - const buffer = Buffer.alloc(scanBytes); - await handle.read(buffer, 0, scanBytes, start); - const chunk = buffer.toString('utf8'); + const lines = chunk.split(/\r?\n/); + const fromIndex = start > 0 ? 1 : 0; - const lines = chunk.split(/\r?\n/); - const fromIndex = start > 0 ? 1 : 0; - - for (let i = lines.length - 1; i >= fromIndex; i--) { - collectLine(lines[i]); - } - - if (scanBytes === fileSize) break; - scanBytes = Math.min(fileSize, scanBytes * 2); + for (let i = lines.length - 1; i >= fromIndex; i--) { + collectLine(lines[i]); } } finally { await handle.close();