UNPKG

paqad-ai

Version:

Spec-driven development framework — AI agents that think before they type

90 lines (87 loc) • 2.58 kB
import { createRequire as __paqadCreateRequire } from 'module'; const require = __paqadCreateRequire(import.meta.url); import { ROUTED_WORKFLOWS } from "./chunk-VOJO7HJ6.js"; import { STAGE_EVIDENCE_DOC_TYPE } from "./chunk-7TBVBCDH.js"; import { sessionLedgerDir } from "./chunk-Q353EDKY.js"; import { init_esm_shims } from "./chunk-IDFRWBMN.js"; // src/pipeline/route-turns.ts init_esm_shims(); import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "fs"; import { join } from "path"; var ROUTE_TURNS_FILE = ".route-turns.jsonl"; var ROUTE_TURNS_CAP = 2e3; var VALID_WORKFLOWS = new Set(ROUTED_WORKFLOWS); function routeTurnsPath(projectRoot, sessionId) { return join(projectRoot, sessionLedgerDir(STAGE_EVIDENCE_DOC_TYPE, sessionId), ROUTE_TURNS_FILE); } function toTurn(line) { try { const parsed = JSON.parse(line); if (typeof parsed.at === "string" && Number.isFinite(Date.parse(parsed.at)) && typeof parsed.workflow === "string" && VALID_WORKFLOWS.has(parsed.workflow)) { return { at: parsed.at, workflow: parsed.workflow }; } } catch { return null; } return null; } function readRouteTurns(projectRoot, sessionId) { let raw; try { raw = readFileSync(routeTurnsPath(projectRoot, sessionId), "utf8"); } catch { return []; } return raw.split("\n").filter((line) => line.trim().length > 0).map(toTurn).filter((turn) => turn !== null); } function appendRouteTurn(projectRoot, sessionId, turn, cap = ROUTE_TURNS_CAP) { const path = routeTurnsPath(projectRoot, sessionId); mkdirSync(join(projectRoot, sessionLedgerDir(STAGE_EVIDENCE_DOC_TYPE, sessionId)), { recursive: true }); appendFileSync(path, `${JSON.stringify({ at: turn.at, workflow: turn.workflow })} `, "utf8"); const lines = readFileSync(path, "utf8").split("\n").filter((line) => line.trim().length > 0); if (lines.length > cap) { writeFileSync(path, `${lines.slice(lines.length - cap).join("\n")} `, "utf8"); } } function episodeStart(turns, workflow) { let start = null; for (let index = turns.length - 1; index >= 0; index -= 1) { const turn = turns[index]; if (turn.workflow !== workflow) { break; } start = turn.at; } return start; } function turnRouteAt(turns, at) { const atMs = Date.parse(at); if (!Number.isFinite(atMs)) { return null; } let route = null; for (const turn of turns) { if (Date.parse(turn.at) > atMs) { break; } route = turn.workflow; } return route; } export { readRouteTurns, appendRouteTurn, episodeStart, turnRouteAt };