Skip to content

Commit c59be2c

Browse files
bloveclaude
andcommitted
test(ag-ui): assert durable subagent card for research delegation
subagent-card.spec.ts asserted the research delegation renders a durable <chat-tool-call-card> with text "research". Since #692 made subagent cards durable (full transcript), a delegation tool call becomes its own subagent group in chat-tool-calls (a call whose id is in agent.subagents()), so the template renders <chat-subagent-card> *instead* of a tool-call card — the asserted element never exists. ag-ui e2e is non-required, so this merged red and stayed red, identically on partial-markdown 0.4.2 and 0.5.1 (i.e. not the markdown bump). Assert the durable <chat-subagent-card> (binds subagent().name verbatim) and refresh the stale comments that described the card as active-only/filtered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 64b5ff8 commit c59be2c

1 file changed

Lines changed: 18 additions & 19 deletions

File tree

examples/ag-ui/angular/e2e/subagent-card.spec.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,15 @@ interface SubagentProbe {
2020
}
2121

2222
// Reads the live `agent.subagents()` projection off the shell component via
23-
// Angular's dev-mode global. The chat-subagents primitive renders a
24-
// <chat-subagent-card> for each subagent whose status is pending/running, and
25-
// the card binds the ORDERED transcript: `messages()` (the assistant turn(s)
26-
// the child streamed, each carrying `toolCallIds`/reasoning) and `toolCalls()`
27-
// (the child's own `lookup` calls, rendered as <chat-tool-call-card>). Under
28-
// the aimock harness the run settles near-instantly (started → finished within
29-
// one SSE flush), so the card transits the RUNNING state below a render frame
30-
// and is filtered out of the DOM by the time the assistant turn finalizes —
31-
// exactly the reason the cockpit subagents spec (and the original card spec)
32-
// asserts on durable signals rather than the card element. We read the
33-
// projected map directly: it IS the data the card renders, and it proves the
34-
// ACTIVITY snapshot/delta pipeline reconstructed the full reason→tool→answer
35-
// transcript and that it settled to `complete`.
23+
// Angular's dev-mode global. The chat-tool-calls primitive renders a durable
24+
// <chat-subagent-card> for each delegation tool call, and the card binds the
25+
// ORDERED transcript: `messages()` (the assistant turn(s) the child streamed,
26+
// each carrying `toolCallIds`/reasoning) and `toolCalls()` (the child's own
27+
// `lookup` calls, rendered as <chat-tool-call-card>). We read the projected map
28+
// directly rather than scraping the rendered card: it IS the data the card
29+
// renders, and asserting on it proves the ACTIVITY snapshot/delta pipeline
30+
// reconstructed the full reason→tool→answer transcript and settled to
31+
// `complete`, independent of card layout.
3632
async function readSubagents(page: Page): Promise<SubagentProbe> {
3733
return page.evaluate(() => {
3834
const ng = (window as unknown as { ng?: { getComponent?: (el: Element) => unknown } }).ng;
@@ -81,13 +77,16 @@ test('research delegation reconstructs the multi-message subagent transcript', a
8177
await input.fill('Research Angular signals and summarize');
8278
await page.getByRole('button', { name: /send/i }).click();
8379

84-
// The orchestrator dispatched the research subagent — its tool-call card is a
85-
// durable DOM signal (renders the tool name verbatim), unlike the
86-
// active-only subagent card.
87-
const researchCall = page
88-
.locator('chat-tool-call-card')
80+
// The orchestrator dispatched the research subagent. A delegation tool call
81+
// renders as a durable <chat-subagent-card> (the full child transcript)
82+
// anchored to that call — it supersedes a bare tool-call card for the turn
83+
// (see the chat-tool-calls grouping: a call with a matching subagent is its
84+
// own subagent group). The card binds the subagent name verbatim, so it is a
85+
// stable DOM signal to wait on.
86+
const researchCard = page
87+
.locator('chat-subagent-card')
8988
.filter({ hasText: /research/i });
90-
await expect(researchCall.first()).toBeVisible({ timeout: 30_000 });
89+
await expect(researchCard.first()).toBeVisible({ timeout: 30_000 });
9190

9291
// Wait for the parent turn to finalize so the full run (delegation + child
9392
// reason/tool/answer loop + settle) has played out.

0 commit comments

Comments
 (0)