Mirror of #3868 by @Abubakar-01.
Wraps `agent.runAgent(...)` in a `useEffect` with an empty dependency
array in both the docs and showcase MDX files, and adds a prose warning
explaining why calling `runAgent` directly in the component body causes
"thread is already processing" errors.
## Summary
Resolves the recurring `docs-sync` manual-review flag on
`integrations/mastra/agent-app-context.mdx` by applying the sync
script's clean-transform to bring the showcase copy in line with
upstream, plus a small typo fix.
- Typo: `useCopilotReadble` → `useCopilotReadable` (both files)
- Clean-transform sync: restores 2 code-block imports
(`useAgentContext`, `useState` — both actually used in the example on
lines 40 + 32), normalizes whitespace
- Bumps `showcase/shell/.docs-sync-sha` from `41b6eb93` to `0e7811402`
## Note
There is an existing auto-generated PR #4044 covering this same file
(plus 2 aws-strands files). Close that PR after merging this one; the
aws-strands files will be handled by a separate future sync run once the
updated workflow (see branch `ci/docs-sync-auto-pr`) is merged.
## Test plan
- [ ] CI green
- [ ] Post-merge: `npx tsx showcase/scripts/sync-docs-from-main.ts
--dry-run` no longer flags this file for review
Feature matrix (generative-ui category):
- Order: Controlled Gen-UI (Display) -> (Interactive) / In-Chat HITL
-> (Interrupt) -> Declarative Generative UI (A2UI) -> MCP Apps
-> Fully Open-Ended Generative UI -> Agentic Generative UI
(In-Chat State Rendering) -> Tool Rendering.
- Merge `hitl-in-chat` with the Controlled Gen-UI (Interactive) idea;
drop the unused `gen-ui-interactive` placeholder.
- Merge standalone `a2ui` entry into Declarative Generative UI (A2UI);
drop the duplicate.
- Rename `gen-ui-agent` display to "Agentic Generative UI (In-Chat
State Rendering)". Moved `tool-rendering` next to it.
- Rename `gen-ui-tool-based` display from "Controlled Generative UI"
to "Controlled Gen-UI (Display)". Dropped the placeholder
`gen-ui-display` entry (was zero-use).
Agentic chat demo (langgraph-python):
- Removed the "Weather in SF" suggestion and the associated
`useRenderTool`/`get_weather` code. The slimmed agent has no backend
tools, so this demo is now pure chat -- just `CopilotChat`, a user
context tag, and one sonnet suggestion.
Regenerated registry + demo-content.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of #4009 by @MalaikaAbb.
The PR restructures the Agent Spec quickstart into two paths (starter
template vs. existing agent) using `TailoredContent`.
**Applied fixes:** corrected the `CopilotSidebar` import in the
"bring-your-own" path from `@copilotkit/react-core/v2` to
`@copilotkit/react-ui`.
## Summary
Makes the docs-sync workflow auto-open a PR on showcase-local conflicts
instead of warn-and-skip. User asked for this after seeing drift
accumulate because manual-review alerts got ignored.
## Behavior
- **Clean transforms / auto-merges**: unchanged fast path — commits to
main via auto_push + auto-merge.
- **Showcase-local conflict**: best-effort 3-way merge via `git
merge-file`. On conflict, upstream-wins content is applied only on the
PR branch (main worktree untouched). Auto-opens a
`docs-sync/needs-review/*` PR tagged `[NEEDS REVIEW]` with auto-merge
disabled — human must review + merge. Slack posts a "⚠️" alert
with PR link.
- **Dedupe**: if an open needs-review PR exists, skip creating a new one
and post a "ℹ️" Slack alert pointing at the existing
PR.
- **Sync SHA marker**: only advances when no conflicts (and no
deletions) exist this run. Ensures the next run still detects the same
drift until human merges.
## Hardening (addressed across 4 commits + 7-agent CR rounds)
- Shell injection: all `execSync` with template-literal interpolation →
`execFileSync` with argv arrays.
- Missing Slack notify for needs-review PRs: added with correct gating.
- Silent re-resolution: upstream-wins content no longer leaks to main
worktree; applied via `conflict-manifest.json` only on PR branch.
- PR collision on re-runs: explicit dedupe check with retry on transient
`gh` API errors (fails the step rather than silently duplicating).
- Exit code / marker logic fixed so auto_push fast path works for clean
merges.
- `stripTrailingEol` + BOM handling for whitespace idempotency.
- Emit `review_items_file` output to `$GITHUB_OUTPUT` so PR body
correctly includes the review-items list.
- Explicit `needs_review=true/false` set on all exit paths including
collision + early-exit, so `notify-auto-sync` doesn't misfire.
- Trap-based cleanup of temp artifacts on signal kill.
## Test plan
- [ ] CI green
- [ ] Post-merge: next docs-sync run with a local conflict opens a
needs-review PR (instead of warn-and-skip)
Rework the Controlled Generative UI demo to be minimal, self-contained,
and render charts via `useComponent`.
Frontend (`src/app/demos/gen-ui-tool-based/`):
- `page.tsx` -- `CopilotKit` + full-screen `CopilotChat` (no sidebar),
two `useComponent` registrations (`render_bar_chart`,
`render_pie_chart`), three chart-oriented suggestions.
- `bar-chart.tsx`, `pie-chart.tsx` -- ported from
`examples/integrations/langgraph-python`. Each file reads top-to-
bottom as imports -> schema -> props type -> component; colors and
animation helpers are inlined inside the component. No shared
chart-config module.
- Haiku card + schema removed.
Agent (`src/agents/main.py`):
- Rewritten using `create_agent` + `CopilotKitMiddleware()` so the
LangGraph middleware injects the frontend `render_*_chart` tools into
the model request at runtime.
- Deleted all backend-tool modules (`tools.py`, `todos.py`,
`a2ui_dynamic_schema.py`, `a2ui_fixed_schema.py`). System prompt
trimmed to a data-viz assistant.
Peripheral cleanups:
- `demos/agentic-chat/page.tsx` -- `change_background` tool + its
suggestion removed; it had nothing to do with chat.
- New `demos/frontend-tools/` (In-App Actions) hosts
`change_background` as its own demo with a `frontend_tools` agent
name registered in `api/copilotkit/route.ts`.
- Stub `gen-ui-tool-based/agent.py` removed.
- `generate-starters.test.ts` no longer requires every python package
to have backend tool imports -- a package with only frontend tools
(like this controlled-gen-ui demo) is now valid.
- Whitelist generated shell data (`demo-content.json`,
`search-index.json`, `starter-content.json`) in check-binaries hook
-- they're generated artifacts like `package-lock.json`.
- Regenerated `demo-content.json` + `registry.json`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Grid polish:
- Light-mode palette (white surface, slate borders, dark text); dropped
the dark-theme tokens.
- Rows are every declared feature, even ones with zero current support.
Empty rows surface feature gaps we want to fill -- hiding them hides
the TODO.
- Cells: `demo · code` as tight blue text links, `-` for supported but
no demo, red `✗` for unsupported. No colored pill buttons.
- Sticky first column + sticky header row. Hover highlight replaces
striped rows.
Internal sort order:
- New `src/lib/sort-order.ts` -- slug -> rank map used only by this app
(intentionally not in the public registry). Orders columns LangChain
first, then Google/MS/AWS, then the rest. Explicitly internal.
- `getIntegrations()` in lib/registry.ts sorts by this map with a
fallback to the registry's `sort_order`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a single command to spin up the exact image Railway deploys,
for any of the 17 showcase packages, with a single shared .env:
./showcase/scripts/dev-local.sh up [<slug> ...] # all if empty
./showcase/scripts/dev-local.sh down|build|logs|ps|ports
Pieces:
- `docker-compose.local.yml` with a service per package. Ports come
from `shared/local-ports.json` (langgraph-python -> 3100, ...).
- `.env.example` as a commit-safe template. Real `.env` is gitignored
and fed to every container via `env_file`, so keys (OPENAI_API_KEY,
etc.) live in one place.
- `dev-local.sh` wraps `docker compose` and handles the
`shared_python/` / `shared_typescript/` staging step that CI does
before `docker build` (see showcase_deploy.yml).
- Staged `shared_*` dirs added to .gitignore.
Shell wiring:
- `shell/next.config.ts` reads `shared/local-ports.json` when
`SHOWCASE_LOCAL=1` is set and injects it as a public env.
- `/integrations/[slug]/[demo]/preview` uses that map to iframe
`http://localhost:<port>` instead of `integration.backend_url`.
Per-slug; any slug not running locally falls back to Railway.
Unset SHOWCASE_LOCAL -> prod behavior, unchanged.
Full workflow + prerequisites (Colima / Docker Desktop) documented in
showcase/README.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The scaffolded BFF hits two bugs on first `pnpm dev`:
- `tsx` doesn't auto-load `.env` and the template's `.env` lives at the
monorepo
root, so `process.env.COPILOTKIT_LICENSE_TOKEN` is undefined and the
runtime
warns "No license token configured" even when `.env` is populated by the
CLI.
- `@copilotkit/runtime: next` currently resolves to `1.55.0-next.9`,
which
predates the thread-naming UUID fix (v1.55.3). The BFF fails with
`Invalid thread ID: must be a UUID` when LangGraph receives the compound
`thread-name:<uuid>:<uuid>` string the runtime used to emit.
The scaffolded BFF was hitting two issues out of the box:
1. tsx doesn't auto-load .env, and the template's .env lives at the
monorepo root. process.env.COPILOTKIT_LICENSE_TOKEN was undefined
at runtime so the runtime logged 'No license token configured'
even when the user had populated .env via `copilotkit license`.
2. @copilotkit/runtime: next resolved to 1.55.0-next.9, which
predates the thread-naming UUID fix (v1.55.3). The BFF blew up
creating LangGraph threads with 'Invalid thread ID: must be a
UUID' because the runtime passed a compound thread-name:<uuid>:
<uuid> string.
Fix both:
- Switch dev script to `tsx watch --env-file=../../.env src/server.ts`
so tsx loads the monorepo root .env.
- Pin @copilotkit/runtime to `latest` so scaffolds get the
thread-naming fix. (The next dist-tag is still stale on npm.)
Mirror of #4038 by @MalaikaAbb.
**Review:** All identifier corrections look correct — `agentId` values
in the MDX docs now match the actual agent `name` fields defined in the
Python backend code, and the built-in agent ID change from "assistant"
to "default" is consistent with the runtime's default naming.
**Included:**
-
`docs/content/docs/integrations/aws-strands/generative-ui/state-rendering.mdx`
-
`docs/content/docs/integrations/aws-strands/shared-state/in-app-agent-read.mdx`
- `docs/content/docs/integrations/built-in-agent/shared-state.mdx`
**Excluded (kept in #4038):**
- `docs/lib/integration-features.ts`
- `packages/cli/src/utils/version.ts`
Assumed these are unrelated to the docs fix and excluded them from the
mirror. If any are required, please update #4038.
langgraph-python, langgraph-fastapi, and langgraph-typescript starters run
langgraph_cli dev which exposes /ok (not /health). The template now probes
/health, so the generator must rewrite this back to /ok for langgraph-* only,
otherwise drift-check fails and regenerating would break those starters'
health routes.
Mirror of #3866 by @Abubakar-01.
**Review:** Both doc files correctly updated: `runtimeContext` renamed
to `requestContext`, mismatched quote in the colleagues description
string fixed, optional chaining added on `colleaguesContextItem?.value`,
and `id` field added to the agent config — all changes are consistent
and accurate across both files.
## Summary
- Point the `langgraph-python-threads` demo's `docker-compose.yml` at
published images on ECR Public
(`public.ecr.aws/cpk/intelligence/{app-api,db-migrations,realtime-gateway}:0.1.0-rc.5`)
instead of `cpki/*:local` images that had to be built from the
intelligence repo.
- Drop the "build local images first" prerequisite from the compose
header
and README step 5.
## Why
The demo previously required cloning the intelligence repo and running
`./scripts/build-local-images.sh` before `docker compose up` would work
—
a non-starter for external users evaluating the template. The published
ECR Public images are anonymously pullable, so `docker compose up -d
--wait`
now works out of the box.
Switch docker-compose to pull app-api, db-migrations, and realtime-gateway
from public.ecr.aws/cpk/intelligence/* at tag 0.1.0-rc.5 instead of locally
built cpki/*:local images, and drop the build-local-images prerequisite
from the README and compose header.
Next.js 15.4.10's turbopack panics ("Next.js package not found") on the
repo's multi-lockfile layout. Webpack dev works; production builds are
unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces a new internal-facing showcase app (`showcase/shell-internal`)
that renders a feature × integration grid. Each cell links to one of two
new canonical standalone routes on the main `shell` app:
- `/integrations/[slug]/[demo]/preview` — iframe-only hosted demo
- `/integrations/[slug]/[demo]/code` — code viewer; supports `?file=<name>`
and `?lines=<start>-<end>` URL params for future line-highlighting
Keeping the canonical pages in `shell` means they can also be embedded in
docs/marketing; `shell-internal` is a pure overview with no duplicated
content (reads `shell/src/data/registry.json` directly).
Also drops `--turbopack` from `shell`'s dev script: Next.js 15.4.10's
turbopack panics on the repo's multi-lockfile layout. Webpack dev works
fine and this doesn't affect production builds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
- Adds `.github/workflows/update-branch.yml` — a labeled-event workflow
that updates a PR's branch with its base when the `qa:update-branch`
label is applied.
- Removes the label after running so the bot can re-apply it on the next
cycle.
- Infrastructure-only change; enables a QA bot to keep PRs current
without human intervention.
## Behavior
1. Bot adds `qa:update-branch` label to any PR.
2. Workflow calls the GitHub `updateBranch` API (same as the "Update
branch" button).
3. Workflow removes the label (in a `finally` block, so it clears even
if the update fails).
Uses the namespaced `qa:` prefix to avoid collisions and leave room for
future bot actions (`qa:triaged`, etc.).
## Test plan
- [ ] Merge this PR.
- [ ] On a separate out-of-date PR, apply the `qa:update-branch` label
and confirm the workflow runs, updates the branch, and removes the
label.
- [ ] Confirm the workflow does nothing when unrelated labels are added.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
pull_request runs in the fork context with restricted permissions, which
would block the updateBranch API call. pull_request_target runs in the
base repo with full permissions — the label trigger is safe since no
checkout of PR code happens here.
Also treat 422 responses (already up to date, nothing to merge) as
informational rather than job failures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Triggers on the qa:update-branch label being added to a PR, calls the
GitHub update-branch API to merge the base into the PR, and removes the
label so it can be re-applied. Enables the QA bot to keep PRs current
without human intervention.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
- Flatten **langgraph-python**, **langgraph-js**, and **mcp-apps**
starters from pnpm/Turborepo monorepos to flat npm projects so `npm
install && npm run dev` works out of the box
- Replace Turborepo with `concurrently` for running dev processes in
parallel
- Move `apps/*` contents to root level, agents/servers to root-level
subdirectories
- Update Dockerfiles, docker-compose files, entrypoints, READMEs, and
.gitignore files
- Remove stray `pnpm-lock.yaml` from **a2a-a2ui** and
**ms-agent-framework-dotnet** starters
- Fix `.gitignore` in langgraph-python and ms-agent-framework-dotnet to
stop ignoring `package-lock.json`
### Before (monorepo structure)
```
apps/
├── app/ # or web/
└── agent/ # or threejs-server/
pnpm-workspace.yaml
turbo.json
```
### After (flat npm project)
```
src/ or app/ # Next.js app at root
agent/ # or threejs-server/
scripts/ # setup + run scripts
package.json # concurrently-based dev scripts
```
## Test plan
- [ ] `npx copilotkit create test-app --framework langgraph-py` creates
a working project
- [ ] `npx copilotkit create test-app --framework langgraph-js` creates
a working project
- [ ] `npx copilotkit create test-app --framework mcp-apps` creates a
working project
- [ ] `npm install && npm run dev` works in each created project
- [ ] Docker builds still work (`docker compose -f
docker-compose.test.yml up`)
Previously schemaHint in HookBundlePayload was always {kind: 'none'} — the
webview received empty form fields and users couldn't edit args. The captured
config object in the registry already carries the real parameters (V1 array
or V2 Zod schema), so we infer the FormSchema from it directly in the webview.
Changes:
- New form/schema/infer-from-config.ts: inferFormSchemaFromConfig(config)
inspects config.parameters, branches to v1ParametersToFormSchema for
arrays, standardSchemaToFormSchema for objects with ~standard vendor, or
returns empty fields. Same detection rules as extractSchemaHint in the
extension host but applied to live runtime data.
- App.tsx: resolve captured config in a useMemo, derive schema from that
config, seed controls once the config is available. Dropped the unused
buildSchema() + schemaHint-based derivation. Removed the duplicate
findConfig call later in the component (now reads from the memo).
- 4 new tests cover V1 array, Zod, missing parameters, and garbage inputs.
Net effect: clicking a useCopilotAction or useRenderTool now renders the
real args form (string/number/boolean/enum inputs) instead of an empty
controls column.
- registry.ts: expose CapturedRenderFn, CapturedRenderToolCall, CapturedTool,
and CapturedCoAgentStateRender with explicit render/parameters/name fields
instead of ad-hoc { [key: string]: unknown } wildcards. Consumers (App.tsx,
the mount-capture test) can now read .render, .parameters, .name typed.
- mount-capture test: drop the duplicate CapturedAction type, use the new
CapturedRenderToolCall directly. Also add a removeTodo lookup assertion —
locks in that the reader captures both actions from the same component's
effect (catches regressions where only the first registration is seen).
The node-resolve-fallback plugin short-circuited all Node builtins to external,
overriding any override the caller might have wanted. Callers who want to
polyfill a builtin at runtime (e.g. pass 'buffer' through a browser shim via
the existing external list) now have the final say: if opts.external matches
the specifier, the plugin returns null and lets rolldown route the resolution
through the caller's external rule set.
The prior save handler triggered scanWorkspace() on every .ts/.tsx save, which
is O(workspace) per save — painful in large monorepos. Replace with:
- HookTreeDataProvider.updateSitesForFile(filePath): re-scan the saved file
only and splice its sites into the cached allSites list. Full rebuild of
the displayed tree happens from the flat list (cheap compared to walking
the filesystem).
- Per-file debounce map with a 250ms window: batches rapid-fire saves
(format-on-save followed by manual save, or auto-save streams) into a
single rescan per file. Cleared on extension deactivation.
No change to semantics beyond timing — the tree converges to the same state
as the prior full rescan, just without touching unrelated files.
- Extract HookNode / HookTreeStatus / buildTreeData / statusKeyForSite /
findLeaf into a new tree-model.ts that doesn't import vscode. Tests can
now exercise the pure model without vi.mock('vscode').
- view-provider.ts becomes the VS Code adapter layer (TreeDataProvider,
getTreeItem, event emitter). It re-exports the model types for source
compatibility with existing consumers.
- setStatus now fires _changeEmitter with the affected leaf instead of a
full refresh. VS Code re-reads only that leaf's getTreeItem, preserving
the user's expand/collapse state elsewhere in the tree.
- Tests: drop vi.mock, add coverage for findLeaf (hit + miss) and the key
format of statusKeyForSite (named vs line fallback). 163 tests total.
Previously the test mutated an outer-scope variable inside waitFor and
relied on the non-null assertion downstream. Refactor to return the
resolved value from waitFor — the testing-library idiom — so there's no
time-dependent outer state and no '!' assertion after the await.
Introduces a minimal CapturedAction type so the test stops carrying a
duplicate '{ render?: unknown; [k: string]: unknown }' cast inline.