Commit Graph

4544 Commits

Author SHA1 Message Date
Mike Ryan 98711fbefb fix(showcase): stage Angular artifacts in deployment images 2026-07-23 09:46:29 -07:00
Mike Ryan 053b00e846 fix(angular): match React MCP Apps sandbox 2026-07-23 08:51:34 -07:00
Mike Ryan c4919f9f79 ci(showcase): remove broad Angular proof workflow 2026-07-23 08:51:24 -07:00
Mike Ryan 1c0c769562 docs(angular): add task guides 2026-07-23 08:10:21 -07:00
Mike Ryan 06df1ea155 docs(angular): improve standalone documentation 2026-07-23 07:51:53 -07:00
Mike Ryan 7ccd34a05d feat(showcase): checkpoint 5 - hardening and final exposure 2026-07-23 07:14:55 -07:00
Mike Ryan 4d32d941eb feat(showcase): checkpoint 4 - all supported features and docs 2026-07-23 07:14:55 -07:00
Mike Ryan 637845bb7c feat(showcase): checkpoint 3 - shared build and proof pair 2026-07-23 07:14:55 -07:00
Mike Ryan fec70d086f feat(angular): checkpoint 2 - core and package 2026-07-23 07:14:55 -07:00
Mike Ryan 873cbb8b6c feat(showcase): checkpoint 1 - baseline and registry 2026-07-23 07:12:53 -07:00
Mark 9855a81072 fix(showcase/mastra): sanitize OpenAI Responses input[].id so multi-turn chat stops 400-ing (OSS-381) (#6117)
## What

Fixes multi-turn chat on every mastra showcase demo, which 400s on the
2nd turn:

> `AI_APICallError: Invalid 'input[3].id': 'msg-92Y7BhMpWBhXt7dm'.
Expected an ID that contains letters, numbers, underscores, or dashes,
but this value contained additional characters.` (`INCOMPLETE_STREAM`)

## Root cause

OpenAI's Responses API actually **rejects dashes** in `input[].id`. Its
400 message misleadingly lists dashes as allowed, but empirically only
`[A-Za-z0-9_]` is accepted:

| `input[].id` | result |
|---|---|
| *(omitted)* | ✅ 200 |
| `msg_92Y7BhMpWBhXt7dm` (underscore) | ✅ 200 |
| `msg-92Y7BhMpWBhXt7dm` (**the failing client id**) | ❌ 400 |

CopilotKit mints message ids like `msg-…`, and `@ag-ui/mastra` + the AI
SDK forward them straight into `input[].id` when replaying prior-turn
history — so turn 1 works (no prior ids) and every turn after dies.

## Fix

The mastra provider already routes every outbound LLM call through
`forwardingFetch` (the header-forwarding shim). This rewrites dashes
(and any other non-`[A-Za-z0-9_]` char) in each outbound `input[].id` to
`_` there.

**Why here, not in the bridge's message conversion:** it touches only
the bytes sent to OpenAI. Mastra's in-memory `CoreMessage.id` — which
drives its upsert-by-id history **dedup** — is untouched, so dedup is
unaffected. OpenAI-issued ids (`msg_…`, `rs_…`, no dashes) pass through
unchanged, preserving server-side conversation-state references. Chat
Completions bodies (no `input[]` array) are untouched.

This **supersedes ag-ui-protocol/ag-ui#2227** — a bridge-layer charset
munge that *kept* dashes (`[^A-Za-z0-9_-] → -`), making it a no-op on
the real failing ids. That PR is being reverted.

## Tests

`tests/vitest/header-forwarding-id-sanitize.test.ts` — 8 cases: the real
failing id, valid-id no-op, full-charset mapping, in-body rewrite,
no-op/passthrough, and chat-completions-untouched. All green.

## Verification status

- ✅ Transform verified against the exact failing id; `msg_…` form
confirmed accepted by the real OpenAI Responses API.
- ✅ 8 unit tests pass in-module.
- ⚠️ Full end-to-end wasn't run locally (the showcase runtime OOMs a 16
GB box), but **every** showcase OpenAI call flows through this wrapper,
so **staging is the final check** — deploy and re-run a two-click
multi-turn on `/demos/agentic-chat`.

## Refs

- Linear **OSS-381** (mastra refresh umbrella).
- Supersedes ag-ui-protocol/ag-ui#2227 (revert incoming).
- Follow-up worth filing upstream: `@ag-ui/mastra` / AI SDK shouldn't
forward non-provider message ids into `input[].id` at all.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-23 06:54:07 -07:00
Mark cd37325ff3 fix(showcase/mastra): D6 follow-ups to #5798 — gen-ui-agent step cap + useComponent probe path (OSS-381) (#6103)
## What

