Files
AgentCompany/src/main/services/goal-change-poller.ts
T

34 lines
1.6 KiB
TypeScript

import type { DatabaseSync } from "node:sqlite";
interface GoalState {
title: string;
description: string;
status: string;
}
/** Returns a notice whenever the run's goal is rewritten or closed after the run started, once per change. */
export function createGoalChangePoller(db: DatabaseSync, goalId: string | null): () => string | null {
if (!goalId) return () => null;
const read = () => db.prepare("select title, description, status from goals where id = ?").get(goalId) as GoalState | undefined;
let seen = read();
return () => {
const now = read();
if (!seen || !now || (now.title === seen.title && now.description === seen.description && now.status === seen.status)) return null;
const before = seen;
seen = now;
console.info(`[task-run] goal ${goalId} changed mid-run (${now.status}); notifying the session`);
if (now.status !== before.status && now.status !== "active") {
return `The goal for this work ("${now.title}") is now ${now.status}. Stop starting new work on it: wrap up, report what you finished, and set this task's status.`;
}
return `The goal for this work changed while you were working. It now reads: "${now.title}" — ${now.description} Re-check your plan against it.`;
};
}
/** Joins mid-run notices from several sources into one follow-up, or null when none has news. */
export function combineMidRunPolls(...polls: Array<() => string | null>): () => string | null {
return () => {
const notices = polls.map((poll) => poll()).filter((notice): notice is string => notice !== null);
return notices.length > 0 ? notices.join("\n\n") : null;
};
}