import { queryDb } from "./db"; import { createDraftTask, getRequirement, listDraftTasks, updateDraftTask, updateRequirementStatus } from "./projectRequirementsRepo"; import { createTask } from "./taskRepo"; import type { Env } from "./types"; async function getAgentByKind(env: Env, kind: string): Promise { const res = await queryDb<{ id: string }>(env.DB, "SELECT id FROM agents WHERE kind = $1 ORDER BY created_at ASC LIMIT 1", [kind]); return res.rows[0]?.id || null; } async function createVirtualTask(env: Env, projectId: string, title: string, description: string, agentId: string, input: any): Promise { let boardId = ""; const boardRes = await queryDb<{ id: string }>(env.DB, "SELECT id, owner_id FROM boards WHERE project_id = $1 AND type = 'ops' LIMIT 1", [ projectId, ]); let ownerId = ""; if (boardRes.rows.length > 0) { boardId = boardRes.rows[0].id; ownerId = (boardRes.rows[0] as any).owner_id; } else { const defBoard = await queryDb<{ id: string; owner_id: string }>(env.DB, "SELECT id, owner_id FROM boards LIMIT 1", []); if (defBoard.rows.length > 0) { boardId = defBoard.rows[0].id; ownerId = defBoard.rows[0].owner_id; } } const task = await createTask(env.DB, ownerId, { board_id: boardId, title, description, assigned_to: agentId, skipRuntimeAvailability: true, input, }); return task.id; } async function waitForTaskDone(env: Env, taskId: string): Promise { const maxWait = 30; // 30 seconds for test for (let i = 0; i < maxWait; i++) { const res = await queryDb<{ status: string; result: string }>(env.DB, "SELECT status, result FROM tasks WHERE id = $1", [taskId]); if (res.rows.length === 0) throw new Error("Task not found"); if (res.rows[0].status === "done" || res.rows[0].status === "complete") { if (res.rows[0].result) { try { return JSON.parse(res.rows[0].result); } catch (_e) { return null; } } return null; } await new Promise((r) => setTimeout(r, 1000)); } throw new Error("Timeout waiting for task"); } export async function runRequirementPipeline(env: Env, projectId: string, reqId: string) { try { let req = await getRequirement(env.DB, reqId); if (!req) return; // 1. PM Phase if (req.status === "pending" || req.status === "processing_pm") { await updateRequirementStatus(env.DB, reqId, "processing_pm"); const pmAgentId = (await getAgentByKind(env, "feature_planner")) || req.pm_model; // simplified if (pmAgentId) { const taskId = await createVirtualTask(env, projectId, `PM Task: ${req.title}`, "Break down requirement", pmAgentId, { requirement: req.description, }); const result = await waitForTaskDone(env, taskId); if (result && Array.isArray(result)) { for (const item of result) { await createDraftTask(env.DB, reqId, { title: item.title, description: item.description }); } } } req = await getRequirement(env.DB, reqId); } // 2. SA Phase if (req!.status === "processing_pm" || req!.status === "processing_sa") { await updateRequirementStatus(env.DB, reqId, "processing_sa"); const saAgentId = (await getAgentByKind(env, "architect")) || req!.sa_model; if (saAgentId) { const draftTasks = await listDraftTasks(env.DB, reqId); const taskId = await createVirtualTask(env, projectId, `SA Task: ${req!.title}`, "Add technical details", saAgentId, { tasks: draftTasks }); const result = await waitForTaskDone(env, taskId); if (result && Array.isArray(result)) { for (const item of result) { if (item.id) { await updateDraftTask(env.DB, item.id, { technical_notes: item.technical_notes }); } } } } req = await getRequirement(env.DB, reqId); } // 3. BA Phase if (req!.status === "processing_sa" || req!.status === "processing_ba") { await updateRequirementStatus(env.DB, reqId, "processing_ba"); const baAgentId = (await getAgentByKind(env, "business_analyst")) || req!.ba_model; if (baAgentId) { const draftTasks = await listDraftTasks(env.DB, reqId); const taskId = await createVirtualTask(env, projectId, `BA Task: ${req!.title}`, "Add business details", baAgentId, { tasks: draftTasks }); const result = await waitForTaskDone(env, taskId); if (result && Array.isArray(result)) { for (const item of result) { if (item.id) { await updateDraftTask(env.DB, item.id, { business_context: item.business_context }); } } } } } await updateRequirementStatus(env.DB, reqId, "completed"); } catch (err: any) { console.error("Pipeline Error:", err); await updateRequirementStatus(env.DB, reqId, "failed", err.message); } }