Commit Graph

14241 Commits

Author SHA1 Message Date
Nathan 🔶 Tarbert 3f632a1859 Revise Angular quickstart link in README
Updated the Angular section to include 'Source Code & Quickstart' instead of 'Source Code - Quickstart coming soon'.
2026-07-23 11:53:11 -04: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 cd0b5b4061 fix(angular): address SDK review findings 2026-07-23 07:48:25 -07:00
Lukas Moschitz f3d01b83c7 fix(showcase): align langgraph-fastapi frontend chrome with langgraph-python
Task 1 of OSS-582 (frontend parity). Bring the app chrome + beautiful-chat
byte-identical to the langgraph-python north star:
- globals.css: adopt LGP theme (@theme inline tokens + green palette)
- middleware.ts: add (was missing) — sets x-pathname like LGP
- layout.tsx: adopt LGP structure; keep FastAPI in title/log (identity carve-out)
- beautiful-chat/page.tsx: sync stale doc comment

Also fix a Dockerfile parity gap: fastapi was missing the COPY manifest.yaml
that LGP has. demos/layout.tsx reads manifest.yaml at request time via
generateMetadata (headers() -> dynamic), so without it every /demos/* route
crashed with an RSC render error (ENOENT /app/manifest.yaml).
2026-07-23 16:26:52 +02: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
Manfred Steyer b3de484be1 feat(angular): MCP Apps activity renderer
Adds the opt-in secondary entry point @copilotkit/angular/mcp-apps for
rendering MCP Apps (MCP ext-apps) inline in the chat:

- CopilotMCPAppsActivityRenderer plus a ready-to-register
  mcpAppsActivityRendererConfig for activityType mcp-apps
- CopilotMCPAppsWidget loads the app's ui:// resource from the configured
  MCP server, embeds it in a sandboxed iframe, and connects an AppBridge
  that relays tool input/result, size changes, links, and log messages
- provideMCPApps registers server URLs and the host identity, capabilities,
  and context announced to embedded apps
- @modelcontextprotocol/sdk and @modelcontextprotocol/ext-apps are optional
  peer dependencies; the main entry point stays free of MCP imports

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
renovate[bot] 962f494183 chore(deps): update ruby/setup-ruby action to v1.321.0 (#6122)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [ruby/setup-ruby](https://redirect.github.com/ruby/setup-ruby) |
action | minor | `v1.320.0` → `v1.321.0` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/592) for more information.

---

### Release Notes

<details>
<summary>ruby/setup-ruby (ruby/setup-ruby)</summary>

###
[`v1.321.0`](https://redirect.github.com/ruby/setup-ruby/releases/tag/v1.321.0)

[Compare
Source](https://redirect.github.com/ruby/setup-ruby/compare/v1.320.0...v1.321.0)

##### What's Changed

- Add jruby-10.1.1.0 by
[@&#8203;ruby-builder-bot](https://redirect.github.com/ruby-builder-bot)
in [#&#8203;932](https://redirect.github.com/ruby/setup-ruby/pull/932)

**Full Changelog**:
<https://github.com/ruby/setup-ruby/compare/v1.320.0...v1.321.0>

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/Los_Angeles)

- Branch creation
  - "before 9am every weekday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/CopilotKit/CopilotKit).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNzUuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI3NS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
2026-07-23 13:36:13 +00:00
Alem Tuzlak ca5773b3df feat(showcase/built-in-agent): close final D6 backend gaps (a2ui-recovery exhaust + multimodal PDF)
- a2ui-recovery: add opt-in createA2UIRecoveryAgent() — generate_a2ui runs a
  validate->retry loop and, once the attempt cap is hit with only invalid
  surfaces, returns the { code: 'a2ui_recovery_exhausted', error, attempts }
  envelope the A2UI middleware paints as the graceful failure card. Wired only
  into the a2ui-recovery route; createDeclarativeGenUIAgent behavior unchanged.
  D6 EXHAUST turn now green.
- multimodal: add opt-in createMultimodalAgent() that flattens PDF document
  parts to text server-side via unpdf (TS equivalent of LGP's pypdf) through a
  new opt-in preprocessMessages hook on createBuiltInAgent (default pass-through,
  other demos byte-identical). D6 PDF turn now green.
- deps: add unpdf for server-side PDF text extraction.

Both fixes opt-in; shared factory defaults unchanged. next build + Docker
rebuild + D6 probes all green.
2026-07-23 15:35:14 +02:00
Lukas Moschitz fa0392f3e5 feat(showcase): add fe-parity.ts frontend parity checker
Diffs an integration's frontend surface (all src/** UI files except
src/agents/** and src/app/api/**, tests, qa) against a reference
integration (default langgraph-python) byte-for-byte, normalizing
integration identity (manifest name/slug) so name-only differences
report as IDENTITY rather than DRIFT. Exits 0 when the frontend is
byte-identical modulo the integration's own name. Supports --md
(markdown audit), --full, --all (fleet ranking), --verbose, --ref.

Complements the structural-only validate-parity.ts. Zero-dependency;
runs on node 23+ directly or via tsx.
2026-07-23 14:43:45 +02:00
Alem Tuzlak dc0ee47f4c fix(showcase): D6 red fixes for built-in-agent (shared-state-read green; recovery/multimodal partial)
- shared-state-read: remove spurious turnIndex:0 on the turn-2 fixture entry
  (turnIndex counts assistant msgs = 1 on turn 2, so the constraint could never
  match -> turn 2 dom-missing). Now D6 GREEN.
- a2ui-recovery: register built-in-agent heal/exhaust prompts in the shared
  probe PROMPTS (new demo BIA lacked) + add its aimock fixture. HEAL turn now
  GREEN; EXHAUST still red pending a backend factory change (emit the
  a2ui_recovery_exhausted envelope) — tracked, not fixable at fixture layer.
- multimodal: fix conversation-runner skipSend baseline (snapshot run-start
  BEFORE preFill, since preFill issues the run on skipSend turns; fast
  in-process runtimes else false-red done-signal-missing). Image turn now
  GREEN; PDF turn still red (BIA runtime has no document/PDF flattening path).

NOTE: conversation-runner.ts is a SHARED harness helper — change is guarded to
skipSend turns (non-skipSend byte-identical) and only corrects the baseline;
flagged for harness-owner review.
2026-07-23 14:28:29 +02:00
Alem Tuzlak 94a23c6bf4 fix(showcase/built-in-agent): byte-identical globals.css (theme tokens for shadcn/AI-Elements)
BIA's globals.css was a 17-line stub missing LGP's @theme inline Tailwind-v4
token map + the :root design-token palette (--background/--card/--primary/
--muted/--accent/--radius + CopilotKit brand vars). Without it every shadcn /
AI-Elements / prompt-kit primitive fell back to unstyled — most visible on
beautiful-chat. Copy LGP's globals.css verbatim so the byte-identical demo
frontends render with the correct theme.
2026-07-23 12:01:15 +02:00
renovate[bot] a2ec6723bf chore(deps): update ruby/setup-ruby action to v1.321.0 2026-07-23 08:56:27 +00:00
shixi-li abcefa1bdb fix(react-core): forward credentials to provisional agents 2026-07-23 16:13:51 +08:00
Jordan Ritter 9b0f9f12e7 chore: remove social copy generator workflow (#6119)
Kills the "📣 Social Copy Generator" bot comment that lands on every PR.
The comment (e.g.
https://github.com/CopilotKit/CopilotKit/pull/6117#issuecomment-5053084113)
is posted by the `post-comment` job in
`.github/workflows/social_copy-generator.yml`, and the
checkbox-triggered `generate` job lives in the same file — the whole
feature was self-contained there, so deleting the one workflow removes
all of it.

After removal, `git grep -i "social copy"`, `git grep -i "social media
copies"`, and `git grep "copy-generator"` all come back empty — no
scripts, prompts, or docs referenced it anywhere else.
2026-07-22 18:23:57 -07:00
Jordan Ritter 3bc5a2961c chore: remove social copy generator workflow 2026-07-22 18:12:55 -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 828bfeb5e1 docs: clarify the Rich Threads journey (#6111)
## Summary

Introduces Rich Threads as the documentation front door for persistent,
resumable agent conversations and guides developers from setup through
UI choice, user scoping, production deployment, and history
synchronization.

## What changed

### Rich Threads overview

- Presents the approved Support Desk screenshot and light/dark
user-journey diagrams.
- Moves cloud-hosted Enterprise Intelligence setup near the top with
both a coding-agent prompt and direct CLI steps.
- Defines Rich Threads around durable AG-UI event history, including
messages, generative UI, multimodal inputs, tool activity, state, and
live-run continuity.
- Explains Threads Drawer versus Headless Threads and links to the
appropriate implementation guide.
- Describes production self-hosting with a direct CopilotKit Engineering
contact path.
- Adds an end-user scoping FAQ linked to detailed `identifyUser`
guidance.

### Implementation and lifecycle

- Documents Threads Drawer for both CLI-created starters and existing
CopilotKit applications.
- Keeps Headless Threads as the custom-UI path and adds user-scoping and
production self-hosting guidance.
- Adds the server-side `identifyUser` contract, separating application
identity from the project Runtime API key.
- Keeps Thread & History Lifecycle and Threads & Persistence
Architecture in the Rich Threads navigation group.

### History synchronization

- Renames the generic guide to **Import & Synchronize Thread History**
and the navigation label to **Synchronize Thread History**.
- Provides dedicated **Synchronize ADK Threads** and **Synchronize
LangGraph Threads** guides.
- Documents one-time historical import followed by future
CopilotKit-mediated persistence.
- Explains that native ADK or LangGraph persistence and analytics can
remain in place when the durable native mechanism stays connected.
- Corrects the importer destination contract: dry runs need no
destination credentials; real imports read flags or exported process
environment values.

### Framework coverage

- Applies shared Rich Threads navigation and content across root,
authored, generated, built-in, and framework-specific routes.
- Keeps existing URLs and implementation identifiers unchanged; no
redirects are required.
- Uses shared sources rather than hand-editing generated framework data.

### Measurement

- Adds conversion events for the coding-agent prompt, CLI setup command,
self-hosting contact, Drawer customization, and history synchronization.

## Validation

- [x] Formatting for all files changed by this PR
- [x] Lint (existing repository warnings only)
- [x] Typecheck
- [x] Tests (33 files, 180 tests)
- [x] Production build
- [x] Desktop/mobile and light/dark browser review across representative
root, authored, generated, built-in, ADK, and LangGraph routes
2026-07-22 16:11:30 -07:00
Sam Julien e8ba4b4045 Merge remote-tracking branch 'origin/main' into codex/ent-1130-rich-threads-docs 2026-07-22 15:47:26 -07: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
Ben Taylor d8e98c0116 fix(examples): adk-angular a11y (closed chat inert) + dev inspector out of prod bundle (#6110)
Two issues found in review after `examples/integrations/adk-angular`
merged (#6097).

## 1. Closed chat stayed keyboard-accessible off-screen
The collapsible chat panel is only translated off-screen (`transform:
translateX(100%)`), so its `copilot-chat` inputs/buttons remained in the
tab order and the accessibility tree while "closed."

**Fix:** mark the `<aside>` `inert` while closed
(`[attr.inert]="chatOpen() ? null : ''"`); removed when open.

## 2. Dev inspector shipped in the production bundle
The `cpk-web-inspector` dev aid (and its `@copilotkit/web-inspector`
dependency, ~660 kB) was statically imported, so it landed in the **4.59
MB** production initial bundle.

**Fix:** gate it behind `@defer (when isDev)` (`isDev = isDevMode()`),
splitting it into a lazy chunk that a production build (`isDev` = false)
never loads.

## Testing (live)

- **Prod build** (`ng build`): initial bundle **4.59 MB → 3.93 MB**;
`@copilotkit/web-inspector` is now a separate lazy chunk (660 kB) that
prod never loads.
- **Dev serve**: the inspector still mounts (`@defer` triggers when
`isDev`).
- **a11y**: with the chat closed, focusing a control inside the panel is
blocked (`document.activeElement` falls back to `body`); open panel
unaffected; the toggle FAB still reopens it.
- `oxlint` 0/0.

Follow-up to OSS-561.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-22 16:37:47 -05: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
Benjamin Taylor d5ad1efcd0 fix(examples): adk-angular a11y + keep dev inspector out of the prod bundle
Two issues found after the example merged:

1. The closed chat panel is only translated off-screen, so its inputs/buttons
   stayed in the tab order and the a11y tree. Mark the <aside> `inert` while
   closed (`[attr.inert]`), so focus/AT skip it; removed when open.
2. The dev web inspector (and its @copilotkit/web-inspector dep, ~660 kB) shipped
   in the production initial bundle. Gate it behind `@defer (when isDev)` so it's
   split into a lazy chunk that a prod build (isDev=false) never loads.

Verified: prod `ng build` initial bundle 4.59 MB -> 3.93 MB with web-inspector now
a lazy chunk; dev serve still mounts the inspector; closed-panel focus is blocked
(activeElement falls back to body), open panel unaffected.
2026-07-22 12:01:41 -05:00
Ben Taylor 747f2cb25d feat(examples): add Angular + ADK integration example (adk-angular) [OSS-561] (#6097)
## What & why

Adds the first **Angular** scaffoldable integration example:
`examples/integrations/adk-angular/` — an Angular 21 SPA wired to a
Google ADK agent over AG-UI, a peer to the React
`examples/integrations/adk`. Angular support is selective (ADK first),
so this surfaces as a new **"Angular + ADK"** entry in `copilotkit init`
(CLI wiring is a companion PR in the Intelligence repo).

## Architecture — 3 processes

Angular is a SPA, so (unlike the Next.js React example, which hosts the
runtime in an API route) the runtime lives in a standalone Node server —
the documented `@copilotkit/angular` pattern.

| Process | Port | Source |
| --- | --- | --- |
| Angular app (`ng serve`) | 4200 | `src/` |
| Copilot Runtime (`tsx server.ts`) | 8200 | `server.ts`
(`createCopilotNodeListener`) |
| Python ADK agent (`uv`) | 8000 | `agent/` — copied from
`examples/integrations/adk` |

One `npm run dev` runs all three via `concurrently`.

## Feature parity with the React ADK example

- Shared agent state (proverbs) via `injectAgentStore` +
`agent.setState`
- Generative UI (weather card) via `renderToolCalls`
- Frontend tool (`setThemeColor`) via `registerFrontendTool`
- Static suggestions (the same 5)
- Threads drawer + env-gated managed Intelligence
(`CopilotKitIntelligence` when `COPILOTKIT_LICENSE_TOKEN` is set, else
`InMemoryAgentRunner` — matching the React `route.ts` gating)
- Dev web inspector (`cpk-web-inspector`), matching the richer React
examples

### Two behaviors that required real fixes (found via live testing, not
static review)

1. **Frontend tools now reach the ADK agent.** `setThemeColor` silently
failed because the ADK agent's tools were static and `ag_ui_adk` only
forwards client tools when the agent includes an `AGUIToolset()`
placeholder. Added it (this affected the React `adk` example identically
— fixed there in a companion PR).
2. **The weather generative-UI card now renders.** A `renderToolCalls`
entry scoped with `agentId` filtered the server-side tool call out;
removed it.

## Chat UI — floating, React-`CopilotSidebar`-style

Angular has no `CopilotSidebar`, so the chat is a hand-rolled
collapsible panel that mirrors React's behavior:

- **Docks + pushes** the content when there's room (viewport ≥ 1200px:
starts expanded, content reflows beside the chat via a right margin),
and **overlays** on narrower screens so the content isn't smushed by the
threads drawer's push.
- Toggle/close match React's `CopilotChatToggleButton` /
`CopilotModalHeader`: lucide `MessageCircle` FAB (bottom-right) to open;
lucide `X` in the panel header to close; no bottom-right "X" (the open
panel covers the FAB, exactly like React).
- Layout uses a global `box-sizing: border-box` reset (React/Next get
this from Tailwind's preflight) so cards don't clip on small screens.

## Dependency

Requires **`@copilotkit/angular@0.2.0`** (published; it carries the
threads drawer + `provideCopilotChatConfiguration`).
`runtime`/`core`/`shared` pinned to `1.63.1` — matches
`@copilotkit/angular@0.2.0`'s own deps (verified: no duplicate
`@copilotkit/core`).

## Testing

`ng build` green; `oxlint` 0/0; a 4-round 7-agent CR loop converged to
zero findings.

Verified **live against the hosted Intelligence platform + a real Gemini
key**:

- **Managed Intelligence connects:** `/api/copilotkit/info` → `mode:
intelligence`, `licenseStatus: valid`, full `threadEndpoints`
(list/inspect/mutations/realtimeMetadata), realtime `wsUrl`.
- **Threads render:** the drawer loads the org's persisted threads with
pagination.
- **Shared state:** proverbs seed on load; add / update / read via chat
all round-trip and update the card.
- **Frontend tool + generative UI:** "set the theme to teal, then get
the weather in Paris" recolors the panel **and** renders a teal-themed
weather card in the chat.
- **Responsive:** dock-and-push at ≥1200px (content beside the chat, 0
overflow); overlay + starts-closed below; no clipping at 580 / 1050 /
1200 / 1400.

Not exercised: nothing outstanding — the previously-untested agent/tool
paths are now confirmed live. (`GOOGLE_API_KEY` is required for live
agent runs; the scaffold + build don't need it.)

## Follow-ups (not in this PR)

- Companion: **CopilotKit/Intelligence** CLI PR adds the `adk-angular`
framework; **CopilotKit/CopilotKit#6107** ports the `AGUIToolset` fix to
the React `adk` example.
- Inherited-from-React demo-quality items (fail-loud on missing
`INTELLIGENCE_API_KEY`, the `.sh || .bat` / `dev:debug` Windows /
`postinstall`-uv script patterns, the agent's broad `except` / dead
`ProverbsState` / prompt typos) — cross-example cleanup.
- Docs: the ADK quickstart/cookbook should note `AGUIToolset()` is
required for frontend tools.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-22 11:46:54 -05:00
Benjamin Taylor 5a27e2ecbb feat(examples): adk-angular chat docks + pushes content when there's room
When the viewport is wide enough (>=1200px) the chat starts expanded and DOCKS:
.layout--pushed adds a right margin equal to the chat width so the proverbs
content reflows beside the chat instead of being covered (mirrors React's
CopilotSidebar margin-inline-end push). Below the breakpoint the chat starts
closed and OVERLAYS on open, so narrow screens aren't smushed.

- DOCK_BREAKPOINT_PX (1200) gates the initial open state; a matching
  @media (min-width:1200px) rule applies the push margin
- --chat-width var keeps the panel width and push margin in sync

Verified live: 1400px starts expanded, content pushed beside the chat (right
929 <= chat left 960), 0 overflow; 1000px starts closed, opening overlays with
no push and no overflow.
2026-07-22 09:25:18 -05:00
Alem Tuzlak 8f4e0b97a2 docs(showcase/built-in-agent): declarative-gen-ui + mcp-apps confirmed D6-green
Both were suspected downstream-host RED; per-demo probes against a context-scoped
aimock confirm GREEN. declarative-gen-ui: cross-slug shadowing was the sole cause
(a2ui-fixed-schema passes on the same host). mcp-apps: fixed via the create_view
elements JSON-string fixture correction. Update manifest note + PARITY_NOTES to
the resolved state.
2026-07-22 16:09:14 +02:00
Alem Tuzlak 14f0af7dd5 fix(showcase/built-in-agent): mcp-apps create_view elements arg must be a JSON string
Excalidraw's MCP create_view tool declares `elements` as a string (JSON-encoded
array) in its inputSchema; the fixtures emitted a raw JSON array. BIA declares
the injected MCP tool locally via jsonSchemaToZod -> z.string(), so the array
failed input validation, the tool never executed against excalidraw, no
ACTIVITY_SNAPSHOT fired, and the MCP Apps iframe never mounted (D6 red).
Stringify the elements arg to match the inputSchema. Verified D6 green.
Same latent fix applied to the flowchart pill in mcp-apps.json.
2026-07-22 16:06:02 +02:00
Benjamin Taylor 336bcdbf6c fix(examples): match React's toggle FAB — MessageCircle only, covered when open
Previously the FAB swapped to an X when open and sat above the panel, so an open
chat showed TWO X's (header + bottom-right). React never does that: its toggle
FAB is always a MessageCircle, and the sidebar (z-1200) covers the FAB (z-1100)
when open, so the only visible close is the header X.

- FAB icon is always MessageCircle (no X swap)
- chat panel z-index 1200 > FAB 1100, so an open panel covers the FAB

Verified live: OPEN shows only the top-right header X (FAB covered); CLOSED shows
the bottom-right MessageCircle FAB to reopen. No bottom-right X in either state.
2026-07-22 08:41:44 -05:00