Commit Graph

22 Commits

Author SHA1 Message Date
Ran Shem Tov cad17c77b9 feat(showcase/google-adk): auto-inject declarative a2ui, un-red recovery demo
Switch declarative-gen-ui to runtime auto-injection (injectA2UITool: true, plain
agent), matching the langgraph-python / AWS Strands gold standard. The ag-ui-adk
0.7.0 adapter auto-injects generate_a2ui via plan_a2ui_injection. Verified under
the canonical D6 driver: all four declarative pills pass (sales-dashboard,
team-performance, at-risk, top-account), plus a2ui-fixed-schema and
beautiful-chat.

Remove the stale known-failing mark from the a2ui-recovery heal e2e and the
OSS-374 inner-render-disambiguation notes (fixture _meta, QA doc, agent
docstring, route comment). Verified against the aimock journal: ag-ui-adk 0.7.0
forwards the run conversation into the inner render_a2ui call, so each pill
matches its own fixture by userMessage and both heal and exhaust pass. The
recovery demo stays backend-owned (the only path with the recovery loop) and
ADK-only (OSS-375 tracks langgraph-python parity).
2026-06-24 15:29:08 +02:00
Mark Fogle 364322987b docs(showcase/google-adk): wire OSS-374/OSS-375 into a2ui-recovery known-failing notes
Replace the "Tracked in Linear" placeholders with the filed issue IDs:
OSS-374 (showcase-aimock inner-subagent disambiguation) and OSS-375
(recovery-demo langgraph-python parity).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 07:51:46 +00:00
Mark Fogle 28d7467fbe docs(showcase/google-adk): document a2ui-recovery heal e2e as a known-failing aimock-deficiency demo
The `heal` e2e test fails against the live showcase aimock because the harness
cannot disambiguate the two pills' inner render_a2ui sub-agent calls (the
backend-owned middleware issues the inner call with a generic render prompt +
shared suggestion context, so the "last user turn" aimock keys on is not the
pill prompt). Both pills match the same inner fixture (the EXHAUST one, by
first-match order), so the heal pill exhausts instead of healing.

This is an aimock harness limitation, not a middleware/demo bug: the middleware
heals free-form args correctly in the OSS-158 toolkit gate and against real
Gemini. Keep the test running (not skipped) as a deliberate demonstration for
the Showcase team; it does not red CI (these specs aren't run for google-adk in
CI). Update the spec header, the heal-test note, the fixture _note, the qa doc,
and the recovery_agent docstring to reflect this accurately (and drop the stale
sequenceIndex description). Tracked in Linear: aimock inner-subagent
disambiguation + recovery-demo LP parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 07:43:27 +00:00
Mark Fogle 1cad3d2ee7 fix(showcase/google-adk): make a2ui-recovery heal deterministic via parse_and_fix (single pass)
The heal fixture relied on per-attempt aimock response switching (sequenceIndex
0=invalid -> 1=valid), but sequenceIndex doesn't advance across the recovery
loop's intra-turn render_a2ui calls in the per-integration Playwright context
(no X-Test-Id), so aimock served invalid on every attempt and the demo never
healed (0 metrics).

Switch the heal pill to a single deterministic response: the inner render_a2ui
returns FREE-FORM args (components/data as JSON strings) that the middleware
heals via parse_and_fix into a valid surface in one pass — no per-attempt
switching. Verified in-sandbox: free-form args -> a2ui_operations with 2 Metric
components. The exhaust pill is unchanged (structurally invalid every attempt ->
a2ui_recovery_exhausted hard-fail, already verified e2e).

