cdd605c672
This pull request was posted by Claude Code using claude-opus-5 on behalf of David. David has not reviewed this diff line by line. Closes https://github.com/CopilotKit/CopilotKit/issues/6363 `Agent.to_ag_ui()`, `AGUIApp` and the whole `pydantic_ai.ag_ui` module were removed in Pydantic AI v2. The docs installed pydantic-ai unpinned, so following the quickstart today gets 2.22.0 and fails twice: first at resolution (`starlette==0.45.3` conflicts with the `>=0.46.2` the `ag-ui` extra requires), then at `AttributeError`. ## What changed **8 doc pages** under `showcase/shell-docs/src/content/docs/integrations/pydantic-ai/` (`quickstart.mdx`, `quickstart/pydantic-ai.mdx`, `human-in-the-loop.mdx`, `human-in-the-loop/agent.mdx`, `generative-ui/tool-rendering.mdx`, and the three `shared-state/` pages): - the agent is served from a Starlette route via `AGUIAdapter.dispatch_request(request, agent=agent)` - `StateDeps` imports move from `pydantic_ai.ag_ui` to `pydantic_ai.ui` - install commands exact-pin `pydantic-ai-slim[ag-ui,openai]==2.22.0` and `ag-ui-protocol==0.1.19`, matching the starter fleet, plus `starlette>=0.46.2` since the snippets import Starlette directly **Per-request deps.** Every stateful snippet builds `StateDeps` inside the request handler: ```python async def run_agent(request: Request) -> Response: return await AGUIAdapter.dispatch_request( request, agent=agent, deps=StateDeps(AgentState()) ) ``` `dispatch_request` validates the client's state into `deps.state` (`pydantic_ai/ui/_adapter.py`, `run_stream_native`), so a module-level instance shared across requests lets concurrent runs clobber each other. The old `to_ag_ui(deps=...)` snippets all did this. **`examples/canvas/pydantic-ai`** — `requirements.txt` pinned, `agent/agent.py` ported, README corrected. **`examples/showcases/pydantic-ai-todos`** — `pyproject.toml` pinned and `uv.lock` regenerated (it was still resolving 1.0.10), `agent/main.py` ported, `src/agent.py` and `src/tools.py` imports moved, README and `src/app/api/copilotkit/route.ts` comments corrected. **`skills/copilotkit-integrations`** — beyond the issue's file list: `SKILL.md`, `sources.md` and `references/integrations/pydantic-ai.md` also taught `to_ag_ui()`. Same rot, same fix. ## Verified by execution The reason these docs rotted is that nothing runs them, so everything below was actually run, not read. - Both install commands were run verbatim in throwaway environments. `uv add 'pydantic-ai-slim[ag-ui,openai]==2.22.0' 'ag-ui-protocol==0.1.19' 'starlette>=0.46.2' uvicorn` and the `pip install` equivalent both resolve, landing pydantic-ai-slim 2.22.0, ag-ui-protocol 0.1.19, starlette 1.3.1. - Every ```python fence on the 8 doc pages was extracted, `exec`'d, and driven with a real `RunAgentInput` POST through `starlette.testclient.TestClient` with the model overridden to `TestModel`. All 8 return 200 `text/event-stream` with a `RUN_STARTED` ... `RUN_FINISHED` sequence and no `RUN_ERROR`. - The canvas agent was installed from its `requirements.txt` and driven the same way: 200, SSE, `RUN_STARTED` ... `TOOL_CALL_*` ... `STATE_SNAPSHOT` ... `RUN_FINISHED`. - The todos agent was installed with `uv sync --frozen` from the regenerated lock and driven the same way. Two sequential requests, one seeding a todo and one sending empty state, each saw only their own state, confirming the per-request deps actually isolate. Not executed: the Next.js frontends and the docs site build (no `node_modules` in this checkout). The TypeScript edits are comment-only. ## Deliberately out of scope `showcase/integrations/pydantic-ai` is left on its v1 fleet pin. It is 418 files, 19 mounts and 190 e2e specs, and CopilotKit said they will take it as https://github.com/CopilotKit/CopilotKit/issues/6364. The dojo and the docs therefore diverge until that lands. The CI guard from the issue's last acceptance criterion is not built here. A proposal for it is posted on https://github.com/CopilotKit/CopilotKit/issues/6363 for the team to own. Two pre-existing malformed code fences were fixed in passing, because leaving them meant the ported snippets still would not run: `quickstart/pydantic-ai.mdx` and `shared-state/predictive-state-updates.mdx` each had TypeScript embedded inside an unterminated ```python fence. The TypeScript now sits in its own fence. Overlaps with https://github.com/CopilotKit/CopilotKit/pull/6355, which ports `examples/integrations/pydantic-ai`. No file overlap.