(_req: http.IncomingMessage, res: http.ServerResponse, urlPath: string)
| 1301 | // ─── Task/Skill management ─── |
| 1302 | |
| 1303 | private handleTaskRetrySkill(_req: http.IncomingMessage, res: http.ServerResponse, urlPath: string): void { |
| 1304 | const taskId = urlPath.replace("/api/task/", "").replace("/retry-skill", ""); |
| 1305 | const task = this.store.getTask(taskId); |
| 1306 | if (!task) { res.writeHead(404, { "Content-Type": "application/json" }); res.end(JSON.stringify({ error: "Task not found" })); return; } |
| 1307 | if (task.status !== "completed") { res.writeHead(400, { "Content-Type": "application/json" }); res.end(JSON.stringify({ error: "Only completed tasks can retry skill generation" })); return; } |
| 1308 | if (!this.ctx) { res.writeHead(500, { "Content-Type": "application/json" }); res.end(JSON.stringify({ error: "Plugin context not available" })); return; } |
| 1309 | |
| 1310 | // Clean up stale task_skills references (e.g., skill was manually deleted) |
| 1311 | const db = (this.store as any).db; |
| 1312 | db.prepare("DELETE FROM task_skills WHERE task_id = ? AND skill_id NOT IN (SELECT id FROM skills)").run(taskId); |
| 1313 | |
| 1314 | this.store.setTaskSkillMeta(taskId, { skillStatus: "queued", skillReason: "手动重试中..." }); |
| 1315 | this.jsonResponse(res, { ok: true, taskId, status: "queued" }); |
| 1316 | |
| 1317 | const ctx = this.ctx; |
| 1318 | const recallEngine = new RecallEngine(this.store, this.embedder, ctx); |
| 1319 | const evolver = new SkillEvolver(this.store, recallEngine, ctx, this.embedder); |
| 1320 | evolver.onTaskCompleted(task).then(() => { |
| 1321 | this.log.info(`Retry skill generation completed for task ${taskId}`); |
| 1322 | }).catch((err) => { |
| 1323 | this.log.error(`Retry skill generation failed for task ${taskId}: ${err}`); |
| 1324 | this.store.setTaskSkillMeta(taskId, { skillStatus: "skipped", skillReason: `error: ${err}` }); |
| 1325 | }); |
| 1326 | } |
| 1327 | |
| 1328 | private embedTaskInBackground(taskId: string, text: string): void { |
| 1329 | if (!this.embedder || !text.trim()) return; |
no test coverage detected