## Summary
- Update default CODEOWNERS reviewers to: @tylerslaton @jpr5 @ranst91
@marthakelly @mme
- Remove @arielweinberger, @ataibarkai, and @suhasdeshpande from
reviewers
- Update showcase path-specific rule to match the new reviewer list
Detect Zod v4 schemas by checking for a toJSONSchema() method on the
schema object. When present, call it directly instead of routing through
zod-to-json-schema (which cannot handle Zod v4 internals).
Priority order:
1. Standard JSON Schema V1 (~standard.jsonSchema.input)
2. Zod v4 native (schema.toJSONSchema())
3. Zod v3 fallback (injected zodToJsonSchema)
Removes the dead vendor === "zod4" check (Zod v4 reports "zod") and
the _def duck-typing fallback (unnecessary with toJSONSchema detection).
Closes#3636
Replace TODO placeholders in all 73 QA checklist files across 17 showcase
packages with specific, actionable test steps derived from reading the
actual demo page source code. Each checklist now references real
data-testid selectors, hook names, expected UI states, and interaction
flows.
Add showcase/QA-COVERAGE.md with a comprehensive matrix showing coverage
across manual QA, Vitest unit tests, Playwright E2E (smoke and interaction),
per-package E2E, aimock fixtures, and CI automation for all 9 demos plus
the Sales Dashboard starter hero.
## Summary
- All non-langgraph Python starters were broken because they tried to
run `uvicorn agent.<module>:app` but those modules don't export a
FastAPI `app` — the demo packages use `agent_server.py` as the FastAPI
wrapper
- Copies `agent_server.py` from each demo package into the starter root,
rewriting `from agents.` to `from agent.` for the starter directory
layout
- Updates all non-langgraph Python `devScript` entries to use
`agent_server:app`
- Updates `Dockerfile.python` template to `COPY agent_server.py` and
`getEntrypointBlock()` to use `agent_server:app`
- Fixes `langgraph-fastapi` to use `langgraph_cli dev` like
`langgraph-python` (it was incorrectly configured as a uvicorn-based
starter when it actually uses a langgraph.json graph config)
- All starters regenerated, `--check` mode passes, 537 tests pass
## Test plan
- [x] `npx tsx generate-starters.ts --check` passes
- [x] `nx test @copilotkit/showcase-scripts` — 537 tests pass
- [ ] Deploy a non-langgraph Python starter (e.g. pydantic-ai) to
Railway and verify it starts
The truthiness check swallowed null, which is a valid value in
react-markdown that explicitly disables the default URL sanitizer.
Changed to an explicit undefined check.
- Add `satisfies OnAfterRequestOptions` for compile-time type safety (consistent with onBeforeRequest)
- Replace `(m: any)` casts with type predicates and explicit `as unknown as Message[]`
- Add TODO comment for hardcoded empty properties
- Expand test to verify all 6 fields of OnAfterRequestOptions
- Add edge case tests for undefined messages and missing threadId/runId
- Mark parameters as optional when null is present in the type union
- Add matching null-union handling to convertJsonSchemaToZodSchema
- Add 7 tests covering null-union edge cases for both converters
Move hasReceivedContent flag inside each content block type handler
so that skipped unknown tool_use blocks do not prevent the fallback
response mechanism from activating. Add tests for unknown tool
skipping behavior.
Extract shared helpers to reduce duplication and centralize unavoidable
casts. Add simulateSetState to mock controller to eliminate double-casts
in the new onStateChanged test. Promote mockClipboard to describe scope
to remove navigator clipboard cast in assertion. Add try/catch error
handling to syncAgentMessages and syncAgentState.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Python starters were trying to run uvicorn with agent.<module>:app but
those modules don't export a FastAPI app. The demo packages use
agent_server.py as the FastAPI wrapper, so starters need it too.
Changes:
- Copy agent_server.py from each demo package into starter root,
rewriting "from agents." to "from agent." for the starter layout
- Update all non-langgraph Python devScripts to use agent_server:app
- Update Dockerfile.python to COPY agent_server.py for non-langgraph
- Update getEntrypointBlock() generic Python to use agent_server:app
- Make langgraph-fastapi use langgraph_cli dev like langgraph-python
(it was incorrectly configured as a uvicorn-based starter)
- Regenerate all starters
Cover the MCP adapter scenario where content arrives as an array of
{type:"text", text:string} objects, and verify non-text parts are
filtered out during normalization.
## Summary
- **drift-detection**: Split inline payload into `jq`-built file +
`payload-file-path`; sanitize playwright output (strip ANSI, head -3,
cap 200 chars)
- **starter-smoke**: Replace `toJSON(format(...))` double-encoding with
`jq` payload builder
- **showcase_deploy**: Replace 300-char inline ternary with readable
shell conditional + `jq`
All three workflows now use the same pattern: build a sanitized JSON
file with `jq -n`, then reference it via `payload-file-path`. This
eliminates raw `%0A` in Slack messages, unformatted stack traces, and
double-encoded JSON.
## Test plan
- [ ] Trigger `showcase_drift-detection.yml` manually — verify Slack
alert formats correctly on failure
- [ ] Trigger `starter-smoke.yml` manually — verify Slack alert on a
known-failing starter
- [ ] Trigger `showcase_deploy.yml` with `service: shell` — verify
deploy notification renders cleanly
- [ ] Confirm no `%0A` or raw escape sequences appear in any Slack
message
Use jq to build JSON payloads safely and payload-file-path to avoid
inline multiline content. Limits error context to 3 lines, strips ANSI
codes, and caps field length at 200 chars.
- drift-detection: split payload build from post, sanitize playwright output
- starter-smoke: replace toJSON(format(...)) double-encoding with jq
- showcase_deploy: replace 300-char inline ternary with readable shell conditional
## Summary
- The langgraph-python starter crashes on Railway because `langgraph_cli
dev --config agent/langgraph.json` can't resolve module paths when
agents live in `agent/` with `dependencies: ["."]` pointing to `/app`
- Restructured starter to match the demo package's **proven working
layout**: agents in `src/agents/`, `langgraph.json` at project root,
entrypoint referencing root config
- Templatized `Dockerfile.python` with `{{AGENT_DIR}}` and
`{{DOCKER_EXTRA_COPY}}` variables so the generator handles different
agent directory structures
- Updated tests to use framework `agentDir` instead of hardcoding
`"agent"`
- All 17 starters regenerated, 518 tests passing
## Test plan
- [ ] Deploy langgraph-python starter to Railway — should return 200
like the demo package
- [ ] Verify other Python starters still build/deploy (Dockerfile
template changed for all)
- [ ] `npx tsx generate-starters.ts --check` passes
- [ ] All vitest suites pass: generate-starters.test.ts (248) +
starter-consistency.test.ts (270)
## Summary
- Shell: starter section breaks out to `max-w-[90rem]` (1440px) while
header/demos stay at `max-w-5xl` (1024px) — gives the dashboard +
sidebar room to breathe
- Starter: renderer selector bar gets `sticky top-0 z-[60]` — stays
visible and clickable above the CopilotKit sidebar (z-50)
- All 17 starters regenerated with sticky header
## Summary
- **Fix concurrency group**: Manual dispatches targeting different
services no longer cancel each other. Push events still cancel stale
deploys (same group), but `workflow_dispatch` runs for different
services get unique groups and run independently.
- **Add post-deploy health check**: After Railway deploy, polls the
service health endpoint (6 attempts over ~90s). Non-blocking for
sleep-on-idle services but logs clearly for visibility.
- **Enhance Slack notification**: Now includes service count and names
in both success and failure messages, plus guards against empty webhook
secret.
When using selfManagedAgents, calling agent.setState() directly only
fires onStateChanged — the inspector subscribed to onStateSnapshotEvent
(pipeline-only) but not onStateChanged, leaving the "Current State"
panel permanently stale. Add onStateChanged handler mirroring the
existing onMessagesChanged pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
- Starter globals.css: `overflow: hidden` → `overflow: auto` so
dashboard content scrolls inside the iframe
- Shell iframe: fixed `600px` → `min(80vh, 900px)` for responsive
scaling with viewport
The "Add a deal" button and CopilotKit sidebar were getting cut off in
the 600px iframe.
Updated JSDoc and troubleshooting docs to accurately describe that
the client-side debug prop forwards config to the AG-UI transport
layer, not CopilotKit's own logging. Removed fabricated console.debug
output examples that don't exist.
debug was only read at construction time. Added setDebug() to
CopilotKitCore and added it to the provider's prop-sync useEffect
so runtime changes to the debug prop take effect.
createLogger() was called on every request when debug was enabled,
instantiating a new pino + pino-pretty stream each time. Now creates
a single logger in the runtime constructor and passes it to handlers.
Added test verifying pre-created logger is reused.
Debug config was silently dropped because ProxiedCopilotRuntimeAgentConfig
had no debug field. Now stores it in the constructor, resolves it in
AgentRegistry before passing, and clone() preserves it. Added 6 tests
verifying the full threading chain.
When users pass the boolean shorthand `debug: true`, verbose previously
defaulted to true, logging full event payloads including user messages,
tool args, and state snapshots. Now defaults to false — users must
explicitly opt in with `debug: { verbose: true }`.
The langgraph-python starter crashes on Railway because of a directory
structure mismatch: agents were in agent/ with langgraph.json inside
agent/, causing langgraph_cli to fail resolving module paths.
Match the demo package's working layout:
- Move agents from agent/ to src/agents/ (same as demo)
- Put langgraph.json at project root (same as demo)
- Point entrypoint at root langgraph.json instead of agent/langgraph.json
- Templatize Dockerfile.python with AGENT_DIR and DOCKER_EXTRA_COPY vars
- Skip langgraph.json path rewriting when agentDir matches agentSourceDir
- Update tests to use framework agentDir instead of hardcoding "agent"
Regenerate all 17 starters.
## Summary
- **Component bug fix:** `CopilotChatReasoningMessage` auto-collapse
`useEffect` unconditionally called `setIsOpen(false)` when streaming
ended, overriding any manual expand/collapse the user had performed.
Added a `userToggledRef` that tracks explicit clicks so the effect only
auto-collapses when the user hasn't interacted.
- **Flaky test fix:** `CopilotChat.e2e.test.tsx` reasoning toggle test
used `fireEvent.click` without `act()`, causing React 18 to defer the
state update through its scheduler. This raced with `waitFor` polling on
slow CI runners (Node 20.x/22.x), producing nondeterministic failures
across multiple PRs.
## Test plan
- [x] Existing reasoning message tests pass with both fixes applied
- [x] Pre-commit hooks (lint, format, test, build) pass
- [ ] Verify intermittent CI failures on unit (20.x/22.x) no longer
reproduce
Note: This fixes the intermittent unit test failures that have been
appearing across multiple unrelated PRs.