Commit Graph

8572 Commits

Author SHA1 Message Date
Sam Julien 3fe20fd9bd fix(shell-docs): rename gen-UI subgroup Open → Open-Ended
The concepts/three-types-of-gen-ui page and the canonical
learn/generative-ui/index page both use "Open-Ended" (with the
suffix) as the third gen-UI category alongside Controlled and
Declarative. The sidebar subsection had been shipped as just "Open"
in the JTBD reorg, leaving readers with three different namings
across the site ("Open" in nav, "Open-Ended" in concept page,
"Open-Ended" / "Fully Generated" in the learn page).

Align the sidebar to the canonical name. The other two subsections
("Controlled" and "Declarative") were already consistent.
2026-04-27 16:23:40 -07:00
Sam Julien b1131f21f5 fix(shell-docs): tighten docs overview to a doc-router shape
Two changes to index.mdx that align it with the new JTBD sidebar
instead of competing with it:

- Drop the lower "Explore by feature" 6-card section. Every entry
  there (Chat UI, Headless UI, Generative UI, Backend & Runtime,
  Programmatic Control, API Reference) was a flatter version of a
  sidebar section the JTBD reorg introduced. The overview pitching
  the same content twice made the page heavier without adding routing
  value.
- Swap one of the 4 top cards (was: Chat UI → /prebuilt-components)
  for Concepts → /concepts/architecture so the conceptual entry
  point is reachable from the docs front door, not just the sidebar
  subgroup.

