Intelligence
Artifacts
Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.
Repository
repositories/aaf-holdings/hq01/lib/workers/instances.ts
5.0 KB
import fs from "node:fs";
import path from "node:path";
import { INSTANCES_ROOT } from "./config";
import type {
WorkerEvent,
WorkerEventType,
WorkerInstance,
WorkerInstanceView,
WorkerStatus,
} from "./types";
/**
* Worker instance store. Instances are ephemeral execution records: they run a
* session and terminate. They never persist as agents — only as history.
*/
const ID_RE = /^WORKER-\d{6}$/;
function nowIso(): string {
return new Date().toISOString();
}
function instDir(id: string): string {
return path.join(INSTANCES_ROOT, id);
}
function instJson(id: string): string {
return path.join(instDir(id), "worker-instance.json");
}
function instHistory(id: string): string {
return path.join(instDir(id), "history", "log.jsonl");
}
function writeInstance(inst: WorkerInstance): void {
const file = instJson(inst.id);
fs.mkdirSync(path.dirname(file), { recursive: true });
const tmp = `${file}.tmp`;
fs.writeFileSync(tmp, JSON.stringify(inst, null, 2) + "\n", "utf8");
fs.renameSync(tmp, file);
}
export function readInstance(id: string): WorkerInstance | null {
if (!ID_RE.test(id)) return null;
try {
return JSON.parse(fs.readFileSync(instJson(id), "utf8")) as WorkerInstance;
} catch {
return null;
}
}
function append(id: string, type: WorkerEventType, detail?: string): void {
const file = instHistory(id);
fs.mkdirSync(path.dirname(file), { recursive: true });
const ev: WorkerEvent = { type, at: nowIso(), detail };
fs.appendFileSync(file, JSON.stringify(ev) + "\n", "utf8");
}
export function instanceHistory(id: string): WorkerEvent[] {
let raw: string;
try {
raw = fs.readFileSync(instHistory(id), "utf8");
} catch {
return [];
}
return raw
.split("\n")
.filter(Boolean)
.map((l) => {
try {
return JSON.parse(l) as WorkerEvent;
} catch {
return null;
}
})
.filter((e): e is WorkerEvent => Boolean(e));
}
function nextId(): string {
let max = 0;
let entries: fs.Dirent[] = [];
try {
entries = fs.readdirSync(INSTANCES_ROOT, { withFileTypes: true });
} catch {
/* none */
}
for (const e of entries) {
if (e.isDirectory() && ID_RE.test(e.name)) {
const n = Number(e.name.slice("WORKER-".length));
if (Number.isFinite(n) && n > max) max = n;
}
}
return `WORKER-${String(max + 1).padStart(6, "0")}`;
}
export function listInstances(): WorkerInstance[] {
let entries: fs.Dirent[];
try {
entries = fs.readdirSync(INSTANCES_ROOT, { withFileTypes: true });
} catch {
return [];
}
return entries
.filter((e) => e.isDirectory() && ID_RE.test(e.name))
.map((e) => readInstance(e.name))
.filter((x): x is WorkerInstance => Boolean(x))
.sort((a, b) => b.id.localeCompare(a.id));
}
export function listInstancesForAssignment(assignmentId: string): WorkerInstance[] {
return listInstances().filter((i) => i.assignment_id === assignmentId);
}
export function listInstancesForMission(missionId: string): WorkerInstance[] {
return listInstances().filter((i) => i.mission_id === missionId);
}
export interface CreateInstanceInput {
template_id: string;
mission_id: string;
objective_id: string;
work_order_id: string;
assignment_id: string;
executive: string;
workspace: string;
model: string;
version: string;
session_id: string;
started_at: string | null;
}
/** Create a running worker instance and record its instantiation. */
export function createInstance(input: CreateInstanceInput): WorkerInstance {
const id = nextId();
const inst: WorkerInstance = {
id,
template_id: input.template_id,
mission_id: input.mission_id,
objective_id: input.objective_id,
work_order_id: input.work_order_id,
assignment_id: input.assignment_id,
executive: input.executive,
session_id: input.session_id,
workspace: input.workspace,
status: "Running",
started_at: input.started_at,
completed_at: null,
report_id: null,
model: input.model,
version: input.version,
};
fs.mkdirSync(path.join(instDir(id), "history"), { recursive: true });
writeInstance(inst);
append(id, "instantiated", `${input.template_id} for ${input.assignment_id}`);
append(id, "session_attached", input.session_id);
return inst;
}
/** Terminate a worker instance, attaching its report. No worker survives. */
export function terminateInstance(
id: string,
opts: { status: WorkerStatus; report_id: string | null; completed_at: string },
): WorkerInstance | null {
const inst = readInstance(id);
if (!inst) return null;
const next: WorkerInstance = {
...inst,
status: opts.status,
report_id: opts.report_id,
completed_at: opts.completed_at,
};
writeInstance(next);
if (opts.report_id) append(id, "report_attached", opts.report_id);
append(id, "terminated", opts.status);
return next;
}
export function getInstanceView(id: string): WorkerInstanceView | null {
const instance = readInstance(id);
if (!instance) return null;
return {
instance,
history: instanceHistory(id).sort((a, b) => b.at.localeCompare(a.at)),
};
}
root · /srv/aaf