{"owner":"Chainlit","repo":"chainlit","hasSkills":true,"totalSkillsCount":4,"totalTokensCount":4788,"categories":["root-instruction","anthropic-skill","claude-rule","copilot-instructions"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md",".shared/skills/karpathy-guidelines/SKILL.md","CLAUDE.md",".github/copilot-instructions.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to AI agents when working with code in this repository.\n\n## Backward Compatibility (CRITICAL)\n\nAll changes **MUST** be backward-compatible. If a refactor or breaking change is unavoidable, notify the user and stop — do not proceed without explicit approval. When approved, prefer adding a compatibility layer over keeping legacy code in place.\n\n## MCP-First Approach (CRITICAL)\n\nWhen available, **ALWAYS** prefer MCP servers over manual alternatives. Use **Context7** for docs/API references, **Serena** for code navigation/refactoring/memory, and **GitHub MCP** for issues/PRs/actions/commits/releases/code search. Fall back to CLI tools, direct file reads, or web searches **ONLY IF** the corresponding MCP is unavailable or cannot fulfill the request.\n\n## Overview\n\nChainlit is a Python framework for building production-ready conversational AI applications. It consists of a Python/FastAPI backend and a React frontend, with a pnpm monorepo for the JS packages.\n\n## Prerequisites\n\n- Python: **3.13** (3.10+ is the framework's minimum, but development targets 3.13)\n- Node.js: **24+**\n- [uv](https://docs.astral.sh/uv/) — Python package manager\n- [pnpm 9](https://pnpm.io/) — Node.js package manager (Corepack)\n\n## Quick Start\n\n### Install\n\n|          | Command                | Directory  |\n| -------- | ---------------------- | ---------- |\n| Backend  | `uv sync --all-extras` | `backend/` |\n| Frontend | `pnpm install`         | repo root  |\n\n### Build\n\n|                   | Command                                      | Directory  | What it does                                                                              |\n| ----------------- | -------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------- |\n| All JS packages   | `pnpm build`                                 | repo root  | Build all workspace packages (frontend, react-client, copilot) via `pnpm run --recursive` |\n| Backend (PyPI)    | `uv build`                                   | `backend/` | Build Python package — builds JS assets first, then bundles into the Python distribution  |\n| Single JS package | `pnpm --filter @chainlit/react-client build` | repo root  | Build one package (useful for publishing)                                                 |\n\n### Dev servers\n\n|          | Command                                           | Directory   | URL                                      |\n| -------- | ------------------------------------------------- | ----------- | ---------------------------------------- |\n| Backend  | `uv run chainlit run chainlit/sample/hello.py -h` | `backend/`  | http://localhost:8000                    |\n| Frontend | `pnpm run dev`                                    | `frontend/` | http://localhost:5173 (proxies to :8000) |\n\n### Tests\n\n|                       | Command                            | Directory   |\n| --------------------- | ---------------------------------- | ----------- |\n| Backend (all)         | `uv run pytest --cov=chainlit/`    | `backend/`  |\n| Backend (single file) | `uv run pytest tests/test_file.py` | `backend/`  |\n| Frontend unit         | `pnpm test`                        | `frontend/` |\n| E2E (Cypress)         | `pnpm test`                        | repo root   |\n\n### Lint & Format\n\n|                     | Command                            | Directory |\n| ------------------- | ---------------------------------- | --------- |\n| Lint JS/TS          | `pnpm lint`                        | repo root |\n| Lint fix JS/TS      | `pnpm lint:fix`                    | repo root |\n| Format check JS/TS  | `pnpm format-check`                | repo root |\n| Format fix JS/TS    | `pnpm format`                      | repo root |\n| Lint Python         | `uv run scripts/lint.py`           | repo root |\n| Lint fix Python     | `uv run scripts/lint.py --fix`     | repo root |\n| Format check Python | `uv run scripts/format.py --check` | repo root |\n| Format fix Python   | `uv run scripts/format.py`         | repo root |\n\nJS/TS lint and format commands accept file/directory arguments: `pnpm lint frontend/`, `pnpm format-check:files frontend/src/App.tsx`. Python scripts also accept file arguments: `uv run scripts/lint.py backend/chainlit/server.py`.\n\n### Type checking\n\n|            | Command                        | Directory |\n| ---------- | ------------------------------ | --------- |\n| Python     | `uv run scripts/type_check.py` | repo root |\n| TypeScript | `pnpm type-check`              | repo root |\n\nType checking runs on whole projects (no per-file mode).\n\nRun `pnpm lint:fix` and `pnpm format` before committing — CI enforces checks on both.\n\n### Commits\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/). Format: `<type>(<optional scope>): <description>`.\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `ci`. Scope is optional but encouraged (e.g. `fix(data): ...`, `feat(i18n): ...`).\n\nAll commits made with AI assistance **must** include a `Co-Authored-By` trailer identifying the AI agent. Add it as the last line of the commit message body:\n\n```\nCo-Authored-By: <Agent Name> <agent-email-or-noreply>\n```\n\nExamples:\n\n- `Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>`\n- `Co-Authored-By: GitHub Copilot <noreply@github.com>`\n- `Co-Authored-By: Gemini CLI <noreply@google.com>`\n\n## Tech Stack\n\n| Layer                          | Stack                                                                                                                     |\n| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |\n| **Frontend**                   | React 18, TypeScript 5.2, Vite 5, Tailwind CSS 3, Vitest, Zod 3                                                           |\n| **Frontend (state & routing)** | Recoil, React Router 6, react-hook-form, socket.io-client, SWR                                                            |\n| **Frontend (rendering)**       | react-markdown + remark-gfm/math + rehype-katex/raw, highlight.js, lucide-react (icons), Radix UI (primitives), Plotly.js |\n| **Backend**                    | Python 3.13, FastAPI, Starlette, Uvicorn, python-socketio, Pydantic 2, PyJWT, httpx                                       |\n| **LLM integrations**           | MCP, LangChain, LlamaIndex, OpenAI SDK, Semantic Kernel, MistralAI                                                        |\n| **Infra / persistence**        | SQLAlchemy (PostgreSQL/SQLite), DynamoDB + S3 (boto3), Azure Blob / Data Lake, Google Cloud Storage, LiteralAI            |\n| **DX**                         | pre-commit hooks, linting, formatting, type checking, unit testing, E2E testing                                           |\n\n## Architecture\n\n### Monorepo structure\n\n```\nbackend/          # Python package (published to PyPI as \"chainlit\")\nfrontend/         # React app (built output served by backend)\nlibs/\n  react-client/   # @chainlit/react-client — published npm package with React hooks\n  copilot/        # Copilot widget (embedded chat bubble)\ncypress/          # E2E tests\n```\n\nThe pnpm workspace includes `frontend/`, `libs/react-client/`, and `libs/copilot/`. The built frontend assets are copied into `backend/chainlit/frontend/dist/` and served as static files.\n\n### Backend (`backend/chainlit/`)\n\n**Entry point for user apps**: `__init__.py` re-exports all public API decorators and classes.\n\n**Key files:**\n\n- `server.py` — FastAPI app, all REST routes (auth, elements, threads, file upload), serves the built frontend SPA, mounts the SocketIO app\n- `socket.py` — SocketIO event handlers for real-time WebSocket communication (connect, message, audio, etc.)\n- `callbacks.py` — Decorator functions registered via `@cl.on_message`, `@cl.on_chat_start`, `@cl.on_audio_chunk`, etc. These store functions on `config.code.*`\n- `config.py` — Reads `.chainlit/config.toml` from `APP_ROOT`. `ChainlitConfig` holds both static TOML config and runtime user-registered callbacks. `APP_ROOT` defaults to `os.getcwd()`.\n- `session.py` — `WebsocketSession` (per-connection state: user, files, MCP connections, message queue) and `HTTPSession`\n- `context.py` — `ChainlitContext` per-coroutine context variable (similar to thread-local), providing access to the current session and emitter\n- `emitter.py` — Sends events back to the frontend through the SocketIO session\n- `data/base.py` — `BaseDataLayer` ABC for persistence (threads, steps, elements, users, feedback). Implementations: `sql_alchemy.py`, `dynamodb.py`, `literalai.py`\n- `auth/` — JWT creation/validation (`jwt.py`), OAuth state cookies (`cookie.py`)\n- `types.py` — Shared Pydantic models for API request/response types\n\n**Data layer pattern**: The data layer is optional (no persistence by default). Register a custom implementation with `@cl.data_layer` decorator or use the built-in SQLAlchemy/DynamoDB/LiteralAI implementations. The `@queue_until_user_message()` decorator on `BaseDataLayer` methods queues write operations until the first user message arrives.\n\n**Integrations**: `langchain/`, `llama_index/`, `openai/`, `semantic_kernel/`, `mistralai/` — each provides callback handlers that bridge those frameworks into Chainlit steps/messages.\n\n### Frontend (`frontend/src/`)\n\nReact 18 + TypeScript + Vite, styled with Tailwind CSS and Radix UI primitives.\n\n- `main.tsx` — React root, wraps app in `RecoilRoot` and `ChainlitContext.Provider`\n- `App.tsx` — Handles auth readiness, chat profile selection, and WebSocket connection lifecycle\n- `router.tsx` — Client-side routes: `/` (Home), `/thread/:id`, `/element/:id`, `/login`, `/login/callback`, `/share/:id`, `/env`\n- `state/` — Recoil atoms: `chat.ts` (messages, elements, tasks), `project.ts` (config, session), `user.ts` (env vars)\n- `components/chat/` — Core chat UI (message list, input bar, elements, audio)\n- `components/header/` — Top navigation bar\n- `components/LeftSidebar/` — Thread history sidebar\n\n### `@chainlit/react-client` (`libs/react-client/src/`)\n\nPublishable npm package — the bridge between the React UI and the backend WebSocket.\n\n- `api.ts` — `ChainlitAPI` class: HTTP calls to backend REST endpoints\n- `useChatSession.ts` — Manages socket.io connection lifecycle\n- `useChatMessages.ts` — Exposes message tree state\n- `useChatData.ts` — Exposes elements, actions, tasklists, connection status\n- `useChatInteract.ts` — `sendMessage`, `replyMessage`, `callAction`, `stopTask`, `clear`\n- `state.ts` — Recoil atoms shared between the lib and consuming apps\n\nState is managed via Recoil; consuming apps must wrap the tree in `<RecoilRoot>` and provide a `ChainlitAPI` instance via `ChainlitContext.Provider`.\n\n### Communication flow\n\n1. User sends a message → `useChatInteract.sendMessage` → emits `client_message` over SocketIO\n2. Backend `socket.py` handler receives it → calls `config.code.on_message(message)`\n3. User's app calls `cl.Message(...).send()` → `emitter.py` emits `new_message` back over SocketIO\n4. Frontend `useChatMessages` updates Recoil state → component re-renders\n\n### App configuration\n\nApps configure Chainlit via `.chainlit/config.toml` (created automatically on first run). Key sections: `[project]` (auth, session timeouts, CORS), `[UI]` (name, theme, layout).\n\n---\n\n## Documentation Verification Requirements\n\nBefore writing/modifying code, verify against official docs.\n\n**Lookup order**: Context7 MCP (preferred) → WebFetch → WebSearch.\n\nPre-resolved Context7 library IDs: [docs/context7.md](docs/context7.md)\n\nCross-reference API signatures and patterns during implementation. When uncertain, always check docs rather than relying on training data.\n",".shared/skills/karpathy-guidelines/SKILL.md":"---\nname: karpathy-guidelines\ndescription: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.\nlicense: MIT\n---\n\n# Karpathy Guidelines\n\nBehavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.\n\n**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.\n\n## 1. Think Before Coding\n\n**Don't assume. Don't hide confusion. Surface tradeoffs.**\n\nBefore implementing:\n\n- State your assumptions explicitly. If uncertain, ask.\n- If multiple interpretations exist, present them - don't pick silently.\n- If a simpler approach exists, say so. Push back when warranted.\n- If something is unclear, stop. Name what's confusing. Ask.\n\n## 2. Simplicity First\n\n**Minimum code that solves the problem. Nothing speculative.**\n\n- No features beyond what was asked.\n- No abstractions for single-use code.\n- No \"flexibility\" or \"configurability\" that wasn't requested.\n- No error handling for impossible scenarios.\n- If you write 200 lines and it could be 50, rewrite it.\n\nAsk yourself: \"Would a senior engineer say this is overcomplicated?\" If yes, simplify.\n\n## 3. Surgical Changes\n\n**Touch only what you must. Clean up only your own mess.**\n\nWhen editing existing code:\n\n- Don't \"improve\" adjacent code, comments, or formatting.\n- Don't refactor things that aren't broken.\n- Match existing style, even if you'd do it differently.\n- If you notice unrelated dead code, mention it - don't delete it.\n\nWhen your changes create orphans:\n\n- Remove imports/variables/functions that YOUR changes made unused.\n- Don't remove pre-existing dead code unless asked.\n\nThe test: Every changed line should trace directly to the user's request.\n\n## 4. Goal-Driven Execution\n\n**Define success criteria. Loop until verified.**\n\nTransform tasks into verifiable goals:\n\n- \"Add validation\" → \"Write tests for invalid inputs, then make them pass\"\n- \"Fix the bug\" → \"Write a test that reproduces it, then make it pass\"\n- \"Refactor X\" → \"Ensure tests pass before and after\"\n\nFor multi-step tasks, state a brief plan:\n\n```\n1. [Step] → verify: [check]\n2. [Step] → verify: [check]\n3. [Step] → verify: [check]\n```\n\nStrong success criteria let you loop independently. Weak criteria (\"make it work\") require constant clarification.\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n@AGENTS.md\n",".github/copilot-instructions.md":"# Chainlit Development Instructions\n\nChainlit is a Python framework for building conversational AI applications with Python backend and React frontend. It uses uv for Python dependency management and pnpm for Node.js packages.\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\n## Working Effectively\n\n### Bootstrap, Build, and Test the Repository\n\n**CRITICAL**: All commands must complete - NEVER CANCEL any build or test operations. Use appropriate timeouts.\n\n1. **Install Dependencies (Required first)**:\n\n   ```bash\n   # Install uv (if not available)\n   python3 -m pip install pipx\n   python3 -m pipx install uv\n   export PATH=\"$HOME/.local/bin:$PATH\"\n\n   # Install pnpm (if not available)\n   npm install -g pnpm\n\n   # Install Python dependencies - takes ~2 minutes, NEVER CANCEL\n   cd backend\n   uv sync --extra tests --extra mypy --extra dev --extra custom-data\n   # Timeout: Use 300+ seconds (5+ minutes)\n\n   # Install Node.js dependencies - takes ~3 minutes, NEVER CANCEL\n   cd ..\n   pnpm install --frozen-lockfile\n   # Timeout: Use 600+ seconds (10+ minutes)\n   # NOTE: Cypress download may fail due to network restrictions - this is expected in CI environments\n   ```\n\n2. **Run Tests**:\n\n   ```bash\n   # Backend tests - takes ~17 seconds, NEVER CANCEL\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run pytest --cov=chainlit/\n   # Timeout: Use 120+ seconds (2+ minutes)\n\n   # Frontend tests - takes ~4 seconds\n   cd ../frontend\n   pnpm test\n   # Timeout: Use 60 seconds\n\n   # E2E tests require Cypress download - may not work in restricted environments\n   # If available: pnpm test:e2e (takes variable time depending on tests)\n   ```\n\n3. **Run Development Servers**:\n\n   ```bash\n   # Start backend (in one terminal)\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run chainlit run chainlit/sample/hello.py -h\n   # Available at http://localhost:8000\n\n   # Start frontend dev server (in another terminal)\n   cd frontend\n   pnpm run dev\n   # Available at http://localhost:5173/\n   ```\n\n## Validation\n\n### Manual Validation Requirements\n\n- **ALWAYS** manually validate any changes by running complete scenarios.\n- **ALWAYS** test the Chainlit application after making changes.\n- Create a test app and verify it runs: `uv run chainlit run /path/to/test.py -h`\n- **ALWAYS** run through at least one complete user workflow after making changes.\n\n### Linting and Formatting - takes ~2 minutes, NEVER CANCEL\n\n```bash\n# Lint (check)\npnpm lint\n# Timeout: Use 300+ seconds (5+ minutes)\n\n# Lint (auto-fix)\npnpm lint:fix\n\n# Check formatting\npnpm format-check\n\n# Fix formatting\npnpm format\n\n# Python (scripts/ wrappers around ruff and mypy)\nuv run scripts/lint.py\nuv run scripts/format.py\nuv run scripts/format.py --check\n```\n\n### CI Requirements\n\n- **ALWAYS** run `pnpm lint` and `pnpm format-check` before committing or the CI (.github/workflows/ci.yaml) will fail.\n- The CI runs: pytest, lint-backend, lint-ui, and e2e-tests.\n- **NEVER CANCEL** any CI commands - they take time but must complete.\n\n## Key Project Structure\n\n### Repository Root\n\n```\n/\n├── README.md\n├── CONTRIBUTING.md\n├── package.json              # Root pnpm workspace config\n├── pnpm-workspace.yaml       # Workspace definition\n├── backend/                  # Python backend with uv\n├── frontend/                 # React frontend app\n├── libs/\n│   ├── react-client/         # React client library\n│   └── copilot/             # Copilot functionality\n├── cypress/                  # E2E tests\n└── .github/\n    ├── workflows/            # CI/CD pipelines\n    └── actions/              # Reusable GitHub actions\n```\n\n### Working with the Backend\n\n- **Technology**: Python 3.10+ with uv, FastAPI, SocketIO\n- **Entry point**: `backend/chainlit/`\n- **Tests**: `backend/tests/`\n- **Dependencies**: Defined in `backend/pyproject.toml`\n- **Hello app**: `backend/chainlit/sample/hello.py`\n\n### Working with the Frontend\n\n- **Technology**: React 18+ with Vite, TypeScript, Tailwind CSS\n- **Entry point**: `frontend/src/`\n- **Dependencies**: Defined in `frontend/package.json`\n- **Build output**: `frontend/dist/`\n\n## Common Tasks\n\n### Creating a New Chainlit App\n\n```python\n# Create app.py\nimport chainlit as cl\n\n@cl.on_message\nasync def main(message: cl.Message):\n    await cl.Message(content=f\"You said: {message.content}\").send()\n\n# Run it\nuv run chainlit run app.py -w\n```\n\n### Timing Expectations\n\n- **pnpm install**: ~3 minutes (may fail on Cypress - this is normal)\n- **uv install**: ~2 minutes\n- **pnpm build**: ~1 minute\n- **pnpm run lint**: ~2 minutes\n- **Backend tests**: ~17 seconds\n- **Frontend tests**: ~4 seconds\n- **pnpm format-check**: ~12 seconds\n- **pnpm format**: ~12 seconds\n\n### Common Gotchas\n\n- **NEVER CANCEL** long-running operations - they need time to complete.\n- Cypress download often fails in CI environments - this is expected.\n- Use `uv run` prefix for all Python commands in backend.\n- Use `export PATH=\"$HOME/.local/bin:$PATH\"` to ensure uv is available.\n- Python lint/format/type-check: use `uv run scripts/lint.py`, `uv run scripts/format.py`, `uv run scripts/type_check.py` from repo root.\n- Frontend dev server connects to backend at localhost:8000.\n- Always start backend before frontend for development.\n\n### File Locations for Quick Reference\n\n- **Main CLI**: `backend/chainlit/cli/`\n- **Server code**: `backend/chainlit/server.py`\n- **Frontend app**: `frontend/src/App.tsx`\n- **React client**: `libs/react-client/src/`\n- **CI workflows**: `.github/workflows/ci.yaml`\n- **uv config**: `backend/pyproject.toml`\n- **Frontend config**: `frontend/package.json`\n\n## Requirements\n\n- **Python**: >= 3.10\n- **Node.js**: >= 20 (24+ recommended)\n- **uv**: 2.1.3 (install via pipx)\n- **pnpm**: Latest (install via npm)\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to AI agents when working with code in this repository.\n\n## Backward Compatibility (CRITICAL)\n\nAll changes **MUST** be backward-compatible. If a refactor or breaking change is unavoidable, notify the user and stop — do not proceed without explicit approval. When approved, prefer adding a compatibility layer over keeping legacy code in place.\n\n## MCP-First Approach (CRITICAL)\n\nWhen available, **ALWAYS** prefer MCP servers over manual alternatives. Use **Context7** for docs/API references, **Serena** for code navigation/refactoring/memory, and **GitHub MCP** for issues/PRs/actions/commits/releases/code search. Fall back to CLI tools, direct file reads, or web searches **ONLY IF** the corresponding MCP is unavailable or cannot fulfill the request.\n\n## Overview\n\nChainlit is a Python framework for building production-ready conversational AI applications. It consists of a Python/FastAPI backend and a React frontend, with a pnpm monorepo for the JS packages.\n\n## Prerequisites\n\n- Python: **3.13** (3.10+ is the framework's minimum, but development targets 3.13)\n- Node.js: **24+**\n- [uv](https://docs.astral.sh/uv/) — Python package manager\n- [pnpm 9](https://pnpm.io/) — Node.js package manager (Corepack)\n\n## Quick Start\n\n### Install\n\n|          | Command                | Directory  |\n| -------- | ---------------------- | ---------- |\n| Backend  | `uv sync --all-extras` | `backend/` |\n| Frontend | `pnpm install`         | repo root  |\n\n### Build\n\n|                   | Command                                      | Directory  | What it does                                                                              |\n| ----------------- | -------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------- |\n| All JS packages   | `pnpm build`                                 | repo root  | Build all workspace packages (frontend, react-client, copilot) via `pnpm run --recursive` |\n| Backend (PyPI)    | `uv build`                                   | `backend/` | Build Python package — builds JS assets first, then bundles into the Python distribution  |\n| Single JS package | `pnpm --filter @chainlit/react-client build` | repo root  | Build one package (useful for publishing)                                                 |\n\n### Dev servers\n\n|          | Command                                           | Directory   | URL                                      |\n| -------- | ------------------------------------------------- | ----------- | ---------------------------------------- |\n| Backend  | `uv run chainlit run chainlit/sample/hello.py -h` | `backend/`  | http://localhost:8000                    |\n| Frontend | `pnpm run dev`                                    | `frontend/` | http://localhost:5173 (proxies to :8000) |\n\n### Tests\n\n|                       | Command                            | Directory   |\n| --------------------- | ---------------------------------- | ----------- |\n| Backend (all)         | `uv run pytest --cov=chainlit/`    | `backend/`  |\n| Backend (single file) | `uv run pytest tests/test_file.py` | `backend/`  |\n| Frontend unit         | `pnpm test`                        | `frontend/` |\n| E2E (Cypress)         | `pnpm test`                        | repo root   |\n\n### Lint & Format\n\n|                     | Command                            | Directory |\n| ------------------- | ---------------------------------- | --------- |\n| Lint JS/TS          | `pnpm lint`                        | repo root |\n| Lint fix JS/TS      | `pnpm lint:fix`                    | repo root |\n| Format check JS/TS  | `pnpm format-check`                | repo root |\n| Format fix JS/TS    | `pnpm format`                      | repo root |\n| Lint Python         | `uv run scripts/lint.py`           | repo root |\n| Lint fix Python     | `uv run scripts/lint.py --fix`     | repo root |\n| Format check Python | `uv run scripts/format.py --check` | repo root |\n| Format fix Python   | `uv run scripts/format.py`         | repo root |\n\nJS/TS lint and format commands accept file/directory arguments: `pnpm lint frontend/`, `pnpm format-check:files frontend/src/App.tsx`. Python scripts also accept file arguments: `uv run scripts/lint.py backend/chainlit/server.py`.\n\n### Type checking\n\n|            | Command                        | Directory |\n| ---------- | ------------------------------ | --------- |\n| Python     | `uv run scripts/type_check.py` | repo root |\n| TypeScript | `pnpm type-check`              | repo root |\n\nType checking runs on whole projects (no per-file mode).\n\nRun `pnpm lint:fix` and `pnpm format` before committing — CI enforces checks on both.\n\n### Commits\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/). Format: `<type>(<optional scope>): <description>`.\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `ci`. Scope is optional but encouraged (e.g. `fix(data): ...`, `feat(i18n): ...`).\n\nAll commits made with AI assistance **must** include a `Co-Authored-By` trailer identifying the AI agent. Add it as the last line of the commit message body:\n\n```\nCo-Authored-By: <Agent Name> <agent-email-or-noreply>\n```\n\nExamples:\n\n- `Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>`\n- `Co-Authored-By: GitHub Copilot <noreply@github.com>`\n- `Co-Authored-By: Gemini CLI <noreply@google.com>`\n\n## Tech Stack\n\n| Layer                          | Stack                                                                                                                     |\n| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |\n| **Frontend**                   | React 18, TypeScript 5.2, Vite 5, Tailwind CSS 3, Vitest, Zod 3                                                           |\n| **Frontend (state & routing)** | Recoil, React Router 6, react-hook-form, socket.io-client, SWR                                                            |\n| **Frontend (rendering)**       | react-markdown + remark-gfm/math + rehype-katex/raw, highlight.js, lucide-react (icons), Radix UI (primitives), Plotly.js |\n| **Backend**                    | Python 3.13, FastAPI, Starlette, Uvicorn, python-socketio, Pydantic 2, PyJWT, httpx                                       |\n| **LLM integrations**           | MCP, LangChain, LlamaIndex, OpenAI SDK, Semantic Kernel, MistralAI                                                        |\n| **Infra / persistence**        | SQLAlchemy (PostgreSQL/SQLite), DynamoDB + S3 (boto3), Azure Blob / Data Lake, Google Cloud Storage, LiteralAI            |\n| **DX**                         | pre-commit hooks, linting, formatting, type checking, unit testing, E2E testing                                           |\n\n## Architecture\n\n### Monorepo structure\n\n```\nbackend/          # Python package (published to PyPI as \"chainlit\")\nfrontend/         # React app (built output served by backend)\nlibs/\n  react-client/   # @chainlit/react-client — published npm package with React hooks\n  copilot/        # Copilot widget (embedded chat bubble)\ncypress/          # E2E tests\n```\n\nThe pnpm workspace includes `frontend/`, `libs/react-client/`, and `libs/copilot/`. The built frontend assets are copied into `backend/chainlit/frontend/dist/` and served as static files.\n\n### Backend (`backend/chainlit/`)\n\n**Entry point for user apps**: `__init__.py` re-exports all public API decorators and classes.\n\n**Key files:**\n\n- `server.py` — FastAPI app, all REST routes (auth, elements, threads, file upload), serves the built frontend SPA, mounts the SocketIO app\n- `socket.py` — SocketIO event handlers for real-time WebSocket communication (connect, message, audio, etc.)\n- `callbacks.py` — Decorator functions registered via `@cl.on_message`, `@cl.on_chat_start`, `@cl.on_audio_chunk`, etc. These store functions on `config.code.*`\n- `config.py` — Reads `.chainlit/config.toml` from `APP_ROOT`. `ChainlitConfig` holds both static TOML config and runtime user-registered callbacks. `APP_ROOT` defaults to `os.getcwd()`.\n- `session.py` — `WebsocketSession` (per-connection state: user, files, MCP connections, message queue) and `HTTPSession`\n- `context.py` — `ChainlitContext` per-coroutine context variable (similar to thread-local), providing access to the current session and emitter\n- `emitter.py` — Sends events back to the frontend through the SocketIO session\n- `data/base.py` — `BaseDataLayer` ABC for persistence (threads, steps, elements, users, feedback). Implementations: `sql_alchemy.py`, `dynamodb.py`, `literalai.py`\n- `auth/` — JWT creation/validation (`jwt.py`), OAuth state cookies (`cookie.py`)\n- `types.py` — Shared Pydantic models for API request/response types\n\n**Data layer pattern**: The data layer is optional (no persistence by default). Register a custom implementation with `@cl.data_layer` decorator or use the built-in SQLAlchemy/DynamoDB/LiteralAI implementations. The `@queue_until_user_message()` decorator on `BaseDataLayer` methods queues write operations until the first user message arrives.\n\n**Integrations**: `langchain/`, `llama_index/`, `openai/`, `semantic_kernel/`, `mistralai/` — each provides callback handlers that bridge those frameworks into Chainlit steps/messages.\n\n### Frontend (`frontend/src/`)\n\nReact 18 + TypeScript + Vite, styled with Tailwind CSS and Radix UI primitives.\n\n- `main.tsx` — React root, wraps app in `RecoilRoot` and `ChainlitContext.Provider`\n- `App.tsx` — Handles auth readiness, chat profile selection, and WebSocket connection lifecycle\n- `router.tsx` — Client-side routes: `/` (Home), `/thread/:id`, `/element/:id`, `/login`, `/login/callback`, `/share/:id`, `/env`\n- `state/` — Recoil atoms: `chat.ts` (messages, elements, tasks), `project.ts` (config, session), `user.ts` (env vars)\n- `components/chat/` — Core chat UI (message list, input bar, elements, audio)\n- `components/header/` — Top navigation bar\n- `components/LeftSidebar/` — Thread history sidebar\n\n### `@chainlit/react-client` (`libs/react-client/src/`)\n\nPublishable npm package — the bridge between the React UI and the backend WebSocket.\n\n- `api.ts` — `ChainlitAPI` class: HTTP calls to backend REST endpoints\n- `useChatSession.ts` — Manages socket.io connection lifecycle\n- `useChatMessages.ts` — Exposes message tree state\n- `useChatData.ts` — Exposes elements, actions, tasklists, connection status\n- `useChatInteract.ts` — `sendMessage`, `replyMessage`, `callAction`, `stopTask`, `clear`\n- `state.ts` — Recoil atoms shared between the lib and consuming apps\n\nState is managed via Recoil; consuming apps must wrap the tree in `<RecoilRoot>` and provide a `ChainlitAPI` instance via `ChainlitContext.Provider`.\n\n### Communication flow\n\n1. User sends a message → `useChatInteract.sendMessage` → emits `client_message` over SocketIO\n2. Backend `socket.py` handler receives it → calls `config.code.on_message(message)`\n3. User's app calls `cl.Message(...).send()` → `emitter.py` emits `new_message` back over SocketIO\n4. Frontend `useChatMessages` updates Recoil state → component re-renders\n\n### App configuration\n\nApps configure Chainlit via `.chainlit/config.toml` (created automatically on first run). Key sections: `[project]` (auth, session timeouts, CORS), `[UI]` (name, theme, layout).\n\n---\n\n## Documentation Verification Requirements\n\nBefore writing/modifying code, verify against official docs.\n\n**Lookup order**: Context7 MCP (preferred) → WebFetch → WebSearch.\n\nPre-resolved Context7 library IDs: [docs/context7.md](docs/context7.md)\n\nCross-reference API signatures and patterns during implementation. When uncertain, always check docs rather than relying on training data.\n",".shared/skills/karpathy-guidelines/SKILL.md":"---\nname: karpathy-guidelines\ndescription: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.\nlicense: MIT\n---\n\n# Karpathy Guidelines\n\nBehavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.\n\n**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.\n\n## 1. Think Before Coding\n\n**Don't assume. Don't hide confusion. Surface tradeoffs.**\n\nBefore implementing:\n\n- State your assumptions explicitly. If uncertain, ask.\n- If multiple interpretations exist, present them - don't pick silently.\n- If a simpler approach exists, say so. Push back when warranted.\n- If something is unclear, stop. Name what's confusing. Ask.\n\n## 2. Simplicity First\n\n**Minimum code that solves the problem. Nothing speculative.**\n\n- No features beyond what was asked.\n- No abstractions for single-use code.\n- No \"flexibility\" or \"configurability\" that wasn't requested.\n- No error handling for impossible scenarios.\n- If you write 200 lines and it could be 50, rewrite it.\n\nAsk yourself: \"Would a senior engineer say this is overcomplicated?\" If yes, simplify.\n\n## 3. Surgical Changes\n\n**Touch only what you must. Clean up only your own mess.**\n\nWhen editing existing code:\n\n- Don't \"improve\" adjacent code, comments, or formatting.\n- Don't refactor things that aren't broken.\n- Match existing style, even if you'd do it differently.\n- If you notice unrelated dead code, mention it - don't delete it.\n\nWhen your changes create orphans:\n\n- Remove imports/variables/functions that YOUR changes made unused.\n- Don't remove pre-existing dead code unless asked.\n\nThe test: Every changed line should trace directly to the user's request.\n\n## 4. Goal-Driven Execution\n\n**Define success criteria. Loop until verified.**\n\nTransform tasks into verifiable goals:\n\n- \"Add validation\" → \"Write tests for invalid inputs, then make them pass\"\n- \"Fix the bug\" → \"Write a test that reproduces it, then make it pass\"\n- \"Refactor X\" → \"Ensure tests pass before and after\"\n\nFor multi-step tasks, state a brief plan:\n\n```\n1. [Step] → verify: [check]\n2. [Step] → verify: [check]\n3. [Step] → verify: [check]\n```\n\nStrong success criteria let you loop independently. Weak criteria (\"make it work\") require constant clarification.\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n@AGENTS.md\n",".github/copilot-instructions.md":"# Chainlit Development Instructions\n\nChainlit is a Python framework for building conversational AI applications with Python backend and React frontend. It uses uv for Python dependency management and pnpm for Node.js packages.\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\n## Working Effectively\n\n### Bootstrap, Build, and Test the Repository\n\n**CRITICAL**: All commands must complete - NEVER CANCEL any build or test operations. Use appropriate timeouts.\n\n1. **Install Dependencies (Required first)**:\n\n   ```bash\n   # Install uv (if not available)\n   python3 -m pip install pipx\n   python3 -m pipx install uv\n   export PATH=\"$HOME/.local/bin:$PATH\"\n\n   # Install pnpm (if not available)\n   npm install -g pnpm\n\n   # Install Python dependencies - takes ~2 minutes, NEVER CANCEL\n   cd backend\n   uv sync --extra tests --extra mypy --extra dev --extra custom-data\n   # Timeout: Use 300+ seconds (5+ minutes)\n\n   # Install Node.js dependencies - takes ~3 minutes, NEVER CANCEL\n   cd ..\n   pnpm install --frozen-lockfile\n   # Timeout: Use 600+ seconds (10+ minutes)\n   # NOTE: Cypress download may fail due to network restrictions - this is expected in CI environments\n   ```\n\n2. **Run Tests**:\n\n   ```bash\n   # Backend tests - takes ~17 seconds, NEVER CANCEL\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run pytest --cov=chainlit/\n   # Timeout: Use 120+ seconds (2+ minutes)\n\n   # Frontend tests - takes ~4 seconds\n   cd ../frontend\n   pnpm test\n   # Timeout: Use 60 seconds\n\n   # E2E tests require Cypress download - may not work in restricted environments\n   # If available: pnpm test:e2e (takes variable time depending on tests)\n   ```\n\n3. **Run Development Servers**:\n\n   ```bash\n   # Start backend (in one terminal)\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run chainlit run chainlit/sample/hello.py -h\n   # Available at http://localhost:8000\n\n   # Start frontend dev server (in another terminal)\n   cd frontend\n   pnpm run dev\n   # Available at http://localhost:5173/\n   ```\n\n## Validation\n\n### Manual Validation Requirements\n\n- **ALWAYS** manually validate any changes by running complete scenarios.\n- **ALWAYS** test the Chainlit application after making changes.\n- Create a test app and verify it runs: `uv run chainlit run /path/to/test.py -h`\n- **ALWAYS** run through at least one complete user workflow after making changes.\n\n### Linting and Formatting - takes ~2 minutes, NEVER CANCEL\n\n```bash\n# Lint (check)\npnpm lint\n# Timeout: Use 300+ seconds (5+ minutes)\n\n# Lint (auto-fix)\npnpm lint:fix\n\n# Check formatting\npnpm format-check\n\n# Fix formatting\npnpm format\n\n# Python (scripts/ wrappers around ruff and mypy)\nuv run scripts/lint.py\nuv run scripts/format.py\nuv run scripts/format.py --check\n```\n\n### CI Requirements\n\n- **ALWAYS** run `pnpm lint` and `pnpm format-check` before committing or the CI (.github/workflows/ci.yaml) will fail.\n- The CI runs: pytest, lint-backend, lint-ui, and e2e-tests.\n- **NEVER CANCEL** any CI commands - they take time but must complete.\n\n## Key Project Structure\n\n### Repository Root\n\n```\n/\n├── README.md\n├── CONTRIBUTING.md\n├── package.json              # Root pnpm workspace config\n├── pnpm-workspace.yaml       # Workspace definition\n├── backend/                  # Python backend with uv\n├── frontend/                 # React frontend app\n├── libs/\n│   ├── react-client/         # React client library\n│   └── copilot/             # Copilot functionality\n├── cypress/                  # E2E tests\n└── .github/\n    ├── workflows/            # CI/CD pipelines\n    └── actions/              # Reusable GitHub actions\n```\n\n### Working with the Backend\n\n- **Technology**: Python 3.10+ with uv, FastAPI, SocketIO\n- **Entry point**: `backend/chainlit/`\n- **Tests**: `backend/tests/`\n- **Dependencies**: Defined in `backend/pyproject.toml`\n- **Hello app**: `backend/chainlit/sample/hello.py`\n\n### Working with the Frontend\n\n- **Technology**: React 18+ with Vite, TypeScript, Tailwind CSS\n- **Entry point**: `frontend/src/`\n- **Dependencies**: Defined in `frontend/package.json`\n- **Build output**: `frontend/dist/`\n\n## Common Tasks\n\n### Creating a New Chainlit App\n\n```python\n# Create app.py\nimport chainlit as cl\n\n@cl.on_message\nasync def main(message: cl.Message):\n    await cl.Message(content=f\"You said: {message.content}\").send()\n\n# Run it\nuv run chainlit run app.py -w\n```\n\n### Timing Expectations\n\n- **pnpm install**: ~3 minutes (may fail on Cypress - this is normal)\n- **uv install**: ~2 minutes\n- **pnpm build**: ~1 minute\n- **pnpm run lint**: ~2 minutes\n- **Backend tests**: ~17 seconds\n- **Frontend tests**: ~4 seconds\n- **pnpm format-check**: ~12 seconds\n- **pnpm format**: ~12 seconds\n\n### Common Gotchas\n\n- **NEVER CANCEL** long-running operations - they need time to complete.\n- Cypress download often fails in CI environments - this is expected.\n- Use `uv run` prefix for all Python commands in backend.\n- Use `export PATH=\"$HOME/.local/bin:$PATH\"` to ensure uv is available.\n- Python lint/format/type-check: use `uv run scripts/lint.py`, `uv run scripts/format.py`, `uv run scripts/type_check.py` from repo root.\n- Frontend dev server connects to backend at localhost:8000.\n- Always start backend before frontend for development.\n\n### File Locations for Quick Reference\n\n- **Main CLI**: `backend/chainlit/cli/`\n- **Server code**: `backend/chainlit/server.py`\n- **Frontend app**: `frontend/src/App.tsx`\n- **React client**: `libs/react-client/src/`\n- **CI workflows**: `.github/workflows/ci.yaml`\n- **uv config**: `backend/pyproject.toml`\n- **Frontend config**: `frontend/package.json`\n\n## Requirements\n\n- **Python**: >= 3.10\n- **Node.js**: >= 20 (24+ recommended)\n- **uv**: 2.1.3 (install via pipx)\n- **pnpm**: Latest (install via npm)\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/Chainlit/chainlit/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nThis file provides guidance to AI agents when working with code in this repository.\n\n## Backward Compatibility (CRITICAL)\n\nAll changes **MUST** be backward-compatible. If a refactor or breaking change is unavoidable, notify the user and stop — do not proceed without explicit approval. When approved, prefer adding a compatibility layer over keeping legacy code in place.\n\n## MCP-First Approach (CRITICAL)\n\nWhen available, **ALWAYS** prefer MCP servers over manual alternatives. Use **Context7** for docs/API references, **Serena** for code navigation/refactoring/memory, and **GitHub MCP** for issues/PRs/actions/commits/releases/code search. Fall back to CLI tools, direct file reads, or web searches **ONLY IF** the corresponding MCP is unavailable or cannot fulfill the request.\n\n## Overview\n\nChainlit is a Python framework for building production-ready conversational AI applications. It consists of a Python/FastAPI backend and a React frontend, with a pnpm monorepo for the JS packages.\n\n## Prerequisites\n\n- Python: **3.13** (3.10+ is the framework's minimum, but development targets 3.13)\n- Node.js: **24+**\n- [uv](https://docs.astral.sh/uv/) — Python package manager\n- [pnpm 9](https://pnpm.io/) — Node.js package manager (Corepack)\n\n## Quick Start\n\n### Install\n\n|          | Command                | Directory  |\n| -------- | ---------------------- | ---------- |\n| Backend  | `uv sync --all-extras` | `backend/` |\n| Frontend | `pnpm install`         | repo root  |\n\n### Build\n\n|                   | Command                                      | Directory  | What it does                                                                              |\n| ----------------- | -------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------- |\n| All JS packages   | `pnpm build`                                 | repo root  | Build all workspace packages (frontend, react-client, copilot) via `pnpm run --recursive` |\n| Backend (PyPI)    | `uv build`                                   | `backend/` | Build Python package — builds JS assets first, then bundles into the Python distribution  |\n| Single JS package | `pnpm --filter @chainlit/react-client build` | repo root  | Build one package (useful for publishing)                                                 |\n\n### Dev servers\n\n|          | Command                                           | Directory   | URL                                      |\n| -------- | ------------------------------------------------- | ----------- | ---------------------------------------- |\n| Backend  | `uv run chainlit run chainlit/sample/hello.py -h` | `backend/`  | http://localhost:8000                    |\n| Frontend | `pnpm run dev`                                    | `frontend/` | http://localhost:5173 (proxies to :8000) |\n\n### Tests\n\n|                       | Command                            | Directory   |\n| --------------------- | ---------------------------------- | ----------- |\n| Backend (all)         | `uv run pytest --cov=chainlit/`    | `backend/`  |\n| Backend (single file) | `uv run pytest tests/test_file.py` | `backend/`  |\n| Frontend unit         | `pnpm test`                        | `frontend/` |\n| E2E (Cypress)         | `pnpm test`                        | repo root   |\n\n### Lint & Format\n\n|                     | Command                            | Directory |\n| ------------------- | ---------------------------------- | --------- |\n| Lint JS/TS          | `pnpm lint`                        | repo root |\n| Lint fix JS/TS      | `pnpm lint:fix`                    | repo root |\n| Format check JS/TS  | `pnpm format-check`                | repo root |\n| Format fix JS/TS    | `pnpm format`                      | repo root |\n| Lint Python         | `uv run scripts/lint.py`           | repo root |\n| Lint fix Python     | `uv run scripts/lint.py --fix`     | repo root |\n| Format check Python | `uv run scripts/format.py --check` | repo root |\n| Format fix Python   | `uv run scripts/format.py`         | repo root |\n\nJS/TS lint and format commands accept file/directory arguments: `pnpm lint frontend/`, `pnpm format-check:files frontend/src/App.tsx`. Python scripts also accept file arguments: `uv run scripts/lint.py backend/chainlit/server.py`.\n\n### Type checking\n\n|            | Command                        | Directory |\n| ---------- | ------------------------------ | --------- |\n| Python     | `uv run scripts/type_check.py` | repo root |\n| TypeScript | `pnpm type-check`              | repo root |\n\nType checking runs on whole projects (no per-file mode).\n\nRun `pnpm lint:fix` and `pnpm format` before committing — CI enforces checks on both.\n\n### Commits\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/). Format: `<type>(<optional scope>): <description>`.\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `ci`. Scope is optional but encouraged (e.g. `fix(data): ...`, `feat(i18n): ...`).\n\nAll commits made with AI assistance **must** include a `Co-Authored-By` trailer identifying the AI agent. Add it as the last line of the commit message body:\n\n```\nCo-Authored-By: <Agent Name> <agent-email-or-noreply>\n```\n\nExamples:\n\n- `Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>`\n- `Co-Authored-By: GitHub Copilot <noreply@github.com>`\n- `Co-Authored-By: Gemini CLI <noreply@google.com>`\n\n## Tech Stack\n\n| Layer                          | Stack                                                                                                                     |\n| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |\n| **Frontend**                   | React 18, TypeScript 5.2, Vite 5, Tailwind CSS 3, Vitest, Zod 3                                                           |\n| **Frontend (state & routing)** | Recoil, React Router 6, react-hook-form, socket.io-client, SWR                                                            |\n| **Frontend (rendering)**       | react-markdown + remark-gfm/math + rehype-katex/raw, highlight.js, lucide-react (icons), Radix UI (primitives), Plotly.js |\n| **Backend**                    | Python 3.13, FastAPI, Starlette, Uvicorn, python-socketio, Pydantic 2, PyJWT, httpx                                       |\n| **LLM integrations**           | MCP, LangChain, LlamaIndex, OpenAI SDK, Semantic Kernel, MistralAI                                                        |\n| **Infra / persistence**        | SQLAlchemy (PostgreSQL/SQLite), DynamoDB + S3 (boto3), Azure Blob / Data Lake, Google Cloud Storage, LiteralAI            |\n| **DX**                         | pre-commit hooks, linting, formatting, type checking, unit testing, E2E testing                                           |\n\n## Architecture\n\n### Monorepo structure\n\n```\nbackend/          # Python package (published to PyPI as \"chainlit\")\nfrontend/         # React app (built output served by backend)\nlibs/\n  react-client/   # @chainlit/react-client — published npm package with React hooks\n  copilot/        # Copilot widget (embedded chat bubble)\ncypress/          # E2E tests\n```\n\nThe pnpm workspace includes `frontend/`, `libs/react-client/`, and `libs/copilot/`. The built frontend assets are copied into `backend/chainlit/frontend/dist/` and served as static files.\n\n### Backend (`backend/chainlit/`)\n\n**Entry point for user apps**: `__init__.py` re-exports all public API decorators and classes.\n\n**Key files:**\n\n- `server.py` — FastAPI app, all REST routes (auth, elements, threads, file upload), serves the built frontend SPA, mounts the SocketIO app\n- `socket.py` — SocketIO event handlers for real-time WebSocket communication (connect, message, audio, etc.)\n- `callbacks.py` — Decorator functions registered via `@cl.on_message`, `@cl.on_chat_start`, `@cl.on_audio_chunk`, etc. These store functions on `config.code.*`\n- `config.py` — Reads `.chainlit/config.toml` from `APP_ROOT`. `ChainlitConfig` holds both static TOML config and runtime user-registered callbacks. `APP_ROOT` defaults to `os.getcwd()`.\n- `session.py` — `WebsocketSession` (per-connection state: user, files, MCP connections, message queue) and `HTTPSession`\n- `context.py` — `ChainlitContext` per-coroutine context variable (similar to thread-local), providing access to the current session and emitter\n- `emitter.py` — Sends events back to the frontend through the SocketIO session\n- `data/base.py` — `BaseDataLayer` ABC for persistence (threads, steps, elements, users, feedback). Implementations: `sql_alchemy.py`, `dynamodb.py`, `literalai.py`\n- `auth/` — JWT creation/validation (`jwt.py`), OAuth state cookies (`cookie.py`)\n- `types.py` — Shared Pydantic models for API request/response types\n\n**Data layer pattern**: The data layer is optional (no persistence by default). Register a custom implementation with `@cl.data_layer` decorator or use the built-in SQLAlchemy/DynamoDB/LiteralAI implementations. The `@queue_until_user_message()` decorator on `BaseDataLayer` methods queues write operations until the first user message arrives.\n\n**Integrations**: `langchain/`, `llama_index/`, `openai/`, `semantic_kernel/`, `mistralai/` — each provides callback handlers that bridge those frameworks into Chainlit steps/messages.\n\n### Frontend (`frontend/src/`)\n\nReact 18 + TypeScript + Vite, styled with Tailwind CSS and Radix UI primitives.\n\n- `main.tsx` — React root, wraps app in `RecoilRoot` and `ChainlitContext.Provider`\n- `App.tsx` — Handles auth readiness, chat profile selection, and WebSocket connection lifecycle\n- `router.tsx` — Client-side routes: `/` (Home), `/thread/:id`, `/element/:id`, `/login`, `/login/callback`, `/share/:id`, `/env`\n- `state/` — Recoil atoms: `chat.ts` (messages, elements, tasks), `project.ts` (config, session), `user.ts` (env vars)\n- `components/chat/` — Core chat UI (message list, input bar, elements, audio)\n- `components/header/` — Top navigation bar\n- `components/LeftSidebar/` — Thread history sidebar\n\n### `@chainlit/react-client` (`libs/react-client/src/`)\n\nPublishable npm package — the bridge between the React UI and the backend WebSocket.\n\n- `api.ts` — `ChainlitAPI` class: HTTP calls to backend REST endpoints\n- `useChatSession.ts` — Manages socket.io connection lifecycle\n- `useChatMessages.ts` — Exposes message tree state\n- `useChatData.ts` — Exposes elements, actions, tasklists, connection status\n- `useChatInteract.ts` — `sendMessage`, `replyMessage`, `callAction`, `stopTask`, `clear`\n- `state.ts` — Recoil atoms shared between the lib and consuming apps\n\nState is managed via Recoil; consuming apps must wrap the tree in `<RecoilRoot>` and provide a `ChainlitAPI` instance via `ChainlitContext.Provider`.\n\n### Communication flow\n\n1. User sends a message → `useChatInteract.sendMessage` → emits `client_message` over SocketIO\n2. Backend `socket.py` handler receives it → calls `config.code.on_message(message)`\n3. User's app calls `cl.Message(...).send()` → `emitter.py` emits `new_message` back over SocketIO\n4. Frontend `useChatMessages` updates Recoil state → component re-renders\n\n### App configuration\n\nApps configure Chainlit via `.chainlit/config.toml` (created automatically on first run). Key sections: `[project]` (auth, session timeouts, CORS), `[UI]` (name, theme, layout).\n\n---\n\n## Documentation Verification Requirements\n\nBefore writing/modifying code, verify against official docs.\n\n**Lookup order**: Context7 MCP (preferred) → WebFetch → WebSearch.\n\nPre-resolved Context7 library IDs: [docs/context7.md](docs/context7.md)\n\nCross-reference API signatures and patterns during implementation. When uncertain, always check docs rather than relying on training data.\n","isInternal":false,"tokens":2676,"sizeBytes":11858},{"name":"SKILL.md","path":".shared/skills/karpathy-guidelines/SKILL.md","rawUrl":"https://raw.githubusercontent.com/Chainlit/chainlit/HEAD/.shared/skills/karpathy-guidelines/SKILL.md","title":"karpathy-guidelines","category":"anthropic-skill","format":"markdown","content":"---\nname: karpathy-guidelines\ndescription: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.\nlicense: MIT\n---\n\n# Karpathy Guidelines\n\nBehavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.\n\n**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.\n\n## 1. Think Before Coding\n\n**Don't assume. Don't hide confusion. Surface tradeoffs.**\n\nBefore implementing:\n\n- State your assumptions explicitly. If uncertain, ask.\n- If multiple interpretations exist, present them - don't pick silently.\n- If a simpler approach exists, say so. Push back when warranted.\n- If something is unclear, stop. Name what's confusing. Ask.\n\n## 2. Simplicity First\n\n**Minimum code that solves the problem. Nothing speculative.**\n\n- No features beyond what was asked.\n- No abstractions for single-use code.\n- No \"flexibility\" or \"configurability\" that wasn't requested.\n- No error handling for impossible scenarios.\n- If you write 200 lines and it could be 50, rewrite it.\n\nAsk yourself: \"Would a senior engineer say this is overcomplicated?\" If yes, simplify.\n\n## 3. Surgical Changes\n\n**Touch only what you must. Clean up only your own mess.**\n\nWhen editing existing code:\n\n- Don't \"improve\" adjacent code, comments, or formatting.\n- Don't refactor things that aren't broken.\n- Match existing style, even if you'd do it differently.\n- If you notice unrelated dead code, mention it - don't delete it.\n\nWhen your changes create orphans:\n\n- Remove imports/variables/functions that YOUR changes made unused.\n- Don't remove pre-existing dead code unless asked.\n\nThe test: Every changed line should trace directly to the user's request.\n\n## 4. Goal-Driven Execution\n\n**Define success criteria. Loop until verified.**\n\nTransform tasks into verifiable goals:\n\n- \"Add validation\" → \"Write tests for invalid inputs, then make them pass\"\n- \"Fix the bug\" → \"Write a test that reproduces it, then make it pass\"\n- \"Refactor X\" → \"Ensure tests pass before and after\"\n\nFor multi-step tasks, state a brief plan:\n\n```\n1. [Step] → verify: [check]\n2. [Step] → verify: [check]\n3. [Step] → verify: [check]\n```\n\nStrong success criteria let you loop independently. Weak criteria (\"make it work\") require constant clarification.\n","frontmatter":{"name":"karpathy-guidelines","description":"Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.","license":"MIT"},"isInternal":false,"tokens":580,"sizeBytes":2523},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/Chainlit/chainlit/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n@AGENTS.md\n","isInternal":false,"tokens":32,"sizeBytes":128},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/Chainlit/chainlit/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"# Chainlit Development Instructions\n\nChainlit is a Python framework for building conversational AI applications with Python backend and React frontend. It uses uv for Python dependency management and pnpm for Node.js packages.\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\n## Working Effectively\n\n### Bootstrap, Build, and Test the Repository\n\n**CRITICAL**: All commands must complete - NEVER CANCEL any build or test operations. Use appropriate timeouts.\n\n1. **Install Dependencies (Required first)**:\n\n   ```bash\n   # Install uv (if not available)\n   python3 -m pip install pipx\n   python3 -m pipx install uv\n   export PATH=\"$HOME/.local/bin:$PATH\"\n\n   # Install pnpm (if not available)\n   npm install -g pnpm\n\n   # Install Python dependencies - takes ~2 minutes, NEVER CANCEL\n   cd backend\n   uv sync --extra tests --extra mypy --extra dev --extra custom-data\n   # Timeout: Use 300+ seconds (5+ minutes)\n\n   # Install Node.js dependencies - takes ~3 minutes, NEVER CANCEL\n   cd ..\n   pnpm install --frozen-lockfile\n   # Timeout: Use 600+ seconds (10+ minutes)\n   # NOTE: Cypress download may fail due to network restrictions - this is expected in CI environments\n   ```\n\n2. **Run Tests**:\n\n   ```bash\n   # Backend tests - takes ~17 seconds, NEVER CANCEL\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run pytest --cov=chainlit/\n   # Timeout: Use 120+ seconds (2+ minutes)\n\n   # Frontend tests - takes ~4 seconds\n   cd ../frontend\n   pnpm test\n   # Timeout: Use 60 seconds\n\n   # E2E tests require Cypress download - may not work in restricted environments\n   # If available: pnpm test:e2e (takes variable time depending on tests)\n   ```\n\n3. **Run Development Servers**:\n\n   ```bash\n   # Start backend (in one terminal)\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run chainlit run chainlit/sample/hello.py -h\n   # Available at http://localhost:8000\n\n   # Start frontend dev server (in another terminal)\n   cd frontend\n   pnpm run dev\n   # Available at http://localhost:5173/\n   ```\n\n## Validation\n\n### Manual Validation Requirements\n\n- **ALWAYS** manually validate any changes by running complete scenarios.\n- **ALWAYS** test the Chainlit application after making changes.\n- Create a test app and verify it runs: `uv run chainlit run /path/to/test.py -h`\n- **ALWAYS** run through at least one complete user workflow after making changes.\n\n### Linting and Formatting - takes ~2 minutes, NEVER CANCEL\n\n```bash\n# Lint (check)\npnpm lint\n# Timeout: Use 300+ seconds (5+ minutes)\n\n# Lint (auto-fix)\npnpm lint:fix\n\n# Check formatting\npnpm format-check\n\n# Fix formatting\npnpm format\n\n# Python (scripts/ wrappers around ruff and mypy)\nuv run scripts/lint.py\nuv run scripts/format.py\nuv run scripts/format.py --check\n```\n\n### CI Requirements\n\n- **ALWAYS** run `pnpm lint` and `pnpm format-check` before committing or the CI (.github/workflows/ci.yaml) will fail.\n- The CI runs: pytest, lint-backend, lint-ui, and e2e-tests.\n- **NEVER CANCEL** any CI commands - they take time but must complete.\n\n## Key Project Structure\n\n### Repository Root\n\n```\n/\n├── README.md\n├── CONTRIBUTING.md\n├── package.json              # Root pnpm workspace config\n├── pnpm-workspace.yaml       # Workspace definition\n├── backend/                  # Python backend with uv\n├── frontend/                 # React frontend app\n├── libs/\n│   ├── react-client/         # React client library\n│   └── copilot/             # Copilot functionality\n├── cypress/                  # E2E tests\n└── .github/\n    ├── workflows/            # CI/CD pipelines\n    └── actions/              # Reusable GitHub actions\n```\n\n### Working with the Backend\n\n- **Technology**: Python 3.10+ with uv, FastAPI, SocketIO\n- **Entry point**: `backend/chainlit/`\n- **Tests**: `backend/tests/`\n- **Dependencies**: Defined in `backend/pyproject.toml`\n- **Hello app**: `backend/chainlit/sample/hello.py`\n\n### Working with the Frontend\n\n- **Technology**: React 18+ with Vite, TypeScript, Tailwind CSS\n- **Entry point**: `frontend/src/`\n- **Dependencies**: Defined in `frontend/package.json`\n- **Build output**: `frontend/dist/`\n\n## Common Tasks\n\n### Creating a New Chainlit App\n\n```python\n# Create app.py\nimport chainlit as cl\n\n@cl.on_message\nasync def main(message: cl.Message):\n    await cl.Message(content=f\"You said: {message.content}\").send()\n\n# Run it\nuv run chainlit run app.py -w\n```\n\n### Timing Expectations\n\n- **pnpm install**: ~3 minutes (may fail on Cypress - this is normal)\n- **uv install**: ~2 minutes\n- **pnpm build**: ~1 minute\n- **pnpm run lint**: ~2 minutes\n- **Backend tests**: ~17 seconds\n- **Frontend tests**: ~4 seconds\n- **pnpm format-check**: ~12 seconds\n- **pnpm format**: ~12 seconds\n\n### Common Gotchas\n\n- **NEVER CANCEL** long-running operations - they need time to complete.\n- Cypress download often fails in CI environments - this is expected.\n- Use `uv run` prefix for all Python commands in backend.\n- Use `export PATH=\"$HOME/.local/bin:$PATH\"` to ensure uv is available.\n- Python lint/format/type-check: use `uv run scripts/lint.py`, `uv run scripts/format.py`, `uv run scripts/type_check.py` from repo root.\n- Frontend dev server connects to backend at localhost:8000.\n- Always start backend before frontend for development.\n\n### File Locations for Quick Reference\n\n- **Main CLI**: `backend/chainlit/cli/`\n- **Server code**: `backend/chainlit/server.py`\n- **Frontend app**: `frontend/src/App.tsx`\n- **React client**: `libs/react-client/src/`\n- **CI workflows**: `.github/workflows/ci.yaml`\n- **uv config**: `backend/pyproject.toml`\n- **Frontend config**: `frontend/package.json`\n\n## Requirements\n\n- **Python**: >= 3.10\n- **Node.js**: >= 20 (24+ recommended)\n- **uv**: 2.1.3 (install via pipx)\n- **pnpm**: Latest (install via npm)\n","isInternal":false,"tokens":1500,"sizeBytes":5928}],"systemPromptSnippet":"<yakaai_skills repo=\"Chainlit/chainlit\">\n<!-- File: AGENTS.md (Tokens: ~2676 | Category: root-instruction) -->\n# AGENTS.md\n\nThis file provides guidance to AI agents when working with code in this repository.\n\n## Backward Compatibility (CRITICAL)\n\nAll changes **MUST** be backward-compatible. If a refactor or breaking change is unavoidable, notify the user and stop — do not proceed without explicit approval. When approved, prefer adding a compatibility layer over keeping legacy code in place.\n\n## MCP-First Approach (CRITICAL)\n\nWhen available, **ALWAYS** prefer MCP servers over manual alternatives. Use **Context7** for docs/API references, **Serena** for code navigation/refactoring/memory, and **GitHub MCP** for issues/PRs/actions/commits/releases/code search. Fall back to CLI tools, direct file reads, or web searches **ONLY IF** the corresponding MCP is unavailable or cannot fulfill the request.\n\n## Overview\n\nChainlit is a Python framework for building production-ready conversational AI applications. It consists of a Python/FastAPI backend and a React frontend, with a pnpm monorepo for the JS packages.\n\n## Prerequisites\n\n- Python: **3.13** (3.10+ is the framework's minimum, but development targets 3.13)\n- Node.js: **24+**\n- [uv](https://docs.astral.sh/uv/) — Python package manager\n- [pnpm 9](https://pnpm.io/) — Node.js package manager (Corepack)\n\n## Quick Start\n\n### Install\n\n|          | Command                | Directory  |\n| -------- | ---------------------- | ---------- |\n| Backend  | `uv sync --all-extras` | `backend/` |\n| Frontend | `pnpm install`         | repo root  |\n\n### Build\n\n|                   | Command                                      | Directory  | What it does                                                                              |\n| ----------------- | -------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------- |\n| All JS packages   | `pnpm build`                                 | repo root  | Build all workspace packages (frontend, react-client, copilot) via `pnpm run --recursive` |\n| Backend (PyPI)    | `uv build`                                   | `backend/` | Build Python package — builds JS assets first, then bundles into the Python distribution  |\n| Single JS package | `pnpm --filter @chainlit/react-client build` | repo root  | Build one package (useful for publishing)                                                 |\n\n### Dev servers\n\n|          | Command                                           | Directory   | URL                                      |\n| -------- | ------------------------------------------------- | ----------- | ---------------------------------------- |\n| Backend  | `uv run chainlit run chainlit/sample/hello.py -h` | `backend/`  | http://localhost:8000                    |\n| Frontend | `pnpm run dev`                                    | `frontend/` | http://localhost:5173 (proxies to :8000) |\n\n### Tests\n\n|                       | Command                            | Directory   |\n| --------------------- | ---------------------------------- | ----------- |\n| Backend (all)         | `uv run pytest --cov=chainlit/`    | `backend/`  |\n| Backend (single file) | `uv run pytest tests/test_file.py` | `backend/`  |\n| Frontend unit         | `pnpm test`                        | `frontend/` |\n| E2E (Cypress)         | `pnpm test`                        | repo root   |\n\n### Lint & Format\n\n|                     | Command                            | Directory |\n| ------------------- | ---------------------------------- | --------- |\n| Lint JS/TS          | `pnpm lint`                        | repo root |\n| Lint fix JS/TS      | `pnpm lint:fix`                    | repo root |\n| Format check JS/TS  | `pnpm format-check`                | repo root |\n| Format fix JS/TS    | `pnpm format`                      | repo root |\n| Lint Python         | `uv run scripts/lint.py`           | repo root |\n| Lint fix Python     | `uv run scripts/lint.py --fix`     | repo root |\n| Format check Python | `uv run scripts/format.py --check` | repo root |\n| Format fix Python   | `uv run scripts/format.py`         | repo root |\n\nJS/TS lint and format commands accept file/directory arguments: `pnpm lint frontend/`, `pnpm format-check:files frontend/src/App.tsx`. Python scripts also accept file arguments: `uv run scripts/lint.py backend/chainlit/server.py`.\n\n### Type checking\n\n|            | Command                        | Directory |\n| ---------- | ------------------------------ | --------- |\n| Python     | `uv run scripts/type_check.py` | repo root |\n| TypeScript | `pnpm type-check`              | repo root |\n\nType checking runs on whole projects (no per-file mode).\n\nRun `pnpm lint:fix` and `pnpm format` before committing — CI enforces checks on both.\n\n### Commits\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/). Format: `<type>(<optional scope>): <description>`.\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `ci`. Scope is optional but encouraged (e.g. `fix(data): ...`, `feat(i18n): ...`).\n\nAll commits made with AI assistance **must** include a `Co-Authored-By` trailer identifying the AI agent. Add it as the last line of the commit message body:\n\n```\nCo-Authored-By: <Agent Name> <agent-email-or-noreply>\n```\n\nExamples:\n\n- `Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>`\n- `Co-Authored-By: GitHub Copilot <noreply@github.com>`\n- `Co-Authored-By: Gemini CLI <noreply@google.com>`\n\n## Tech Stack\n\n| Layer                          | Stack                                                                                                                     |\n| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |\n| **Frontend**                   | React 18, TypeScript 5.2, Vite 5, Tailwind CSS 3, Vitest, Zod 3                                                           |\n| **Frontend (state & routing)** | Recoil, React Router 6, react-hook-form, socket.io-client, SWR                                                            |\n| **Frontend (rendering)**       | react-markdown + remark-gfm/math + rehype-katex/raw, highlight.js, lucide-react (icons), Radix UI (primitives), Plotly.js |\n| **Backend**                    | Python 3.13, FastAPI, Starlette, Uvicorn, python-socketio, Pydantic 2, PyJWT, httpx                                       |\n| **LLM integrations**           | MCP, LangChain, LlamaIndex, OpenAI SDK, Semantic Kernel, MistralAI                                                        |\n| **Infra / persistence**        | SQLAlchemy (PostgreSQL/SQLite), DynamoDB + S3 (boto3), Azure Blob / Data Lake, Google Cloud Storage, LiteralAI            |\n| **DX**                         | pre-commit hooks, linting, formatting, type checking, unit testing, E2E testing                                           |\n\n## Architecture\n\n### Monorepo structure\n\n```\nbackend/          # Python package (published to PyPI as \"chainlit\")\nfrontend/         # React app (built output served by backend)\nlibs/\n  react-client/   # @chainlit/react-client — published npm package with React hooks\n  copilot/        # Copilot widget (embedded chat bubble)\ncypress/          # E2E tests\n```\n\nThe pnpm workspace includes `frontend/`, `libs/react-client/`, and `libs/copilot/`. The built frontend assets are copied into `backend/chainlit/frontend/dist/` and served as static files.\n\n### Backend (`backend/chainlit/`)\n\n**Entry point for user apps**: `__init__.py` re-exports all public API decorators and classes.\n\n**Key files:**\n\n- `server.py` — FastAPI app, all REST routes (auth, elements, threads, file upload), serves the built frontend SPA, mounts the SocketIO app\n- `socket.py` — SocketIO event handlers for real-time WebSocket communication (connect, message, audio, etc.)\n- `callbacks.py` — Decorator functions registered via `@cl.on_message`, `@cl.on_chat_start`, `@cl.on_audio_chunk`, etc. These store functions on `config.code.*`\n- `config.py` — Reads `.chainlit/config.toml` from `APP_ROOT`. `ChainlitConfig` holds both static TOML config and runtime user-registered callbacks. `APP_ROOT` defaults to `os.getcwd()`.\n- `session.py` — `WebsocketSession` (per-connection state: user, files, MCP connections, message queue) and `HTTPSession`\n- `context.py` — `ChainlitContext` per-coroutine context variable (similar to thread-local), providing access to the current session and emitter\n- `emitter.py` — Sends events back to the frontend through the SocketIO session\n- `data/base.py` — `BaseDataLayer` ABC for persistence (threads, steps, elements, users, feedback). Implementations: `sql_alchemy.py`, `dynamodb.py`, `literalai.py`\n- `auth/` — JWT creation/validation (`jwt.py`), OAuth state cookies (`cookie.py`)\n- `types.py` — Shared Pydantic models for API request/response types\n\n**Data layer pattern**: The data layer is optional (no persistence by default). Register a custom implementation with `@cl.data_layer` decorator or use the built-in SQLAlchemy/DynamoDB/LiteralAI implementations. The `@queue_until_user_message()` decorator on `BaseDataLayer` methods queues write operations until the first user message arrives.\n\n**Integrations**: `langchain/`, `llama_index/`, `openai/`, `semantic_kernel/`, `mistralai/` — each provides callback handlers that bridge those frameworks into Chainlit steps/messages.\n\n### Frontend (`frontend/src/`)\n\nReact 18 + TypeScript + Vite, styled with Tailwind CSS and Radix UI primitives.\n\n- `main.tsx` — React root, wraps app in `RecoilRoot` and `ChainlitContext.Provider`\n- `App.tsx` — Handles auth readiness, chat profile selection, and WebSocket connection lifecycle\n- `router.tsx` — Client-side routes: `/` (Home), `/thread/:id`, `/element/:id`, `/login`, `/login/callback`, `/share/:id`, `/env`\n- `state/` — Recoil atoms: `chat.ts` (messages, elements, tasks), `project.ts` (config, session), `user.ts` (env vars)\n- `components/chat/` — Core chat UI (message list, input bar, elements, audio)\n- `components/header/` — Top navigation bar\n- `components/LeftSidebar/` — Thread history sidebar\n\n### `@chainlit/react-client` (`libs/react-client/src/`)\n\nPublishable npm package — the bridge between the React UI and the backend WebSocket.\n\n- `api.ts` — `ChainlitAPI` class: HTTP calls to backend REST endpoints\n- `useChatSession.ts` — Manages socket.io connection lifecycle\n- `useChatMessages.ts` — Exposes message tree state\n- `useChatData.ts` — Exposes elements, actions, tasklists, connection status\n- `useChatInteract.ts` — `sendMessage`, `replyMessage`, `callAction`, `stopTask`, `clear`\n- `state.ts` — Recoil atoms shared between the lib and consuming apps\n\nState is managed via Recoil; consuming apps must wrap the tree in `<RecoilRoot>` and provide a `ChainlitAPI` instance via `ChainlitContext.Provider`.\n\n### Communication flow\n\n1. User sends a message → `useChatInteract.sendMessage` → emits `client_message` over SocketIO\n2. Backend `socket.py` handler receives it → calls `config.code.on_message(message)`\n3. User's app calls `cl.Message(...).send()` → `emitter.py` emits `new_message` back over SocketIO\n4. Frontend `useChatMessages` updates Recoil state → component re-renders\n\n### App configuration\n\nApps configure Chainlit via `.chainlit/config.toml` (created automatically on first run). Key sections: `[project]` (auth, session timeouts, CORS), `[UI]` (name, theme, layout).\n\n---\n\n## Documentation Verification Requirements\n\nBefore writing/modifying code, verify against official docs.\n\n**Lookup order**: Context7 MCP (preferred) → WebFetch → WebSearch.\n\nPre-resolved Context7 library IDs: [docs/context7.md](docs/context7.md)\n\nCross-reference API signatures and patterns during implementation. When uncertain, always check docs rather than relying on training data.\n\n<!-- File: .shared/skills/karpathy-guidelines/SKILL.md (Tokens: ~580 | Category: anthropic-skill) -->\n---\nname: karpathy-guidelines\ndescription: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.\nlicense: MIT\n---\n\n# Karpathy Guidelines\n\nBehavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.\n\n**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.\n\n## 1. Think Before Coding\n\n**Don't assume. Don't hide confusion. Surface tradeoffs.**\n\nBefore implementing:\n\n- State your assumptions explicitly. If uncertain, ask.\n- If multiple interpretations exist, present them - don't pick silently.\n- If a simpler approach exists, say so. Push back when warranted.\n- If something is unclear, stop. Name what's confusing. Ask.\n\n## 2. Simplicity First\n\n**Minimum code that solves the problem. Nothing speculative.**\n\n- No features beyond what was asked.\n- No abstractions for single-use code.\n- No \"flexibility\" or \"configurability\" that wasn't requested.\n- No error handling for impossible scenarios.\n- If you write 200 lines and it could be 50, rewrite it.\n\nAsk yourself: \"Would a senior engineer say this is overcomplicated?\" If yes, simplify.\n\n## 3. Surgical Changes\n\n**Touch only what you must. Clean up only your own mess.**\n\nWhen editing existing code:\n\n- Don't \"improve\" adjacent code, comments, or formatting.\n- Don't refactor things that aren't broken.\n- Match existing style, even if you'd do it differently.\n- If you notice unrelated dead code, mention it - don't delete it.\n\nWhen your changes create orphans:\n\n- Remove imports/variables/functions that YOUR changes made unused.\n- Don't remove pre-existing dead code unless asked.\n\nThe test: Every changed line should trace directly to the user's request.\n\n## 4. Goal-Driven Execution\n\n**Define success criteria. Loop until verified.**\n\nTransform tasks into verifiable goals:\n\n- \"Add validation\" → \"Write tests for invalid inputs, then make them pass\"\n- \"Fix the bug\" → \"Write a test that reproduces it, then make it pass\"\n- \"Refactor X\" → \"Ensure tests pass before and after\"\n\nFor multi-step tasks, state a brief plan:\n\n```\n1. [Step] → verify: [check]\n2. [Step] → verify: [check]\n3. [Step] → verify: [check]\n```\n\nStrong success criteria let you loop independently. Weak criteria (\"make it work\") require constant clarification.\n\n<!-- File: CLAUDE.md (Tokens: ~32 | Category: claude-rule) -->\n# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n@AGENTS.md\n\n<!-- File: .github/copilot-instructions.md (Tokens: ~1500 | Category: copilot-instructions) -->\n# Chainlit Development Instructions\n\nChainlit is a Python framework for building conversational AI applications with Python backend and React frontend. It uses uv for Python dependency management and pnpm for Node.js packages.\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\n## Working Effectively\n\n### Bootstrap, Build, and Test the Repository\n\n**CRITICAL**: All commands must complete - NEVER CANCEL any build or test operations. Use appropriate timeouts.\n\n1. **Install Dependencies (Required first)**:\n\n   ```bash\n   # Install uv (if not available)\n   python3 -m pip install pipx\n   python3 -m pipx install uv\n   export PATH=\"$HOME/.local/bin:$PATH\"\n\n   # Install pnpm (if not available)\n   npm install -g pnpm\n\n   # Install Python dependencies - takes ~2 minutes, NEVER CANCEL\n   cd backend\n   uv sync --extra tests --extra mypy --extra dev --extra custom-data\n   # Timeout: Use 300+ seconds (5+ minutes)\n\n   # Install Node.js dependencies - takes ~3 minutes, NEVER CANCEL\n   cd ..\n   pnpm install --frozen-lockfile\n   # Timeout: Use 600+ seconds (10+ minutes)\n   # NOTE: Cypress download may fail due to network restrictions - this is expected in CI environments\n   ```\n\n2. **Run Tests**:\n\n   ```bash\n   # Backend tests - takes ~17 seconds, NEVER CANCEL\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run pytest --cov=chainlit/\n   # Timeout: Use 120+ seconds (2+ minutes)\n\n   # Frontend tests - takes ~4 seconds\n   cd ../frontend\n   pnpm test\n   # Timeout: Use 60 seconds\n\n   # E2E tests require Cypress download - may not work in restricted environments\n   # If available: pnpm test:e2e (takes variable time depending on tests)\n   ```\n\n3. **Run Development Servers**:\n\n   ```bash\n   # Start backend (in one terminal)\n   cd backend\n   export PATH=\"$HOME/.local/bin:$PATH\"\n   uv run chainlit run chainlit/sample/hello.py -h\n   # Available at http://localhost:8000\n\n   # Start frontend dev server (in another terminal)\n   cd frontend\n   pnpm run dev\n   # Available at http://localhost:5173/\n   ```\n\n## Validation\n\n### Manual Validation Requirements\n\n- **ALWAYS** manually validate any changes by running complete scenarios.\n- **ALWAYS** test the Chainlit application after making changes.\n- Create a test app and verify it runs: `uv run chainlit run /path/to/test.py -h`\n- **ALWAYS** run through at least one complete user workflow after making changes.\n\n### Linting and Formatting - takes ~2 minutes, NEVER CANCEL\n\n```bash\n# Lint (check)\npnpm lint\n# Timeout: Use 300+ seconds (5+ minutes)\n\n# Lint (auto-fix)\npnpm lint:fix\n\n# Check formatting\npnpm format-check\n\n# Fix formatting\npnpm format\n\n# Python (scripts/ wrappers around ruff and mypy)\nuv run scripts/lint.py\nuv run scripts/format.py\nuv run scripts/format.py --check\n```\n\n### CI Requirements\n\n- **ALWAYS** run `pnpm lint` and `pnpm format-check` before committing or the CI (.github/workflows/ci.yaml) will fail.\n- The CI runs: pytest, lint-backend, lint-ui, and e2e-tests.\n- **NEVER CANCEL** any CI commands - they take time but must complete.\n\n## Key Project Structure\n\n### Repository Root\n\n```\n/\n├── README.md\n├── CONTRIBUTING.md\n├── package.json              # Root pnpm workspace config\n├── pnpm-workspace.yaml       # Workspace definition\n├── backend/                  # Python backend with uv\n├── frontend/                 # React frontend app\n├── libs/\n│   ├── react-client/         # React client library\n│   └── copilot/             # Copilot functionality\n├── cypress/                  # E2E tests\n└── .github/\n    ├── workflows/            # CI/CD pipelines\n    └── actions/              # Reusable GitHub actions\n```\n\n### Working with the Backend\n\n- **Technology**: Python 3.10+ with uv, FastAPI, SocketIO\n- **Entry point**: `backend/chainlit/`\n- **Tests**: `backend/tests/`\n- **Dependencies**: Defined in `backend/pyproject.toml`\n- **Hello app**: `backend/chainlit/sample/hello.py`\n\n### Working with the Frontend\n\n- **Technology**: React 18+ with Vite, TypeScript, Tailwind CSS\n- **Entry point**: `frontend/src/`\n- **Dependencies**: Defined in `frontend/package.json`\n- **Build output**: `frontend/dist/`\n\n## Common Tasks\n\n### Creating a New Chainlit App\n\n```python\n# Create app.py\nimport chainlit as cl\n\n@cl.on_message\nasync def main(message: cl.Message):\n    await cl.Message(content=f\"You said: {message.content}\").send()\n\n# Run it\nuv run chainlit run app.py -w\n```\n\n### Timing Expectations\n\n- **pnpm install**: ~3 minutes (may fail on Cypress - this is normal)\n- **uv install**: ~2 minutes\n- **pnpm build**: ~1 minute\n- **pnpm run lint**: ~2 minutes\n- **Backend tests**: ~17 seconds\n- **Frontend tests**: ~4 seconds\n- **pnpm format-check**: ~12 seconds\n- **pnpm format**: ~12 seconds\n\n### Common Gotchas\n\n- **NEVER CANCEL** long-running operations - they need time to complete.\n- Cypress download often fails in CI environments - this is expected.\n- Use `uv run` prefix for all Python commands in backend.\n- Use `export PATH=\"$HOME/.local/bin:$PATH\"` to ensure uv is available.\n- Python lint/format/type-check: use `uv run scripts/lint.py`, `uv run scripts/format.py`, `uv run scripts/type_check.py` from repo root.\n- Frontend dev server connects to backend at localhost:8000.\n- Always start backend before frontend for development.\n\n### File Locations for Quick Reference\n\n- **Main CLI**: `backend/chainlit/cli/`\n- **Server code**: `backend/chainlit/server.py`\n- **Frontend app**: `frontend/src/App.tsx`\n- **React client**: `libs/react-client/src/`\n- **CI workflows**: `.github/workflows/ci.yaml`\n- **uv config**: `backend/pyproject.toml`\n- **Frontend config**: `frontend/package.json`\n\n## Requirements\n\n- **Python**: >= 3.10\n- **Node.js**: >= 20 (24+ recommended)\n- **uv**: 2.1.3 (install via pipx)\n- **pnpm**: Latest (install via npm)\n</yakaai_skills>"}