meshagent-cli 0.49.1__tar.gz → 0.50.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/PKG-INFO +17 -17
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/chatbot.py +2 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/cli_test.py +21 -1
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/containers.py +5 -3
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/image.py +7 -3
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/image_test.py +18 -3
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/mailbot.py +2 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/process.py +102 -2
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/process_test.py +40 -2
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/room_connect.py +9 -3
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/room_connect_test.py +12 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/rooms.py +21 -6
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/rooms_test.py +60 -3
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/service_accounts.py +1 -1
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/service_accounts_test.py +19 -12
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/services.py +75 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/services_test.py +67 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/task_runner.py +2 -0
- meshagent_cli-0.50.1/meshagent/cli/version.py +1 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/webserver.py +6 -1
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/worker.py +2 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent_cli.egg-info/PKG-INFO +17 -17
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent_cli.egg-info/requires.txt +16 -16
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/pyproject.toml +16 -16
- meshagent_cli-0.49.1/meshagent/cli/version.py +0 -1
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/LICENSE +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/README.md +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/__init__.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/_filedrop.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/agent.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/agent_cli_options_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/agent_package_cli.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/agent_package_cli_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/agents.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/agents_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/ask.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/ask_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/async_typer.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/async_typer_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/auth.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/auth_async.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/auth_async_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/auth_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/call.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/cli.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/cli_mcp.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/common_options.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/config.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/config_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/containers_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/__init__.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/backend-agent/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/contact-form/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/slack-channel/channel.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/slack-channel/scripts/configure-slack.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/slack-channel/scripts/setup-slack-dev-route.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/slack-channel/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/task-queue-dashboard/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/telegram-channel/channel.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/configure-telegram.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/create-bot-token.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/telegram-channel/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/twilio-channel/channel.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/twilio-channel/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/webserver/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/whatsapp-channel/channel.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_project_templates/python/whatsapp-channel/server.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/create_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/dataset.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/dataset_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/developer.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/developer_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/doctor.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/doctor_dockerfiles/__init__.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/doctor_templates/__init__.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/doctor_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/feeds.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/feeds_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/helper.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/helper_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/helpers.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/host.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/iam.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/iam_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/launch.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/launch_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/llm.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/llm_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/local_settings.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/local_settings_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/mailbot_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/mailboxes.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/mailboxes_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/meeting_transcriber.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/memory.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/memory_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/meshagent_images.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/meshagent_images_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/messaging.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/messaging_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/mounts.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/multi.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/oci_archive.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/oci_archive_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/participant_token.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/port.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/port_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/preamble_rules.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/preamble_rules_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/process_live_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/projects.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/projects_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/queue.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/queue_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/registry.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/registry_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/room.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/room_services.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/room_services_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/root_commands.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/root_commands_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/routes.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/routes_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sample_channel_http_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sample_channel_live_e2e_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/scheduled_tasks.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/scheduled_tasks_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/secrets.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/secrets_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sessions.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sessions_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sqlite.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sqlite_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/storage.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/storage_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/subscriptions.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sync.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/sync_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/task_runner_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/testing.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/thread_inspect.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/thread_inspect_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/thread_sidebar.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tool_call_summary.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tool_call_summary_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tool_integrations.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tool_integrations_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/__init__.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/auth_switch.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/auth_switch_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/create.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/deploy_room.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/deploy_room_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/project_activate.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/project_activate_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/setup.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/setup_splash_frames.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/tui/setup_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/version_check.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/version_check_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/voicebot.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/volumes.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/volumes_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/webserver_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent/cli/worker_test.py +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent_cli.egg-info/SOURCES.txt +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent_cli.egg-info/dependency_links.txt +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent_cli.egg-info/entry_points.txt +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/meshagent_cli.egg-info/top_level.txt +0 -0
- {meshagent_cli-0.49.1 → meshagent_cli-0.50.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.50.1
|
|
4
4
|
Summary: CLI for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -22,8 +22,8 @@ Requires-Dist: openpyxl~=3.1
|
|
|
22
22
|
Requires-Dist: xlsxwriter~=3.2
|
|
23
23
|
Requires-Dist: pathspec<2,>=1.0.3
|
|
24
24
|
Requires-Dist: zstandard~=0.25.0
|
|
25
|
-
Requires-Dist: meshagent-llm-proxy==0.
|
|
26
|
-
Requires-Dist: meshagent-codex==0.
|
|
25
|
+
Requires-Dist: meshagent-llm-proxy==0.50.1
|
|
26
|
+
Requires-Dist: meshagent-codex==0.50.1
|
|
27
27
|
Requires-Dist: rich~=14.3.0
|
|
28
28
|
Requires-Dist: sounddevice~=0.5
|
|
29
29
|
Requires-Dist: textual<9.0,>=8.2.3
|
|
@@ -32,23 +32,23 @@ Requires-Dist: prompt-toolkit~=3.0.52
|
|
|
32
32
|
Requires-Dist: ascii-magic~=2.3
|
|
33
33
|
Requires-Dist: pillow~=11.3.0
|
|
34
34
|
Provides-Extra: all
|
|
35
|
-
Requires-Dist: meshagent-agents[all]==0.
|
|
36
|
-
Requires-Dist: meshagent-api[all]==0.
|
|
37
|
-
Requires-Dist: meshagent-commoncrawl==0.
|
|
38
|
-
Requires-Dist: meshagent-scrapy==0.
|
|
39
|
-
Requires-Dist: meshagent-computers==0.
|
|
40
|
-
Requires-Dist: meshagent-openai==0.
|
|
41
|
-
Requires-Dist: meshagent-anthropic==0.
|
|
42
|
-
Requires-Dist: meshagent-otel==0.
|
|
43
|
-
Requires-Dist: meshagent-mcp==0.
|
|
44
|
-
Requires-Dist: meshagent-tools==0.
|
|
35
|
+
Requires-Dist: meshagent-agents[all]==0.50.1; extra == "all"
|
|
36
|
+
Requires-Dist: meshagent-api[all]==0.50.1; extra == "all"
|
|
37
|
+
Requires-Dist: meshagent-commoncrawl==0.50.1; extra == "all"
|
|
38
|
+
Requires-Dist: meshagent-scrapy==0.50.1; extra == "all"
|
|
39
|
+
Requires-Dist: meshagent-computers==0.50.1; extra == "all"
|
|
40
|
+
Requires-Dist: meshagent-openai==0.50.1; extra == "all"
|
|
41
|
+
Requires-Dist: meshagent-anthropic==0.50.1; extra == "all"
|
|
42
|
+
Requires-Dist: meshagent-otel==0.50.1; extra == "all"
|
|
43
|
+
Requires-Dist: meshagent-mcp==0.50.1; extra == "all"
|
|
44
|
+
Requires-Dist: meshagent-tools==0.50.1; extra == "all"
|
|
45
45
|
Requires-Dist: supabase-auth~=2.28.0; extra == "all"
|
|
46
46
|
Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
|
|
47
47
|
Provides-Extra: mcp-service
|
|
48
|
-
Requires-Dist: meshagent-agents[all]==0.
|
|
49
|
-
Requires-Dist: meshagent-api==0.
|
|
50
|
-
Requires-Dist: meshagent-mcp==0.
|
|
51
|
-
Requires-Dist: meshagent-tools==0.
|
|
48
|
+
Requires-Dist: meshagent-agents[all]==0.50.1; extra == "mcp-service"
|
|
49
|
+
Requires-Dist: meshagent-api==0.50.1; extra == "mcp-service"
|
|
50
|
+
Requires-Dist: meshagent-mcp==0.50.1; extra == "mcp-service"
|
|
51
|
+
Requires-Dist: meshagent-tools==0.50.1; extra == "mcp-service"
|
|
52
52
|
Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
|
|
53
53
|
Dynamic: license-file
|
|
54
54
|
|
|
@@ -1471,6 +1471,8 @@ def _build_shell_tool_env(
|
|
|
1471
1471
|
env["MESHAGENT_TOKEN"] = room.protocol.token
|
|
1472
1472
|
env["OPENAI_API_KEY"] = room.protocol.token
|
|
1473
1473
|
env["ANTHROPIC_API_KEY"] = room.protocol.token
|
|
1474
|
+
env["GROK_API_KEY"] = room.protocol.token
|
|
1475
|
+
env["XAI_API_KEY"] = room.protocol.token
|
|
1474
1476
|
return env
|
|
1475
1477
|
|
|
1476
1478
|
|
|
@@ -4,7 +4,7 @@ import types
|
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
|
-
from meshagent.api import RoomException
|
|
7
|
+
from meshagent.api import RoomDisabledError, RoomException
|
|
8
8
|
from meshagent.agents import channel_process
|
|
9
9
|
from meshagent.cli import async_typer
|
|
10
10
|
from meshagent.cli import cli
|
|
@@ -134,6 +134,26 @@ def test_app_prints_room_exception_without_traceback(capsys) -> None:
|
|
|
134
134
|
assert captured.out == ""
|
|
135
135
|
|
|
136
136
|
|
|
137
|
+
def test_app_prints_disabled_room_message_and_exits_nonzero(capsys) -> None:
|
|
138
|
+
app = async_typer.AsyncTyper()
|
|
139
|
+
|
|
140
|
+
@app.callback()
|
|
141
|
+
def app_callback() -> None:
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
@app.command("connect")
|
|
145
|
+
def connect_command() -> None:
|
|
146
|
+
raise RoomDisabledError()
|
|
147
|
+
|
|
148
|
+
with pytest.raises(SystemExit) as exc_info:
|
|
149
|
+
app(["connect"])
|
|
150
|
+
|
|
151
|
+
assert exc_info.value.code == 1
|
|
152
|
+
captured = capsys.readouterr()
|
|
153
|
+
assert captured.err == "This room is currently disabled.\n"
|
|
154
|
+
assert captured.out == ""
|
|
155
|
+
|
|
156
|
+
|
|
137
157
|
def test_main_exits_with_status_returned_by_async_typer(monkeypatch) -> None:
|
|
138
158
|
monkeypatch.setattr(channel_process, "dispatch_main", lambda **kwargs: False)
|
|
139
159
|
monkeypatch.setattr(cli, "app", lambda: 23)
|
|
@@ -780,12 +780,14 @@ async def run_container(
|
|
|
780
780
|
"--template",
|
|
781
781
|
help=(
|
|
782
782
|
"Allowed values: agent, none. agent: MeshAgent mounts room storage "
|
|
783
|
-
"at /data, sets MESHAGENT_TOKEN, OPENAI_API_KEY,
|
|
784
|
-
"ANTHROPIC_API_KEY
|
|
783
|
+
"at /data, sets MESHAGENT_TOKEN, OPENAI_API_KEY, "
|
|
784
|
+
"ANTHROPIC_API_KEY, GROK_API_KEY, and XAI_API_KEY to a "
|
|
785
|
+
"container-scoped MeshAgent token. agent "
|
|
785
786
|
"also sets SMTP_PASSWORD to that token, SMTP_USERNAME to the "
|
|
786
787
|
"container name, SMTP_PORT to 587, SMTP_HOSTNAME from "
|
|
787
788
|
"MESHAGENT_MAIL_DOMAIN when available, plus OPENAI_BASE_URL, "
|
|
788
|
-
"ANTHROPIC_BASE_URL,
|
|
789
|
+
"ANTHROPIC_BASE_URL, GROK_BASE_URL, XAI_BASE_URL, "
|
|
790
|
+
"MESHAGENT_API_URL, MESHAGENT_ROOM_URL, "
|
|
789
791
|
"MESHAGENT_ROOM, MESHAGENT_PROJECT_ID, MESHAGENT_SESSION_ID, "
|
|
790
792
|
"OTEL_ENDPOINT, OTEL_PYTHON_LOG_LEVEL, and MESHAGENT_MAIL_DOMAIN "
|
|
791
793
|
"from the room runtime when available. Manual env values win. "
|
|
@@ -140,6 +140,8 @@ _TOKEN_ENVIRONMENT_NAMES = (
|
|
|
140
140
|
"MESHAGENT_TOKEN",
|
|
141
141
|
"OPENAI_API_KEY",
|
|
142
142
|
"ANTHROPIC_API_KEY",
|
|
143
|
+
"GROK_API_KEY",
|
|
144
|
+
"XAI_API_KEY",
|
|
143
145
|
)
|
|
144
146
|
_DEFAULT_MESHAGENT_IMAGE_PREFIX = PROD_MESHAGENT_IMAGE_PREFIX
|
|
145
147
|
_IMAGE_TAG_RE = re.compile(r"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$")
|
|
@@ -4584,12 +4586,14 @@ async def deploy_image(
|
|
|
4584
4586
|
"--template",
|
|
4585
4587
|
help=(
|
|
4586
4588
|
"Allowed values: agent, none. agent: MeshAgent mounts room storage "
|
|
4587
|
-
"at /data, sets MESHAGENT_TOKEN, OPENAI_API_KEY,
|
|
4588
|
-
"ANTHROPIC_API_KEY
|
|
4589
|
+
"at /data, sets MESHAGENT_TOKEN, OPENAI_API_KEY, "
|
|
4590
|
+
"ANTHROPIC_API_KEY, GROK_API_KEY, and XAI_API_KEY to a "
|
|
4591
|
+
"container-scoped MeshAgent token. agent "
|
|
4589
4592
|
"also sets SMTP_PASSWORD to that token, SMTP_USERNAME to the "
|
|
4590
4593
|
"container name, SMTP_PORT to 587, SMTP_HOSTNAME from "
|
|
4591
4594
|
"MESHAGENT_MAIL_DOMAIN when available, plus OPENAI_BASE_URL, "
|
|
4592
|
-
"ANTHROPIC_BASE_URL,
|
|
4595
|
+
"ANTHROPIC_BASE_URL, GROK_BASE_URL, XAI_BASE_URL, "
|
|
4596
|
+
"MESHAGENT_API_URL, MESHAGENT_ROOM_URL, "
|
|
4593
4597
|
"MESHAGENT_ROOM, MESHAGENT_PROJECT_ID, MESHAGENT_SESSION_ID, "
|
|
4594
4598
|
"OTEL_ENDPOINT, OTEL_PYTHON_LOG_LEVEL, and MESHAGENT_MAIL_DOMAIN "
|
|
4595
4599
|
"from the room runtime when available. Manual env values win. "
|
|
@@ -3131,7 +3131,12 @@ async def test_deploy_image_creates_room_service_with_mounts_env_secret_and_toke
|
|
|
3131
3131
|
assert env_by_name["MESHAGENT_TOKEN"].token.api.secrets is None
|
|
3132
3132
|
assert env_by_name["MESHAGENT_TOKEN"].token.api.services is not None
|
|
3133
3133
|
assert env_by_name["MESHAGENT_TOKEN"].token.role == "agent"
|
|
3134
|
-
for env_name in (
|
|
3134
|
+
for env_name in (
|
|
3135
|
+
"OPENAI_API_KEY",
|
|
3136
|
+
"ANTHROPIC_API_KEY",
|
|
3137
|
+
"GROK_API_KEY",
|
|
3138
|
+
"XAI_API_KEY",
|
|
3139
|
+
):
|
|
3135
3140
|
assert env_by_name[env_name].token is not None
|
|
3136
3141
|
assert env_by_name[env_name].token == env_by_name["MESHAGENT_TOKEN"].token
|
|
3137
3142
|
assert "restarted_service_id" not in captured
|
|
@@ -3208,7 +3213,12 @@ async def test_deploy_image_identity_overrides_env_secret_and_token_identity(
|
|
|
3208
3213
|
assert env_by_name["APP_SECRET"].secret == SecretValue(id="secret-1")
|
|
3209
3214
|
assert env_by_name["MESHAGENT_TOKEN"].token is not None
|
|
3210
3215
|
assert env_by_name["MESHAGENT_TOKEN"].token.identity == "custom-agent"
|
|
3211
|
-
for env_name in (
|
|
3216
|
+
for env_name in (
|
|
3217
|
+
"OPENAI_API_KEY",
|
|
3218
|
+
"ANTHROPIC_API_KEY",
|
|
3219
|
+
"GROK_API_KEY",
|
|
3220
|
+
"XAI_API_KEY",
|
|
3221
|
+
):
|
|
3212
3222
|
assert env_by_name[env_name].token is not None
|
|
3213
3223
|
assert env_by_name[env_name].token == env_by_name["MESHAGENT_TOKEN"].token
|
|
3214
3224
|
assert captured["room_client_closed"] is True
|
|
@@ -5252,7 +5262,12 @@ async def test_deploy_image_updates_existing_service_route_and_replaces_environm
|
|
|
5252
5262
|
assert env_by_name["MESHAGENT_TOKEN"].token.api.admin is not None
|
|
5253
5263
|
assert env_by_name["MESHAGENT_TOKEN"].token.api.secrets is None
|
|
5254
5264
|
assert env_by_name["MESHAGENT_TOKEN"].token.api.tunnels is not None
|
|
5255
|
-
for env_name in (
|
|
5265
|
+
for env_name in (
|
|
5266
|
+
"OPENAI_API_KEY",
|
|
5267
|
+
"ANTHROPIC_API_KEY",
|
|
5268
|
+
"GROK_API_KEY",
|
|
5269
|
+
"XAI_API_KEY",
|
|
5270
|
+
):
|
|
5256
5271
|
assert env_by_name[env_name].token is not None
|
|
5257
5272
|
assert env_by_name[env_name].token == env_by_name["MESHAGENT_TOKEN"].token
|
|
5258
5273
|
assert updated_spec.ports is not None
|
|
@@ -395,6 +395,8 @@ def build_mailbot(
|
|
|
395
395
|
env["MESHAGENT_TOKEN"] = self.room.protocol.token
|
|
396
396
|
env["OPENAI_API_KEY"] = self.room.protocol.token
|
|
397
397
|
env["ANTHROPIC_API_KEY"] = self.room.protocol.token
|
|
398
|
+
env["GROK_API_KEY"] = self.room.protocol.token
|
|
399
|
+
env["XAI_API_KEY"] = self.room.protocol.token
|
|
398
400
|
|
|
399
401
|
if require_shell:
|
|
400
402
|
if supports_openai_shell:
|
|
@@ -2178,6 +2178,7 @@ ThreadStorageBackends = ThreadStorageBackend | str | list[str] | tuple[str, ...]
|
|
|
2178
2178
|
DEFAULT_PROCESS_THREAD_STORAGE_BACKENDS: tuple[str, ...] = ("dataset",)
|
|
2179
2179
|
ContextManagementMode = Literal["auto", "standalone", "none"]
|
|
2180
2180
|
ProcessToolSearchMode = Literal["room", "agent", "none"]
|
|
2181
|
+
LlmDelegationPolicy = Literal["required", "optional"]
|
|
2181
2182
|
|
|
2182
2183
|
ShellCopyEnvOption = Annotated[
|
|
2183
2184
|
list[str],
|
|
@@ -3471,9 +3472,19 @@ def _provider_name_for_model(model: str) -> str:
|
|
|
3471
3472
|
return "openai-realtime"
|
|
3472
3473
|
if model.startswith("claude-"):
|
|
3473
3474
|
return "anthropic"
|
|
3475
|
+
if model.startswith("grok-"):
|
|
3476
|
+
return "grok"
|
|
3474
3477
|
return "openai"
|
|
3475
3478
|
|
|
3476
3479
|
|
|
3480
|
+
def _grok_base_url() -> str:
|
|
3481
|
+
for name in ("GROK_BASE_URL", "XAI_BASE_URL"):
|
|
3482
|
+
value = os.getenv(name)
|
|
3483
|
+
if value is not None and value.strip() != "":
|
|
3484
|
+
return value.strip()
|
|
3485
|
+
raise ValueError("GROK_BASE_URL or XAI_BASE_URL is required for Grok models")
|
|
3486
|
+
|
|
3487
|
+
|
|
3477
3488
|
def _normalize_thread_storage_backend(
|
|
3478
3489
|
thread_storage: str,
|
|
3479
3490
|
) -> NormalizedThreadStorageBackend:
|
|
@@ -4324,7 +4335,7 @@ def _format_model_list(
|
|
|
4324
4335
|
|
|
4325
4336
|
|
|
4326
4337
|
def _supports_openai_responses_builtin_tools(*, model: str) -> bool:
|
|
4327
|
-
return _provider_name_for_model(model)
|
|
4338
|
+
return _provider_name_for_model(model) in {"openai", "grok"}
|
|
4328
4339
|
|
|
4329
4340
|
|
|
4330
4341
|
def _supports_anthropic_builtin_tools(*, model: str) -> bool:
|
|
@@ -4337,7 +4348,8 @@ def _has_openai_responses_provider(
|
|
|
4337
4348
|
if llm_participant is not None:
|
|
4338
4349
|
return False
|
|
4339
4350
|
return any(
|
|
4340
|
-
spec.backend == "llm" and spec.provider
|
|
4351
|
+
spec.backend == "llm" and spec.provider in {"openai", "grok"}
|
|
4352
|
+
for spec in model_specs
|
|
4341
4353
|
)
|
|
4342
4354
|
|
|
4343
4355
|
|
|
@@ -4355,6 +4367,16 @@ def _build_decision_llm_adapter(
|
|
|
4355
4367
|
log_requests=log_llm_requests,
|
|
4356
4368
|
)
|
|
4357
4369
|
|
|
4370
|
+
if decision_model.startswith("grok-"):
|
|
4371
|
+
return OpenAIResponsesAdapter(
|
|
4372
|
+
model=decision_model,
|
|
4373
|
+
provider="grok",
|
|
4374
|
+
base_url=_grok_base_url(),
|
|
4375
|
+
api_key=api_key,
|
|
4376
|
+
mode="request",
|
|
4377
|
+
log_requests=log_llm_requests,
|
|
4378
|
+
)
|
|
4379
|
+
|
|
4358
4380
|
client = _openai_proxy_client(
|
|
4359
4381
|
api_key=api_key,
|
|
4360
4382
|
meshagent_project_id=meshagent_project_id,
|
|
@@ -4701,6 +4723,7 @@ def _build_runtime_agent(
|
|
|
4701
4723
|
verbose_dataset: bool = False,
|
|
4702
4724
|
save_audio_input: bool = False,
|
|
4703
4725
|
preamble_rule: bool = True,
|
|
4726
|
+
llm_delegation: LlmDelegationPolicy = "optional",
|
|
4704
4727
|
):
|
|
4705
4728
|
builder = _builder_for_runtime(runtime)
|
|
4706
4729
|
selected_models = (
|
|
@@ -4790,6 +4813,7 @@ def _build_runtime_agent(
|
|
|
4790
4813
|
builder_kwargs["preamble_rule"] = preamble_rule
|
|
4791
4814
|
builder_kwargs["websocket_auth"] = websocket_auth
|
|
4792
4815
|
builder_kwargs["room_token"] = room_token
|
|
4816
|
+
builder_kwargs["llm_delegation"] = llm_delegation
|
|
4793
4817
|
return builder(**builder_kwargs)
|
|
4794
4818
|
|
|
4795
4819
|
|
|
@@ -4857,6 +4881,8 @@ def _build_shell_tool_env(
|
|
|
4857
4881
|
env["MESHAGENT_TOKEN"] = room.protocol.token
|
|
4858
4882
|
env["OPENAI_API_KEY"] = room.protocol.token
|
|
4859
4883
|
env["ANTHROPIC_API_KEY"] = room.protocol.token
|
|
4884
|
+
env["GROK_API_KEY"] = room.protocol.token
|
|
4885
|
+
env["XAI_API_KEY"] = room.protocol.token
|
|
4860
4886
|
return env
|
|
4861
4887
|
|
|
4862
4888
|
|
|
@@ -5061,9 +5087,13 @@ def build_chatbot(
|
|
|
5061
5087
|
if resolved_decision_model is None:
|
|
5062
5088
|
resolved_decision_model = _DEFAULT_OPENAI_REALTIME_DECISION_MODEL
|
|
5063
5089
|
else:
|
|
5090
|
+
is_grok_model = model.startswith("grok-")
|
|
5064
5091
|
llm_adapter = OpenAIResponsesAdapter(
|
|
5065
5092
|
model=model,
|
|
5093
|
+
provider="grok" if is_grok_model else "openai",
|
|
5094
|
+
base_url=_grok_base_url() if is_grok_model else None,
|
|
5066
5095
|
api_key=api_key,
|
|
5096
|
+
mode="request" if is_grok_model else "websocket",
|
|
5067
5097
|
log_requests=log_llm_requests,
|
|
5068
5098
|
)
|
|
5069
5099
|
|
|
@@ -5482,6 +5512,7 @@ def build_process_agent(
|
|
|
5482
5512
|
verbose_dataset: bool = False,
|
|
5483
5513
|
save_audio_input: bool = False,
|
|
5484
5514
|
preamble_rule: bool = True,
|
|
5515
|
+
llm_delegation: LlmDelegationPolicy = "optional",
|
|
5485
5516
|
):
|
|
5486
5517
|
from meshagent.agents import (
|
|
5487
5518
|
AgentMessageThreadStatusPublisher,
|
|
@@ -5698,6 +5729,7 @@ def build_process_agent(
|
|
|
5698
5729
|
openai_models: list[str] = []
|
|
5699
5730
|
realtime_models: list[str] = []
|
|
5700
5731
|
anthropic_models: list[str] = []
|
|
5732
|
+
grok_models: list[str] = []
|
|
5701
5733
|
provider_order: list[str] = []
|
|
5702
5734
|
for selected_spec in llm_model_specs:
|
|
5703
5735
|
selected_model = selected_spec.model
|
|
@@ -5711,6 +5743,9 @@ def build_process_agent(
|
|
|
5711
5743
|
elif provider_name == "anthropic":
|
|
5712
5744
|
if selected_model not in anthropic_models:
|
|
5713
5745
|
anthropic_models.append(selected_model)
|
|
5746
|
+
elif provider_name == "grok":
|
|
5747
|
+
if selected_model not in grok_models:
|
|
5748
|
+
grok_models.append(selected_model)
|
|
5714
5749
|
elif selected_model not in openai_models:
|
|
5715
5750
|
openai_models.append(selected_model)
|
|
5716
5751
|
|
|
@@ -5777,6 +5812,24 @@ def build_process_agent(
|
|
|
5777
5812
|
allowed_models=None if unfiltered_llm_backend else anthropic_models,
|
|
5778
5813
|
),
|
|
5779
5814
|
)
|
|
5815
|
+
if grok_models:
|
|
5816
|
+
providers_by_name["grok"] = LLMProvider(
|
|
5817
|
+
name="grok",
|
|
5818
|
+
adapter=OpenAIResponsesAdapter(
|
|
5819
|
+
model=grok_models[0],
|
|
5820
|
+
provider="grok",
|
|
5821
|
+
base_url=_grok_base_url(),
|
|
5822
|
+
api_key=api_key,
|
|
5823
|
+
mode="request",
|
|
5824
|
+
log_requests=log_llm_requests,
|
|
5825
|
+
context_management=context_management,
|
|
5826
|
+
compaction_threshold=compaction_threshold,
|
|
5827
|
+
max_output_tokens=max_output_tokens,
|
|
5828
|
+
reasoning_effort=reasoning_effort,
|
|
5829
|
+
tool_search="server" if tool_search != "none" else None,
|
|
5830
|
+
allowed_models=None if unfiltered_llm_backend else grok_models,
|
|
5831
|
+
),
|
|
5832
|
+
)
|
|
5780
5833
|
for provider_name in provider_order:
|
|
5781
5834
|
provider = providers_by_name.get(provider_name)
|
|
5782
5835
|
if provider is not None:
|
|
@@ -6108,6 +6161,12 @@ def build_process_agent(
|
|
|
6108
6161
|
connection = await provider.adapter.create_realtime_connection(
|
|
6109
6162
|
protocol=protocol,
|
|
6110
6163
|
model=resolved_model,
|
|
6164
|
+
llm_authorization_token=(
|
|
6165
|
+
start_thread.llm_authorization.token
|
|
6166
|
+
if start_thread.llm_authorization is not None
|
|
6167
|
+
and not start_thread.llm_authorization.is_expired()
|
|
6168
|
+
else None
|
|
6169
|
+
),
|
|
6111
6170
|
)
|
|
6112
6171
|
return AgentRealtimeConnectionInfo(
|
|
6113
6172
|
protocol=connection.protocol,
|
|
@@ -6936,6 +6995,7 @@ def build_process_agent(
|
|
|
6936
6995
|
turns=turns,
|
|
6937
6996
|
)
|
|
6938
6997
|
),
|
|
6998
|
+
llm_delegation=llm_delegation,
|
|
6939
6999
|
)
|
|
6940
7000
|
if room is not None:
|
|
6941
7001
|
process.register_content_scheme(_room_content_scheme(room=room))
|
|
@@ -7194,6 +7254,13 @@ async def join(
|
|
|
7194
7254
|
Optional[str],
|
|
7195
7255
|
typer.Option(..., help="Delegate LLM interactions to a remote participant"),
|
|
7196
7256
|
] = None,
|
|
7257
|
+
llm_delegation: Annotated[
|
|
7258
|
+
LlmDelegationPolicy,
|
|
7259
|
+
typer.Option(
|
|
7260
|
+
"--llm-delegation",
|
|
7261
|
+
help="Require per-turn LLM delegation or allow it when provided.",
|
|
7262
|
+
),
|
|
7263
|
+
] = "optional",
|
|
7197
7264
|
decision_model: DecisionModelOption = None,
|
|
7198
7265
|
transcription_model: TranscriptionModelOption = (
|
|
7199
7266
|
DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL
|
|
@@ -7403,6 +7470,7 @@ async def join(
|
|
|
7403
7470
|
require_discovery=require_discovery,
|
|
7404
7471
|
require_advanced_shell=require_advanced_shell,
|
|
7405
7472
|
llm_participant=llm_participant,
|
|
7473
|
+
llm_delegation=llm_delegation,
|
|
7406
7474
|
decision_model=decision_model,
|
|
7407
7475
|
transcription_model=transcription_model,
|
|
7408
7476
|
voice=voice,
|
|
@@ -7689,6 +7757,13 @@ async def service(
|
|
|
7689
7757
|
Optional[str],
|
|
7690
7758
|
typer.Option(..., help="Delegate LLM interactions to a remote participant"),
|
|
7691
7759
|
] = None,
|
|
7760
|
+
llm_delegation: Annotated[
|
|
7761
|
+
LlmDelegationPolicy,
|
|
7762
|
+
typer.Option(
|
|
7763
|
+
"--llm-delegation",
|
|
7764
|
+
help="Require per-turn LLM delegation or allow it when provided.",
|
|
7765
|
+
),
|
|
7766
|
+
] = "optional",
|
|
7692
7767
|
decision_model: DecisionModelOption = None,
|
|
7693
7768
|
transcription_model: TranscriptionModelOption = (
|
|
7694
7769
|
DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL
|
|
@@ -7865,6 +7940,7 @@ async def service(
|
|
|
7865
7940
|
require_discovery=require_discovery,
|
|
7866
7941
|
require_advanced_shell=require_advanced_shell,
|
|
7867
7942
|
llm_participant=llm_participant,
|
|
7943
|
+
llm_delegation=llm_delegation,
|
|
7868
7944
|
decision_model=decision_model,
|
|
7869
7945
|
transcription_model=transcription_model,
|
|
7870
7946
|
voice=voice,
|
|
@@ -8125,6 +8201,13 @@ async def spec(
|
|
|
8125
8201
|
Optional[str],
|
|
8126
8202
|
typer.Option(..., help="Delegate LLM interactions to a remote participant"),
|
|
8127
8203
|
] = None,
|
|
8204
|
+
llm_delegation: Annotated[
|
|
8205
|
+
LlmDelegationPolicy,
|
|
8206
|
+
typer.Option(
|
|
8207
|
+
"--llm-delegation",
|
|
8208
|
+
help="Require per-turn LLM delegation or allow it when provided.",
|
|
8209
|
+
),
|
|
8210
|
+
] = "optional",
|
|
8128
8211
|
decision_model: DecisionModelOption = None,
|
|
8129
8212
|
transcription_model: TranscriptionModelOption = (
|
|
8130
8213
|
DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL
|
|
@@ -8281,6 +8364,7 @@ async def spec(
|
|
|
8281
8364
|
require_discovery=require_discovery,
|
|
8282
8365
|
require_advanced_shell=require_advanced_shell,
|
|
8283
8366
|
llm_participant=llm_participant,
|
|
8367
|
+
llm_delegation=llm_delegation,
|
|
8284
8368
|
decision_model=decision_model,
|
|
8285
8369
|
transcription_model=transcription_model,
|
|
8286
8370
|
voice=voice,
|
|
@@ -8557,6 +8641,13 @@ async def deploy(
|
|
|
8557
8641
|
Optional[str],
|
|
8558
8642
|
typer.Option(..., help="Delegate LLM interactions to a remote participant"),
|
|
8559
8643
|
] = None,
|
|
8644
|
+
llm_delegation: Annotated[
|
|
8645
|
+
LlmDelegationPolicy,
|
|
8646
|
+
typer.Option(
|
|
8647
|
+
"--llm-delegation",
|
|
8648
|
+
help="Require per-turn LLM delegation or allow it when provided.",
|
|
8649
|
+
),
|
|
8650
|
+
] = "optional",
|
|
8560
8651
|
decision_model: DecisionModelOption = None,
|
|
8561
8652
|
transcription_model: TranscriptionModelOption = (
|
|
8562
8653
|
DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL
|
|
@@ -8716,6 +8807,7 @@ async def deploy(
|
|
|
8716
8807
|
require_discovery=require_discovery,
|
|
8717
8808
|
require_advanced_shell=require_advanced_shell,
|
|
8718
8809
|
llm_participant=llm_participant,
|
|
8810
|
+
llm_delegation=llm_delegation,
|
|
8719
8811
|
decision_model=decision_model,
|
|
8720
8812
|
transcription_model=transcription_model,
|
|
8721
8813
|
voice=voice,
|
|
@@ -11061,6 +11153,13 @@ async def run(
|
|
|
11061
11153
|
Optional[str],
|
|
11062
11154
|
typer.Option(..., help="Delegate LLM interactions to a remote participant"),
|
|
11063
11155
|
] = None,
|
|
11156
|
+
llm_delegation: Annotated[
|
|
11157
|
+
LlmDelegationPolicy,
|
|
11158
|
+
typer.Option(
|
|
11159
|
+
"--llm-delegation",
|
|
11160
|
+
help="Require per-turn LLM delegation or allow it when provided.",
|
|
11161
|
+
),
|
|
11162
|
+
] = "optional",
|
|
11064
11163
|
decision_model: DecisionModelOption = None,
|
|
11065
11164
|
transcription_model: TranscriptionModelOption = (
|
|
11066
11165
|
DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL
|
|
@@ -11375,6 +11474,7 @@ async def run(
|
|
|
11375
11474
|
require_discovery=require_discovery,
|
|
11376
11475
|
require_advanced_shell=require_advanced_shell,
|
|
11377
11476
|
llm_participant=llm_participant,
|
|
11477
|
+
llm_delegation=llm_delegation,
|
|
11378
11478
|
decision_model=decision_model,
|
|
11379
11479
|
transcription_model=transcription_model,
|
|
11380
11480
|
voice=voice,
|
|
@@ -1420,6 +1420,7 @@ def test_build_process_agent_passes_custom_realtime_transcription_model(
|
|
|
1420
1420
|
def test_build_process_agent_groups_repeated_models_by_provider(
|
|
1421
1421
|
monkeypatch: pytest.MonkeyPatch,
|
|
1422
1422
|
) -> None:
|
|
1423
|
+
monkeypatch.setenv("GROK_BASE_URL", "https://grok.example.test/v1")
|
|
1423
1424
|
created_adapters: list[dict[str, object]] = []
|
|
1424
1425
|
|
|
1425
1426
|
class _FakeOpenAIAdapter:
|
|
@@ -1437,6 +1438,9 @@ def test_build_process_agent_groups_repeated_models_by_provider(
|
|
|
1437
1438
|
response_options=None,
|
|
1438
1439
|
tool_search=None,
|
|
1439
1440
|
allowed_models=None,
|
|
1441
|
+
provider="openai",
|
|
1442
|
+
base_url=None,
|
|
1443
|
+
mode="websocket",
|
|
1440
1444
|
) -> None:
|
|
1441
1445
|
del api_key
|
|
1442
1446
|
del client
|
|
@@ -1447,9 +1451,11 @@ def test_build_process_agent_groups_repeated_models_by_provider(
|
|
|
1447
1451
|
del reasoning_effort
|
|
1448
1452
|
del response_options
|
|
1449
1453
|
del tool_search
|
|
1454
|
+
del base_url
|
|
1455
|
+
del mode
|
|
1450
1456
|
created_adapters.append(
|
|
1451
1457
|
{
|
|
1452
|
-
"provider":
|
|
1458
|
+
"provider": provider,
|
|
1453
1459
|
"model": model,
|
|
1454
1460
|
"allowed_models": allowed_models,
|
|
1455
1461
|
}
|
|
@@ -1514,7 +1520,13 @@ def test_build_process_agent_groups_repeated_models_by_provider(
|
|
|
1514
1520
|
)
|
|
1515
1521
|
|
|
1516
1522
|
agent_cls = process.build_process_agent(
|
|
1517
|
-
model=[
|
|
1523
|
+
model=[
|
|
1524
|
+
"gpt-5.6-sol",
|
|
1525
|
+
"gpt-5.4",
|
|
1526
|
+
"claude-opus-4-7",
|
|
1527
|
+
"gpt-realtime",
|
|
1528
|
+
"grok-4.6",
|
|
1529
|
+
],
|
|
1518
1530
|
rule=[],
|
|
1519
1531
|
toolkit=[],
|
|
1520
1532
|
schema=[],
|
|
@@ -1540,9 +1552,31 @@ def test_build_process_agent_groups_repeated_models_by_provider(
|
|
|
1540
1552
|
"model": "claude-opus-4-7",
|
|
1541
1553
|
"allowed_models": ["claude-opus-4-7"],
|
|
1542
1554
|
},
|
|
1555
|
+
{
|
|
1556
|
+
"provider": "grok",
|
|
1557
|
+
"model": "grok-4.6",
|
|
1558
|
+
"allowed_models": ["grok-4.6"],
|
|
1559
|
+
},
|
|
1543
1560
|
]
|
|
1544
1561
|
|
|
1545
1562
|
|
|
1563
|
+
def test_grok_base_url_never_falls_back_to_openai(
|
|
1564
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
1565
|
+
) -> None:
|
|
1566
|
+
monkeypatch.setenv("OPENAI_BASE_URL", "https://openai.example.test/v1")
|
|
1567
|
+
monkeypatch.delenv("GROK_BASE_URL", raising=False)
|
|
1568
|
+
monkeypatch.delenv("XAI_BASE_URL", raising=False)
|
|
1569
|
+
|
|
1570
|
+
with pytest.raises(
|
|
1571
|
+
ValueError,
|
|
1572
|
+
match="GROK_BASE_URL or XAI_BASE_URL is required for Grok models",
|
|
1573
|
+
):
|
|
1574
|
+
process._grok_base_url()
|
|
1575
|
+
|
|
1576
|
+
monkeypatch.setenv("XAI_BASE_URL", " https://xai.example.test/v1 ")
|
|
1577
|
+
assert process._grok_base_url() == "https://xai.example.test/v1"
|
|
1578
|
+
|
|
1579
|
+
|
|
1546
1580
|
def test_build_process_agent_passes_project_header_client_to_openai_adapters(
|
|
1547
1581
|
monkeypatch: pytest.MonkeyPatch,
|
|
1548
1582
|
) -> None:
|
|
@@ -7075,6 +7109,8 @@ async def test_chatbot_require_advanced_shell_uses_container_toolkit_with_shell_
|
|
|
7075
7109
|
"MESHAGENT_TOKEN": "test-token",
|
|
7076
7110
|
"OPENAI_API_KEY": "test-token",
|
|
7077
7111
|
"ANTHROPIC_API_KEY": "test-token",
|
|
7112
|
+
"GROK_API_KEY": "test-token",
|
|
7113
|
+
"XAI_API_KEY": "test-token",
|
|
7078
7114
|
}
|
|
7079
7115
|
|
|
7080
7116
|
|
|
@@ -7124,6 +7160,8 @@ async def test_process_agent_require_advanced_shell_uses_container_toolkit_with_
|
|
|
7124
7160
|
"MESHAGENT_TOKEN": "token",
|
|
7125
7161
|
"OPENAI_API_KEY": "token",
|
|
7126
7162
|
"ANTHROPIC_API_KEY": "token",
|
|
7163
|
+
"GROK_API_KEY": "token",
|
|
7164
|
+
"XAI_API_KEY": "token",
|
|
7127
7165
|
}
|
|
7128
7166
|
finally:
|
|
7129
7167
|
await agent.stop()
|
|
@@ -29,6 +29,8 @@ _CONNECTED_TOKEN_ENV_NAMES = (
|
|
|
29
29
|
"MESHAGENT_TOKEN",
|
|
30
30
|
"OPENAI_API_KEY",
|
|
31
31
|
"ANTHROPIC_API_KEY",
|
|
32
|
+
"GROK_API_KEY",
|
|
33
|
+
"XAI_API_KEY",
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
if TYPE_CHECKING:
|
|
@@ -500,6 +502,8 @@ async def _build_connected_command_env(
|
|
|
500
502
|
child_env["MESHAGENT_ROOM"] = room_env.room_name
|
|
501
503
|
child_env["OPENAI_BASE_URL"] = f"{api_url}/openai/v1"
|
|
502
504
|
child_env["ANTHROPIC_BASE_URL"] = f"{api_url}/anthropic"
|
|
505
|
+
child_env["GROK_BASE_URL"] = f"{api_url}/grok/v1"
|
|
506
|
+
child_env["XAI_BASE_URL"] = child_env["GROK_BASE_URL"]
|
|
503
507
|
_set_connected_token_environment(
|
|
504
508
|
child_env=child_env,
|
|
505
509
|
connected_token=connected_token,
|
|
@@ -528,7 +532,8 @@ app = async_typer.AsyncTyper(add_completion=False)
|
|
|
528
532
|
help=(
|
|
529
533
|
"Connect to a room and run a local command with "
|
|
530
534
|
"MESHAGENT_API_URL, MESHAGENT_PROJECT_ID, MESHAGENT_TOKEN, "
|
|
531
|
-
"OPENAI_API_KEY, ANTHROPIC_API_KEY,
|
|
535
|
+
"OPENAI_API_KEY, ANTHROPIC_API_KEY, GROK_API_KEY, XAI_API_KEY, and "
|
|
536
|
+
"MESHAGENT_ROOM set by "
|
|
532
537
|
"the default agent template. Use -- before the local command."
|
|
533
538
|
),
|
|
534
539
|
)
|
|
@@ -580,8 +585,9 @@ def _connect_command(
|
|
|
580
585
|
show_default=True,
|
|
581
586
|
help=(
|
|
582
587
|
"Allowed values: agent, none. agent: MeshAgent sets MESHAGENT_TOKEN, "
|
|
583
|
-
"OPENAI_API_KEY, and
|
|
584
|
-
"and sets OPENAI_BASE_URL,
|
|
588
|
+
"OPENAI_API_KEY, ANTHROPIC_API_KEY, GROK_API_KEY, and XAI_API_KEY to a "
|
|
589
|
+
"room-scoped MeshAgent token, and sets OPENAI_BASE_URL, "
|
|
590
|
+
"ANTHROPIC_BASE_URL, GROK_BASE_URL, XAI_BASE_URL, MESHAGENT_API_URL, "
|
|
585
591
|
"MESHAGENT_PROJECT_ID, and MESHAGENT_ROOM for the connected room unless "
|
|
586
592
|
"manually set. Provider base URLs use the project API endpoint. none: "
|
|
587
593
|
"MeshAgent applies no template defaults."
|
|
@@ -440,6 +440,10 @@ def test_room_connect_runs_command_with_connected_room_env(
|
|
|
440
440
|
assert captured_env["ANTHROPIC_BASE_URL"] == "https://env.meshagent.test/anthropic"
|
|
441
441
|
assert captured_env["OPENAI_API_KEY"] == "room-jwt"
|
|
442
442
|
assert captured_env["ANTHROPIC_API_KEY"] == "room-jwt"
|
|
443
|
+
assert captured_env["GROK_BASE_URL"] == "https://env.meshagent.test/grok/v1"
|
|
444
|
+
assert captured_env["XAI_BASE_URL"] == captured_env["GROK_BASE_URL"]
|
|
445
|
+
assert captured_env["GROK_API_KEY"] == "room-jwt"
|
|
446
|
+
assert captured_env["XAI_API_KEY"] == "room-jwt"
|
|
443
447
|
|
|
444
448
|
|
|
445
449
|
def test_room_connect_ignores_ambient_participant_token_for_other_room(
|
|
@@ -561,13 +565,21 @@ async def test_room_connect_env_satisfies_llm_proxy_docs_samples(
|
|
|
561
565
|
"OPENAI_API_KEY",
|
|
562
566
|
"ANTHROPIC_BASE_URL",
|
|
563
567
|
"ANTHROPIC_API_KEY",
|
|
568
|
+
"GROK_BASE_URL",
|
|
569
|
+
"GROK_API_KEY",
|
|
570
|
+
"XAI_BASE_URL",
|
|
571
|
+
"XAI_API_KEY",
|
|
564
572
|
}
|
|
565
573
|
assert sample_required_env <= child_env.keys()
|
|
566
574
|
assert child_env["MESHAGENT_TOKEN"] == "room-jwt"
|
|
567
575
|
assert child_env["OPENAI_API_KEY"] == child_env["MESHAGENT_TOKEN"]
|
|
568
576
|
assert child_env["ANTHROPIC_API_KEY"] == child_env["MESHAGENT_TOKEN"]
|
|
577
|
+
assert child_env["GROK_API_KEY"] == child_env["MESHAGENT_TOKEN"]
|
|
578
|
+
assert child_env["XAI_API_KEY"] == child_env["MESHAGENT_TOKEN"]
|
|
569
579
|
assert child_env["OPENAI_BASE_URL"] == "https://env.meshagent.test/openai/v1"
|
|
570
580
|
assert child_env["ANTHROPIC_BASE_URL"] == "https://env.meshagent.test/anthropic"
|
|
581
|
+
assert child_env["GROK_BASE_URL"] == "https://env.meshagent.test/grok/v1"
|
|
582
|
+
assert child_env["XAI_BASE_URL"] == child_env["GROK_BASE_URL"]
|
|
571
583
|
|
|
572
584
|
|
|
573
585
|
@pytest.mark.asyncio
|