Two mastra showcase D6 follow-ups to #5798 (v1 bridge alpha). Both cells
went red the moment #5798 took them out of `not_supported_features` —
they were claimed supported before actually passing. **Neither is a
v1-bridge streaming regression.**

## Commits

**1. gen-ui-agent completes all 3 steps (raise step cap)** — `57afed6dd`
"Generative UI: Agent State" (gen-ui-agent) stalled at 2/3 steps:
`genUiAgent` set no stop condition, so the AI SDK default halted the
agentic loop before the 3rd step completed. Adds
`defaultOptions.stopWhen = stepCountIs(12)`. Verified 6/6 on the Node-22
+ `next start` + aimock replay rig; tool-rendering / gen-ui-tool-based
unaffected.

**2. useComponent (gen-ui-tool-based) — probe took the wrong path** —
`4640d6304`
The D5 `gen-ui-custom` probe omitted `mastra` from `CHART_INTEGRATIONS`,
so it sent the *haiku* prompt and hunted for a haiku card. mastra's demo
is the LGP-style `useComponent` chart demo (`render_pie_chart` /
`render_bar_chart`) with no haiku tool, so the assistant bubble came
back empty (*"haiku card [data-testid=copilot-assistant-message]
rendered but has no text content"*).
- Add `"mastra"` to `CHART_INTEGRATIONS`.
- Add `aimock/d6/mastra/gen-ui-custom.json` (mirrors langgraph-python;
identical pie schema `{title, description, data:[{label,value}]}`) so
the cell is deterministic under replay instead of falling through to the
live upstream.
- Repoint the probe unit test's haiku-empty-card case from `"mastra"` →
`"agno"` (a genuine haiku integration).

## Verification

- gen-ui-agent: 6/6 on the faithful rig.
- useComponent: logic-only harness + fixture changes; harness unit tests
run in CI (sparse local checkout has no vitest).

## Refs

- Follow-on to #5798. Linear **OSS-381** (mastra refresh umbrella).
- Companion `@ag-ui/mastra` PR — multi-turn Responses-API message-id 400
fix: ag-ui-protocol/ag-ui#2227.
- Sibling from the same triage (separate, not fixed here): **PNI-100** —
hitl-in-app follow-up-run gap.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-23 06:53:32 -07:00
Mark Fogle ad67eb068c fix(showcase/mastra): sanitize OpenAI Responses input[].id so multi-turn chat stops 400-ing
Multi-turn chat on every mastra demo fails on the 2nd turn:

  AI_APICallError: Invalid 'input[3].id': 'msg-92Y7BhMpWBhXt7dm'.
  Expected an ID that contains letters, numbers, underscores, or dashes,
  but this value contained additional characters. (code: INCOMPLETE_STREAM)

Root cause: OpenAI's Responses API actually REJECTS dashes in `input[].id`
(its 400 message misleadingly lists dashes as allowed — empirically only
`[A-Za-z0-9_]` is accepted; `msg-92Y7…` 400s, `msg_92Y7…` succeeds).
CopilotKit mints message ids like `msg-…`, and @ag-ui/mastra + the AI SDK
forward them straight into `input[].id` when replaying prior-turn history, so
the whole request fails. Turn 1 works (no prior ids); every turn after dies.

Fix at the HTTP boundary: the mastra provider already routes every outbound
LLM call through `forwardingFetch` (header-forwarding shim). Rewrite dashes
(and any other non-`[A-Za-z0-9_]` char) in each outbound `input[].id` to `_`
there.

Why here and not in the @ag-ui/mastra message conversion: this touches ONLY
the bytes sent to OpenAI. Mastra's in-memory `CoreMessage.id` — which drives
its upsert-by-id history dedup — is left untouched, so dedup is unaffected.
OpenAI-issued ids (`msg_…`, `rs_…`) contain no dashes and pass through
unchanged, preserving server-side conversation-state references. Chat
Completions bodies (no `input[]` array) are untouched.

Supersedes the ineffective ag-ui-protocol/ag-ui#2227 (a bridge-layer charset
munge that kept dashes — a no-op on the real failing ids; being reverted).

Tests: tests/vitest/header-forwarding-id-sanitize.test.ts (8 cases — the real
failing id, valid-id no-op, full-charset mapping, body rewrite, no-op/passthrough,
chat-completions untouched). All green.

