-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add Agent.to_web() method and web chat UI #3456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 42 commits
1cfa48e
d83caa5
bfffd4b
055e120
6bc8b16
32f7e1d
cf0e177
e7f44eb
c4ffde3
0595c27
0d24941
e5b30c2
f2dd19a
8ca7a27
fa3bb5f
e45c93f
f90b570
da8032c
0ab07b6
191897f
1faae3f
8423e89
a32c15a
91f9533
441d6a0
558985f
85f63bc
cd91e81
a132f26
943c7a8
831bdf3
125c059
025f1b5
0701b22
40b5c78
0673277
974bac2
4b58307
74f09e9
897e4e4
10d32fe
1c93cf0
b60f2ff
ee21cfb
cf1da90
372db8b
32cc5c5
48094d2
cd1e683
c1ba780
6984dfd
cf54985
106c8b9
f491e57
16e36dc
48bd838
b45156c
3733a56
b57fb38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,10 +51,73 @@ Either way, running `clai` will start an interactive session where you can chat | |
| - `/multiline`: Toggle multiline input mode (use Ctrl+D to submit) | ||
| - `/cp`: Copy the last response to clipboard | ||
|
|
||
| ## Web Chat UI | ||
|
|
||
| Launch a web-based chat interface for your agent: | ||
|
|
||
| ```bash | ||
| clai web --agent module:agent_variable | ||
| ``` | ||
|
|
||
| For example, if you have an agent defined in `my_agent.py`: | ||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
|
|
||
| my_agent = Agent('openai:gpt-5', system_prompt='You are a helpful assistant.') | ||
dsfaccini marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| Launch the web UI with: | ||
|
|
||
| ```bash | ||
| clai web --agent my_agent:my_agent | ||
| ``` | ||
|
|
||
| This will start a web server (default: http://127.0.0.1:7932) with a chat interface for your agent. | ||
|
|
||
| ### Web Command Options | ||
|
|
||
| - `--agent`, `-a`: Agent to serve in `module:variable` format | ||
| - `--models`, `-m`: Comma-separated models to make available (e.g., `gpt-5,sonnet-4-5`) | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `--tools`, `-t`: Comma-separated builtin tool IDs to enable (e.g., `web_search,code_execution`) | ||
|
||
| - `--instructions`, `-i`: System instructions for generic agent (when `--agent` not specified) | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `--host`: Host to bind the server to (default: 127.0.0.1) | ||
| - `--port`: Port to bind the server to (default: 7932) | ||
|
|
||
| ### Using with Models and Tools | ||
|
|
||
| You can specify which models and builtin tools are available in the UI via CLI flags: | ||
|
|
||
| ```bash | ||
| # Generic agent with specific models and tools | ||
| clai web -m gpt-5,sonnet-4-5 -t web_search,code_execution | ||
|
|
||
| # Custom agent with additional models | ||
| clai web --agent my_agent:my_agent -m gpt-5,gemini-2.5-pro | ||
|
|
||
| # Generic agent with system instructions | ||
| clai web -m gpt-5 -i 'You are a helpful coding assistant' | ||
| ``` | ||
|
|
||
| You can also launch the web UI directly from an `Agent` instance using `Agent.to_web()`: | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
| from pydantic_ai.builtin_tools import WebSearchTool | ||
|
|
||
| agent = Agent('openai:gpt-5') | ||
|
|
||
| # Use defaults | ||
| app = agent.to_web() | ||
|
|
||
| # Or customize models and tools | ||
| app = agent.to_web(builtin_tools=[WebSearchTool()]) | ||
| ``` | ||
|
|
||
dsfaccini marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ## Help | ||
|
|
||
| ``` | ||
| usage: clai [-h] [-m [MODEL]] [-a AGENT] [-l] [-t [CODE_THEME]] [--no-stream] [--version] [prompt] | ||
| usage: clai [-h] [-m [MODEL]] [-a AGENT] [-l] [-t [CODE_THEME]] [--no-stream] [--version] [prompt] {web} ... | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Pydantic AI CLI v... | ||
|
|
||
|
|
@@ -66,6 +129,8 @@ Special prompts: | |
|
|
||
| positional arguments: | ||
| prompt AI Prompt, if omitted fall into interactive mode | ||
| {web} Available commands | ||
| web Launch web chat UI for an agent | ||
|
|
||
| options: | ||
| -h, --help show this help message and exit | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,32 @@ Either way, running `clai` will start an interactive session where you can chat | |
| - `/multiline`: Toggle multiline input mode (use Ctrl+D to submit) | ||
| - `/cp`: Copy the last response to clipboard | ||
|
|
||
| ### Web Chat UI | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a lot of duplication here with
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I wasn't sure about it as well, I thought there maybe be people who look more at the repo than the docs, I know I sometimes do, so I left it in both places, but I can just link to the docs from the readme. |
||
|
|
||
| Launch a web-based chat interface for your agent: | ||
|
|
||
| ```bash | ||
| clai web --agent module:agent_variable | ||
| ``` | ||
|
|
||
| For example, if you have an agent defined in `my_agent.py`: | ||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
|
|
||
| my_agent = Agent('openai:gpt-5', instructions='You are a helpful assistant.') | ||
| ``` | ||
|
|
||
| Launch the web UI with: | ||
|
|
||
| ```bash | ||
| clai web --agent my_agent:my_agent | ||
| ``` | ||
|
|
||
| This will start a web server (default: http://127.0.0.1:7932) with a chat interface for your agent. | ||
|
|
||
| For more details on web UI options, MCP server configuration, and programmatic usage with `Agent.to_web()`, see the [Web Chat UI documentation](ui/web.md). | ||
|
|
||
| ### Help | ||
|
|
||
| To get help on the CLI, use the `--help` flag: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| # Web Chat UI | ||
|
|
||
| Pydantic AI includes a built-in web chat interface that you can use to interact with your agents through a browser. | ||
|
|
||
| <!-- TODO: Add screenshot of the web chat UI here --> | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Installation | ||
|
|
||
| Install the `web` extra to get the required dependencies: | ||
|
|
||
| ```bash | ||
| pip/uv-add 'pydantic-ai-slim[web]' | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| There are two ways to launch the web chat UI: | ||
|
|
||
| ### 1. Using the CLI (`clai web`) | ||
|
|
||
| The simplest way to start the web UI is using the `clai web` command: | ||
|
|
||
| ```bash | ||
| # With a custom agent | ||
| clai web --agent my_module:my_agent | ||
|
|
||
| # With specific models | ||
| clai web -m openai:gpt-5 -m anthropic:claude-sonnet-4-5 | ||
|
|
||
| # With builtin tools | ||
| clai web -m openai:gpt-5 -t web_search -t code_execution | ||
|
|
||
| # Generic agent with system instructions | ||
| clai web -m openai:gpt-5 -i 'You are a helpful coding assistant' | ||
| ``` | ||
|
|
||
| #### CLI Options | ||
|
|
||
| | Option | Description | | ||
| |--------|-------------| | ||
| | `--agent`, `-a` | Agent to serve in `module:variable` format | | ||
| | `--model`, `-m` | Model to make available (repeatable) | | ||
| | `--tool`, `-t` | Builtin tool to enable (repeatable) | | ||
| | `--instructions`, `-i` | System instructions (when `--agent` not specified) | | ||
| | `--host` | Host to bind server (default: 127.0.0.1) | | ||
| | `--port` | Port to bind server (default: 7932) | | ||
| | `--mcp` | Path to MCP server config JSON file | | ||
|
||
|
|
||
| Model names without a provider prefix are automatically inferred: | ||
|
|
||
| - `gpt-*`, `o1`, `o3` → OpenAI | ||
| - `claude-*`, `sonnet`, `opus`, `haiku` → Anthropic | ||
| - `gemini-*` → Google | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### 2. Using `Agent.to_web()` Programmatically | ||
|
||
|
|
||
| For more control, you can create a web app from an agent instance: | ||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
| from pydantic_ai.builtin_tools import WebSearchTool | ||
|
|
||
| agent = Agent('openai:gpt-5') | ||
|
|
||
| @agent.tool_plain | ||
| def get_weather(city: str) -> str: | ||
| return f'The weather in {city} is sunny' | ||
|
|
||
| # Create app with model names (their display names are auto-generated) | ||
| app = agent.to_web( | ||
| models=['openai:gpt-5', 'anthropic:claude-sonnet-4-5'], | ||
| builtin_tools=[WebSearchTool()], | ||
| ) | ||
|
|
||
| # Or with custom display labels | ||
| app = agent.to_web( | ||
| models={'GPT 5': 'openai:gpt-5', 'Claude': 'anthropic:claude-sonnet-4-5'}, | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| builtin_tools=[WebSearchTool()], | ||
| ) | ||
| ``` | ||
|
|
||
| The returned Starlette app can be run with any ASGI server: | ||
|
|
||
| ```bash | ||
| uvicorn my_module:app --host 0.0.0.0 --port 8080 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the same port the CLI uses |
||
| ``` | ||
|
|
||
| !!! note "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. | ||
|
|
||
| ## MCP Server Configuration | ||
|
|
||
| You can enable [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) servers using a JSON configuration file: | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```bash | ||
| clai web --agent my_agent:my_agent --mcp mcp-servers.json | ||
| ``` | ||
|
|
||
| Example JSON configuration: | ||
|
|
||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "deepwiki": { | ||
| "url": "https://mcp.deepwiki.com/mcp" | ||
| }, | ||
| "github": { | ||
| "url": "https://api.githubcopilot.com/mcp", | ||
| "authorizationToken": "${GITHUB_TOKEN}" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Environment variables can be referenced using `${VAR_NAME}` syntax, with optional defaults: `${VAR_NAME:-default_value}`. | ||
|
|
||
| Each server entry supports: | ||
|
|
||
| | Field | Description | | ||
| |-------|-------------| | ||
| | `url` (required) | The MCP server URL | | ||
| | `authorizationToken` | Authorization token for the server | | ||
| | `description` | Description shown in the UI | | ||
| | `allowedTools` | List of allowed tool names | | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| | `headers` | Additional HTTP headers | | ||
|
|
||
| ## Builtin Tool Support | ||
|
||
|
|
||
| When using the new models API, builtin tool support is automatically determined from each model's profile. The UI will only show tools that the selected model supports. | ||
|
|
||
| Available builtin tools: | ||
|
|
||
| - `web_search` - Web search capability | ||
| - `code_execution` - Code execution in a sandbox | ||
| - `image_generation` - Image generation | ||
| - `web_fetch` - Fetch content from URLs | ||
| - `memory` - Persistent memory across conversations | ||
|
|
||
| !!! note "Memory Tool Requirements" | ||
| The `memory` tool requires the agent to have memory configured via the | ||
| `memory` parameter when creating the agent. It cannot be enabled via | ||
| the CLI `-t memory` flag alone - an agent with memory must be provided | ||
| via `--agent`. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's first have an example without an agent, to show that it will work that way as well