fix(web): render the subagent expansion below the tool call's own content (#33)
Co-authored-by: Alice <alice@prismshadow.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,22 @@ test("subagent card survives a reload; child session title is generated from its
|
||||
// Under live streaming, the child session card is nested inside the run_subagent tool card.
|
||||
await openSubagent();
|
||||
|
||||
// --- DOM order: the subagent expansion renders BELOW the tool's own content ---
|
||||
// Expand the run_subagent tool card itself so its arguments block is in the DOM, then assert
|
||||
// the child-session card comes after it in document order (it used to render between the tool
|
||||
// header and the expanded arguments/output).
|
||||
const toolRow = page.locator("button[aria-expanded]").filter({ hasText: "run_subagent" }).first();
|
||||
await toolRow.click();
|
||||
await expect(toolRow).toHaveAttribute("aria-expanded", "true");
|
||||
const argsPre = page.locator("pre", { hasText: '"prompt"' }).first();
|
||||
await expect(argsPre).toBeVisible();
|
||||
const subagentBtn = page.getByRole("button", { name: /子会话/ }).first();
|
||||
const cardFollowsArgs = await argsPre.evaluate(
|
||||
(pre, card) => Boolean(pre.compareDocumentPosition(card) & Node.DOCUMENT_POSITION_FOLLOWING),
|
||||
await subagentBtn.elementHandle(),
|
||||
);
|
||||
expect(cardFollowsArgs, "subagent expansion renders below the tool arguments/output").toBe(true);
|
||||
|
||||
// --- Must still hold after reload (the fix's goal: parent Trace's child session pointer + server-side expansion) ---
|
||||
await page.reload();
|
||||
await openSubagent();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Tool call card: collapses to a single line by
|
||||
* default — status icon + tool name + duration (a live-ticking timer while running) + status
|
||||
* badge; clicking expands full arguments, output, and any nested subagent.
|
||||
* badge; clicking expands full arguments and output; a nested subagent renders below them
|
||||
* regardless of collapsed state.
|
||||
* The pending-approval row is always visible regardless of collapsed state; when a pending
|
||||
* approval appears anywhere in a nested subagent chain, the card auto-expands once (respecting
|
||||
* the user's choice if they've manually collapsed it since).
|
||||
@@ -194,18 +195,6 @@ export function ToolCallCard({ item, ctx }: { item: ToolCallItem; ctx: StreamRen
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Subagent card: always visible (not hidden after completion, only collapsed by default), unaffected by the tool card's collapsed state. */}
|
||||
{item.subagent && (
|
||||
<div className="px-3 pb-2">
|
||||
<SubagentCard
|
||||
sessionId={item.subagentSessionId ?? ""}
|
||||
model={item.subagent}
|
||||
running={!item.outputComplete}
|
||||
ctx={ctx}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Expanded details: full arguments / output */}
|
||||
{open && (
|
||||
<div className="anim-fade">
|
||||
@@ -238,6 +227,18 @@ export function ToolCallCard({ item, ctx }: { item: ToolCallItem; ctx: StreamRen
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Subagent card: always visible (not hidden after completion, only collapsed by default), unaffected by the tool card's collapsed state. Rendered below the expanded arguments/output so the nested conversation reads after the tool call's own content, not between the header and its details; pt-2 keeps a gap from the tinted args/output blocks above. */}
|
||||
{item.subagent && (
|
||||
<div className="px-3 pb-2 pt-2">
|
||||
<SubagentCard
|
||||
sessionId={item.subagentSessionId ?? ""}
|
||||
model={item.subagent}
|
||||
running={!item.outputComplete}
|
||||
ctx={ctx}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user