Updates the agent docstring, qa checklist, and spec test name/comment to reflect
heal = parse_and_fix healing (not invalid->valid retry). aimock-fixtures schema
test: 818 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 07:00:06 +00:00
Mark Fogle 8d12b29bc0 test(showcase/google-adk): fix a2ui-recovery e2e user-bubble selector for react-core 1.60
The clickPill helper (copied from declarative-gen-ui.spec.ts) matched the user
message with the stale '[data-message-role="user"]' selector, which no longer
exists in @copilotkit/react-core/v2 >= 1.60 — the user bubble is now
'[data-testid="copilot-user-message"]' (CopilotChatUserMessage). The message
dispatched fine; the helper just never found the bubble, timing out before the
heal/exhaust assertions ran. The sibling google-adk specs carry the same stale
selector (they don't run in CI for this integration, so it drifted unnoticed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 06:29:20 +00:00
Mark Fogle c1d03df20b test(showcase/google-adk): add a2ui-recovery e2e spec (mirrors AG-UI dojo recovery spec)
Playwright spec for the ADK-only a2ui-recovery demo, mirroring the AG-UI dojo
reference (apps/dojo/e2e/tests/adkMiddlewareTests/a2uiRecovery.spec.ts):
assert the STABLE end-states and skip the transient 'Retrying...' label
(threshold-gated/timing-dependent).

- heal pill: recovered surface paints (>=2 declarative-metric tiles), no
  hard-failure UI, no render-error banners
- exhaust pill: 'Couldn't generate the UI' shows (A2UIRecoveryStates on the
  a2ui_recovery_exhausted envelope), no faulty surface ever paints, chat stays usable

Selectors verified against @copilotkit/react-core/v2 A2UIRecoveryStates (failure
text) and the showcase declarative catalog testids. Clears the validate-parity
'no e2e spec' warning. Runs in the browser-e2e stack (frontend + aimock + agent_server).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 03:21:24 +00:00
Jordan Ritter d5152eaa83 fix(showcase/e2e+qa): composition exclusions + KPI=4 contract alignment
- Scope clickPill locator to data-message-role='user' bubble so the pill
  button itself can no longer satisfy the dispatch guard
- Dedup clickPill retry: skip click if the user bubble already exists
- Hero pill: assert declarative-card count=0 (OSS-136 no-Card rule),
  metric count >=4 (was >=3 — KPI strip is 4 tiles per composition rule)
- At-risk pill: assert no chart and no table testids (composition rule)
- Top-account pill: assert no data-table and no status-badge testids
- Rename hero test title to 'KPI strip + pie + bar (no surrounding card)'
  so the title no longer falsifies the body
- QA docs: replace 'card + metrics + pie + bar' Expected Results with
  '4 KPI metrics + 1 PieChart + 1 BarChart, no surrounding Card per OSS-136'
- Probe responseTimeoutMs derived from FIRST_SIGNAL_TIMEOUT_MS so it
  matches the e2e 90s budget
2026-06-15 09:35:46 -07:00
Maxim 1e0d200f53 feat(showcase): dashboard-grade surfaces on every declarative-gen-ui pill
Hero loses its surrounding card (bare KPI strip over the chart cards,
pinned to all six months); team performance pairs the rep table with a
quota-attainment bar chart; top account pairs the fact card with a
product-line pie (new dataset entry); at-risk becomes a risk panel — KPI
strip (ARR at risk / accounts / biggest exposure) over three side-by-side
severity cards with reason + next action. Fixtures re-captured from live
responses; D5 probe drops declarative-card from the hero set; e2e asserts
the accompanying charts and the risk panel; QA docs updated.
2026-06-13 00:16:53 +02:00
Maxim 06c819d0fb feat(showcase): match declarative-gen-ui renderers to beautiful-chat's sales dashboard
Ports beautiful-chat's exact visual language into the catalog renderers:
DashboardCard chrome (12px radius, 20px padding, soft shadow) for Card and
chart wrappers, its Metric typography with colored trend deltas, a recharts
donut (innerRadius 40, paddingAngle 2, tooltip, no legend) replacing the
custom SVG donut, and uniform blue bars on a dashed grid. E2E pie
fingerprints move from circle/legend assertions to recharts sectors; the
hero surface-count guard allows the two ResponsiveContainers (pie + bar)
one composed dashboard now produces.
2026-06-13 00:16:53 +02:00
Maxim 667114cfa4 test(showcase): assert pill clicks dispatched in declarative-gen-ui e2e
Click a pill, then require the user-message bubble before asserting on
the surface; retry the click if it was swallowed. On slow dev-server
hydration the first click can land before the chat send pipeline is
wired, which previously burned the full surface-assertion budget and
masked the real failure point.
2026-06-13 00:14:49 +02:00
Maxim 4de75ff900 feat(showcase): rework declarative-gen-ui demo into a sales-analyst dashboard (OSS-136)
The demo now plays an embedded sales analyst for a fictional company:
suggestion pills are natural business questions (chart-type steering moved
from user prompts into the system prompt), the hero pill composes a full
dashboard (KPI metrics + pie + bar in one surface) modelled on
beautiful-chat's sales dashboard, and the catalog gains DataTable,
gap-aware Row/Column, Metric trendValue, and the beautiful-chat palette.
Dataset + composition rules ship as frontend agent context
(sales-context.ts) so they reach both the primary agent and the secondary
A2UI planner in LGP and ADK alike. E2E specs and QA docs updated to the
new pill set.
2026-06-13 00:14:47 +02:00
Jordan Ritter 93b5fdd467 test(showcase): align google-adk e2e specs to langgraph-python canonical
Integration specs had drifted/staled vs LGP gold standard; copied LGP's canonical
specs verbatim and removed the orphan shared-state-write spec whose demo exists
in neither LGP nor google-adk.
2026-05-29 23:59:32 -07:00
Jordan Ritter 6e6878349a fix(showcase): use pressSequentially instead of fill for sandboxed iframe input
fill() silently no-ops inside sandbox="allow-scripts" iframes on some
Playwright/Chromium combos because the null origin blocks the
set-value protocol message. The input.value stays empty, so the
host-side evaluateExpression handler rejects it with "Unsupported
characters" and the test never sees a console log.

