Commit Graph

12000 Commits

Author SHA1 Message Date
Lukas Moschitz 08da190b21 docs(core): note mock memory refresh is a no-op stand-in
The in-memory store's refresh() has no transport to re-pull from; add
an inline comment making that explicit and pointing to RD-34 as the
owner of the real REST snapshot re-fetch.
2026-06-24 14:05:41 +02:00
Lukas Moschitz c1ff8c8948 fix(core): drop recall-only score on memory supersede
In ɵcreateMemoryStore's updateMemory, destructure score out of the
current memory before spreading onto the superseded entry. score is
a recall-only field and must not appear on freshly created list
memories. Adds a red-green test asserting score is undefined on the
superseded result.
2026-06-24 14:05:17 +02:00
Lukas Moschitz cc5a1f3738 fix(core): auto-unregister memory stores on agent removal 2026-06-24 13:35:57 +02:00
Lukas Moschitz c6cbee392b feat(core): register/get memory store on CopilotKitCore
Adds MemoryStoreRegistry and wires registerMemoryStore/unregisterMemoryStore/
getMemoryStore/getMemoryStores onto CopilotKitCore, mirroring the thread-store
registry pattern (frozen snapshot cache, no subscriber notifications).
2026-06-24 12:41:11 +02:00
Lukas Moschitz 5a97f3285a feat(core): canonical ɵcreateMemoryStore factory for SDK bindings 2026-06-24 12:35:56 +02:00
Lukas Moschitz dcf18d46d1 feat(core): add in-memory memory store mock + contract for SDK bindings 2026-06-24 12:26:52 +02:00
Ran Shemtov 6a6f551dfc feat(showcase/google-adk): surface ag-ui-adk 0.7.0 A2UI middleware + ADK-only recovery demo (#5662)
## What

Surfaces the OSS-158 A2UI work — now published as **`ag-ui-adk 0.7.0`**
— in the `google-adk` showcase, and adds an explicit **ADK-only
`a2ui-recovery` demo**.

Before this PR, the google-adk A2UI demos ran on a **hand-rolled
`google.genai` planner** (pinned `ag-ui-adk==0.6.3`, predating all the
A2UI work), so the middleware's recovery loop / healing / hard-fail were
never exercised. This re-wires them onto the published middleware
(`get_a2ui_tool`) and makes the recovery behavior visible.

## Key decisions

- **Backend-owned wiring (`injectA2UITool: false`)** for
`declarative-gen-ui` + `beautiful-chat`, replacing the hand-rolled
planner with the middleware's `get_a2ui_tool()` (forced `render_a2ui`
sub-agent + toolkit validate→retry recovery +
`render_as_llm_instructions`/`parse_and_fix` healing +
`a2ui_recovery_exhausted` hard-fail). This matches the **AWS Strands /
ag2 external-framework convention**, not langgraph-python's
runtime-driven `injectA2UITool: true`.
- The explicit `false` is **load-bearing**: the planner now lives in the
ADK middleware, so letting the runtime also inject would double-bind the
tool slot. It's also required post-**#5611** (a provider catalog
otherwise defaults `injectA2UITool` to `true`).
- **`a2ui-recovery` is ADK-only by design.** The validate→retry loop +
hard-fail envelope live in the ADK middleware; the runtime path
langgraph-python uses (`@ag-ui/a2ui-middleware`) is single-pass
parse-and-salvage with **no** recovery loop, so there's no LP parity
reference for this demo (exempt from LP e2e-parity). It reuses the
declarative-gen-ui catalog — no new components.

## Changes (commits)

1. `chore`: bump `ag-ui-adk==0.7.0`
2. `feat`: re-wire `declarative-gen-ui` + `beautiful-chat` onto the
backend-owned middleware path
3. `chore`: remove the dead hand-rolled planner + orphaned
`SalesPipelineAgent` from `main.py` (retire `test_generate_a2ui.py`; fix
the stale manifest highlight)
4. `feat`: add the ADK-only `a2ui-recovery` demo (heal + exhaust pills;
agent/route/page/manifest/qa/aimock-fixture +
`feature-registry`/`constraints` entries)
5. `test`: add `a2ui-recovery.spec.ts` (mirrors the AG-UI dojo recovery
spec)

Depends on `ag-ui-adk 0.7.0` (published to PyPI via ag-ui#2017).

## Verification (in-sandbox, all green)

- **Backend**: import-smoke (41 agents construct); OSS-158 assurance
gate through the exact wiring — sub-agent emit, recovery (invalid→valid,
2 attempts), hard-fail (`a2ui_recovery_exhausted`, capped at 3); a live
trial against real Gemini emitted a real `a2ui_operations` envelope.
- **Python suite**: 62 passed.
- **Static validators**: `generate-registry` ✅, `validate-constraints`
(google-adk OK) ✅, `validate-parity` 20/20 pass ✅, `aimock-fixtures` 818
passed ✅, `validate-fixture-tool-surface` no drift ✅.

## E2E coverage & parity

`a2ui-recovery` is **ADK-only** — the validate→retry recovery loop +
hard-fail envelope live in the `ag_ui_adk` middleware, and
langgraph-python's runtime A2UI path (`@ag-ui/a2ui-middleware`,
single-pass parse-and-salvage) has no equivalent. **There is therefore
no langgraph-python reference for this demo, and the d6 `e2e-parity`
harness skips it by design** (parity-exempt, like `voice` / the `byoc-*`
variants). Its automated coverage is the per-integration Playwright spec
`tests/e2e/a2ui-recovery.spec.ts`, run via `pnpm test:e2e` against the
local stack (aimock + `pnpm dev` with `GOOGLE_GEMINI_BASE_URL` →
aimock).

## ⚠️ Known-failing e2e test, kept on purpose (showcase-aimock
deficiency)

Running `pnpm test:e2e tests/e2e/a2ui-recovery.spec.ts` against the
local stack gives **2 pass / 1 fail**: page-load ✅, **exhaust/hard-fail
✅**, **heal ❌**. The heal failure is **left in deliberately** as a live
demonstration for the Showcase team — it does **not** red CI (these
per-integration specs aren't run for google-adk in CI; we only see it
via a manual run).

