-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Open
dsfaccini
wants to merge
51
commits into
pydantic:main
Choose a base branch
from
dsfaccini:clai-chat
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,950
−142
Open
Changes from 17 commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
1cfa48e
add Agent.to_web() method and web chat UI module #3295
dsfaccini d83caa5
add "web" group
dsfaccini bfffd4b
try import create_chat_app
dsfaccini 055e120
fix tests to run on CI
dsfaccini 6bc8b16
fix example to use tool_plain
dsfaccini 32f7e1d
add clai web - tested with uv run clai web
dsfaccini cf0e177
wip: remove agent discovery and fix tests
dsfaccini e7f44eb
rename command
dsfaccini c4ffde3
rename function
dsfaccini 0595c27
- define builtin tool ids
dsfaccini 0d24941
fix tests
dsfaccini e5b30c2
- update CLI commands and improve agent loading mechanism
dsfaccini f2dd19a
Merge branch 'main' into clai-chat
dsfaccini 8ca7a27
import sorting
dsfaccini fa3bb5f
more import sorting
dsfaccini e45c93f
covergae?
dsfaccini f90b570
Merge upstream/main into clai-chat
dsfaccini da8032c
Merge upstream/main into clai-chat
dsfaccini 0ab07b6
- remove agent_options - add supported_builtin_tools - swap fastapi f…
dsfaccini 191897f
refactor from --web to web, adjust flags, add tests, update docs
dsfaccini 1faae3f
remove clai import on test
dsfaccini 8423e89
coverage
dsfaccini a32c15a
- consolidate web docs in own doc
dsfaccini 91f9533
remove memory cache and swap prints for consoles
dsfaccini 441d6a0
use snapshots where it makes sense
dsfaccini 558985f
Merge branch 'main' into clai-chat
dsfaccini 85f63bc
make _web a private module
dsfaccini cd91e81
move supported_builtin_tools to abstract tool set type
dsfaccini a132f26
warning about memory tool
dsfaccini 943c7a8
move name formatting to model method
dsfaccini 831bdf3
move to toolsets
dsfaccini 125c059
update docstring
dsfaccini 025f1b5
take agent's own model into account
dsfaccini 0701b22
bit of docs
dsfaccini 40b5c78
move builtin tool support to profile and move check to base model class
dsfaccini 0673277
fix test profile classes to avoid ci api key error
dsfaccini 974bac2
Merge branch 'main' into clai-chat
dsfaccini 4b58307
coverage
dsfaccini 74f09e9
add anthropic prefix
dsfaccini 897e4e4
fix naming
dsfaccini 10d32fe
remove get agent utility and make supported builtin tools a classmethod
dsfaccini 1c93cf0
remove test
dsfaccini b60f2ff
Add screenshot link for web chat UI
dsfaccini ee21cfb
- remove builtin_tools suport check for specific models, base model t…
dsfaccini cf1da90
support double instructions
dsfaccini 372db8b
remove program check, tie tool arg options to constant and set up aut…
dsfaccini 32cc5c5
merge
dsfaccini 48094d2
add support for model instances, deps and settings
dsfaccini cd1e683
fix tests after cli adjustments
dsfaccini c1ba780
separate chat command
dsfaccini 6984dfd
Merge branch 'main' into clai-chat
dsfaccini File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """Chat UI module for clai.""" | ||
|
|
||
| from .cli import run_web_command | ||
|
|
||
| __all__ = ['run_web_command'] |
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| """CLI command for launching a web chat UI for discovered agents.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import importlib.util | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
| from pydantic import BaseModel, ImportString, ValidationError | ||
|
|
||
| from pydantic_ai import Agent | ||
| from pydantic_ai.ui.web import AIModel, BuiltinToolDef, create_web_app | ||
|
|
||
|
|
||
| def load_agent_options( | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| config_path: Path, | ||
| ) -> tuple[list[AIModel] | None, list[BuiltinToolDef] | None]: | ||
| """Load agent options from a config file. | ||
| Args: | ||
| config_path: Path to the config file (e.g., agent_options.py) | ||
| """ | ||
| if not config_path.exists(): | ||
| return None, None | ||
|
|
||
| try: | ||
| spec = importlib.util.spec_from_file_location('agent_options_config', config_path) | ||
| if spec is None or spec.loader is None: | ||
| print(f'Warning: Could not load config from {config_path}') | ||
| return None, None | ||
|
|
||
| module = importlib.util.module_from_spec(spec) | ||
| spec.loader.exec_module(module) | ||
|
|
||
| models = getattr(module, 'models', None) | ||
| builtin_tool_defs = getattr(module, 'builtin_tool_definitions', None) | ||
|
|
||
| return models, builtin_tool_defs | ||
|
|
||
| except Exception as e: | ||
| print(f'Warning: Error loading config from {config_path}: {e}') | ||
| return None, None | ||
|
|
||
|
|
||
| class _AgentLoader(BaseModel): | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """Helper model for loading agents using Pydantic's ImportString.""" | ||
|
|
||
| agent: ImportString # type: ignore[valid-type] | ||
|
|
||
|
|
||
| def load_agent(agent_path: str) -> Agent | None: | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """Load an agent from module path in uvicorn style. | ||
| Args: | ||
| agent_path: Path in format 'module:variable', e.g. 'test_agent:my_agent' | ||
| Returns: | ||
| Agent instance or None if loading fails | ||
| """ | ||
| sys.path.insert(0, str(Path.cwd())) | ||
|
|
||
| try: | ||
| loader = _AgentLoader(agent=agent_path) | ||
| agent = loader.agent # type: ignore[reportUnknownVariableType] | ||
|
|
||
| if not isinstance(agent, Agent): | ||
| print(f'Error: {agent_path} is not an Agent instance') | ||
| return None | ||
|
|
||
| return agent # pyright: ignore[reportUnknownVariableType] | ||
|
|
||
| except ValidationError as e: | ||
| print(f'Error loading agent from {agent_path}: {e}') | ||
| return None | ||
|
|
||
|
|
||
| def run_web_command( | ||
| agent_path: str, | ||
| host: str = '127.0.0.1', | ||
| port: int = 8000, | ||
| config_path: Path | None = None, | ||
| auto_config: bool = True, | ||
| ) -> int: | ||
| """Run the chat command to serve an agent via web UI. | ||
| Args: | ||
| agent_path: Agent path in 'module:variable' format, e.g. 'test_agent:my_agent' | ||
| host: Host to bind the server to | ||
| port: Port to bind the server to | ||
| config_path: Path to agent_options.py config file | ||
| auto_config: Auto-discover agent_options.py in current directory | ||
| """ | ||
| agent = load_agent(agent_path) | ||
| if agent is None: | ||
| return 1 | ||
|
|
||
| models, builtin_tool_defs = None, None | ||
| if config_path: | ||
| print(f'Loading config from {config_path}...') | ||
| models, builtin_tool_defs = load_agent_options(config_path) | ||
| elif auto_config: | ||
| default_config = Path.cwd() / 'agent_options.py' | ||
| if default_config.exists(): | ||
| print(f'Found config file: {default_config}') | ||
| models, builtin_tool_defs = load_agent_options(default_config) | ||
|
|
||
| app = create_web_app(agent, models=models, builtin_tool_defs=builtin_tool_defs) | ||
|
|
||
| print(f'\nStarting chat UI for {agent_path}...') | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| print(f'Open your browser at: http://{host}:{port}') | ||
| print('Press Ctrl+C to stop the server\n') | ||
|
|
||
| try: | ||
| import uvicorn | ||
|
|
||
| uvicorn.run(app, host=host, port=port) | ||
| return 0 | ||
| except KeyboardInterrupt: | ||
| print('\nServer stopped.') | ||
| return 0 | ||
| except ImportError: | ||
| print('Error: uvicorn is required to run the chat UI') | ||
| print('Install it with: pip install uvicorn') | ||
dsfaccini marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return 1 | ||
| except Exception as e: | ||
| print(f'Error starting server: {e}') | ||
| return 1 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.