Files
wehub-resource-sync 9201ef759e
CI / lint (push) Waiting to run
CI / mypy (push) Waiting to run
CI / docs (push) Waiting to run
CI / test on 3.10 (standard) (push) Waiting to run
CI / test on 3.11 (standard) (push) Waiting to run
CI / test on 3.12 (standard) (push) Waiting to run
CI / test on 3.10 (all-extras) (push) Waiting to run
CI / test on 3.11 (all-extras) (push) Waiting to run
CI / test on 3.12 (all-extras) (push) Waiting to run
CI / test on 3.13 (all-extras) (push) Waiting to run
CI / test on 3.14 (pydantic-evals) (push) Waiting to run
CI / test on 3.13 (standard) (push) Waiting to run
CI / test on 3.14 (standard) (push) Waiting to run
CI / test on 3.14 (all-extras) (push) Waiting to run
CI / test on 3.10 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.11 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.12 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.13 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.14 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.10 (pydantic-evals) (push) Waiting to run
CI / test on 3.11 (pydantic-evals) (push) Waiting to run
CI / test on 3.12 (pydantic-evals) (push) Waiting to run
CI / test on 3.13 (pydantic-evals) (push) Waiting to run
CI / test on 3.10 (lowest-versions) (push) Waiting to run
CI / test on 3.11 (lowest-versions) (push) Waiting to run
CI / test on 3.12 (lowest-versions) (push) Waiting to run
CI / test on 3.13 (lowest-versions) (push) Waiting to run
CI / test on 3.14 (lowest-versions) (push) Waiting to run
CI / test examples on 3.11 (push) Waiting to run
CI / test examples on 3.12 (push) Waiting to run
CI / test examples on 3.13 (push) Waiting to run
CI / test examples on 3.14 (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / check (push) Blocked by required conditions
CI / deploy-docs (push) Blocked by required conditions
CI / deploy-docs-preview (push) Blocked by required conditions
CI / build release artifacts (push) Blocked by required conditions
CI / publish to PyPI (push) Blocked by required conditions
CI / Send tweet (push) Blocked by required conditions
Harness Compat / harness compat (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 13:27:52 +08:00

147 lines
4.8 KiB
Markdown

# Web Chat UI
Pydantic AI includes a built-in web chat interface that you can use to interact with your agents through a browser.
![Web Chat UI](img/web-chat-ui.png)
For CLI usage with `clai web`, see the [CLI - Web Chat UI documentation](cli.md#web-chat-ui).
!!! note
The web UI is meant for local development and debugging. In production, you can use one of the [UI Event Stream integrations](ui/overview.md) to connect your agent to a custom frontend.
## Installation
Install the `web` extra (installs Starlette and Uvicorn):
```bash
pip/uv-add 'pydantic-ai-slim[web]'
```
## Basic Usage
Create a web app from an agent instance using [`Agent.to_web()`][pydantic_ai.agent.Agent.to_web]:
```python
from pydantic_ai import Agent
agent = Agent('openai:gpt-5.2', instructions='You are a helpful assistant.')
@agent.tool_plain
def get_weather(city: str) -> str:
return f'The weather in {city} is sunny'
app = agent.to_web()
```
Run the app with any ASGI server:
```bash
uvicorn my_module:app --host 127.0.0.1 --port 7932
```
## Configuring Models
You can specify additional models to make available in the UI. Models can be provided as a list of model names/instances or a dictionary mapping display labels to model names/instances.
```python
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
# Model with custom configuration
anthropic_model = AnthropicModel('claude-sonnet-4-5')
agent = Agent('openai:gpt-5.2')
app = agent.to_web(
models=['openai:gpt-5.2', anthropic_model],
)
# Or with custom display labels
app = agent.to_web(
models={'GPT 5.2': 'openai:gpt-5.2', 'Claude': anthropic_model},
)
```
## Native Tool Support
Configure [native tools](native-tools.md) on the agent with `capabilities=[NativeTool(...)]` to expose them as options in the UI (shown only for models that support each tool):
```python
from pydantic_ai import Agent
from pydantic_ai.capabilities import NativeTool
from pydantic_ai.native_tools import CodeExecutionTool, WebSearchTool
agent = Agent(
'openai:gpt-5.2',
capabilities=[NativeTool(CodeExecutionTool()), NativeTool(WebSearchTool())],
)
app = agent.to_web(models=['anthropic:claude-sonnet-4-6'])
```
!!! note "Memory Tool"
The `memory` native tool is not supported via `to_web()` or `clai web`. If your agent needs memory, configure the [`MemoryTool`][pydantic_ai.native_tools.MemoryTool] directly on the agent at construction time.
## Extra Instructions
You can pass extra instructions that will be included in each agent run:
```python
from pydantic_ai import Agent
agent = Agent('openai:gpt-5.2')
app = agent.to_web(instructions='Always respond in a friendly tone.')
```
## Tool Approval
Tools that [require approval](deferred-tools.md#human-in-the-loop-tool-approval) are surfaced in the UI as approve/reject prompts: when the agent calls such a tool, the UI renders the pending call and lets you approve or deny it before the run continues. This works out of the box — no extra configuration is needed.
!!! warning
The chat endpoint executes tool approvals relayed by the client, including for tools marked `requires_approval=True`. The server trusts the approval decision it receives, so a client with direct access to the endpoint can approve any pending call. As noted above, the web UI is meant for local development — this is fine when it's bound to localhost, but do not expose `to_web()` to untrusted clients without putting authentication in front of it.
## Reserved Routes
The web UI app uses the following routes which should not be overwritten:
- `/` and `/{id}` - Serves the chat UI
- `/api/chat` - Chat endpoint (POST, OPTIONS)
- `/api/configure` - Frontend configuration (GET)
- `/api/health` - Health check (GET)
The app cannot currently be mounted at a subpath (e.g., `/chat`) because the UI expects these routes at the root. You can add additional routes to the app, but avoid conflicts with these reserved paths.
## Custom HTML Source
By default, the web UI is fetched from a CDN and cached locally. You can provide `html_source` to override this for offline usage or enterprise environments.
For offline usage, download the html file once while you have internet access:
```python
from pydantic_ai.ui import DEFAULT_HTML_URL
print(DEFAULT_HTML_URL) # Use this URL to download the UI HTML file
#> https://cdn.jsdelivr.net/npm/@pydantic/ai-chat-ui@2.0.0/dist/index.html
```
You can then download the file using the URL printed above:
```bash
curl -o ~/pydantic-ai-ui.html <chat_ui_url>
```
Then use `html_source` to point to your local file or custom URL:
```python
from pydantic_ai import Agent
agent = Agent('openai:gpt-5.2')
# Use a local file (e.g., for offline usage)
app = agent.to_web(html_source='~/pydantic-ai-ui.html')
# Or use a custom URL (e.g., for enterprise environments)
app = agent.to_web(html_source='https://cdn.example.com/ui/index.html')
```