302148523f
Publish terminal daemon completions to the session that started the process so idle agents can resume without polling hub status. Persist every unacknowledged generation with a stable completion ID and immutable snapshot. Replay the collection after reconnect or broker recovery, and clear each event only after the owning client acknowledges it. Signed-off-by: Christian Stewart <christian@aperture.us>
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { prompt } from "@oh-my-pi/pi-utils";
|
|
import type { DaemonCompletionNotification } from "../launch/protocol";
|
|
import launchCompletionTemplate from "../prompts/session/launch-completion.md" with { type: "text" };
|
|
import type { CustomMessage } from "./messages";
|
|
|
|
/** Yield-queue kind for broker-owned supervised process completions. */
|
|
export const LAUNCH_COMPLETION_MESSAGE_TYPE = "launch-completion";
|
|
|
|
/** One broker completion awaiting injection into its owning session. */
|
|
export type LaunchCompletionEntry = DaemonCompletionNotification;
|
|
|
|
/** Whether a broker completion belongs to the primary session or its advisor. */
|
|
export function isLaunchCompletionOwner(owner: string, sessionId: string): boolean {
|
|
return owner === sessionId || owner === `${sessionId}-advisor`;
|
|
}
|
|
|
|
/** Build one model-visible notification per terminal supervised process exit. */
|
|
export function buildLaunchCompletionBatchMessage(entries: LaunchCompletionEntry[]): CustomMessage {
|
|
return {
|
|
role: "custom",
|
|
customType: LAUNCH_COMPLETION_MESSAGE_TYPE,
|
|
content: entries
|
|
.map(({ daemon }) =>
|
|
prompt.render(launchCompletionTemplate, {
|
|
name: daemon.name,
|
|
state: daemon.state,
|
|
exitCode: daemon.exitCode,
|
|
hasExitCode: daemon.exitCode !== undefined,
|
|
}),
|
|
)
|
|
.join("\n"),
|
|
display: true,
|
|
attribution: "agent",
|
|
details: { daemons: entries.map(entry => entry.daemon) },
|
|
timestamp: Date.now(),
|
|
};
|
|
}
|