pressSequentially sends individual key events that always reach the
input regardless of sandbox restrictions.
2026-05-18 21:41:37 -07:00
Alem Tuzlak 02e48162c4 test(showcase/google-adk): sync e2e specs to langgraph-python north-star
Ports 16 diverged Playwright e2e specs verbatim from langgraph-python
and adds 3 previously-missing specs (chat-customization-css,
prebuilt-sidebar, reasoning-custom). All 19 files are byte-identical
to LGP, mirroring the same approach the recent ADK parity push used
for the demo pages.

Why this matters even though D5 is the gold standard: the per-package
Playwright suites (`pnpm test:e2e`) are the local dev validation loop.
Without parity here, a contributor editing google-adk's CopilotChat
surface has no local check that matches what langgraph-python ships,
and tiny divergences between the two surfaces (missing testids, stale
selectors, wrong assertion shapes) silently accumulate until they
surface as D5 regressions in CI.
2026-05-14 20:54:21 +02:00
github-actions[bot] 204f2fc7ec style: auto-fix formatting 2026-05-13 04:43:51 +00:00
Tyler Slaton 8966ef4f91 chore(showcase/google-adk/declarative-{hashbrown,json-render}): sed internal URL refs to declarative-*
QA3's sed pass missed making it into the consolidated commit. Landing
now so the e2e specs target the demo's current URL after the
byoc→declarative rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:41:06 -07:00
Tyler Slaton ef1ca9808c feat(showcase/google-adk): QA-blitz parity ports — agent prompts, tool surface, e2e specs
Result of 10 parallel QA agents auditing all 30 active demos against
langgraph-python (north-star). Each agent ported drift back to LP-verbatim
across three axes:

