feat(core,cli,server,web): add goal mode — loop Tasks on one Session until an objective completes (#66)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
rank-Yu
2026-07-27 23:43:24 +08:00
committed by GitHub
parent e1141ca010
commit 46463bee26
61 changed files with 3411 additions and 188 deletions
+40 -1
View File
@@ -625,6 +625,29 @@ export interface TaskCreateRequest {
* (in queue order, one at a time). The response then carries `queued: true`.
*/
queueIfBusy?: boolean;
/**
* Present = goal mode: the input's text becomes the objective (leading `[use_skills]`
* blocks and the like are stripped from the recorded objective; the round-1 message keeps
* them) and the server loops the Session until the goal reaches a terminal state.
* `budget` is the token budget (uncached input + output); omitted or -1 = unlimited.
*/
goal?: { budget?: number };
}
/** Goal-mode run state (from goal_state; the chat page's banner restores from the latest row). */
export interface GoalStateView {
objective: string;
status: "active" | "complete" | "blocked" | "budget_limited" | "aborted";
/** Token budget; -1 = unlimited. */
budget: number;
used: number;
rounds: number;
updatedAt: string;
}
export interface GoalResponse {
/** The Session's most recent goal run; null if it never ran one. */
goal: GoalStateView | null;
}
export interface TaskCreateResponse {
@@ -694,7 +717,23 @@ export type ServerEvent =
sessionId: string;
source: SessionSource;
}
| ScheduleServerEvent;
| ScheduleServerEvent
| GoalServerEvent;
/** Goal-mode progress on the session channel (the chat page drives its goal banner from these). */
export type GoalServerEvent =
/** A goal run began (published before the first round). */
| { type: "goal_started"; sessionId: string; objective: string; budget: number }
/** A round is starting; `used` is the runner's accounting up to this point. */
| { type: "goal_round"; sessionId: string; round: number; used: number; budget: number }
/** The goal reached a terminal state. */
| {
type: "goal_finished";
sessionId: string;
outcome: "complete" | "blocked" | "budget_limited" | "aborted";
rounds: number;
used: number;
};
/** Schedule notification (user-level event stream; firing and delivery are notified via /api/events). */
export type ScheduleServerEvent =