diff --git a/packages/tui/src/context/data.tsx b/packages/tui/src/context/data.tsx index df0ca9ee23b..d70a71be5ce 100644 --- a/packages/tui/src/context/data.tsx +++ b/packages/tui/src/context/data.tsx @@ -344,7 +344,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({ }) break case "session.next.step.ended": - setStore("session", "status", event.data.sessionID, event.data.finish === "tool-calls" ? "running" : "idle") + setStore("session", "status", event.data.sessionID, "running") message.update(event.data.sessionID, (draft, index) => { const currentAssistant = message.assistant(draft, index, event.data.assistantMessageID) if (!currentAssistant) return @@ -357,7 +357,6 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({ }) break case "session.next.step.failed": - setStore("session", "status", event.data.sessionID, "idle") message.update(event.data.sessionID, (draft, index) => { const currentAssistant = message.assistant(draft, index, event.data.assistantMessageID) if (!currentAssistant) return @@ -527,6 +526,9 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({ case "session.next.compaction.started": setStore("session", "status", event.data.sessionID, "running") break + case "session.next.execution.settled": + setStore("session", "status", event.data.sessionID, "idle") + break case "session.next.revert.staged": if (store.session.info[event.data.sessionID]) setStore("session", "info", event.data.sessionID, "revert", event.data.revert) diff --git a/packages/tui/test/cli/tui/data.test.tsx b/packages/tui/test/cli/tui/data.test.tsx index c6d1756f7be..fc7af6c8ede 100644 --- a/packages/tui/test/cli/tui/data.test.tsx +++ b/packages/tui/test/cli/tui/data.test.tsx @@ -283,6 +283,21 @@ test("tracks session status from active sessions and execution events", async () tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }, }, }) + await wait(() => { + const assistant = data.session.message.get("session-live", "message-live") + return assistant?.type === "assistant" && assistant.finish === "stop" + }) + expect(data.session.status("session-live")).toBe("running") + + emitEvent(events, { + id: "evt_execution_settled", + type: "session.next.execution.settled", + data: { + sessionID: "session-live", + timestamp: 3, + outcome: "success", + }, + }) await wait(() => data.session.status("session-live") === "idle") emitEvent(events, { @@ -308,6 +323,22 @@ test("tracks session status from active sessions and execution events", async () error: { type: "unknown", message: "Provider unavailable" }, }, }) + await wait(() => { + const assistant = data.session.message.get("session-failed", "message-failed") + return assistant?.type === "assistant" && assistant.finish === "error" + }) + expect(data.session.status("session-failed")).toBe("running") + + emitEvent(events, { + id: "evt_failed_execution_settled", + type: "session.next.execution.settled", + data: { + sessionID: "session-failed", + timestamp: 5, + outcome: "failure", + error: { type: "unknown", message: "Provider unavailable" }, + }, + }) await wait(() => data.session.status("session-failed") === "idle") } finally { app.renderer.destroy()