(res: http.ServerResponse)
| 4013 | } |
| 4014 | |
| 4015 | private handleMigrateScan(res: http.ServerResponse): void { |
| 4016 | try { |
| 4017 | const ocHome = this.getOpenClawHome(); |
| 4018 | const memoryDir = path.join(ocHome, "memory"); |
| 4019 | const agentsDir = path.join(ocHome, "agents"); |
| 4020 | |
| 4021 | const sqliteFiles: Array<{ file: string; chunks: number }> = []; |
| 4022 | if (fs.existsSync(memoryDir)) { |
| 4023 | for (const f of fs.readdirSync(memoryDir)) { |
| 4024 | if (f.endsWith(".sqlite")) { |
| 4025 | try { |
| 4026 | const Database = require("better-sqlite3"); |
| 4027 | const db = new Database(path.join(memoryDir, f), { readonly: true }); |
| 4028 | const row = db.prepare("SELECT COUNT(*) as cnt FROM chunks").get() as { cnt: number }; |
| 4029 | sqliteFiles.push({ file: f, chunks: row.cnt }); |
| 4030 | db.close(); |
| 4031 | } catch { /* skip unreadable */ } |
| 4032 | } |
| 4033 | } |
| 4034 | } |
| 4035 | |
| 4036 | let sessionCount = 0; |
| 4037 | let messageCount = 0; |
| 4038 | if (fs.existsSync(agentsDir)) { |
| 4039 | for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) { |
| 4040 | if (!entry.isDirectory()) continue; |
| 4041 | const sessDir = path.join(agentsDir, entry.name, "sessions"); |
| 4042 | if (!fs.existsSync(sessDir)) continue; |
| 4043 | const jsonlFiles = fs.readdirSync(sessDir).filter(f => f.includes(".jsonl")); |
| 4044 | sessionCount += jsonlFiles.length; |
| 4045 | for (const f of jsonlFiles) { |
| 4046 | try { |
| 4047 | const content = fs.readFileSync(path.join(sessDir, f), "utf-8"); |
| 4048 | const lines = content.split("\n").filter(l => l.trim()); |
| 4049 | for (const line of lines) { |
| 4050 | try { |
| 4051 | const obj = JSON.parse(line); |
| 4052 | if (obj.type === "message") { |
| 4053 | const role = obj.message?.role ?? obj.role; |
| 4054 | if (role === "user" || role === "assistant") { |
| 4055 | const mc = obj.message?.content ?? obj.content; |
| 4056 | let txt = ""; |
| 4057 | if (typeof mc === "string") txt = mc; |
| 4058 | else if (Array.isArray(mc)) txt = mc.filter((p: any) => p.type === "text" && p.text).map((p: any) => p.text).join("\n"); |
| 4059 | else txt = JSON.stringify(mc); |
| 4060 | if (role === "user") txt = stripInboundMetadata(txt); |
| 4061 | if (txt && txt.length >= 10) messageCount++; |
| 4062 | } |
| 4063 | } |
| 4064 | } catch { /* skip bad lines */ } |
| 4065 | } |
| 4066 | } catch { /* skip unreadable */ } |
| 4067 | } |
| 4068 | } |
| 4069 | } |
| 4070 | |
| 4071 | const cfgPath = this.getOpenClawConfigPath(); |
| 4072 | let hasEmbedding = false; |
no test coverage detected