1. Agent layer
   - tool_rendering_common.py: rebuilt to LP's surface — get_weather,
     search_flights(origin, destination), get_stock_price, roll_d20,
     roll_dice. Removed the ADK-only query_data.
   - tool_rendering_*_agent.py (4 variants): ported LP's travel/concierge
     prompt; reasoning-chain variant got LP's chain-two-tools prompt.
   - beautiful_chat_agent.py: ported LP's per-tool system prompt; added
     manage_sales_todos / get_sales_todos / generate_a2ui; dropped the
     redundant schedule_meeting (frontend HITL handles it).
   - open_gen_ui_agents.py: ported LP's full SYSTEM_PROMPT for both
     variants, including the Websandbox.connection.remote.* contract
     for the advanced sandbox demo (was `window.sandbox.*`, which the
     LP frontend's Websandbox bridge silently no-ops).
   - byoc_agents.py: fused LP's hashbrown + json-render prompts so the
     single ADK byoc_agent emits both wire shapes. Aliases exported for
     a future per-route split.
   - declarative_gen_ui_agent.py: ported LP's a2ui_dynamic SYSTEM_PROMPT.
   - a2ui_fixed_agent.py: picked up LP's #4734 regression guard
     ("exactly ONCE", "do NOT call again").
   - agent_config_agent.py: rewrote to read useAgentContext (was
     state["config"]); reconciled schema to LP's 3-field camelCase
     {tone, expertise, responseLength} with LP's value enums.
   - subagents_agent.py: dropped the "running" placeholder; returns
     plain str so the LP-verbatim frontend's `result?.trim()` works.
   - hitl_in_app_agent.py / hitl_in_chat_book_call_agent.py: prompts +
     tool-result shape ({approved, reason}) aligned to LP.
   - AGUIToolset() added wherever it was missing on the bespoke agents
     (multimodal, mcp_apps, a2ui_fixed) so frontend-registered tools
     reach the model.

2. Dedicated runtime routes
   - copilotkit-multimodal/route.ts (new) — mirrors LP shape with
     ADK's HttpAgent + AGENT_URL pattern.
   - copilotkit-agent-config/route.ts (new) — same pattern.
   - copilotkit-mcp-apps/route.ts — refreshed.

3. Frontend ports (ADK frontend brought to LP-verbatim where it had
   drifted from the parity blitz state)
   - tool-rendering family (4 demos): full re-port — WeatherCard,
     FlightListCard, StockCard, D20Card, ReasoningBlock, CatchallRenderer,
     suggestions, and the page wiring with all useRenderTool /
     useDefaultRenderTool / reasoningMessage registrations.
   - a2ui-fixed-schema, mcp-apps, multimodal: full frontend re-ports
     with their _components/ Tailwind primitives.
   - frontend-tools, frontend-tools-async, agent-config: ported LP's
     component structure (separate Background, NotesCard with query_notes,
     config-context-relay).
   - shared-state-read, shared-state-read-write, readonly-state-agent-context:
     ported LP's demo-layout + _components + suggestions. recipe-card.tsx
     pulled directly from LP (one QA agent had adapted to Unicode glyphs
     thinking ADK lacked lucide-react — it doesn't, after the parity blitz).
   - shared-state-streaming, subagents, hitl-in-app: ported LP's
     DocumentView / supervisor-activity / TicketsPanel structure.
     hitl-in-app/page.tsx pulled directly from LP to keep the hyphenated
     agent slug aligned with the renamed registry key.
   - auth, hitl-in-chat: ported LP's SignInCard-first auth UX and the
     time-picker Tailwind port.
   - prebuilt-popup: pulled LP's main-content + suggestions split.

4. Test fixtures
   - 30 tests/e2e/<slug>.spec.ts ported from LP, several overwriting
     stale stubs (shared-state-streaming, subagents, auth, hitl-in-chat,
     shared-state-read, agent-config).
   - 30 qa/<slug>.md ported from LP with ADK env-var and registry
     references substituted (GOOGLE_API_KEY, AGENT_URL, registry.py).
   - QA3's byoc-hashbrown / byoc-json-render specs renamed to
     declarative-hashbrown / declarative-json-render with internal
     URL references substituted (the orchestrator pass had already
     renamed the demo dirs + manifest entries).

Frontend changes from QA agents were filtered: kept where they ported
LP-verbatim into ADK, replaced with direct LP pulls where the agent
had made ADK-specific adaptations (one Unicode-glyph case, one
stale-registry-slug case).

Not touched per blitz rules: shared_chat.py, registry.py, manifest.yaml,
src/app/api/copilotkit/route.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:58:06 -07:00
Tyler Slaton ac36b01aed feat(showcase/google-adk/open-gen-ui+beautiful-chat): port agent prompts, tool surface, and e2e specs
- open_gen_ui_agents.py: port LP's minimal + advanced system prompts
  verbatim. Advanced prompt now tells Gemini to call
  `Websandbox.connection.remote.<fn>` (matching the LP frontend's
  websandbox bridge — the prior `window.sandbox.*` prompt produced UIs
  that silently no-op'd) and includes the full sandbox-iframe restriction
  set (no `<form>`, no `type="submit"`, addEventListener / keydown only),
  CDN script guidance, and the return-shape contract.
- beautiful_chat_agent.py: add `manage_sales_todos`, `get_sales_todos`,
  and `generate_a2ui` (mirrors `agents/main.py.generate_a2ui` — forced
  Gemini tool call, full `_A2uiError` shape) so the Task Manager and
  Sales Dashboard pills exercise their backend tools end-to-end. Drop
  `schedule_meeting` — the frontend handles meeting scheduling via the
  `scheduleTime` `useFrontendTool` HITL renderer.
- Copy LP's `tests/e2e/{open-gen-ui,open-gen-ui-advanced,beautiful-chat}.spec.ts`
  and `qa/{open-gen-ui,open-gen-ui-advanced,beautiful-chat}.md` fixtures
  into the ADK integration, retitled for Google ADK and adjusted for
  ADK env-var names (`GOOGLE_API_KEY`, `AGENT_URL`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:33:54 -07:00
Alem Tuzlak 4882c61fb6 feat(showcase): align headless demos to north-star parity across all integrations 2026-05-05 15:12:43 +02:00
Alem Tuzlak 9845dadebb fix(aimock): re-key HITL confirmations on toolCallId so back-to-back flows work
Bug: in a single chat session, running both HITL booking flows
back-to-back (Alice 1:1 → then Sales call without refresh) used to
skip the time-picker on the second flow and jump straight to
"Booked ..." text.

Cause: confirmation fixtures were matched on `hasToolResult: true`,
which fires whenever the conversation has ANY tool message in
history. After the first flow finished, the second user message
short-circuited to a confirmation match before the second flow's
toolCall fixture (gated on `hasToolResult: false`) had a chance to
fire. The picker never rendered.

Fix: re-key the two confirmation fixtures on `toolCallId` (the
specific tool_call_id of the matching `book_call` invocation), which
only fires when the LAST conversation message is a tool result with
that id — exactly the moment we want the confirmation. Drop the
`hasToolResult: false` constraint on the toolCall fixtures so they
match a fresh user request regardless of prior tool history.

Add a back-to-back regression test to all 17 hitl-in-chat specs:
walk Alice flow to completion, then sales flow without refresh,
assert two `time-picker-card` elements rendered. If the multi-flow
regression returns, the second card never appears and the test
fails at `toHaveCount(2)`.
2026-05-01 12:42:53 +02:00
Alem Tuzlak 8cb84e88eb test(showcase): replicate hitl-in-chat regression spec across all 17 integrations
The hitl-in-chat demo ships in 17 integrations (langgraph-python plus
16 others — mastra, strands, ag2, agno, crewai-crews,
langgraph-typescript, langgraph-fastapi, pydantic-ai, llamaindex,
langroid, claude-sdk-python, claude-sdk-typescript, ms-agent-python,
ms-agent-dotnet, spring-ai, google-adk). All shipped placeholder e2e
specs that only checked the chat input was visible — none exercised
the actual booking flow.

Replace each with the full booking-flow spec written for
langgraph-python:
1. The "Schedule a 1:1 with Alice" suggestion renders the time-picker
   card AND the Tokyo greeting is absent (regression guard against
   the broad aimock `userMessage: "Alice"` matcher).
2. Picking a slot transitions to the picked-state card and produces
   a "Booked … Alice" assistant follow-up.
3. The "Book a call with sales" suggestion runs the same flow with
   the sales attendee.

Also add the matching aimock fixture pair for the sales suggestion
in feature-parity.json — without it, case 3 would only pass against
real OpenAI, not the aimock-backed CI deployments. The pair mirrors
the Alice fixture pair: `book_call` toolCall on first turn,
confirmation message after the picker resolves.

Per-integration coverage matters because each integration has its
own framework-specific HITL wiring (`useHumanInTheLoop` binding to
the agent, agent-side tool registration, run streaming protocol)
that can regress independently of the shared aimock fixture.
2026-05-01 12:25:36 +02:00
Jordan Ritter dd06dd89d1 refactor(showcase): rename packages/ to integrations/
The showcase framework directories better reflect their role as
integration examples rather than distributable packages.
Renames showcase/packages/ -> showcase/integrations/ and updates
the test docker-compose file reference accordingly.
2026-04-28 07:47:35 -07:00