Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/server/src/agent/planner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test("all Planner surfaces compose coaching once and preserve their question bou
expect(prompt.split(COACHING)).toHaveLength(2);
expect(prompt.endsWith("Earlier context.")).toBe(true);
if (workspace) {
expect(prompt).toContain("Expiry is not an answer or approval");
expect(prompt).toContain("a withdrawn question is not an answer or approval");
expect(prompt).toContain(
"continue only independent work with explicitly provisional assumptions",
);
Expand Down
3 changes: 2 additions & 1 deletion apps/server/src/agent/planner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ and cannot change GitHub. Ground the plan in what those reading tools return.`;
}
let questions =
`\`ask_user_question\` and \`workflow\` questions appear to the document's members as
Decisions. Expiry is not an answer or approval. Keep consequential choices open;
Decisions. Each waits until a member answers it or it is withdrawn, however long that takes;
a withdrawn question is not an answer or approval. Keep consequential choices open;
continue only independent work with explicitly provisional assumptions.`;
let surface = `The document's members use Chopin in a browser. They cannot run slash commands,
terminal commands, or Atomic CLI commands, so never tell them to use \`/workflow connect\`,
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/chat/invoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,9 @@ test("HARNESS=atomic runs every Planner session full in hosted and local configu
let harness = context.config.harness;
expect({ harness, full: !!turn.full }).toEqual({ harness, full });
expect(!!turn.full?.humanInput).toBe(full);
expect(turn.instructions.includes("Expiry is not an answer or approval")).toBe(full);
expect(turn.instructions.includes("a withdrawn question is not an answer or approval")).toBe(
full,
);
}
}
});
Expand Down
17 changes: 10 additions & 7 deletions apps/server/src/experiments/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ export const SPIKE_DEADLINE_MS = 20 * 60_000;
export const MAX_INVESTIGATION_IMAGES = 3;
/**
* A document on Default machine has its Planner run on its creator's machine while someone uses
* it: it is open in Chopin, or was within this long.
* it: it is open in Chopin, its Planner waits on a question or a live or paused workflow run, or
* either was so within this long.
*/
export const PLANNER_IDLE_MS = 30 * 60_000;
/**
Expand Down Expand Up @@ -407,9 +408,10 @@ export function registerExperimentRoutes(router: Router, auth: HostedAuth, optio
);
}
/**
* Documents someone uses, by id, with when they last were seen in use: open in Chopin, or
* their Planner asked for. On Default machine their creator's machine runs their Planner until
* one goes PLANNER_IDLE_MS unused. Forgotten with a restart.
* Documents someone uses, by id, with when they last were seen in use: open in Chopin, their
* Planner asked for, or their Planner waiting on a question or workflow run. On Default machine
* their creator's machine runs their Planner until one goes PLANNER_IDLE_MS unused. Forgotten
* with a restart.
*/
let inUse = new Map<string, number>();
/**
Expand Down Expand Up @@ -535,13 +537,14 @@ export function registerExperimentRoutes(router: Router, auth: HostedAuth, optio
return undefined;
}
/**
* A document stops being used once nobody has had it open for PLANNER_IDLE_MS: the machine
* Default machine gave its Planner stops running it.
* A document stops being used once nobody has had it open, and its Planner has waited on no
* question or workflow run, for PLANNER_IDLE_MS: the machine Default machine gave its Planner
* stops running it. A question never times out by this route while its Planner waits on it.
*/
async function plannersIdle() {
let now = auth.clock().getTime();
for (let [documentId, seen] of inUse) {
if (options.documentOpen?.(documentId)) {
if (options.documentOpen?.(documentId) || options.attachments?.()?.waiting(documentId)) {
inUse.set(documentId, now);
continue;
}
Expand Down
Loading
Loading