feat(core,server,web,cli): mid-run steering messages and square-bracket markers (#63)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Yaowei ZhengandClaude Fable 5 authored and GitHub committed 2026-07-26 23:01:18 +08:00
1 parent abd5b13d52
commit 7584171482
81 files changed
+3139 -930

No files matched your search

+9 -4
View File
@@ -63,6 +63,7 @@ function approvalFakeSession(sessionId: string): RuntimeSession {
toolPermission: () => "rw",
generateTitle: async () => ({ title: null, usage: null }),
compactability: () => "ok" as const,
steer: () => false,
async *run(_input: OmniMessage[], opts: { approve: ApproveFn; signal: AbortSignal }) {
const tc = toolCall({ name: "exec_command", arguments: "{}", toolCallId: "tc-sse" });
yield tc;
@@ -107,7 +108,7 @@ describe("sse-stream", () => {
it("FD-1: a new subscription's first frame is always the task_state snapshot (idle)", async () => {
const frames = await readSseFrames(await getStream(), 1);
expect(frames[0]!.event).toBe("server_event");
expect(JSON.parse(frames[0]!.data)).toEqual({ type: "task_state", state: "idle" });
expect(JSON.parse(frames[0]!.data)).toEqual({ type: "task_state", state: "idle", queued: 0 });
expect(frames[0]!.id).toMatch(/^[0-9a-f]{8}-\d+$/); // FD-2: opaque string id
});
@@ -117,7 +118,11 @@ describe("sse-stream", () => {
await waitFor(() => t.deps.manager.pendingApprovalCount(SID) === 1);
const frames = await readSseFrames(await getStream(), 2);
expect(JSON.parse(frames[0]!.data)).toEqual({ type: "task_state", state: "running" });
expect(JSON.parse(frames[0]!.data)).toEqual({
type: "task_state",
state: "running",
queued: 0,
});
const approval = JSON.parse(frames[1]!.data) as {
type: string;
toolCall: { payload: { tool_call_id: string } };
@@ -136,7 +141,7 @@ describe("sse-stream", () => {
2,
);
expect(JSON.parse(frames[0]!.data)).toEqual({ type: "resync_required" });
expect(JSON.parse(frames[1]!.data)).toEqual({ type: "task_state", state: "idle" });
expect(JSON.parse(frames[1]!.data)).toEqual({ type: "task_state", state: "idle", queued: 0 });
});
it("FD-2: same-epoch Last-Event-ID hitting the buffer → replays later events, then the task_state snapshot", async () => {
@@ -146,6 +151,6 @@ describe("sse-stream", () => {
const frames = await readSseFrames(await getStream({ "Last-Event-ID": first.id }), 2);
expect(frames[0]!.event).toBeUndefined(); // replayed OmniMessage
expect((JSON.parse(frames[0]!.data) as { payload: { text: string } }).payload.text).toBe("m2");
expect(JSON.parse(frames[1]!.data)).toEqual({ type: "task_state", state: "idle" });
expect(JSON.parse(frames[1]!.data)).toEqual({ type: "task_state", state: "idle", queued: 0 });
});
});