ROOT CAUSE of the recurring BrowserPool collapse: the long-lived harness container runs a single Node process that launches chromium repeatedly under sustained d6 cron load (init fill, hygiene recycles, crash-recovery relaunches). Every chromium.launch() Playwright performs mkdtemp's TWO ephemeral dirs under the OS temp dir — a `playwright_chromium*dev_profile-*` userDataDir and a `playwright-artifacts-*` dir — and with `--disable-dev-shm-usage` (passed by the harness AND a Playwright default) chromium routes its shared-memory/cache I/O into that profile dir under /tmp instead of /dev/shm. Playwright removes those dirs in the child process's `close` handler, but the removal is BEST-EFFORT: processLauncher logs-and- swallows any removeFolders failure (ENOSPC, EBUSY, a hung close on a wedged chromium, the Node process being signalled). Over hours the orphaned `playwright_*` dirs accumulate MONOTONICALLY in the container's /tmp until the filesystem exhausts inodes/space — at which point chromium can no longer create its profile dir and dies INSTANTLY on startup, so EVERY launch throws `browserType.launch: Target page, context or browser has been closed`. The set empties, self-heal relaunches into the SAME exhausted /tmp, and the pool wedges PERMANENTLY — only a container restart (fresh /tmp) clears it. PREVENTION (distinct from #5234's circuit-breaker, which only PURGES after the wedge has already taken the fleet down): proactively sweep stale `${tmpdir()}/playwright_*` dirs on a cadence — once at init() and on every recycle relaunch — so /tmp never reaches exhaustion. The sweep is AGE-GATED (only dirs whose mtime is older than staleProfileDirTtlMs, default 5 min): a dir for a launch in flight or a live browser is touched continuously and is far younger than the TTL, so the sweep can NEVER delete a dir still in use. Both the TTL and the sweep impl are env/option-tunable; the sweep is fire-and-forget (never on a launch's critical path) and best-effort (failures logged, never fatal). EVIDENCE: confirmed empirically that each chromium.launch() creates 2 playwright* temp dirs and that graceful close removes them, while a failed/ swallowed cleanup orphans them; corroborated by the recurring staging signature (every launch throws "Target page ... has been closed", self-heal-launch-failed repeating, only a restart recovers) captured in the in-flight circuit-breaker work. Red-green tests: assert the sweep fires at init and on every recycle (crash + hygiene), that across 30 recycle cycles /tmp stays bounded at ~2*browserCount instead of growing 2-per-cycle, and that the real defaultSweepStaleProfileDirs removes an hour-old orphan while NEVER deleting a fresh (in-use) dir or a non-playwright dir. All four fail without the wiring.
CopilotKit
Build agent-native applications with generative UI, shared state, and human-in-the-loop workflows.
What is CopilotKit
CopilotKit is a best-in-class SDK for building full-stack agentic applications, Generative UI, and chat applications.
We are the company behind the AG-UI Protocol - adopted by Google, LangChain, AWS, Microsoft, Mastra, PydanticAI, and more!
https://github.com/user-attachments/assets/72b7b4f3-b6e7-460c-a932-5746fe3c8db3
Features:
- Chat UI – A React-based chat interface that supports message streaming, tool calls, and agent responses.
- Backend Tool Rendering – Enables agents to call backend tools that return UI components rendered directly in the client.
- Generative UI – Allows agents to generate and update UI components dynamically at runtime based on user intent and agent state.
- Shared State – A synchronized state layer that both agents and UI components can read from and write to in real time.
- Human-in-the-Loop – Lets agents pause execution to request user input, confirmation, or edits before continuing.
https://github.com/user-attachments/assets/55bf6714-62a7-4d5d-9232-07747cc0763b
Quick Start
New projects:
npx copilotkit@latest create -f <framework>
Existing projects:
npx copilotkit@latest init
https://github.com/user-attachments/assets/7372b27b-8def-40fb-a11d-1f6585f556ad
What this gives you:
- CopilotKit installed – Core packages are fully set up in your app
- Provider configured – Context, state, and hooks ready to use
- Agent <> UI connected – Agents can stream actions and render UI immediately
- Deployment-ready – Your app is ready to deploy
Complete getting started guide →
How it works:
CopilotKit connects your UI, agents, and tools into a single interaction loop.
This enables:
- Agents that ask users for input
- Tools that render UI
- Stateful workflows across steps and sessions
⭐️ useAgent Hook
The useAgent hook is a proper superset of useCoAgent and sits directly on AG-UI, giving more control over the agent connection.
// Programmatically access and control your agents
const { agent } = useAgent({ agentId: "my_agent" });
// Render and update your agent's state
return <div>
<h1>{agent.state.city}</h1>
<button onClick={() => agent.setState({ city: "NYC" })}>
Set City
</button>
</div>
Check out the useAgent docs to learn more.
https://github.com/user-attachments/assets/67928406-8abc-49a1-a851-98018b52174f
Generative UI
Generative UI is a core CopilotKit pattern that allows agents to dynamically render UI as part of their workflow.
https://github.com/user-attachments/assets/3cfacac0-4ffd-457a-96f9-d7951e4ab7b6
Compare the Three Types
Explore:
Generative UI educational repo →
🖥️ AG-UI: The Agent–User Interaction Protocol
Connect agent workflow to user-facing apps, with deep partnerships and 1st-party integrations across the agentic stack—including LangGraph, CrewAI, and more.
npx create-ag-ui-app my-agent-app
🤝 Community
Have questions or need help?
Join our Discord →Read the Docs →
Try Copilot Cloud →
Stay up to date with our latest releases!
Follow us on LinkedIn →Follow us on X →
🙋🏽♂️ Contributing
Thanks for your interest in contributing to CopilotKit! 💜
We value all contributions, whether it's through code, documentation, creating demo apps, or just spreading the word.
Here are a few useful resources to help you get started:
-
For code contributions, CONTRIBUTING.md.
-
For documentation-related contributions, check out the documentation contributions guide.
-
Want to contribute but not sure how? Join our Discord and we'll help you out!
Install as a Claude Code plugin
The CopilotKit monorepo doubles as a Claude Code plugin — all 9 skills (3 package meta-skills + 6 lifecycle journey skills) are available once installed.
Add the repo as a Claude Code marketplace:
claude plugin marketplace add https://github.com/CopilotKit/CopilotKit
claude plugin install copilotkit
Skills are discovered from skills/<slug>/SKILL.md at the repo root. The three package meta-skills (runtime, react-core, a2ui-renderer) are generated mirrors of the source-of-truth files at packages/<pkg>/skills/<pkg>/ — do not edit the mirror directly. To update content, edit the source under packages/*/skills/ and run:
pnpm sync:plugin-skills
A lefthook pre-commit check (pnpm check:plugin-skills) rejects commits that drift the mirror. The plugin version is pinned to packages/runtime/package.json and is also kept in sync by the same script.
Skill inventory
| Slug | Type | Source |
|---|---|---|
runtime |
core | packages/runtime/skills/runtime/ |
react-core |
framework | packages/react-core/skills/react-core/ |
a2ui-renderer |
framework | packages/a2ui-renderer/skills/a2ui-renderer/ |
0-to-working-chat |
lifecycle | skills/0-to-working-chat/ |
spa-without-runtime |
lifecycle | skills/spa-without-runtime/ |
go-to-production |
lifecycle | skills/go-to-production/ |
scale-to-multi-agent |
lifecycle | skills/scale-to-multi-agent/ |
v1-to-v2-migration |
lifecycle | skills/v1-to-v2-migration/ |
debug-and-troubleshoot |
lifecycle | skills/debug-and-troubleshoot/ |
📄 License
This repository's source code is available under the MIT License.