import * as Effect from "effect/Effect"; import fixture, { PersonalAgent as FixturePersonalAgent } from "./think-worker"; import { getAgentByName } from "agents"; import type { Env } from "../../worker/personal-agent"; import type { BeginTaskRun, TaskRunProjection } from "../../worker/task-store"; import { nextCron } from "../../worker/task-validation"; export { Conversation, Sandbox } from "./think-worker"; export class PersonalAgent extends FixturePersonalAgent { // These tests isolate the intent/history store. Execution has its own real // native alarm/Think fixture; synthetic future history must not execute here. protected reconcileTaskSchedules() { return Effect.void; } async reconcileTaskExecution() {} protected reconcileTaskRead() { return Effect.void; } protected readTaskSummary(id: unknown) { return Effect.sync(() => this.tasks.get(id)); } private failTaskSqlPattern = ""; failTaskStatement(pattern: string) { this.failTaskSqlPattern = pattern; } sql>( strings: TemplateStringsArray, ...values: (string | number | boolean | null)[] ): T[] { if ( this.failTaskSqlPattern && strings.join("?").includes(this.failTaskSqlPattern) ) { this.failTaskSqlPattern = ""; throw new Error("Fixture task SQL failure"); } return super.sql(strings, ...values); } inspectTasks() { return { tasks: this.sql`SELECT * FROM flarebot_tasks ORDER BY id`, runs: this.sql`SELECT * FROM flarebot_task_runs ORDER BY id`, }; } fixtureRuns(inputs: BeginTaskRun[]) { return inputs.map((input) => this.beginTaskRun(input)); } fixtureProjection(input: TaskRunProjection) { return this.projectTaskRun(input); } async nativeTaskSchedules() { return (await this.listSchedules()).filter( (schedule) => !["expireSession", "maintainSkills"].includes(schedule.callback), ); } async nativeSkillMaintenance() { return (await this.listSchedules()).filter( (schedule) => schedule.callback === "maintainSkills", ); } } // A separate test entry seeds projection metadata, never production execution. // The deployed Worker contains no fixture routes, inference bypass or seeding RPC. export default { async fetch(request, env, ctx) { const path = new URL(request.url).pathname; if (path.startsWith("/__tasks/")) { const personal = await getAgentByName( env.PersonalAgent as unknown as DurableObjectNamespace, "personal", ); try { if (path === "/__tasks/fail") { const { statement } = await request.json<{ statement: string }>(); await personal.failTaskStatement(statement); return Response.json({ configured: true }); } if (path === "/__tasks/begin") return Response.json( await personal.fixtureRuns(await request.json()), ); if (path === "/__tasks/project") return Response.json( await personal.fixtureProjection(await request.json()), ); if (path === "/__tasks/inspect") return Response.json(await personal.inspectTasks()); if (path === "/__tasks/schedules") return Response.json(await personal.nativeTaskSchedules()); if (path === "/__tasks/skill-maintenance") return Response.json(await personal.nativeSkillMaintenance()); if (path === "/__tasks/utc") return Response.json({ offset: new Date().getTimezoneOffset(), monday: nextCron("0 9 * * 1", Date.parse("2030-01-07T08:59:59Z")), leap: nextCron("0 9 29 2 *", Date.parse("2030-01-01T00:00:00Z")), }); } catch (error) { return Response.json( { error: error instanceof Error ? error.message : "Fixture failure" }, { status: 400 }, ); } } return fixture.fetch(request, env, ctx); }, } satisfies ExportedHandler;