Skip to content

Commit 0b02f58

Browse files
committed
fix(webapp): render output-denied as a terminal HITL state
A denied human-in-the-loop tool can land in the terminal `output-denied` state, not just `approval-responded`. The conversation view now shows the denial label for `output-denied`, and the buffered `.in` resolution overlay treats `output-denied` as terminal so a later replay cannot overwrite it, matching the SDK authoritative-state semantics.
1 parent 39ea16f commit 0b02f58

2 files changed

Lines changed: 5 additions & 2 deletions

File tree

apps/webapp/app/components/runs/v3/agent/AgentMessageView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export function renderPart(part: UIMessage["parts"][number], i: number) {
129129
resultSummary = "calling...";
130130
} else if (p.state === "approval-requested") {
131131
resultSummary = "awaiting approval";
132-
} else if (p.state === "approval-responded") {
132+
} else if (p.state === "approval-responded" || p.state === "output-denied") {
133133
resultSummary = p.approval?.approved
134134
? "approved"
135135
: `denied${p.approval?.reason ? `: ${p.approval.reason}` : ""}`;

apps/webapp/app/components/runs/v3/agent/AgentView.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,10 @@ function useAgentSessionMessages({
311311
const idx = parts.findIndex((p) => (p as { toolCallId?: string }).toolCallId === toolCallId);
312312
if (idx < 0) continue;
313313
const cur = parts[idx]!;
314-
const terminal = cur.state === "output-available" || cur.state === "output-error";
314+
const terminal =
315+
cur.state === "output-available" ||
316+
cur.state === "output-error" ||
317+
cur.state === "output-denied";
315318
const nextState = res.state != null && !terminal ? res.state : cur.state;
316319
const sameApproval = JSON.stringify(cur.approval) === JSON.stringify(res.approval);
317320
if (

0 commit comments

Comments
 (0)