**Diagnosis (from the agent logs):** the showcase aimock **cannot
disambiguate the two pills' _inner_ `render_a2ui` sub-agent calls.** The
backend-owned middleware (`get_a2ui_tool`) issues the inner render with
a *generic* render prompt + shared suggestion context, so the "last user
turn" aimock keys on is **not** the pill prompt. Both pills therefore
match the **same** inner fixture (the EXHAUST one, by first-match order)
→ the heal pill **exhausts** (`a2ui_recovery_exhausted`, "Couldn't
generate the UI", 0 `declarative-metric`) instead of healing. The agent
log shows the heal pill running the full 3-attempt loop on the exhaust
payload (`unresolved_child 'never-defined'`).

This is an **aimock harness limitation, not a middleware/demo bug** —
the middleware heals free-form args correctly in the OSS-158 toolkit
gate (in-sandbox) and against real Gemini; the exhaust path proves the
recovery loop + hard-fail envelope + aimock context routing all work
end-to-end in the browser.

Two follow-ups (Linear):
- **OSS-374 — Showcase-aimock inner-subagent disambiguation** — the
harness needs a way to key an inner sub-agent call per pill (e.g. on
`surfaceId`/`intent`, or a per-pill agent/context). Likely **not**
ADK-specific: any backend-owned A2UI integration (Strands/ag2) that
wants per-pill inner renders hits the same wall.
- **OSS-375 — Recovery-demo langgraph-python parity** — `a2ui-recovery`
is ADK-only (LP's runtime A2UI path has no recovery loop); tracked so
the parity exemption is explicit and revisited as other frameworks gain
an equivalent.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-24 11:51:51 +02:00
Ran Shemtov aacc9eaa61 Merge branch 'main' into mark/oss-158-adk-a2ui-showcase 2026-06-24 11:51:41 +02:00
Ran Shemtov e231417ef0 chore(showcase): upgrade @copilotkit packages to 1.61.1 (#5664)
## What

Upgrade every `@copilotkit/*` dependency across the showcase from
`1.60.2` (plus stray `latest` override pins) to an exact `1.61.1` pin,
and regenerate the standalone npm lockfiles to match.

## Changes

- **22 `package.json`**: 20 integrations +
`langgraph-typescript/src/agent` + `shell`. All `@copilotkit/*` deps
pinned to exact `1.61.1` (`core`, `react-core`, `react-ui`, `runtime`,
`sdk-js`, `shared`, `voice`, `a2ui-renderer`, plus the
`web-inspector>core` overrides). The two `latest` override pins are now
exact `1.61.1` to honor the repo's exact-pin discipline.
- **22 `package-lock.json`**: regenerated with `npm install
--package-lock-only --legacy-peer-deps` (matches the `npm ci
--legacy-peer-deps` the Dockerfiles use). Transitive
`@copilotkit/runtime-client-gql` -> `1.61.1` and
`@copilotkit/license-verifier` -> `~0.5.0` came along.
- **`showcase/scripts/showcase-canonical-pins.json`**:
`canonicalCopilotKitVersion` `1.60.2` -> `1.61.1` (the pin SSOT consumed
by `validate-pins.ts`).

## Out of scope (intentionally unchanged)

- `@copilotkit/aimock` stays on its own version line (`1.26.1`).
- Python `copilotkit` SDK was already `0.1.94` in every
`requirements.txt`; no pyproject refs. No-op.
- Root `pnpm-lock.yaml` untouched — the integrations and shells are not
pnpm-workspace members (they ship standalone npm lockfiles).

## Validation

- `validate-pins`: ratchet unchanged (`FAIL=38`, identical hash) — zero
`@copilotkit` drift; the 38 are pre-existing non-copilotkit framework
range-pins already in `fail-baseline.json`.
- `validate-parity`: 20/20 pass.
- `validate-fixture-tool-surface`: no drift.
- `showcase/scripts` vitest: 2102 passed, 5 skipped.
2026-06-24 11:31:03 +02:00
Ran Shem Tov 9b77e8eeed chore(showcase): upgrade @copilotkit packages to 1.61.1
Bump every @copilotkit/* dependency across the showcase integrations and
the shell from 1.60.2 (and stray "latest" override pins) to an exact
1.61.1 pin, and move the canonical pin source of truth to match.
Regenerate each standalone npm package-lock.json with the same
--legacy-peer-deps flag the Dockerfiles use for "npm ci".

- showcase/integrations/*/package.json + package-lock.json
- showcase/integrations/langgraph-typescript/src/agent/*
- showcase/shell/package.json + package-lock.json
- showcase/scripts/showcase-canonical-pins.json: canonical 1.60.2 to 1.61.1

aimock stays on its own version line (1.26.1). The Python copilotkit SDK
was already 0.1.94 across every requirements.txt, so no change there.

validate-pins ratchet is unchanged (FAIL=38, identical hash);
validate-parity, validate-fixture-tool-surface, and the showcase/scripts
vitest suite (2102 tests) all pass.
2026-06-24 10:39:59 +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
Tyler Slaton 53bd214818 feat: AG-UI standard interrupt support in useInterrupt (#5480)
## Summary

Adds first-class support for the **AG-UI standard interrupt protocol**
to `useInterrupt`, while keeping the legacy `on_interrupt` custom-event
path working (additive, no breaking changes).

The AG-UI spec
([concepts/interrupts](https://docs.ag-ui.com/concepts/interrupts))
pauses a run via `RUN_FINISHED` with `outcome: { type: "interrupt",
interrupts: Interrupt[] }` and resumes via a `resume: ResumeEntry[]`
array. CopilotKit previously only spoke the non-standard `on_interrupt`
+ `forwardedProps.command.resume` dialect; the standard resume path was
literally unreachable.

## What changed

- **core** — `CopilotKitCore.runAgent` forwards a standard `resume:
ResumeEntry[]` to `agent.runAgent` (no-op when omitted), making the spec
resume path reachable.
- **react-core `useInterrupt`** — dual-path detection (standard
`RUN_FINISHED outcome:interrupt` + `pendingInterrupts`, alongside legacy
`on_interrupt`); surfaces `interrupt` (primary) + `interrupts` (full
open set); `resolve(payload?, interruptId?)` / `cancel(interruptId?)`
that accumulate per-interrupt responses and auto-submit a spec `resume`
array once all open interrupts are addressed; expiry handling via
`isInterruptExpired`; re-exports `Interrupt` / `ResumeEntry` /
`ResumeStatus`.
- **vue** — full parity, incl. `CopilotChatMessageView.vue` slot
bindings.
- **react-native** — re-exports the standard interrupt types.
- **docs** — 4 shell-docs pages (`human-in-the-loop/useInterrupt`,
`headless`, and both reference pages).

`responseSchema` is surfaced on `interrupt` but not validated
client-side (the agent stays authoritative, per spec).

## Notable fix

vue legacy `resolve` now defers clearing the interrupt card to
`onRunStartedEvent` — matching react-core **and** vue's own standard
path. Previously it cleared synchronously, reintroducing a UX regression
react-core had a dedicated test/comment guarding against.

## Verification

- Tests green: react-core **1285**, vue **19**, core resume **2**
- `nx run-many -t build` green across core / react-core / react-native /
vue
- oxlint/oxfmt clean across all changed files
- Independent integration review **APPROVED**; multi-agent code review
converged (only doc + a vue-parity issue, all fixed; a
multi-interrupt-without-id safety warning was added)

## Deferred (separate follow-up PR — pre-existing, out-of-subject)

Surfaced incidentally during review, untouched by this PR:
- `run-handler.ts` parallel tool-call results spliced in reverse order
(`:623`/`:763`)
- wildcard tool handler not passed the abort `signal`
- `runTool` follow-up runs even after abort (missing the
`processAgentResult` abort guard)
- `isArgumentError` computed but never read (dead field)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-23 21:19:33 -07:00
Mark Fogle 133305d2eb test(showcase): bump catalog cell counts for the a2ui-recovery feature
Adding a2ui-recovery to the shared feature-registry cross-joins it across all
20 integrations (wired for google-adk, unshipped elsewhere), so the catalog
generator's hardcoded counts move: cross-join 920->940, metadata.total_cells
900->920, LGP 46->47 (unshipped 7->8). docs_only stays 20; the relative
sum-checks are unchanged. Fixes the Validate Showcase failure on #5662.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 04:10:10 +00:00
Tyler Slaton 2291fc545f fix(react-core): resolve interrupt typecheck failures 2026-06-23 21:08:37 -07:00
Tyler Slaton f330e9b795 fix(runtime): fail loud on malformed approval request 2026-06-23 20:56:33 -07:00
Mark 01b8b47fd2 Merge branch 'main' into mark/oss-158-adk-a2ui-showcase 2026-06-23 20:55:28 -07:00
Tyler Slaton a2f936ec61 style: format config files 2026-06-23 20:52:56 -07:00
Tyler Slaton a13c3ee663 chore: merge main into PR 5480 2026-06-23 20:50:16 -07:00
github-actions[bot] 580b0b683e style: auto-fix formatting 2026-06-24 03:42:22 +00:00
Tyler Slaton e3dfff8e18 fix(showcase): make strands-typescript demos work (+ strands-python parity) (#5632)
## Summary

Bug hunt on the **strands-typescript** showcase integration, comparing
every flagged demo against the reference **strands (Python)**
integration on real OpenAI (gpt-4o). Every showcase-side fix was applied
to **both** integrations for 1:1 parity. Each flagged issue was
classified as showcase-side (fixed here), upstream `@ag-ui/aws-strands`
adapter (chipped, not fixed here), or shared-with-Python.

## Fixed here (showcase) — verified working on real LLM, both
integrations

- **readonly-state-agent-context** — agent ignored `useAgentContext`
("Who am I?" hallucinated). Root cause: neither adapter surfaces
`RunAgentInput.context` to the model. Fix: lift `context` into the
prompt in `buildStatePrompt` / `build_state_prompt`. (Same context
channel also feeds open-gen-ui — see below.)
- **open-gen-ui** + **open-gen-ui-advanced** — model answered in plain
text instead of calling `generateSandboxedUi`. The
`openGenerativeUI.designSkill` is delivered via the same dropped
`context` channel; with context now lifted into the prompt, an added
imperative makes the model call the tool. Advanced cell also clarifies
sandbox functions are iframe→host bridges, not LLM tools.
- **hitl-in-chat** — "Schedule a 1:1 with Alice" sometimes produced no
time-picker (the shared backend `schedule_meeting` tool won over the
frontend `book_call` HITL). Fix: sharpen `book_call` to own scheduling
intents.
- **tool-rendering catch-all** ("Roll a d20" / "Chain tools") — no dice
tool existed. Fix: add a `roll_dice` tool (shared python tools + TS).

## Also

- **Register strands-typescript as a dashboard baseline partner**
(`BASELINE_PARTNERS`) so it gets its own coverage column like
langgraph-typescript. D5 (e2e-deep) is **green** for strands-typescript.

## Deferred / out of scope (by decision)

- **a2ui-fixed-schema** and **declarative-gen-ui** — both depend on A2UI
(`generate_a2ui`) which strands-typescript intentionally does not ship
yet. Pre-existing; left intact to handle later. (My exploratory route
opt-in was reverted.)
- **multimodal** attachments fail with a git-LFS pointer error — a
shared deploy-environment issue (same on Python), not a demo bug; base
chat works.

## Upstream (ag-ui `@ag-ui/aws-strands` TS adapter) — chipped, not fixed
here

These are genuine TS-vs-Python adapter divergences; Python's adapter
handles both. Tracked as task chips to land upstream first, then
incorporate:

- **U2 — empty tool-result content** (`agent.ts:178`): the adapter sends
`{text:""}` for empty render-tool results → OpenAI 400
(`STRANDS_ERROR`). Breaks beautiful-chat + chart demos (renders, then
the run dies and poisons the thread). Python coerces to a non-empty
placeholder.
- **U1 — INCOMPLETE_STREAM on parallel tool calls** (`agent.ts`
~1730-1756 / ~1864-1921): emits `RUN_FINISHED` without draining
`TOOL_CALL_END` for parallel calls; rejected by the AG-UI client verify
layer. Trips the catch-all "Chain tools" pill.

## Verification

- All fixes confirmed via real-LLM browser testing on both
strands-typescript (:3119) and strands-python (:3112) production
containers.
- `oxlint` 0 errors, `oxfmt` clean. D5 strands-typescript green. Both
containers rebuilt + booted clean.
- Note: shell-dashboard `vitest` could not run in the worktree
(`@vitejs/plugin-react` transitive dev-dep absent); the only
test-affecting change is the `BASELINE_PARTNERS` count 26→27, verified
by inspection — CI runs the suite authoritatively.

## Not yet green (separate follow-up)

D6 (e2e-full) for strands-typescript is 25/35; the remaining reds are
pre-existing (newly-merged) demo/fixture gaps and one harness-level
`__name` page.evaluate error — unrelated to this bug hunt.
2026-06-23 20:37:38 -07: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
Tyler Slaton f4a1e7fc36 fix(showcase): restore CI for strands PR 2026-06-23 19:46:43 -07:00
Ran Shem Tov f0ce7a7175 feat(showcase): wire dynamic A2UI declarative-gen-ui for strands + strands-typescript
Implements the Declarative Generative UI (A2UI dynamic schema) demo for both
the strands (Python) and strands-typescript integrations, bringing them to 1:1
parity with the canonical langgraph-python demo.

Backend:
- Add a dedicated dynamic-A2UI agent (a2ui_dynamic.py / buildA2uiDynamicAgent)
  that wires no generate_a2ui tool. The runtime route sets
  injectA2UITool: true + defaultCatalogId "declarative-gen-ui-catalog"; the
  Strands adapter auto-injects generate_a2ui and drives a secondary render_a2ui
  planner. StrandsAgentConfig.a2ui supplies the catalog id and a
  composition_guide (sales dataset + composition rules) so the planner is
  self-contained.
- Mount the agent on the /declarative-gen-ui sub-path and point the route's
  HttpAgent at it, mirroring the a2ui-fixed-schema pattern.
- Bump ag_ui_strands 0.1.9 -> 0.2.1 (Python): the A2UI auto-injection config
  (default_catalog_id, guidelines, render planner) landed in 0.2.0. Pulls
  ag-ui-a2ui-toolkit transitively. strands-typescript already on 0.2.2.

Frontend:
- Port the langgraph-python declarative-gen-ui frontend (suggestions,
  sales-context, definitions incl DataTable, renderers, chat) so the demo
  matches the shared D5/D6 probe's sales-analyst pills and catalog components.

Fixtures:
- Author gen-ui-declarative D6 fixtures for both slugs from the langgraph-python
  template (3 legs per pill: outer generate_a2ui, inner render_a2ui, narration).

Verified on real OpenAI (gpt-4o): both integrations paint a real A2UI surface
(4 Metric tiles + Revenue-by-Region PieChart + Monthly Revenue BarChart +
narration), matching the probe's expected testids and counts.

Note: the gen-ui-declarative D6 cell currently cannot go green because the
shared harness hits "ReferenceError: __name is not defined" in the probe's
page.evaluate (turn 1 preFill), before any agent call. That harness-tooling bug
is owned separately; the fixtures and wiring here are correct and the real-LLM
paint confirms the expected surface.
2026-06-23 19:46:43 -07:00
Ran Shem Tov 620cf00974 fix(showcase): green strands + strands-typescript D6 cells via id-invariant fixtures + real multimodal assets
Strands mints UUID tool_call_ids for tool results (confirmed via the aimock
journal), so the langgraph-python toolCallId-keyed follow-up fixtures never
matched and the agent re-emitted the tool, looping (text-unstable) across
frontend-tools, gen-ui-agent, gen-ui-open, gen-ui-open-advanced,
gen-ui-headless-complete, reasoning-chain and the weather pills. Re-key the
affected multi-leg fixtures to the id- and thread-history-invariant
sequenceIndex pattern (as built-in-agent does), for both integrations.

Also:
- Add write_document poem/email/quantum fixtures for shared-state-streaming
  (was a stale single fixture that 404d).
- Strip content from reasoning-chain tool legs (content+toolCalls in one
  fixture is undefined behavior); reasoning rides toolCalls alone.
- Narrow the over-broad d4 summarize catch-all to "Summarize the sales
  pipeline" so it stops shadowing gen-ui-agent competitor pill; matches
  langgraph-python.
- Commit the real multimodal sample.png/sample.pdf (were git-LFS pointers
  the harness could not resolve).
2026-06-23 19:46:43 -07:00
Ran Shem Tov 74208d8299 feat(showcase): add write_document tool, drop get_weather stopStreamingAfterResult (strands, strands-typescript)
Add a write_document tool + document state hook to both Strands agents
so the shared-state-streaming demo can stream a document into
state.document (mirrors langgraph-python StateStreamingMiddleware). Strands
updates state from the full tool args, which the D6 probe tolerates.

Remove the get_weather stopStreamingAfterResult / stop_streaming_after_result
guard from both agents so weather concludes with a natural follow-up turn,
matching the langgraph-python gold standard; the accompanying multi-turn
id-invariant weather fixtures prevent the aimock replay loop without it.
2026-06-23 19:46:43 -07:00
Ran Shem Tov 405d78d8e6 fix(showcase): shim __name + crypto.randomUUID in D6 harness page contexts
The D6 fleet worker drives each integration over its insecure Docker
origin (http://<slug>:10000), where crypto.randomUUID is undefined so
hand-rolled headless chats threw and never mounted (sse-missing). tsx/
esbuild also wraps named inner functions in __name(...) calls that leak
into page.evaluate and throw __name is not defined.

Add installBrowserContextShims (init-scripts.ts): a __name no-op helper
and a crypto.randomUUID secure-context polyfill, registered via
addInitScript at document_start of every D6 page; wired into the
d6-all-pills newPage goto path.
2026-06-23 19:46:43 -07:00
Ran Shem Tov f404791ecd chore(showcase): bump @ag-ui/aws-strands 0.2.0 -> 0.2.2 (strands-typescript)
0.2.2 ships the adapter fixes for the two upstream defects this hunt surfaced:
empty tool-result content (render-tool demos -> OpenAI 400) and RUN_FINISHED
emitted before parallel tool calls drain (INCOMPLETE_STREAM). With the bump,
beautiful-chat, the chart demos, and the catch-all 'Chain tools' pill complete
cleanly. Verified on real gpt-4o.
2026-06-23 19:46:43 -07:00
Ran Shem Tov a5dea4164c feat(showcase): render a2ui-fixed-schema via dedicated agent + A2UIMiddleware
Both integrations: a dedicated `a2ui_fixed_schema` backend agent exposes a
`display_flight` tool that returns the A2UI `a2ui_operations` envelope
(createSurface -> updateComponents -> updateDataModel) built from a fixed,
pre-authored flight layout targeting the page's `copilotkit://flight-fixed-catalog`
catalog. Mirrors the upstream ag-ui dojo a2ui_fixed_schema demo (ag-ui#2021)
adapted to the showcase's existing catalog/renderers.

- TS returns the envelope as an object (lands in a json content block); Python
  returns it as a JSON string (text block) — per each SDK's tool-return shape.
- Enable the runtime A2UIMiddleware on the a2ui-fixed-schema route
  (injectA2UITool: false, defaultCatalogId pinned) so it detects the envelope
  and paints; the agent emits the envelope itself, so no generate_a2ui injection.
- Mount the agent on the /a2ui-fixed-schema sub-path; point the route there.

Verified on real gpt-4o: the flight card paints on both integrations.
2026-06-23 19:46:43 -07:00
Ran Shem Tov e223fe0fb9 feat(showcase): register strands-typescript as a dashboard baseline partner
Add strands-typescript to BASELINE_PARTNERS so it gets its own coverage
column alongside its Python sibling (mirroring how langgraph-typescript sits
beside langgraph-python). Bump the partner-count assertion 26 -> 27.
2026-06-23 19:46:43 -07:00
Ran Shem Tov 0978b4f5ad fix(showcase): make strands + strands-typescript context, open-gen-ui, hitl, and dice demos work
Apply the same fixes to both the strands (Python) and strands-typescript
integrations for 1:1 parity:

- Lift RunAgentInput.context into the prompt (buildStatePrompt /
  build_state_prompt) so useAgentContext values (readonly-state-agent-context)
  and the openGenerativeUI design-skill / sandbox-function context actually
  reach the model. The adapter does not surface context on its own; this
  mirrors langgraph's lift-context-into-prompt pattern.
- open-gen-ui: prepend an imperative to the visualization design skill (and add
  a design skill to the advanced cell) so the model calls generateSandboxedUi
  instead of answering in plain text, and clarify that sandbox functions are
  iframe->host bridges, not LLM tools.
- hitl-in-chat: sharpen the book_call description so it wins scheduling intents
  over the shared backend schedule_meeting tool (which renders no picker).
- Add a roll_dice tool (shared python tools + TS tools) so the tool-rendering
  catch-all 'Roll a d20' and 'Chain tools' pills work.
2026-06-23 19:46:43 -07:00
Jordan Ritter b7d9e1f0e1 chore(showcase): remove redundant harness-legacy service from SSOT and fixtures (#5658)
## Why

The pool-fleet migration is **complete**. The control-plane harness plus
the prod workers (deployed 2026-06-19, `HARNESS_ROLE=worker`, pool count
2) are live in both envs and cover every probe dimension the interim
`harness-legacy` fleet-migration bridge was holding live.
`harness-legacy` is now dead config.

This PR is the **code-side cleanup only**. The live Railway
`harness-legacy` service is torn down separately (see follow-up below).

## What changed

- **SSOT** (`showcase/scripts/railway-envs.ts`): removed the entire
`harness-legacy` entry and the now-dead `key === "harness-legacy"`
special-case branch in `computePromoteClosure`. Updated stale doc
comments that referenced legacy.
- **Stale `harness-workers` comment fixed**: it claimed the worker is
"STAGING-ONLY". The prod worker is in fact live on Railway (deployed
2026-06-19, `HARNESS_ROLE=worker`, pool count 2). Comment now states
workers run in BOTH envs, while flagging that this SSOT entry still
models only the staging instance — see ambiguity note below.
- **Generated artifact**: regenerated `railway-envs.generated.json` (41
-> 40 services).
- **Golden snapshot** (`__tests__/fixtures/railway-envs.golden.json` +
its test header): dropped the `harness-legacy` block.
- **Fixtures / expectation sets**: removed `harness-legacy` from the
`GATE_IGNORED` sets in `__tests__/verify-railway-image-refs.test.ts`,
the `envsFor` assertion + the `computePromoteClosure` exclusion test in
`railway-envs.test.ts`, the promote-notify fixtures (`success.json`,
`partial.json`, `total-failure.json`), and the `redeploy-env.ts` doc
comments. Updated service-count assertions (41 -> 40) in
`railway-envs.test.ts`, `__tests__/verify-railway-image-refs.test.ts`,
and `__tests__/emit-railway-envs-json.test.ts`.
- **Ruby spec**
(`bin/spec/test_promote_single_service_fleet_invariants.rb`): renamed
the synthetic prod-only fixture name from `harness-legacy` to
`deprecated-prod-only-svc` (a fabricated example name with no SSOT
coupling; renamed to avoid implying the SSOT still carries legacy).

## Red-green proof

This is a behavior change to the SSOT. A new assertion (`railway-envs
SSOT > does NOT contain harness-legacy`) was added and observed FAILING
with the entry still present, then PASSING after removal.

**RED** (assertion added, SSOT entry still present):
```
 FAIL  railway-envs.test.ts > railway-envs SSOT > does NOT contain harness-legacy (fleet-migration bridge retired)
AssertionError: expected [ Array(41) ] to not include 'harness-legacy'
 ❯ railway-envs.test.ts:137:23
    136|     const names = listServiceNames();
    137|     expect(names).not.toContain("harness-legacy");
       |                       ^

 Test Files  1 failed (1)
      Tests  1 failed | 103 skipped (104)
```

**GREEN** (SSOT entry removed + fixtures updated):
```
 Test Files  4 passed (4)
      Tests  171 passed (171)
```
(`railway-envs.test.ts`, `__tests__/verify-railway-image-refs.test.ts`,
`__tests__/railway-envs.golden.test.ts`,
`__tests__/emit-railway-envs-json.test.ts`)

Ruby spec:
```
5 runs, 42 assertions, 0 failures, 0 errors, 0 skips
```

## Pre-push gates

- Formatter (`oxfmt --check`): green
- Lint (`oxlint`): 0 errors (2 pre-existing warnings in
`redeploy-env.ts`, unrelated)
- Typecheck (`tsc -p scripts/tsconfig.json`): green for changed files (1
pre-existing unrelated error in `generate-search-index.ts`, present on
the clean base)
- Tests: full `scripts` suite 2086 passed / 12 skipped. (Two test files
hit a flaky `/tmp/...-generated-data.lock` EEXIST parallel-mkdir race;
they pass when run serially and do not touch `harness-legacy`.)

## Follow-up infra step (NOT in this PR)

- [ ] Delete the live Railway `harness-legacy` service (id
`11279eba-97eb-417e-82a5-7cb4254eb147`) from **both** staging and prod
environments. Manual infra step handled separately by the orchestrator.

## Ambiguity note (prod-worker SSOT entry)

The `harness-workers` SSOT entry currently declares **only** a `staging`
env — there is no `prod` env entry, even though a prod worker is live on
Railway. Per task scope I did **not** invent the prod `serviceInstance`
config (it isn't verifiable from the repo), so I only corrected the
comment to stop asserting "staging-only" and left the entry shape
unchanged. Backfilling a real `prod` env entry is a separate follow-up.

---

## Update: README count sync + code review

Added commit `5859ae4` (`docs(showcase): sync promote-notify README
counts...`): the harness-legacy removal dropped each promote-notify
fixture by one service, so `test-fixtures/promote-notify/README.md` was
updated 29/26/29 → **28/25/28** (counts derived from the fixtures via
`jq`, not hand-set).

**Code review:** 11-agent CR round + 11-agent confirmation round, both
converged to **0 mandatory (bucket a) findings**; Procedure 3 bucket-(c)
promotion audit returned **PROMOTE_TO_A = 0**. The harness-legacy
removal is clean — no dangling SSOT references, generated JSON 41→40
exact, no behavior change.

### Follow-up backlog (NOT this PR — surfaced by CR)

_Distinct-subject (candidate spin-off PRs):_
- **prototype-key hardening** — `verify-railway-image-refs.ts:268`
`findUntrackedServices` uses bare `SERVICES[name]` instead of
`Object.hasOwn`; a Railway service named `constructor`/`toString` is
silently treated as tracked → Railway↔SSOT drift false-negative (real
bug, 2 reviewers).
- **harness-workers prod-backfill** — SSOT declares only a staging env
though a prod worker is live; promote-notify fixtures encode
harness-workers as a promote outcome vs SSOT-skipped;
`serviceId===prodInstanceId` smell.
- **promote-notify fixture fleet completeness** — fixtures model a
28-service fleet, omit the 12 `starter-*` services (live fleet = 40).

_Pre-existing subject-neutral nits:_ `emit-railway-envs-json.ts`
`--check` uncurated-crash edge; `serviceEnvPairs()` unconsumed export;
orphaned `promote-notify/validate.sh`; stale "starter-* staging-only"
rationale in the Ruby fleet spec; truncation-suffix/`failed_count`
README contract with no fixture coverage; unguarded `sibling` nil in the
Ruby spec.
2026-06-23 18:05:51 -07:00
Jordan Ritter ec646bbf4f Merge remote-tracking branch 'origin/main' into chore/remove-harness-legacy-ssot
# Conflicts:
#	showcase/scripts/railway-envs.generated.json
#	showcase/scripts/railway-envs.ts
2026-06-23 17:56:18 -07:00
Mark Fogle 06e6de87c7 feat(showcase/google-adk): add ADK-only a2ui-recovery demo (OSS-158 recovery made visible)
A new demo that surfaces the ag_ui_adk >= 0.7.0 validate->retry recovery loop
+ recovery-exhausted hard-fail envelope, rendered as the building/retrying/
failed lifecycle by @ag-ui/a2ui-middleware >= 0.0.10. Two pills, driven by
aimock fixtures that key the inner render_a2ui call by recovery attempt
(sequenceIndex):
- HEAL: attempt 0 structurally-invalid (unresolved child) -> heals to valid
- EXHAUST: invalid on every attempt -> a2ui_recovery_exhausted fallback

Backend-owned (get_a2ui_tool, recovery.maxAttempts=3, injectA2UITool=false),
reusing the declarative-gen-ui catalog + sales context. ADK-only by design:
the recovery loop lives in the ADK middleware; langgraph-python's runtime A2UI
path (@ag-ui/a2ui-middleware single-pass) has no equivalent, so there is no LP
parity reference (exempt from LP e2e-parity). Ported from ag-ui
examples/.../a2ui_recovery.py.

Wires: recovery_agent.py + registry; copilotkit-a2ui-recovery route;
demos/a2ui-recovery page/chat/suggestions; manifest demo+feature; qa spec;
aimock fixture; feature-registry + constraints (constrained-explicit) entries.

Verified in-sandbox: import-smoke (41 agents, recovery cfg), generate-registry +
validate-constraints + validate-parity (20/20 pass) + aimock-fixtures (818) +
python suite (62) all green. Browser e2e (lifecycle render + sequenceIndex
routing) + e2e spec are the documented outside-sandbox steps.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 00:49:18 +00:00
Jordan Ritter eaa3a0a3fd fix(showcase): honest promote-notify message + durable healthcheckPath tracking (#5657)
## Summary

Two related fixes to the showcase promote pipeline:

**Promote-notify Slack message — say what actually happened.**
Previously a partial promote rendered a message that read as if
*everything* failed, with no indication of which services promoted vs.
failed. Now the message:
- announces `🚂 Promoting showcase → prod (N): <names>` with a legible
count
- on a partial/failed outcome leads with `Promoted:` / `Failed:` (one
header each, then bullets) so you can see exactly which services
succeeded and which didn't
- reports real wall-clock elapsed (integer-coerced; degrades to omitting
the phrase if metadata is unparseable)
- drops the constant `verify-prod:` legend line that preceded the
meaningful data

**Durable healthcheckPath tracking — stop the silent prod drift.** The
promote pin path and the provisioning path could leave a service's
Railway `healthcheckPath` diverged from intent (this is what left aimock
answering on the wrong path in prod). Now:
- `healthcheckPath` is tracked per-service/per-env in the SSOT
(`railway-envs`)
- the promote pin re-asserts it (omit-when-absent — never sends `null`)
- `deploy-to-railway` provisioning routes through `isTrackedService` /
`resolveProvisionHealthcheck`, so a tracked-null service correctly
*omits* the healthcheck while an untracked one keeps the `/api/health`
default

## Test plan
- [x] `test_promote_healthcheck_reassert.rb` — pin re-asserts SSOT
healthcheck, omits when absent, never null (3 runs / 11 assertions)
- [x] `deploy-to-railway.healthcheck.test.ts` + `railway-envs.test.ts` +
`emit-railway-envs-json.test.ts` (121 tests)
- [x] snapshot-ivar lint green (2 runs / 32 assertions)
- [x] notify renderer dry-run mirrors success / partial / total-failure
shapes
2026-06-23 17:44:44 -07:00
Mark Fogle 0e7b803c3e chore(showcase/google-adk): remove dead hand-rolled A2UI planner + SalesPipelineAgent
The hand-rolled google.genai generate_a2ui planner (and the orphaned
SalesPipelineAgent that consumed it) in main.py are superseded by the
ag_ui_adk 0.7.0 middleware (get_a2ui_tool), now wired backend-owned in
declarative_gen_ui_agent.py / beautiful_chat_agent.py. main.py is reduced to
the shared tool wrappers + before_model/before_agent callbacks still covered
by tests; dead A2UI imports pruned.

- delete tests/python/test_generate_a2ui.py (tested the removed planner)
- manifest declarative-gen-ui: drop stale src/agents/main.py highlight + fix description

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 00:32:32 +00:00
Jordan Ritter 5859ae4057 docs(showcase): sync promote-notify README counts after harness-legacy removal
PR #5658 dropped harness-legacy from the fixtures but the README still
showed pre-removal counts, contradicting the edited fixtures.
2026-06-23 17:19:29 -07:00
Jordan Ritter 0809c25dac chore(showcase): remove redundant harness-legacy service from SSOT and fixtures
The pool-fleet migration is complete: the control-plane harness plus the
prod workers (deployed 2026-06-19, HARNESS_ROLE=worker, pool count 2) now
cover every probe dimension the interim `harness-legacy` fleet-migration
bridge was holding live, so `harness-legacy` is dead config.

This is the code-side cleanup only:
- Remove the `harness-legacy` entry from the railway-envs SSOT and the
  now-dead `key === "harness-legacy"` special-case in computePromoteClosure.
- Regenerate railway-envs.generated.json (41 -> 40 services).
- Drop harness-legacy from the golden snapshot, the gateIgnore expectation
  sets, the promote-notify fixtures, and the redeploy-env doc comments;
  update the service-count assertions (41 -> 40).
- Fix the stale "STAGING-ONLY" harness-workers comment: prod workers are
  live on Railway, though this SSOT entry still models the staging
  instance only (no prod env backfilled here yet).

The live Railway `harness-legacy` service is torn down separately as a
follow-up infra step.
2026-06-23 17:05:26 -07:00
Jordan Ritter 59e18693eb feat(showcase): honest promote-notify message + durable healthcheckPath SSOT tracking
Promote-notify Slack message: name the promoted AND failed services (one
Failed: header + bullets), legible "(N): <names>" count, real wall-clock
elapsed (integer-coerced), and drop the constant verify-prod legend line.

Durable healthcheckPath: track it per-service/env in the SSOT (railway-envs),
re-assert it on the promote pin path (omit-when-absent, never null), and route
deploy-to-railway provisioning through isTrackedService/resolveProvisionHealthcheck
so a tracked-null service omits the healthcheck while an untracked one keeps the
/api/health default — fixing the silent prod-healthcheck drift that refused aimock.

Tests: ruby pin-reassert spec + deploy-to-railway healthcheck spec + emit/golden/accessor.
2026-06-23 16:56:16 -07:00
Mark Fogle 55f4f43afd feat(showcase/google-adk): surface 0.7.0 A2UI middleware (backend-owned) in declarative-gen-ui + beautiful-chat
Replace the hand-rolled google.genai A2UI planners (in main.py and
beautiful_chat_agent.py) with the published ag-ui-adk >= 0.7.0 middleware
sub-agent via get_a2ui_tool(), surfacing OSS-158 (forced render_a2ui
sub-agent + toolkit validate->retry recovery loop + recovery-exhausted
hard-fail envelope + render_as_llm_instructions / parse_and_fix healing).

Wiring is BACKEND-OWNED (injectA2UITool: false), matching the AWS Strands /
ag2 external-framework convention rather than langgraph-python's
runtime-driven injectA2UITool: true. Backend-owned is required: the planner
now lives in the ADK middleware, so letting the runtime also inject would
double-bind the tool slot. The explicit  is load-bearing post
CopilotKit#5611 (a provider catalog otherwise defaults injectA2UITool to true).

- declarative_gen_ui_agent / beautiful_chat_agent: tools include
  get_a2ui_tool({model, default_catalog_id}); beautiful keeps its other tools.
- shared_chat: add get_a2ui_model() to resolve a concrete Gemini BaseLlm for
  the sub-agent (mirrors get_model's aimock-proxy wiring).
- routes: injectA2UITool stays false (declarative + beautiful-chat).
- registry/agent_server: no spec-level a2ui config needed (tool is agent-owned).

Verified vs published 0.7.0 + real Gemini: backend-wired generate_a2ui emits
a2ui_operations; OSS-158 gate (subagent + recovery invalid->valid + hard-fail
a2ui_recovery_exhausted) all retained through this exact wiring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 23:19:45 +00:00
Mark Fogle ebd87a23f3 chore(showcase): bump google-adk to ag-ui-adk 0.7.0 (OSS-158 A2UI middleware)
Pins the published middleware that ships the A2UI auto-inject + toolkit
recovery + render_as_llm_instructions/parse_and_fix path. Foundational
step; the A2UI agent re-wire onto that path follows under verification
once 0.7.0 is on PyPI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 23:19:45 +00:00
Tyler Slaton 2ea3e66702 fix: repair check-types across all packages and gate it in CI (#5365)
## What this does

Follow-up to #5356. CI never ran `check-types`, so type errors piled up
silently across the monorepo. #5356 fixed shared, a2ui-renderer, and
angular. This PR fixes every remaining package and adds a CI gate so it
cannot happen again.

Almost all of the diff is mechanical type repair: type annotations,
`import type` splits, casts, ambient declarations, and tsconfig
module-resolution bumps. The sections below call out the parts that are
not purely mechanical so review can focus there.

## Where to focus your review

These are the only changes with runtime or public-API impact. Everything
else is type-level and behavior-preserving.

1. **License gating wired to /info** (shared, react-core, vue,
react-native). Behavioral change, details below.
2. **react-native bug fix**: a `catch` binding referenced by
`TypeError.cause` had been lint-stripped and is restored, plus a `{
cause }` is now attached to a parse error.
3. **runtime `Schema` passthrough**: a type-only cap on `tool()` schema
inference. Runtime behavior is unchanged; it only stops tsc from blowing
past 8 GB.
4. **New public type export**: `Anchor` from web-inspector, consumed by
react-core's `inspectorDefaultAnchor`.
5. **New CI job**, see the CI section.

## License context wired to /info

Follow-up to @MikeRyanDev's review on #5356 (wire the inert license
machinery to /info). `createLicenseContextValue` now takes the
server-reported license status instead of a hardwired null.
`checkFeature()` returns false only when the runtime reports `expired`
or `invalid`, and fails open otherwise (null, none, expiring, and valid
all keep features on). The React, Vue, and React Native providers feed
the status they already track from /info. New tests cover the gating in
shared and react-core. Per-feature data is not in /info yet, so gating
is uniform across features.

## Type fixes by package

- **core** (392 errors): bundler module resolution (matches the tsdown
build and the vue package), strict-mode and AG-UI drift in sources and
tests, added `@types/phoenix`.
- **react-core** (255): component, hook, and test drift (now-private
`activeRunCompletionPromise`, RunFinished outcome union, slot prop
types, StandardSchema variance), ambient declarations for `katex` CSS
and the react-markdown JSX namespace, plus the `Anchor` export.
- **runtime** (393, previously hidden behind an OOM crash):
BuiltInAgentConfiguration narrowing, AI SDK v6 and AG-UI drift, the
UserMessage attachment migration, OpenAI v4/v5 surface changes, and the
`Schema` passthrough noted above.
- **react-native** (23): provider/core bridge types, RN 0.85 drift, and
the `catch`/`cause` bug fix noted above.
- **smaller fixes**: runtime-client-gql (UserMessage image narrowing,
pinned `types`), web-inspector (nodenext import extensions, RunFinished
narrowing), react-textarea (es2023 lib for `toReversed`), react-ui,
voice, agentcore-runner, sqlite-runner (one-liners), sdk-js (bundler
resolution plus the missing `@standard-schema/spec` dev dep),
examples/v2/node (drop stale node10 resolution overrides).

## CI

New `check-types` job in `static_quality.yml`: run graphql codegen, then
`nx run-many -t check-types --parallel=1` with a 12 GB heap. The runtime
typecheck alone peaks near 10 GB and takes about 5 minutes on a 16 GB
runner, so it runs serially.

## Testing

- `nx run-many -t check-types` passes for all 24 projects locally and in
CI.
- All package test suites pass: core 431, react-core 1271, runtime 1523,
vue 1001, react-native 246, runtime-client-gql 129, plus the smaller
packages.
- Lockfile diff is only the two added type-only dev dependencies
(`@types/phoenix`, `@standard-schema/spec`).

## Follow-ups (not in this PR)

- react-core's built `.d.mts` files emit extensionless relative imports,
which silently degrade consumer types to `any` under `skipLibCheck`
(found while fixing react-native).
- The AI SDK x zod type-instantiation cost in runtime deserves a real
fix (40M instantiations); trace data available.
- `@ai-sdk/anthropic`'s new `authToken` setting is not forwarded by the
Anthropic adapter.
- `MCPClientProvider.tools()` has diverged from AI SDK v6's `ToolSet`
typing.
2026-06-23 15:41:18 -07:00
github-actions[bot] 3284bc863f style: auto-fix formatting 2026-06-23 22:34:58 +00:00
Tyler Slaton 75611b272c chore: merge main into PR 5480 2026-06-23 15:32:09 -07:00
Tyler Slaton 6d9397c42e Preserve quickstart CTA styling in shell docs reference pages (#5654)
## Summary
- Add a dedicated `shell-docs-primary-cta` style for the hero quickstart
link so it keeps the primary CTA color inside reference content.
- Cover the new class usage in the hero and framework overview tests.

## Testing
- Updated unit tests to verify the quickstart CTA class and the matching
global CSS override.
- Updated unit tests to verify the framework overview markup includes
the primary CTA class.
2026-06-23 15:27:06 -07:00
Austin Merrick 4ba201b5c4 fix: repair check-types across all packages and gate it in CI
Repairs TypeScript check-types across the monorepo and adds a CI gate so
regressions are caught going forward:

- core: bundler module resolution and strict-mode fixes
- sdk-js: bundler module resolution; keep codegen, formatter, packaging working
- react-core: fixes across components, hooks, and tests
- react-native: restore catch binding referenced by TypeError cause
- runtime: repair check-types and bound AI SDK schema inference
- web-inspector: nodenext import extensions, export Anchor
- remaining packages and node example: assorted check-types repairs
- deps: add missing type-only devDependencies
- license context driven from /info licenseStatus
- ci: run check-types in the static quality workflow

Squashed from 12 commits for a single, easily-revertable change.
2026-06-23 15:26:47 -07:00
Tyler Slaton 307a52c8eb Preserve quickstart CTA styling in reference content 2026-06-23 15:26:36 -07:00
Jordan Ritter 3b9696265d fix(showcase): recover ag2 + llamaindex staging from crash-loops (#5642)
## Summary

Both the **AG2** and **LlamaIndex** showcase integrations were 100% red
on the staging matrix (every cell `BE ×`, 0 green all day). Root cause
was **not** per-cell logic — each framework's Next.js frontend was
crash-looping under matrix load, driven by an agent-side hot loop. This
PR fixes both root-cause loops.

### LlamaIndex — `sse-missing` (commit forwarding request-time tools)
- **Root cause:** the llama-index AG-UI adapter never forwarded
`RunAgentInput.tools`, so page-injected tools (`toggleTheme`,
`pieChart`, `barChart`, `scheduleTime`, MCP, `generateSandboxedUi`) were
invisible to the LLM → `RUN_ERROR` (404 `no_fixture_match` →
`openai.NotFoundError`) → no `RUN_FINISHED` → `sse-missing`. The retry
storm OOM-crashed the frontend (Node fatal, `next-server` v15.5.18).
- **Fix:** new `RequestAwareAGUIChatWorkflow` (`_request_tools.py`) that
forwards request tools, re-roles the tool-result on an LLM-bound copy
only, and skips duplicate frontend-tool chunk emission (bare snapshot
already carries them). Applied to beautiful_chat / mcp_apps /
open_gen_ui / open_gen_ui_advanced routers; added the `search_flights`
backend tool to beautiful_chat for langgraph-python parity.
- **Red→green:** beautiful-chat **0/5 → 5/5** (toggle-theme,
schedule-meeting, search-flights, pie-chart, bar-chart), freshly
re-confirmed via `--d6 --rebuild`; `mcp-apps` red→green.

### AG2 — `generate_a2ui` empty-arg validation loop
- **Root cause:** the declarative route pointed `HttpAgent` at the root
catch-all agent instead of the dedicated `/declarative-gen-ui` mount,
and `generate_a2ui` required a `context` arg the model emits as `{}` →
pydantic `context Field required` → infinite retry. **630 loop
iterations** observed; the flood starved the ag2 frontend (502s).
- **Fix:** dedicated mount + `injectA2UITool:false` + no-arg
`generate_a2ui` (matches langgraph-python / google-adk) + regenerated
aimock fixture to 4-pill parity + ported the stale ag2
renderers/definitions.
- **Red→green:** **630 → 0** validation errors, `runsFinished=1`, clean
`generate_a2ui → TOOL_CALL_RESULT → RUN_FINISHED`.

## Known remaining (pre-existing, separate, NOT regressions)
- **ag2 `gen-ui-declarative`:** run completes but the a2ui surface
components don't paint (autogen↔AG-UI bridge `TOOL_CALL_RESULT` →
A2UIMiddleware surface-conversion gap). Tracked separately.
- **llamaindex `open-gen-ui`:** `sse-missing` resolved; residual
sandboxed-UI iframe render gap is **pre-existing** (red since
2026-06-01, fc=509 — predates this crash).

## Test plan
- [x] LlamaIndex beautiful-chat `--d6 --rebuild`: 5/5 green (fresh,
isolated)
- [x] LlamaIndex mcp-apps: red→green
- [x] AG2 declarative hot-loop: 630→0 validation errors, runsFinished=1
- [x] Pyright clean on both integrations (verified in-Docker with real
deps)
- [x] oxfmt clean
- [ ] Post-deploy: re-run D6 matrix on staging to confirm ag2 +
llamaindex column recovery

## Deploy note
Staging is **image-sourced, main-only** (the "Showcase: Build & Push"
workflow builds GHCR images and redeploys on push to `main`). This
branch will NOT auto-deploy. To validate on staging before merge: `gh
workflow run showcase_build.yml --ref fix/llamaindex-sse-request-tools
-f service=ag2` (and `service=llamaindex`).
2026-06-23 15:21:11 -07:00