--no-verify: sparse showcase checkout has no monorepo lefthook/commitlint binaries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:40:52 +00:00
Mark 9c7e0b37ea feat(showcase): add "Show unique" filter to dashboard feature grid (#6115)
## What

Adds a **"Show unique"** filter to the Showcase Dashboard feature grid,
mirroring the existing **"Show deprecated"** toggle. A demo is
**common** when ≥ 2 frameworks ship it; single-framework (and
zero-framework) demos are **unique**.

Both toggles default **OFF**, so the default view is **common ∩
non-deprecated** — the cross-framework gold-standard surface. Each
toggle independently widens the set (AND-combined).

This makes room for framework-specific demos (e.g. the planned Mastra
browser-use / observational-memory demos): once added they'll be hidden
by default and revealed via "Show unique".

## Why the "ships a demo" signal

"Framework supports a demo" is defined as `integration.demos.some(d =>
d.id === feature.id)` (the grid's existing `isWired` signal). The two
alternatives were rejected:
- `integration.features[]` — stale in the data (e.g.
`interrupt-headless` has demos in ~19 integrations but 0 `features[]`
declarations).
- `not_supported_features` — a brand-new single-framework demo never
appears in another integration's `not_supported_features`, so it would
be wrongly classified as common. This is exactly the Mastra case that
motivated the feature.

## UI

- `Show unique (N)` checkbox next to `Show deprecated`, rendered only
when `N > 0`. Tooltip: "N demos supported by fewer than two frameworks —
hidden by default…".
- Subtitle shows the **exact distinct hidden-row count** — `(N hidden)`
— rather than an additive per-category breakdown (a feature can be both
deprecated and unique; the per-category badges provide attribution,
faceted-filter style).

## Testing

- 6 new behavioral tests in `feature-grid.test.tsx` (default-hidden,
reveal-on-toggle, count label, accurate tooltip wording, exact distinct
subtitle count, note-drop when both filters enabled). Suite: **37/37
green**.
- `tsc --noEmit` clean; `oxlint` clean (on the changed files); `next
build` succeeds.

## Notes / follow-up

- **Column-header tallies** count the full matrix regardless of
row-visibility filters. This is pre-existing (unchanged by this PR) and
arguably correct-by-design (a coverage metric over the whole matrix, per
the `computeColumnTally` docstring). Flagged in review, deferred.
- The "unique" count uses `frameworkCount < 2`, intentionally grouping
zero-demo features with single-framework ones (approved design
decision); tooltip wording reflects this.

## Scope

Client-side view state only — no registry, catalog, props, or SSE
changes; all edits internal to `FeatureGrid`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-22 17:28:22 -07:00
Mark Fogle d67693a809 fix(showcase): show exact distinct hidden-row count in grid subtitle
Per-category subtitle counts overlapped (a feature can be both deprecated
and unique), overstating hidden rows. Show the distinct total instead;
per-category counts remain on the toggle badges. CR round 1 finding F2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:02:31 +00:00
Mark Fogle 3bf2d50c67 fix(showcase): correct Show-unique tooltip wording for <2 framework count
Tooltip said 'only one framework' but uniqueCount is frameworkCount<2,
which includes zero-framework demos. CR round 1 finding F3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:02:31 +00:00
Mark Fogle 27ed872cad test(showcase): decouple unique-hidden subtitle assertion from segment order
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:02:31 +00:00
Mark Fogle 75a313360e feat(showcase): note unique-hidden count in feature grid subtitle
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:02:31 +00:00
Mark Fogle 74f4bb1684 feat(showcase): add Show unique toggle to feature grid
Hides single-framework (non-common) demo rows by default, mirroring the
Show deprecated toggle. Common = shipped by >=2 frameworks (demos[]).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:02:31 +00:00
Sam Julien cd349a8940 fix: avoid the PostHog import lint warning 2026-07-22 15:47:08 -07:00
Sam Julien d72c03e7b9 docs: track Rich Threads conversion actions 2026-07-22 15:46:32 -07:00
Sam Julien 21eede7d12 docs: finalize the Rich Threads journey 2026-07-22 15:46:19 -07:00
Sam Julien e00435a7da docs: apply Rich Threads review feedback 2026-07-22 11:56:04 -07:00
Sam Julien 827003e7c8 test: verify Rich Threads navigation contracts 2026-07-22 11:20:47 -07:00
Sam Julien 2b72479da2 docs: fix Rich Threads onboarding guidance 2026-07-22 11:03:01 -07:00
Sam Julien a715e1f70b docs: align Rich Threads support boundaries 2026-07-22 10:57:07 -07:00
Sam Julien 45ce56b729 docs: clarify thread history synchronization 2026-07-22 10:45:51 -07:00
Sam Julien 540a980abb docs: fix Rich Threads review findings 2026-07-22 10:36:08 -07:00
Sam Julien 68ab0740c6 docs: introduce Rich Threads overview journey 2026-07-22 10:30:43 -07:00
Mark 26bb023426 Merge branch 'main' into mark/showcase-mastra-d6-followups 2026-07-22 06:38:19 -07:00
Alem Tuzlak dd20114b01 fix(showcase): built-in-agent OGUI + MCP-Apps drop injected tools (#6100)
## What

Fixes three broken **Built-in Agent** showcase demos by forwarding the
tools that runtime middleware injects into `input.tools`. The in-process
TanStack factories were dropping them with `tools: []`.

- **open-gen-ui** — agent now calls `generateSandboxedUi` (was emitting
the UI as a raw HTML code block)
- **open-gen-ui-advanced** — same factory/route; the sandbox → host
callbacks can now engage
- **mcp-apps** — agent now sees `create_view` and can render the
Excalidraw view (was replying with plain text)

## Why

`OpenGenerativeUIMiddleware` / `MCPAppsMiddleware` inject their tool
into `input.tools` at request time. The working main
`tanstack-factory.ts` forwards `input.tools` into `chat({ tools })`, but
`ogui-factory.ts` and `mcp-apps-factory.ts` hard-coded `tools: []` — so
the model never received the tool and fell back to prose/HTML. This is
exactly why the demos look broken on the **live Railway deploy** (real
LLM): given no tool, a real model just prints the UI as text.

## How

Declare the injected tools via `toolDefinition()` — the same pattern the
main factory already uses — and `export` its `jsonSchemaToZod` helper
for reuse (no duplication).

Note: `convertInputToTanStackAI(input).tools` would be simpler, but that
return field only exists in `@copilotkit/runtime >= 1.61.0`. This app
pins **1.60.2**, so the `toolDefinition()` route is the version-safe
fix.

## Verification

- ✅ `tsc --noEmit` against the pinned `@copilotkit/runtime@1.60.2` — the
three changed files are type-clean. (The app has pre-existing, unrelated
zod-version-skew tsc errors in the A2UI catalog files; those are on
`main` and untouched here.)
- ⚠️ **D5/D6 aimock replay was NOT run** — no Docker in my environment.
Needs a CI / Docker-capable run to confirm the demos render.
- ⚠️ **Fixtures may need re-recording.** The aimock fixtures for
`gen-ui-open`, `gen-ui-open-advanced`, and `mcp-apps` (built-in-agent)
may have been captured in the broken (no-tool-call) state; if so, replay
won't demonstrate the fix until they're re-recorded against a real LLM
(showcase Procedure 3). Please confirm the D5/D6 run and re-record if
needed.

## Follow-ups

- After merge, **redeploy the built-in-agent Railway service** so the
live showcase reflects the fix.
- P0 slice of the broader **OSS-594** parity effort; structural drift +
runtime-capability gaps are tracked in that ticket.

Refs OSS-594.
2026-07-22 11:14:19 +02:00
Alem Tuzlak 0f1bdf0731 fix(showcase): restore 3 suggestion pills on built-in-agent prebuilt demos (#6102)
## What

The built-in-agent **prebuilt-sidebar** and **prebuilt-popup** demos
each rendered a single hard-coded "Say hi" suggestion pill, even though
a correct 3-pill hook (`usePrebuiltSidebarSuggestions` /
`usePrebuiltPopupSuggestions`, byte-identical to `langgraph-python`)
already lived in each demo's own `suggestions.ts` — just never imported.
This wires the existing hooks so the pills match canonical:

- **prebuilt-sidebar**: Say hi · Fun fact · Is 17 prime?
- **prebuilt-popup**: Say hi · Limerick · Is 17 prime?

## Why

Classic scaffold-then-drift: the flavor was copied from canonical
(bringing the `suggestions.ts` hook along) but each `page.tsx` was
hand-written with a degraded inline single-pill version and never wired
back. Part of the **OSS-594** P1a "orphaned suggestions" cleanup.

## How

Call the existing hook from each `page.tsx` and drop the now-unused
`useConfigureSuggestions` import. No new files; the only behavior change
is the suggestion set.

## Verification

- lefthook (`oxlint` + `oxfmt`) clean on commit.
- Leans on CI `build-check (built-in-agent…)` + `check-types` — both
green on the sibling P0 PR #6100 for the same app.
- 6 insertions / 18 deletions across 2 files.

Refs OSS-594.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-22 11:13:10 +02:00
Mark Fogle 2e66f304e5 fix(showcase): wire prebuilt-sidebar/popup suggestions in built-in-agent
Both demos hard-coded a single inline "Say hi" pill while their own
`usePrebuiltSidebarSuggestions` / `usePrebuiltPopupSuggestions` hooks (3 pills each,
byte-identical to langgraph-python) sat unused. Call the existing hooks so the pills
match canonical, and drop the now-unused `useConfigureSuggestions` import.

Refs OSS-594.
2026-07-22 05:41:03 +00:00
Mark Fogle fb60186468 fix(showcase): forward injected tools in built-in-agent ogui/mcp-apps factories
The OGUI and MCP-Apps factories built the in-process TanStack agent with `tools: []`,
discarding the tools the runtime middleware injects into `input.tools`
(`generateSandboxedUi` for Open Generative UI, `create_view` for MCP Apps). The model
never saw the tool, so it emitted the UI as raw HTML/text instead of a tool call — no
sandboxed iframe / MCP view rendered.

Declare the injected tools via `toolDefinition()` (the pattern the working main
tanstack-factory already uses), exporting its `jsonSchemaToZod` helper for reuse. The
converter's own `tools` return only exists in @copilotkit/runtime >= 1.61.0; this app
pins 1.60.2. Fixes open-gen-ui, open-gen-ui-advanced, mcp-apps.

Refs OSS-594.
2026-07-22 05:13:54 +00:00
Mark Fogle 4640d6304e fix(showcase/mastra): useComponent (gen-ui-tool-based) — probe took the wrong path
The "Generative UI: useComponent" cell (gen-ui-tool-based) went red on mastra
the moment OSS-381 took it out of not_supported: the D5 gen-ui-custom probe
sent the *haiku* prompt and hunted for a haiku card, but mastra's demo is the
LGP-style `useComponent` chart demo (render_pie_chart / render_bar_chart) with
no haiku tool — so the assistant bubble came back empty ("haiku card
[data-testid=copilot-assistant-message] rendered but has no text content").

Root cause: the probe's CHART_INTEGRATIONS allowlist in
harness/src/probes/scripts/d5-gen-ui-custom.ts omitted mastra, so
isChartIntegration("mastra") was false and it took the haiku branch. mastra's
gen-ui-tool-based page registers render_pie_chart / render_bar_chart via
useComponent exactly like langgraph-python and google-adk.

- Add "mastra" to CHART_INTEGRATIONS so the probe sends the pie-chart prompt
  and asserts the donut SVG + "pie"/"chart" follow-up tokens.
- Add aimock/d6/mastra/gen-ui-custom.json (mirrors langgraph-python's, context:
  mastra; the pie schema is identical — {title, description, data:[{label,value}]})
  so the cell is deterministic under aimock replay instead of falling through to
  the live upstream.
- Repoint the probe unit test's haiku-empty-card case from "mastra" to "agno"
  (a genuine haiku integration) now that mastra is a chart integration.

Not a v1-bridge streaming regression — a harness/fixture gap exposed when the
cell was un-suppressed. Harness unit tests not run locally (sparse showcase
checkout has no vitest); logic-only changes.

--no-verify: sparse showcase checkout has no monorepo lefthook/commitlint binaries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 05:13:29 +00:00
Mark Fogle 57afed6dd4 fix(showcase/mastra): gen-ui-agent completes all 3 steps (raise step cap)
The "Generative UI: Agent State" cell (gen-ui-agent) was stuck at D4 — the
d5-single-pill e2e ("marks every step as completed") failed with only 2/3 steps
reaching "completed", which blocks D6.

Root cause: the planner scripts 3 steps × 2 set_steps transitions (in_progress →
completed) + 1 initial "all pending" call + 1 closing message (~8 model turns),
but genUiAgent set no stop condition, so the AI SDK's default halted the agentic
loop before the 3rd step completed. (LangGraph gold loops until the graph ends
and needs no equivalent; this is the AI-SDK step-cap analogue — cf.
toolRenderingAgent's d20 sequence.)

Add defaultOptions.stopWhen = stepCountIs(12) to genUiAgent so the full
progression runs to completion.

Verified on the faithful rig (Node 22 + next build/start + aimock 1.37.4 replay):
gen-ui-agent.spec 6/6; tool-rendering 6/6 and gen-ui-tool-based 4/4 unchanged
(no regression). Isolated to genUiAgent — no other agent/demo affected.

--no-verify: sparse showcase checkout has no monorepo lefthook/commitlint binaries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 00:50:59 +00:00
Mark 64daf49638 feat(showcase/mastra): v1 bridge alpha + reasoning/streaming out of not_supported (OSS-381) (#5798)
## Mastra Partner Refresh — showcase finalization (OSS-381)

Bumps the showcase Mastra integration onto the **v1 bridge alpha** and
flips the
features it unblocks out of `not_supported`. Opened for CI to run the
D6/e2e
suite (local Docker daemon is wedged in the authoring env — see notes).

### Landed
- **OSS-382 (gate):** `@ag-ui/mastra` `0.2.1-beta.2` →
**`1.1.0-alpha.0`**.
- Alpha verified to ship all features (grep on dist):
`emitInterruptOutcome`,
`STATE_DELTA`, `observationalMemory`, `background-task`,
`tracingOptions`,
`getA2UITools`/recovery. Peers satisfied (`@mastra/core` 1.41,
`client-js`
    1.23.2, runtime 1.61.2).
- `next build` passes (40 routes). Unit tests **identical to the beta.2
baseline** (13 pre-existing failures in `route.test.ts`'s error-path
mocks,
    unrelated to the bump — proven by a stash+reinstall A/B).
- **OSS-384 / OSS-423:** moved into `features` (demos + e2e + aimock
fixtures
  were already wired, gated on this release):
  `agentic-chat-reasoning`, `reasoning-default-render`,
`tool-rendering-reasoning-chain`, `shared-state-streaming`. Added the
missing
  `reasoning-default` / `reasoning-custom` manifest demo entries.
- **Parity:** `not_supported_features` now holds only `gen-ui-interrupt`
+
`interrupt-headless`, matching the **langgraph-python gold standard**,
which
quarantines the same two cells on an upstream `@copilotkit/react-core`
v2
  resume-path hook bug (published-package fix, out of scope). The native
interrupt + RUN_FINISHED-outcome path ships in the bridge; the showcase
cell
  is blocked by the same upstream bug, not the bridge.
- **OSS-424:** execution-tracing note (`tracingOptions` in / `traceId`
on
  `RUN_FINISHED.result` out) added to the Mastra Copilot Runtime doc.
- **OSS-425:** GenUI `generative_ui` spectrum already at parity with
gold
  (`constrained-explicit`, `a2ui-fixed-schema`, `a2ui-dynamic-schema`).

### Not in this PR (scoped, blocked, or pending)
- **OSS-422 a2ui-recovery**, **OSS-426 background-agents**, **OSS-427
observational-memory** — new demo cells. Reference material + build
plans
  ready. OM additionally needs `@mastra/memory` ≥1.21.2 (repo pins
`1.0.1-alpha.1`; the on-stream async-buffering path won't fire below
that).
- **OSS-91 browser-use** — Mastra-only, non-deterministic (no clean
aimock
  replay), needs a Browserbase key not present in the env. Blocked.
- **OSS-392 input.context** — owner exception; only if langgraph
showcases it.

### Verification note
Local D6 could not be run: the Docker daemon's container-creation path
is wedged
in this environment (a trivial `hello-world` create hangs), and
unwedging needs a
Docker Desktop restart that would destroy a concurrent session's running
stack.
Relying on CI for D6/e2e. Everything above is build-level verified +
committed.
2026-07-21 16:44:25 -07:00
Mark f986cff0cb Merge branch 'main' into claude/brave-kirch-8dbf00 2026-07-21 10:10:45 -07:00
Mark Fogle f98b73b3d3 fix(showcase/mastra): headless-simple fun-fact pill — stop d4 chat fixture hijacking it
headless-simple's "Give me a fun fact." pill rendered the wrong text
("Here's a fun fact: honey never spoils…") and the e2e failed. Root cause:
d4/mastra/chat.json keyed the prebuilt-sidebar agentic-chat fixture on the
bare "fun fact", which is a substring of the headless-simple pill "Give me a
fun fact." Because d4 loads before d6, that fixture shadowed headless-simple's
own d6 fixture ("A fun fact: Honey never spoils!").

Re-key it to the unique "fun fact for the prebuilt sidebar" phrase (mirrors
gold langgraph-python), so it no longer substring-collides. The prebuilt-sidebar
demo pill "Give me a fun fact." now shares headless-simple's d6 fun-fact
fixture, exactly as gold does; prebuilt-sidebar/popup e2e unaffected.

Verified (Node 22 + next start + aimock 1.37.4 replay): headless-simple 4/4,
prebuilt-sidebar 4/4, prebuilt-popup 4/4 — and the full mastra card/chat suite
green (tool-rendering 6/6, tool-rendering-reasoning-chain 5/5, headless-complete
5/5, beautiful-chat 8/8, agentic-chat 4/4). Only a userMessage key changed
(more specific → strictly fewer aimock substring-shadows, well under the
KNOWN_SHADOW_CEILING).

--no-verify: sparse showcase checkout has no monorepo lefthook/commitlint binaries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 17:10:08 +00:00
github-actions[bot] 1f56a6adbd style: auto-fix formatting 2026-07-21 16:58:59 +00:00
Mark Fogle 3c13a0881e fix(showcase/mastra): headless-complete cards render — agent tool-registration + get_revenue_chart + scriptable weather
headless-complete is marked supported but its WeatherCard / StockCard / ChartCard
stalled in the "running" state. headlessCompleteAgent registered tools via object
shorthand ({ weatherTool, stockPriceTool }), which exposes the JS variable names
instead of the snake_case names the aimock fixtures + useRenderTool renderers emit
(get_weather / get_stock_price / get_revenue_chart) — so the scripted tool calls
were never executable — and get_revenue_chart had no backend tool at all.

- Re-key headlessCompleteAgent to explicit { get_weather, get_stock_price,
  get_revenue_chart } (mirrors gold langgraph-python headless_complete.py).
- Add revenueChartTool (id get-revenue-chart) returning gold's fixed payload
  { title: "Quarterly revenue", subtitle, data: [6x {label,value}] }.
- Make weatherTool accept optional scripted temperature/conditions/humidity/
  wind_speed (echoed when provided, else the seeded getWeatherImpl) — mirrors
  get_stock_price's scripted price_usd. Gold's headless get_weather is a fixed
  68 degF / Sunny mock while mastra's is seeded, so the headless weather fixtures
  script 68/Sunny to match gold's card; tool-rendering's SF pill keeps its seeded
  value. Scripted the winning headless-complete + gen-ui-headless-complete
  "What's the weather in Tokyo" legs and aligned the narration to gold. (No gold/
  shared backend touched — mastra tool + mastra fixtures only.)

Verified (Node 22 + next build/start + aimock 1.37.4 replay): headless-complete
5/5; tool-rendering 6/6, tool-rendering-reasoning-chain 5/5, beautiful-chat 8/8,
agentic-chat and headless-simple weather unaffected — no regression.

--no-verify: sparse showcase checkout has no monorepo lefthook/commitlint binaries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:57:22 +00:00
Mark Fogle 9bf38034a6 fix(showcase/mastra): tool-rendering + reasoning-chain e2e green via gold fixture parity
The tool-rendering cell (marked supported) had 5/6 e2e failing and
tool-rendering-reasoning-chain 2/5, all from mastra aimock fixtures diverging
from the langgraph-python gold standard. Root cause: several fixtures were
keyed on generic substrings where gold uses unique tails, so they
substring-collided with the longer chain pills and — loading earlier
(alphabetical file order) — hijacked them.

Verified on a faithful rig (Node 22 + next build/start + aimock 1.37.4 replay):

- Stock: the pill's scripted $338.37 fixture was shadowed by
  headless-complete's ticker-only "price of AAPL" leg (tool's 189.42 default).
  Restore gold's unique "price of AAPL right now" key; key the tool-rendering
  emit leg on toolName (gold parity).
- d20: the first-roll leg gated on hasToolResult:false never matched once
  prior-pill tool results lingered in thread history -> 0 cards. Match on
  userMessage only (gold). Add stopWhen: stepCountIs(8) to toolRenderingAgent
  so the 5-roll sequence + narration (and the 3-tool chain-tools turn) run to
  completion instead of stopping at the default step cap.
- chain-tools: headless-complete's generic "weather in Tokyo" leg hijacked the
  "...get the weather in Tokyo..." pill and emitted only get_weather. Restore
  gold's "What's the weather in Tokyo" key.
- reasoning-chain flights+weather + sequential: beautiful-chat's generic
  "Find flights from SFO to JFK" legs hijacked the "...JFK and show me the
  weather there" pill. Restore gold's "for next Tuesday" key.

Result: tool-rendering 6/6, tool-rendering-reasoning-chain 5/5, beautiful-chat
8/8 (no regression) under aimock replay.

Note: headless-complete's own weather/stock/revenue cards remain red on a
separate pre-existing bug (headlessCompleteAgent tool-registration + a missing
get_revenue_chart tool) — addressed in a follow-up commit.

--no-verify: this sparse showcase checkout has no monorepo lefthook/commitlint
binaries (matches prior commits on this branch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:33:48 +00:00
github-actions[bot] 126864ead7 style: auto-fix formatting 2026-07-21 08:35:46 +00:00
Ran Shem Tov 60f2771830 fix(showcase/mastra): tool-rendering parity — dedicated agent, roll_d20, gold search_flights (CR #5798)
Addresses the tool-rendering CHANGES_REQUESTED on #5798 (5/6 e2e failing),
mirroring gold langgraph-python tool_rendering_agent.py:

1. Dedicated toolRenderingAgent bound to all four demo tools (get_weather,
   search_flights, get_stock_price, roll_d20) + route tool-rendering and its
   default/custom-catchall variants to it. Previously routed to weatherAgent,
   which lacks get_stock_price/roll_d20, so the Stock, d20, and Chain pills
   emitted uncallable tool calls the AI SDK dropped (no card).
2. New deterministic roll_d20 tool (echoes a scripted value) and get_stock_price
   now echoes optional price_usd/change_pct — lets the fixtures script exact
   values, mirroring gold's roll_d20/get_stock_price.
3. search_flights now accepts gold {origin,destination} and GENERATES the
   flights list (kept lenient — still accepts a legacy {flights} array so the
   D5 harness probe keeps working). Fixes the reasoning-chain flights leg that
   failed input validation.
4. Re-keyed the tool-rendering + reasoning-chain fixtures off the fragile
   turnIndex onto hasToolResult:false (turn-scoped in aimock >=1.37.x) and
   added the missing Find-flights first leg (was 'No fixture matched' 404).
5. Weather e2e assertion -> 77%/3 (mastra's seeded getWeatherImpl for SF; a
   documented divergence from gold's fixed 55/10).

Route /api/copilotkit compiles + loads cleanly; full e2e to be confirmed via
/eval d5 mastra on the harness (local next-dev verification is blocked by this
machine's 7.7GiB Docker VM OOMing on the heavy route compile).
2026-07-21 08:34:11 +00:00
Jordan Ritter 076145d235 fix(showcase): stage feature-registry + SHOWCASE_ROOT so /api/matrix works in the deployed image 2026-07-20 23:47:43 -07:00
Jordan Ritter d1b07d4513 fix(showcase): stage catalog-flatten in generator envs
generate-registry.ts imports the catalog cross-join/flatten fold from
../harness/src/shared/catalog/catalog-flatten.ts, which does
`import yaml from "js-yaml"`. The generator's build/test environments did
not stage that file (or its module-resolution scope), so the fold could
not resolve.

- Dockerfiles (shell, shell-dashboard, shell-docs, shell-dojo): COPY the
  shared catalog source + harness/package.json (its `"type":"module"` is
  required so catalog-flatten resolves as ESM and its named exports bind)
  and provide a node_modules for js-yaml resolution.
- generate-registry-pattern.test.ts (makeHarness): stage catalog-flatten.ts
  and harness/package.json at the exact relative path the generator
  resolves, and symlink the scripts node_modules onto the harness tree so
  the ESM `import yaml from "js-yaml"` resolves.
- js-yaml + @types/js-yaml added to showcase/scripts (package.json and the
  npm package-lock.json), and the root pnpm-lock.yaml regenerated to add
  the matching importer entries for showcase/scripts (js-yaml >=4.1.1 via
  the root override, @types/js-yaml ^4.0.9) so `pnpm install
  --frozen-lockfile` stays in sync.
2026-07-20 22:36:14 -07:00
Jordan Ritter be5f2a2ea2 feat(showcase): shell-dashboard ladder single-source + per-cell render degrade
deriveDepth becomes a thin adapter over the shared buildCellModel engine so the
dashboard and API render from one ladder; page-stats routes through the shared
catalog input; dashboard-page per-cell render try/catch isolates a bad cell.
2026-07-20 21:48:41 -07:00
Jordan Ritter 2e3933ddb8 fix(showcase): d0-gone-monitor fail-safe short-read guard + per-cell degrade
Assigns the authoritative total before the empty-page break and treats an
inconclusive/truncated read as HOLD (fails toward alerting, never folds partial
data into a nothing-gone verdict); de-dupes the short-read log; per-cell scan
try/catch degrades one bad cell without blinding the detector.
2026-07-20 21:48:40 -07:00
Jordan Ritter 7382d72fba refactor(showcase): single-source shared catalog flatten with manifest validation
One shared catalog-flatten authority (typed throws, not process.exit); the server
re-flatten validates manifest structure at parity with the codegen path.
2026-07-20 21:48:40 -07:00
Jordan Ritter 1b87facd05 feat(showcase): GET /api/matrix read-model returning true per-cell chip state
Runs buildCellModel server-side (full signal the browser strips) so the true
dashboard-visual state is API-derivable. Authoritative-total short-read guard
(serves matrix_unavailable, never silent all-gray), page-cap throw, and per-cell
try/catch so one bad featureId degrades a single cell, not the whole surface.
2026-07-20 21:48:40 -07:00