import { mkdirSync, writeFileSync, appendFileSync } from 'fs'; import { join } from 'path'; import { logger } from '../../logger.js'; /** raw保存対象のツール名一覧 */ export const RAW_SAVE_TOOLS = new Set([ 'WebFetch', 'WebSearch', 'XSearch', 'XUserPosts', 'XPostDetail', 'BrowseWeb', 'GetYouTubeTranscript', 'SearchYouTube', 'SearchAmazon', 'TranscribeAudio', 'SearchMicrosoftLearn', 'FetchMicrosoftLearn', 'SearchMicrosoftLearnCache', 'RefreshMicrosoftLearnCache', ]); /** DownloadFile はパス記録のみ(二重保存回避) */ export const RAW_LOG_ONLY_TOOLS = new Set(['DownloadFile']); export function generateRawFilename(toolName: string, ext: string): string { const now = new Date(); const ts = [ now.getFullYear(), String(now.getMonth() + 1).padStart(2, '0'), String(now.getDate()).padStart(2, '0'), '-', String(now.getHours()).padStart(2, '0'), String(now.getMinutes()).padStart(2, '0'), String(now.getSeconds()).padStart(2, '0'), '-', String(now.getMilliseconds()).padStart(3, '0'), ].join(''); return `${toolName.toLowerCase()}-${ts}${ext}`; } /** * ツール実行結果を logs/raw/ に保存する。 * RAW_SAVE_TOOLS に含まれないツールの場合は何もしない。 */ export function saveRawData( workspacePath: string, toolName: string, content: string, ): void { if (!RAW_SAVE_TOOLS.has(toolName)) return; try { const rawDir = join(workspacePath, 'logs', 'raw'); mkdirSync(rawDir, { recursive: true }); const filename = generateRawFilename(toolName, '.txt'); const filePath = join(rawDir, filename); writeFileSync(filePath, content, 'utf-8'); const logEntry = { timestamp: new Date().toISOString(), tool: toolName, filename, bytes: Buffer.byteLength(content, 'utf-8'), }; appendFileSync( join(workspacePath, 'logs', 'rawdata-history.jsonl'), JSON.stringify(logEntry) + '\n', 'utf-8', ); } catch (err) { logger.warn(`[raw-save] failed to save raw data for ${toolName}: ${err}`); } } /** * DownloadFile のパス情報を rawdata-history.jsonl に記録する(ファイルコピーはしない)。 */ export function logRawDownload( workspacePath: string, toolName: string, savedPath: string, bytes: number, ): void { try { const logEntry = { timestamp: new Date().toISOString(), tool: toolName, filename: savedPath, bytes, type: 'reference', }; appendFileSync( join(workspacePath, 'logs', 'rawdata-history.jsonl'), JSON.stringify(logEntry) + '\n', 'utf-8', ); } catch (err) { logger.warn(`[raw-save] failed to log download for ${toolName}: ${err}`); } }