From a2342cadae847b4df2cd0eed1f1ac2616c00036b Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 20 Jun 2026 19:48:09 -0700 Subject: [PATCH] Fix task chat always showing "no agent is working" in ephemeral mode isActiveAgentSession required a persistent assignedAgentId/checkedOutBy, but the scheduler only sets those when ephemeralAgentsEnabled === false (scheduler.ts:1857). The default is ephemeralAgentsEnabled: true (settings-schema.ts:351), so an actively-executing in-progress task never has either field and always read as idle, showing the "No agent is working on this task right now" hint while an agent was running. sessionLive only covers live CLI sessions, not ephemeral runs. Treat assignment as sufficient-but-not-necessary: a non-blocked, non-"queued" in-progress task is a live agent session on its own. "queued" (the waiting marker) stays assignment-gated and in-review is unchanged, so existing FN-6314 idle/active behavior is preserved. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../fix-task-chat-ephemeral-agent-working.md | 5 +++ .../dashboard/app/components/TaskChatTab.tsx | 14 +++++++- .../components/__tests__/TaskChatTab.test.tsx | 34 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-task-chat-ephemeral-agent-working.md diff --git a/.changeset/fix-task-chat-ephemeral-agent-working.md b/.changeset/fix-task-chat-ephemeral-agent-working.md new file mode 100644 index 0000000000..6842db64aa --- /dev/null +++ b/.changeset/fix-task-chat-ephemeral-agent-working.md @@ -0,0 +1,5 @@ +--- +"@runfusion/fusion": patch +--- + +Fix the task detail chat always showing "No agent is working on this task" for in-progress tasks. The active-session check required a persistent `assignedAgentId`/`checkedOutBy`, but in the default ephemeral-agents mode the scheduler never sets those fields, so an actively-executing task always read as idle. An assignment is now sufficient-but-not-necessary: a non-blocked, non-`queued` in-progress task counts as a live agent session on its own (`queued` stays assignment-gated, in-review is unchanged). diff --git a/packages/dashboard/app/components/TaskChatTab.tsx b/packages/dashboard/app/components/TaskChatTab.tsx index ac5d77d10b..3d8421e85f 100644 --- a/packages/dashboard/app/components/TaskChatTab.tsx +++ b/packages/dashboard/app/components/TaskChatTab.tsx @@ -172,8 +172,20 @@ function isActiveAgentSession(task: Task | TaskDetail, opts: { sessionLive?: boo const statusAllowsReviewSteering = !task.status || REVIEW_STEERABLE_STATUSES.has(task.status); const columnAllowsSteering = (task.column === "in-progress" && statusAllowsProgressSteering) || (task.column === "in-review" && statusAllowsReviewSteering); + // In the default ephemeral-agents mode the scheduler never writes + // `assignedAgentId`/`checkedOutBy` — those are only set when + // `ephemeralAgentsEnabled === false` (scheduler.ts). An actively-executing + // in-progress task therefore has no assignment field yet IS being worked, so + // requiring `hasAssignedAgent` made the chat always show "no agent is working" + // for default-mode tasks. Treat assignment as sufficient-but-not-necessary: + // a non-blocked, non-`queued` in-progress task is a live session on its own. + // `queued` is the documented waiting/blocked marker (self-healing.ts), so it + // stays assignment-gated; in-review keeps requiring an assignment. + const inProgressExecuting = task.column === "in-progress" + && statusAllowsProgressSteering + && task.status !== "queued"; return columnAllowsSteering - && hasAssignedAgent; + && (hasAssignedAgent || inProgressExecuting); } function isToolLikeEntry(entry: AgentLogEntry): boolean { diff --git a/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx b/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx index 0d043c7a8d..ea046c0cba 100644 --- a/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx +++ b/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx @@ -1802,6 +1802,40 @@ describe("TaskChatTab", () => { expectComposerSendableAfterDraft(); }); + it.each([undefined, "planning", "merging", "merging-fix"])( + "treats an actively-executing in-progress task as an active session even without an assignment (ephemeral mode): %s status", + (status) => { + // In the default ephemeral-agents mode the scheduler never writes + // assignedAgentId/checkedOutBy, so a running in-progress task has no + // assignment field yet IS being worked. It must NOT show the idle + // "no agent is working" hint. + render( + , + ); + + expectActiveSessionCopy(); + expect(screen.getByLabelText("Message active agent session")).not.toBeDisabled(); + }, + ); + + it("keeps a queued (waiting) unassigned in-progress task idle in ephemeral mode", () => { + render( + , + ); + + expectIdleSessionHint(); + }); + it.each(["busy", "ready", "starting", "waitingOnInput"] as const)("treats %s CLI sessions as live", (agentState) => { expect(isCliSessionLive(makeCliSession(agentState))).toBe(true); });