The overview is now: 4 top cards (Quickstart, API Reference, Concepts,
Generative UI), the LandingCodeShowcase, and the IntegrationGrid.
Tighter and clearly a doc-router rather than a product-pitch redux.
2026-04-27 16:23:40 -07:00
Sam Julien 2ee45ceead fix(shell-docs): update mergeFrameworkNav anchor for JTBD section names
The merge anchor was hardcoded to "app control" with fallbacks to
"threads" and "backend". After the JTBD reorg renamed "App Control"
→ "Give Your App Agent Powers" and "Backend" → "Agents & Backends",
none of the candidates matched and every framework-scoped sidebar fell
back to append-at-end, relegating the framework section ("Built-in
Agent", "LangGraph (Python)", etc.) to the bottom of the nav.

Restore the original placement by adding the new section names to the
anchor candidate list: "give your app agent powers" (the renamed App
Control) and "agents & backends" (the renamed Backend) take priority,
with the old names kept as fallbacks for resilience. The match is
case-insensitive and stops at the first hit. Verified the framework
section now lands between Give Your App Agent Powers and Agents &
Backends for /built-in-agent/* and /langgraph-python/*.
2026-04-27 16:23:40 -07:00
Sam Julien 3600c1f6cc chore(shell-docs): strip narrative comments from redirects block
The redirect entries are self-describing — source, destination, and
permanent flag say everything the runtime needs. The block comments
were rationale that belongs in commit messages, not in a config file
that future readers scan for shape.
2026-04-27 16:23:40 -07:00
Sam Julien 133264f615 fix(shell-docs): 301 /concepts/oss-vs-cloud → /concepts/oss-vs-enterprise
The previous commit renamed the file but didn't add a redirect, so
any open browser tab or external link to /concepts/oss-vs-cloud now
404s — surfacing as a "sidebar disappeared" experience because the
404 page doesn't render the docs shell. Add the 301 redirect alongside
the migrate-to-* and frontend-actions ones.
2026-04-27 16:23:40 -07:00
Sam Julien fed518552b fix(shell-docs): rename concepts/oss-vs-cloud → oss-vs-enterprise
"Cloud" implied a single deployment shape (managed-only). "Enterprise"
is the accurate name for the layer — same Intelligence Platform runs
hosted at Copilot Cloud or self-hosted via the copilot-intelligence
Helm chart. The page already used "Enterprise" terminology in the
body; this aligns the slug, page title, and meta entry to match.

File renamed via git mv (history preserved). search-index.json paths
update on the next build (gitignored, regenerated).
2026-04-27 16:23:40 -07:00
Sam Julien db0dfe5820 feat(shell-docs): fill out the three concept pages with real content
Replaces the TODO placeholders left by the JTBD restructure with
written explanation-layer content sourced from existing repo material
(learn/architecture, learn/generative-ui, learn/intelligence-platform,
ag-ui/concepts/architecture, premium/overview) and from two CopilotKit
blog posts ("AG-UI Is Redefining the Agent–User Interaction Layer"
and "The Three Types of Generative UI: Static, Declarative and Fully
Generated").

- concepts/architecture.mdx: the three-layer stack (frontend, runtime,
  agent), AG-UI as the protocol bridge between runtime and agent, the
  request flow at a glance. Reuses the existing architecture-diagram
  PNG via ImageZoom and links out to the deeper learn/* coverage.
- concepts/three-types-of-gen-ui.mdx: a freedom-vs-control framing of
  Controlled / Declarative / Open-Ended generative UI with one concrete
  example per type and explicit "when to pick" guidance. Notes the
  alias terminology (Static, Fully Generated) so readers can match the
  blog and the learn/ pages. Cross-links to the implementation pages
  for each type.
- concepts/oss-vs-cloud.mdx: clear OSS-vs-Enterprise feature split with
  a capability-by-capability table, hosted-vs-self-hosted explanation,
  and a decision rubric ("if you want CopilotKit to *be* your
  conversation persistence layer, that's where Enterprise begins").

All three keep the explanation-layer scope (Diátaxis): they orient
and explain, then point the reader at the canonical detailed pages
for implementation specifics. None of them duplicate how-to content.
2026-04-27 16:23:40 -07:00
Sam Julien 5fbb586a71 fix(shell-docs): drop redundant What is CopilotKit concept page
The concepts/what-is-copilotkit.mdx placeholder duplicated the
overview rendered at /index.mdx — same intent ("orient the reader"),
same target audience. Keep the index page as the single what-is
entry point and remove the concept-page slot.
2026-04-27 16:23:40 -07:00
Sam Julien f9d0da3b59 fix(shell-docs): suppress duplicate group title when section header already labels it
The current meta convention pairs a `---X---` section header with a
`...x` spread that resolves to a sub-meta whose `title` is also "X".
buildNavTree emitted both a section node and a group node with the
same title, and the renderers showed each one — so users saw "BUILD
GENERATIVE UI" (section, uppercase tracking-widest) followed by
"Build Generative UI" (group, regular case) for the same content.
The doubling was already on the live site for one section
("Generative UI") and didn't get pushback there, but the JTBD reorg
makes it more visible: every spread-backed section ends up doubled
(Migrate, Other, etc.).

Fix in two halves, kept narrow:

- buildNavTree: when the previously-pushed node is a section header
  with the same title that the spread's group would carry, set the
  group's title to empty string. The group still wraps its children
  for indentation/nesting; only the redundant inner label is dropped.
- All three nav renderers (renderNavItem in docs-page-view.tsx,
  OverviewNavItem in app/[[...slug]]/page.tsx, RenderNav in
  app/[framework]/[[...slug]]/page.tsx) gain a `{node.title && ...}`
  guard so an empty string doesn't render an empty <div>.

Sections without a matching spread (Get Started → index/quickstart/
coding-agents listed inline) and spreads without a preceding section
header (legacy framework-tree work, override merges) are unaffected.
A spread whose sub-meta title differs from the section header (e.g.
section "Observe & Operate" + ...troubleshooting whose title is
"Troubleshooting") still renders both labels, which is correct —
they're meaningfully different and the inner one acts as a
sub-grouping label.
2026-04-27 16:23:40 -07:00
Sam Julien c119768195 feat(shell-docs): JTBD information-architecture restructure
Restructures the top-level sidebar from feature-primitive sections
(Basics / App Control / Backend / Generative UI / Platform / Premium
Features / Troubleshooting) into 9 jobs-to-be-done sections that match
how readers describe what they want to build. Decisions captured in
the IA Restructure plan.

Section structure:

  1. Get Started — index, quickstart, coding-agents, + concepts subtree
     (placeholders for what-is-copilotkit, architecture,
     three-types-of-gen-ui, oss-vs-cloud)
  2. Build Chat UIs — prebuilt-components, custom-look-and-feel,
     multimodal-attachments
  3. Build Generative UI — nested Controlled / Declarative / Open
     subgroups (tool-based, tool-rendering, state-rendering, reasoning,
     your-components / a2ui + dynamic-schema + fixed-schema / mcp-apps)
  4. Give Your App Agent Powers — frontend-tools, shared-state,
     multi-agent/subagents, programmatic-control
  5. Agents & Backends — built-in-agent (new), copilot-runtime,
     custom-agent, ag-ui, runtime-server-adapter
  6. Observe & Operate — inspector, vs-code-extension, +
     troubleshooting subgroup (event-inspector, hook-explorer,
     debug-mode, observability-connectors, common-issues,
     error-debugging)
  7. Enterprise — premium/overview, premium/observability,
     premium/self-hosting, threads (merged from former Threads section
     per product call: threads + persistence are part of Enterprise)
  8. Migrate — v2, 1.10.X, 1.8.2 (moved out of Troubleshooting and
     renamed to drop the redundant 'migrate-to-' prefix)
  9. Other — contributing, telemetry (unchanged)

  Reference stays as a separate root-true tree, not surfaced through the
  top-level meta. Its v1/v2 treatment is a follow-up decision.

Page moves and new files:

  - Migration guides moved from troubleshooting/migrate-to-{v2,1.10.X,
    1.8.2}.mdx to migrate/{v2,1.10.X,1.8.2}.mdx with 301 redirects from
    the old URLs in next.config.ts. Migrate gets its own first-class
    section with a lucide/RefreshCw icon — separate from
    Troubleshooting per IA-analysis pillar ("I'm upgrading deliberately"
    ≠ "something broke").
  - 4 concept placeholders + index under content/docs/concepts/. Each
    has frontmatter (title, description, icon, doc_type: explanation)
    and a TODO body referencing where the content will come from
    (existing repo material + blog posts). Slot exists; content
    backfills later.
  - New built-in-agent.mdx at root — 1-page summary that places BIA in
    Agents & Backends as a peer to copilot-runtime / custom-agent / etc,
    with a link out to the full BIA-scoped docs at /built-in-agent.

Other meta moves:

  - programmatic-control: Basics → Give Your App Agent Powers
  - inspector: Basics → Observe & Operate
  - vs-code-extension: Platform → Observe & Operate
  - multimodal-attachments: Platform → Build Chat UIs
  - runtime-server-adapter: Platform → Agents & Backends
  - The 3 migration pages: Troubleshooting → Migrate (with file moves)

Removed dead code: the `...unselected` line in top-level meta.json
was a no-op (unselected/meta.json has `root: true` so the spread
produced nothing). Stripped during the rewrite.

Multiple new visible labels are intentional. The renderer renders
sections (uppercase tracking-widest) and groups (medium-weight regular
case) at the same level when a section spreads a sub-meta with a
matching title — same pattern that's been live for 'Generative UI'
through every prior PR. The Build Generative UI nesting (Controlled /
Declarative / Open) is a deliberate three-types-of-gen-UI subgrouping
inside the section, surfaced via subsection headers in
generative-ui/meta.json's pages array.
2026-04-27 16:23:40 -07:00
Jordan Ritter 4320408805 fix(showcase-ops): use bare probe_id for run-history lookup (#4338)
## Summary

- Fix probe run history always returning empty — the invoker writes PB
rows with bare `cfg.id` (e.g. `e2e-deep`) but the HTTP handler queried
with the scheduler entry ID including the `probe:` prefix (e.g.
`probe:e2e-deep`), so they never matched

## Test plan

- [x] 1320 tests pass
- [x] Typecheck clean
- [ ] CI green
- [ ] After deploy, click probe:e2e-deep row on dashboard and confirm
"Recent Runs" populates
2026-04-27 15:49:40 -07:00
Jordan Ritter 1b89648f02 fix(showcase-ops): use bare probe_id for run-history lookup
The invoker writes PB rows with bare cfg.id (e.g. 'e2e-deep') but
the HTTP handler passed the scheduler entry id with 'probe:' prefix
(e.g. 'probe:e2e-deep') to writer.recent(). The IDs never matched,
so run history always returned empty.
2026-04-27 15:49:19 -07:00
Jordan Ritter 07d66b3db8 feat(showcase-ops): D5 probe speed — bounded parallelism + feature-type filtering (#4337)
## Summary

- **Bounded-parallel feature execution**: replaces sequential feature
loop in e2e-deep driver with a Semaphore-gated `Promise.allSettled` pool
(`FEATURE_CONCURRENCY=2`), cutting per-service wall-clock time roughly
in half
- **Feature-type filtering on trigger API**: extends the
`/api/probes/:id/trigger` endpoint to accept `featureTypes` filter,
threading it through HTTP handler → scheduler → invoker → ProbeContext →
driver — enabling targeted probe runs against specific feature types
- **Config tuning**: bumps `max_concurrency` 2→4 and `timeout_ms`
300s→180s in e2e-deep.yml to match the faster execution model

## Key changes

| File | Change |
|------|--------|
| `e2e-deep.ts` | Semaphore class, `FEATURE_CONCURRENCY`, parallel pool,
feature-type filter, canonical `isD5FeatureType` import |
| `probes.ts` | `featureTypes` validation, `slugsProvided` envelope
semantics |
| `types/index.ts` | `featureTypes?: string[]` on `ProbeContext` |
| `scheduler.ts` | `featureTypes` on `TriggerOptions.filter` |
| `probe-invoker.ts` | `featureTypes` on `InvokerTriggerOptions.filter`
+ `ExecuteOneOpts`, threaded to ProbeContext |
| `e2e-parity.ts` | Replaced redundant `ALL_KNOWN_FEATURES` with
canonical `isD5FeatureType` |
| `e2e-deep.yml` | `max_concurrency: 4`, `timeout_ms: 180000` |
| Tests | 15 new tests (8 driver + 7 HTTP) covering parallelism,
filtering, Semaphore, graceful degradation |

## Test plan

- [x] 1320 showcase-ops tests pass (including 15 new)
- [x] Typecheck clean
- [x] Build clean
- [x] CR loop converged: 2 fix rounds + 2 confirmation rounds, 0 bucket
(a) findings
- [ ] CI green
- [ ] Trigger a real D5 probe cycle on Railway to verify wall-clock
improvement
2026-04-27 15:24:27 -07:00
Jordan Ritter c92524f9ee ci: retrigger after auto-format 2026-04-27 15:13:41 -07:00
Sam Julien 1a5ee31dc4 chore(showcase/starters): regenerate mastra starter for region marker drift 2026-04-27 15:09:50 -07:00
Sam Julien ac727e72ed docs(showcase/mastra): runtime-inject-tool sibling file for declarative-gen-ui
Completes the declarative-gen-ui cell for mastra (5/5 regions). The
runtime-inject-tool snippet teaches the TS-runtime injectA2UITool flag —
mastra's actual route bundles generateA2uiTool into weatherAgent so it
doesn't follow this pattern, but the docs page is teaching the runtime
feature itself, so a docs-only sibling file matches the established
pattern (see chat-component.snippet.tsx in agentic-chat).
2026-04-27 15:09:50 -07:00
github-actions[bot] 4dc2eea5ed style: auto-fix formatting 2026-04-27 15:09:50 -07:00
Sam Julien 3d68634670 docs(showcase/mastra): add region markers for shell-docs snippet coverage
Adds the @region[name] / @endregion[name] markers the shell-docs <Snippet>
mechanism needs to resolve mastra-scoped code blocks. Brings 10 cells from
"missing snippet" warnings to clean rendered code in the docs.

Two patterns:

  1. In-place markers (12 of the 14 file edits) — wrap existing demo source
     where it already reads as a clean teaching example. Comment-only,
     stripped from rendered output, zero runtime change.

  2. Sibling <region>.snippet.tsx files (2 new files) — for cases where
     the production demo carries QA hooks (frontend tools, render tools,
     agent context) that aren't relevant to the docs page being taught.
     Lives in the demo folder so the bundler picks it up; not imported,
     not rendered. Used for agentic-chat/chat-component (mastra Chat is
     QA-laden) and tool-rendering/render-flight-tool + catchall-renderer
     (mastra demo only renders weather, not flights or catchall).

Cells advanced to ready: prebuilt-popup, prebuilt-sidebar, frontend-tools,
chat-customization-css, agentic-chat-reasoning, chat-slots, agentic-chat,
tool-rendering, headless-complete, plus partial coverage on declarative-gen-ui
(provider-a2ui-prop only; runtime-inject-tool is missing on every framework
and needs a cross-cutting authoring round on langgraph-python first).

Out of scope: a2ui-fixed-schema and the runtime-inject-tool region on
declarative-gen-ui (cross-cutting — reference framework lacks them too);
shared-state-*, subagents, gen-ui-*, mcp-apps, open-gen-ui*, interrupt-headless
(stub or no-folder on mastra — engineering work).
2026-04-27 15:09:50 -07:00
github-actions[bot] aab249262f style: auto-fix formatting 2026-04-27 22:04:51 +00:00
Jordan Ritter f1ee30f243 fix: CR round 2 — scope envelope regression, rejected-promise side-row 2026-04-27 15:02:08 -07:00
Jordan Ritter 6b4dc68de4 fix: CR round 1 — hitl-steps allowlist, Semaphore guards, YAML accuracy, response envelope 2026-04-27 15:02:08 -07:00
Jordan Ritter 5c31e171cd docs: add showcase-ops memory budget note to RAILWAY.md
Documents the D5 e2e-deep Chromium memory envelope (4 services x 2
features = 8 concurrent contexts, ~2.4GB peak) and the two tuning
knobs operators should adjust if OOM occurs.
2026-04-27 15:02:07 -07:00
Jordan Ritter bb698a5819 test: add integration tests for bounded-parallel execution and feature-type filtering
Semaphore unit tests verify the counting semaphore gates concurrent
access correctly at limit=1, limit=2, and limit>=N. Feature parallelism
test confirms FEATURE_CONCURRENCY=2 produces peak context count of 2
when 4 features run. Feature-type filtering tests cover the driver-level
ctx.featureTypes filter (filtered-by-trigger note, all-filtered short-
circuit) and the HTTP handler validation (empty array, empty strings,
non-array, combined slugs+featureTypes, rate-limit non-consumption on
400). Graceful degradation test verifies correct aggregate results
regardless of concurrency level.

Exports Semaphore class and FEATURE_CONCURRENCY constant from
e2e-deep.ts for direct unit testing.
2026-04-27 15:02:07 -07:00
Jordan Ritter fba6132552 feat: apply featureTypes filter in e2e-deep driver before execution loop
When ctx.featureTypes is set from the trigger layer, partition runnable
features into kept and filtered sets before the execution loop begins.
Filtered features are recorded as skipped with a "filtered-by-trigger"
note so dashboards can distinguish trigger-scoped runs from no-script
skips. Logging emits the filter and excluded count when active.
2026-04-27 15:02:07 -07:00
Jordan Ritter 26df046389 feat: parse and validate featureTypes filter in trigger HTTP handler
Accept optional featureTypes in the trigger request body filter. Validates
that featureTypes is a non-empty array of non-empty strings when present,
returning 400 with a descriptive error otherwise. Forwards the validated
featureTypes into TriggerOptions alongside existing slug filtering.
2026-04-27 15:02:07 -07:00
Jordan Ritter 8e8745a382 feat: add bounded-parallel feature execution to e2e-deep driver
Replace the sequential for-loop over runnable features with a
semaphore-gated Promise.allSettled pool capped at
FEATURE_CONCURRENCY=2. Each feature already creates its own
independent browser context, so there is no shared mutable state
between concurrent runs. Results are collected from settled promises
to preserve input ordering. Setting FEATURE_CONCURRENCY=1 degrades
to identical sequential behaviour.
2026-04-27 15:02:07 -07:00
Jordan Ritter 5a8a25f871 feat: thread featureTypes filter through probe type system
Add optional featureTypes?: string[] to ProbeContext, TriggerOptions,
and InvokerTriggerOptions. The invoker extracts the field from trigger
opts and forwards it into the ProbeContext passed to each driver, so
drivers like e2e-deep can restrict their run scope to specific feature
types without changes to the scheduler or HTTP layer.
2026-04-27 15:02:07 -07:00
Jordan Ritter 920e61b392 chore: bump e2e-deep max_concurrency to 4 and timeout to 180s
Production memory headroom supports 4 parallel chromium contexts.
Higher concurrency cuts tail latency roughly in half; tighter timeout
matches the reduced per-worker wall-clock budget.
2026-04-27 15:02:06 -07:00
Max Korp 946eec954b Revert "chore(threads-example): bump @copilotkit/* deps to 1.56.4" (#4336)
Bumped into some weirdness with this, rolling back for the upcoming demo
2026-04-27 14:46:39 -07:00
Max Korp 7232c15bc2 Revert "chore(threads-example): bump @copilotkit/* deps to 1.56.4" 2026-04-27 14:45:02 -07:00
Jordan Ritter acbca3fb80 Remove VS Code extension — migrated to standalone repo (#4335)
## Summary

- Removes `packages/vscode-extension/` (176 files) — migrated to
[CopilotKit/vscode-extension](https://github.com/CopilotKit/vscode-extension)
- Removes 3 extension-specific GitHub workflows (CI, publish,
changelog-sync)
- The standalone repo has full git history, working CI, verified OIDC
publishing, and branch protection

## Why

The extension is a leaf node in the monorepo dependency graph (nothing
depends on it) and has its own independent release cycle. Extracting it
simplifies the monorepo and gives the extension its own CI/CD without Nx
overhead.

## Test plan

- [x] Standalone repo builds, types clean, 184 tests pass
- [x] Dry-run publish validates OIDC auth chain (Marketplace + Open VSX)
- [x] CI green on standalone repo main branch
- [x] Landing page live at vscode.copilotkit.dev
2026-04-27 14:37:22 -07:00
Jordan Ritter 36d8cb33fd chore: remove VS Code extension — migrated to CopilotKit/vscode-extension
The extension is a leaf node in the monorepo dependency graph (nothing
depends on it) and has its own independent release cycle. The standalone
repo at CopilotKit/vscode-extension has full git history, working CI,
verified OIDC publishing, and branch protection.
2026-04-27 14:21:44 -07:00
Ben Taylor a30c4dbb40 chore(threads-example): bump @copilotkit/* deps to 1.56.4 (#4334)
<!--
Thank you for sending the PR! We appreciate you spending the time to
work on these changes.

Help us understand your motivation by explaining why you decided to make
this change.


**Please PLEASE reach out to us first before starting any significant
work on new or existing features.**

By the time you've gotten here, you're looking at creating a pull
request so hopefully we're not too late.

We love community contributions! That said, we want to make sure we're
all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align
with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in
progress.

As described in our contributing guide, please file an issue first:
https://github.com/ag-ui-protocol/ag-ui/issues
Or, reach out to us on Discord: https://discord.com/invite/6dffbvGU3D


You can learn more about contributing to copilotkit here:
https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md

Happy contributing!

-->

## What does this PR do?

(Describe the changes introduced in this PR)

## Related PRs and Issues

- (Direct link to related PR or issue, if relevant)

## Checklist

- [ ] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
2026-04-27 16:12:35 -05:00
Ben Taylor 9a085cf96a Merge branch 'main' into chore/update-threads-example-packages 2026-04-27 16:07:32 -05:00
Benjamin Taylor 05c9056d88 chore(threads-example): bump @copilotkit/* deps to 1.56.4
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:03:57 -05:00
Jordan Ritter 0377ca3f13 fix(showcase): post-merge CI fixes for google-adk parity (#4333)
## Summary
- Add missing `@json-render/core` and `@json-render/react` deps to
google-adk `package.json` (Docker build was failing on byoc-json-render
demo)
- Update catalog test expectations to match actual generated counts
after merge
- Regenerate google-adk starter to match template output (drift check
was failing)

## Why
PR #4318 (google-adk parity) introduced merge conflicts during rebase
that left catalog counts stale, and the byoc-json-render demo was
missing its `@json-render/*` dependencies. The starter had manual CR
fixes that diverged from the generator template.

## Test plan
- [ ] Showcase: Validate passes (catalog counts)
- [ ] Showcase: Verify Starters Match Template passes (drift check)
- [ ] Showcase: Build & Deploy passes (Docker build with @json-render
deps)
2026-04-27 13:22:04 -07:00
Ben Taylor bf8aca7ee7 chore: release monorepo v1.56.4 (#4332)
## Release monorepo v1.56.4

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.56.4`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.56.4`
   - Creates git tag `monorepo/v1.56.4`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.56.4
2026-04-27 15:21:16 -05:00
Jordan Ritter 48623f4faf fix(showcase): post-merge CI fixes for google-adk parity (#4318)
1. Add missing @json-render/core and @json-render/react deps to
   google-adk package.json (Docker build failed on byoc-json-render
   demo imports)
2. Update catalog test expectations to match actual generated counts
   (wired 482, crewai-crews 28, LGP 37 wired + 2 unshipped)
3. Regenerate google-adk starter from template to eliminate drift
   detected by the starter consistency check
2026-04-27 13:16:02 -07:00
BenTaylorDev f19afade44 chore: release monorepo v1.56.4 2026-04-27 15:05:59 -05:00
Jordan Ritter 84d90deb1a feat(showcase/google-adk): port langgraph-python demos to fill dashboard column (#4318)
## Summary

Brings the **Google ADK** column on
https://dashboard.showcase.copilotkit.ai/#coverage from 8 wired cells
(parity_tier `minimal`) up to **35 wired cells** (parity_tier `partial`)
— using `langgraph-python` (38/39) as the reference. All ports use real
Google ADK + Gemini 2.5 Flash agents wired through `ag-ui-adk`; nothing
is stubbed.

### Backend

- `src/agent_server.py` refactored from a single shared `LlmAgent`
mounted at `/` to one `ADKAgent` per demo at `/<agent_name>`, driven by
a new `src/agents/registry.py` source-of-truth (with an `AgentSpec`
dataclass for `predict_state` / `emit_messages_snapshot` kwargs).
- 18 new per-demo agent modules covering reasoning (Gemini thinking
mode), tool-rendering (4 variants), HITL (in-chat + in-app),
shared-state (read-write + per-token streaming via
`PredictStateMapping`), multi-agent supervisor, A2UI dynamic +
fixed-schema, BYOC, open-gen-ui (basic + advanced), agent-config,
readonly-context, multimodal, beautiful-chat, plus the existing
recipe-themed shared-state-read.

### Frontend

- `src/app/api/copilotkit/route.ts` now maps each agent name to its
matching backend path.
- 6 dedicated runtime routes for demos that need bespoke runtime config:
- `copilotkit-auth` — V2 `createCopilotRuntimeHandler` with an
`onRequest` 401 gate
- `copilotkit-declarative-gen-ui` and `copilotkit-a2ui-fixed-schema` —
`a2ui.injectA2UITool: false` because the agents own their own A2UI tools
- `copilotkit-byoc-hashbrown`, `copilotkit-byoc-json-render`,
`copilotkit-ogui` (shared by open-gen-ui + advanced)
- 26 new / replaced demo pages with their helper components.

### Manifest

`showcase/packages/google-adk/manifest.yaml` declares 35 features (was
8). `pnpm generate-registry` validates clean.

### Skipped (intentional)

- `gen-ui-interrupt`, `interrupt-headless` — depend on LangGraph's
`interrupt()` graph primitive; ADK has no direct equivalent. The
high-level `useHumanInTheLoop` case is covered via `hitl-in-chat`.
- `mcp-apps` — `ag_ui_adk` does support `MCPToolset`, but a working
MCP-driven UI demo is a separate chunk; left for follow-up.

## Test plan

- [x] `pnpm generate-registry` validates manifest end-to-end (Catalog:
reference = langgraph-python with 37 wired features; google-adk now at
35/39 wired)
- [x] `npx tsc --noEmit` in `showcase/packages/google-adk` — no new
errors (pre-existing `byoc-json-render/registry.tsx` and
`shared-state-write/page.tsx` errors untouched)
- [x] Python syntax: `ast.parse` over every file in `src/agents/` — all
parse cleanly
- [ ] Local smoke test: `pnpm dev` in `showcase/packages/google-adk`,
hit each new `/demos/*` route, verify L2/L3 health
- [ ] Railway deploy: confirm health probes go green and dashboard
column lights up

## Caveats worth knowing before deploy

1. **Per-token streaming** in `shared-state-streaming` uses
`PredictStateMapping(stream_tool_call=True)`. Per `ag_ui_adk` docs, true
per-token argument streaming requires Gemini 3+ via Vertex AI; on Gemini
2.5 Flash this should still work but at chunk-level granularity.
2. **Subagents** uses direct `genai.Client.models.generate_content`
calls inside each delegation tool, not ADK's native `sub_agents` /
`AgentTool`. Functionally equivalent for the demo; a follow-up could
refactor to ADK-native multi-agent.
3. **A2UI fixed-schema** has an inline `_build_flight_operations` helper
instead of importing `copilotkit.a2ui`. The `copilotkit` Python SDK
isn't in `requirements.txt` for this package — adding it later and
refactoring is straightforward.
4. **`/agents/state` collision**: `ag_ui_adk.add_adk_fastapi_endpoint`
hardcodes `POST /agents/state` regardless of the `path` arg. With N
agents mounted, only the first registered agent's state endpoint is
reachable. Most demos don't use it; `headless-complete` could.
5. **Beautiful-chat** is intentionally minimal vs. the langgraph-python
sibling's richer canvas/layout split.
2026-04-27 13:03:59 -07:00
github-actions[bot] b7dce5c1b4 style: auto-fix formatting 2026-04-27 19:54:21 +00:00
Alem Tuzlak 3daa7dbba0 fix: align google-adk starter with packages — route rewrite, deps, sample_agent
Rewrite starter route.ts to use HttpAgent (matching packages pattern),
fix default port to 8123, add full 37-agent list including sample_agent,
add missing @ag-ui/client dependency, register sample_agent in registry.
2026-04-27 12:52:53 -07:00
Alem Tuzlak 9c5a0ac850 fix: correct OGUI instructions, sandbox regex, and ternary precedence
Update open-gen-ui agent instructions to emit HTML directly instead
of fenced blocks (the runtime's generateSandboxedUi tool handles
rendering). Tighten sandbox evaluateExpression regex to reject **
exponentiation. Fix ternary operator precedence in 3 agent files
where string concatenation bound tighter than the conditional.
2026-04-27 12:52:53 -07:00
Alem Tuzlak ba5bf65881 fix: handle promise rejections in google-adk demo pages
Replace swallowed .catch(() => {}) with console.error logging in
headless-simple, headless-complete, and shared-state-read demos.
2026-04-27 12:52:53 -07:00
Alem Tuzlak f282a1674e fix: harden google-adk route error handling and add auth catch-all
Remove stack trace leaks from error responses, replace @ts-ignore
with @ts-expect-error, hoist CopilotRuntime to module scope, and
add [[...slug]] catch-all for the V2 auth endpoint so sub-route
requests don't 404.
2026-04-27 12:52:53 -07:00
Alem Tuzlak d8a208297d refactor(google-adk): track strip-prior-block in inject callbacks
Round 5 review surfaced a fragility in the empty-write guard. The
`if not new_text` short-circuit added in Round 4 correctly avoids
clobbering the LlmAgent static `instruction=` field when there's
nothing to inject — but if a prior callback DID embed a block in the
existing Content and the user has since cleared state, the early
return leaves the stale block in place because we never write the
stripped result back.

In practice this is unreachable: `_INSTRUCTION` is non-empty for all
three agents, so `original_text` after stripping always retains at
least the static instruction. But the explicit `stripped_prior_block`
flag makes the invariant honest if anyone ever wires up an LlmAgent
with an empty `instruction=` and removes the implicit dependency on
the static instruction being non-empty.
2026-04-27 12:52:53 -07:00
Alem Tuzlak ebb9247ccb style(google-adk): drop unnecessary {} fallback in state spreads
eslint-plugin-unicorn no-useless-fallback-in-spread — spreading
undefined into an object literal is a no-op, so '?? {}' is redundant.
Functionally identical, silences the lint warning.
2026-04-27 12:52:53 -07:00
Alem Tuzlak 5d3269c113 fix(google-adk): preserve static instruction + persisted notes
Two related issues surfaced in Round 4 review of the ADK showcase:

1. The before-model callbacks in agent_config_agent,
   readonly_state_agent_context_agent, and shared_state_read_write_agent
   guarded the empty-write branch with `if not new_text and original is
   None`. That missed the case where `original` is a non-None Content
   with empty text — possible after stripping a prior block that was
   the entire Content. In that branch the callback wrote
   Content(text=""), clobbering the LlmAgent's static `instruction=`.
   Tightened the guard to `if not new_text: return None`.

2. The shared-state-read-write seed effect spread the observed agent
   state but unconditionally assigned `notes: []`, wiping any
   backend-persisted notes when the user landed without persisted
   preferences. Falls back to `agentState?.notes ?? []` instead.
2026-04-27 12:52:52 -07:00
Alem Tuzlak d1d5a936b1 fix(showcase/google-adk): CR Round 3 — splice prior block, fail-loud guards, sanitize errors, spread state writes
Round 3 confirmation found bugs Round 2's fixes left behind in the same
files. All fixes target subject-scoped + load-bearing concerns.

bucket (a) findings:

A1 (strip-prior-block content loss): all three before-model-callback
agents (\`agent_config_agent\`, \`readonly_state_agent_context_agent\`,
\`shared_state_read_write_agent\`) sliced
\`original_text[end_idx + len(END_MARKER):]\` to remove the prior
injected block. That dropped content from index 0 to sig_idx as well —
fine for the steady-state pattern where our block is at position 0,
but if any other middleware ever prepends content to system_instruction
between turns, that prefix would be silently lost. Splice instead:
\`original_text[:sig_idx] + original_text[end_idx + len(END_MARKER):]\`.

A2 (empty-block + empty-original still rewrites system_instruction):
when both \`block\` is None and \`original\` is None, the callbacks were
still writing \`Content(role="system", parts=[Part(text="")])\`,
overwriting whatever the LlmAgent's \`instruction=\` field would have
contributed. Added an early return for that case so the static
instruction passes through.

A3 (sub-agent error message exposes raw exception text):
\`_invoke_sub_agent\` was raising
\`_SubAgentError(f"sub-agent call failed: {exc.__class__.__name__}: {exc}")\`.
\`{exc}\` for genai HTTP errors can include URLs, request IDs, partial
credentials, and quota details. The error string lands in
\`state["delegations"][i].result\` and ships to the public Railway
deploy. Sanitized to surface only \`exc.__class__.__name__\` to clients;
\`logger.exception\` keeps the full trace + str(exc) server-side.

A4 (agent.setState seed/handler effects clobber unrelated state keys):
\`agent.setState({ config: INITIAL_CONFIG })\` and the matching prefs
seed/handlers replaced the whole state object rather than merging. If
the runtime adds any other keys (e.g. \`copilotkit\` for the read-only
context middleware, future framework additions), they were wiped on
every config write. Now spread the observed state on every write.

A5 (\`_build_prefs_block\` missing the empty-recognized-keys guard): a
truthy prefs dict containing only unrecognized keys (schema drift /
forward-extension UI prop) would still emit a block consisting only of
\`[SIG, "Tailor every response to these preferences. ADDR_USER_BY_NAME"]\`,
i.e. directives without directives. Added the same
\`if len(lines) == 1: return None\` guard already present in
\`agent_config_agent._format_config\` and
\`readonly_state_agent_context_agent._format_context\`.

Bucket (b) defensive items applied:

- subagents \`_invoke_sub_agent\` parts extraction: dropped the redundant
  \`if content is not None\` ternary; \`getattr(None, "parts", None)\`
  already returns the default.

Starter regenerated.

Call-site enumeration:
- splice path inside \`_inject_config\`/\`_inject_context\`/
  \`_inject_preferences\`: signature unchanged; only callers are the
  matching LlmAgent before_model_callback bindings.
- \`_SubAgentError\` constructor message format changed (still str
  argument): consumers stringify it via str(exc); behaviour unchanged
  apart from the redacted exception body.
- \`agent.setState\` payloads in agent-config + shared-state-read-write
  pages: consumed only by the matching runtime route per page; the
  spread shape is a superset of the prior shape, so backend callbacks
  see the same fields plus any pre-existing keys (which they already
  read defensively).
- \`_build_prefs_block\` early-return: only consumer is
  \`_inject_preferences\` in the same module; new return path is None,
  same as the existing \`not prefs\` early return.
2026-04-27 12:52:52 -07:00
Alem Tuzlak 6323ccf205 fix(showcase/google-adk): CR Round 2 — fix bugs introduced by Round 1 + remaining bucket (a) cleanups
Round 2 (confirmation) surfaced bugs in code my Round 1 fixes touched.

bucket (a) findings:

- subagents_agent._update_delegation: dropped the synthetic
  \`sub_agent: "unknown"\` fallback I added in Round 1. The frontend's
  \`Delegation.sub_agent\` union is
  \`research_agent | writing_agent | critique_agent\`; an "unknown" value
  fell through SUB_AGENT_BADGE_CLASS / SUB_AGENT_LABEL maps and rendered
  as \`undefined\` text + className. Now we log loudly and skip — no row
  beats a malformed row.

- subagents_agent._invoke_sub_agent: cleaned up the
  \`getattr(content, "parts", None) or [] if content is not None else []\`
  ternary. \`getattr(None, ...)\` already returns the default, so the
  outer conditional was dead.

- agent_config_agent._format_config: added \`if len(lines) == 1: return None\`
  guard before appending CONFIG_END_MARKER. A truthy config dict with no
  recognized keys (schema drift / future-extension forwardedProps) was
  emitting a meaningless [SIGNATURE, END_MARKER] block telling the LLM
  to "Honour every directive above" with zero directives. Mirrors the
  same guard in readonly_state_agent_context_agent._format_context.

- delegation-log.tsx: added STATUS_BADGE_CLASS + STATUS_LABEL maps and
  a status-derived border-color so running/completed/failed entries are
  visually distinguishable. Without this, my Round 1 backend fix that
  actually emits all three states had no UI signal — every entry was
  the same muted gray. Now: amber spinner + "running…" while the
  sub-agent works, emerald on completion, red on failure.

- hitl-in-app/page.tsx: added an unmount cleanup that rejects every
  still-pending approval (with reason "user navigated away before
  responding") so the agent's tool-call promises never orphan when
  the user leaves the page mid-approval. Also added \`key={head.id}\`
  on ApprovalDialog so any future local state in the dialog component
  is per-request rather than leaking from one approval to the next as
  the head rotates.

- tool-rendering-custom-catchall: aligned the renderer's status type
  with what the runtime + page actually emit. The runtime's
  DefaultRenderProps status enum is
  \`"inProgress" | "executing" | "complete"\` and the page collapses both
  pre-completion variants to "executing"; there is no "incomplete"
  state today. The renderer's \`"incomplete"\` branch was unreachable
  dead code from a copy-paste of an older type. Narrowed the prop type
  to \`"executing" | "complete"\` and dropped the dead branch.

- manifest.yaml highlight arrays: 7 demos with dedicated runtime
  routes (a2ui-fixed-schema, declarative-gen-ui, byoc-json-render,
  byoc-hashbrown, auth, open-gen-ui, open-gen-ui-advanced) were
  pointing at the unified \`src/app/api/copilotkit/route.ts\` instead
  of their own dedicated route file. Documentation drift the showcase
  tooling uses to render source listings — pointed each at its real
  route. Also added \`src/app/demos/auth/demo-token.ts\` to the auth
  highlight list so the bundled demo-token note is visible alongside
  the page.

bucket (b) cheap items applied:

- AgentSpec.predict_state: \`Iterable\` → \`Sequence\`. A one-shot
  generator passed by mistake would empty after the first request;
  Sequence forces a re-iterable container. Module-level lists already
  satisfy this contract.

Starter regenerated to keep drift-check green.

Call-site enumeration:
- \`STATUS_BADGE_CLASS\`, \`STATUS_LABEL\`, \`ENTRY_BORDER_BY_STATUS\`
  (new): private to \`delegation-log.tsx\`.
- \`pendingQueueRef\` (new): private to hitl-in-app/page.tsx unmount cleanup.
- \`_update_delegation\` signature unchanged; only the missing-entry
  branch behaviour changed (no longer appends).
- \`AgentSpec.predict_state\` widened constraint
  (Iterable→Sequence): only consumed in agent_server.py's
  ADKAgent construction; passing a list still satisfies Sequence.
- CustomCatchallRendererProps.status narrowed
  (executing|complete|incomplete → executing|complete): only
  consumer is the page in the same demo folder; it now passes a
  matching union.
2026-04-27 12:52:52 -07:00