deepagents-cli 0.0.35__tar.gz → 0.0.37__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.
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/.gitignore +3 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/CHANGELOG.md +25 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/PKG-INFO +2 -2
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_version.py +1 -1
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/app.py +36 -4
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/command_registry.py +6 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/config.py +27 -4
- deepagents_cli-0.0.37/deepagents_cli/deploy/__init__.py +18 -0
- deepagents_cli-0.0.37/deepagents_cli/deploy/bundler.py +272 -0
- deepagents_cli-0.0.37/deepagents_cli/deploy/commands.py +416 -0
- deepagents_cli-0.0.37/deepagents_cli/deploy/config.py +411 -0
- deepagents_cli-0.0.37/deepagents_cli/deploy/templates.py +488 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/integrations/sandbox_factory.py +7 -3
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/main.py +52 -6
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/model_config.py +99 -16
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/ui.py +9 -0
- deepagents_cli-0.0.37/deepagents_cli/widgets/notification_settings.py +156 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/pyproject.toml +14 -5
- deepagents_cli-0.0.37/scripts/debug_server.sh +67 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/conftest.py +3 -2
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/test_acp_mode.py +6 -1
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/test_compact_resume.py +7 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/test_sandbox_factory.py +22 -6
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/test_sandbox_operations.py +7 -2
- deepagents_cli-0.0.37/tests/unit_tests/deploy/test_bundler.py +245 -0
- deepagents_cli-0.0.37/tests/unit_tests/deploy/test_commands.py +75 -0
- deepagents_cli-0.0.37/tests/unit_tests/deploy/test_config.py +302 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_config.py +34 -4
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_main.py +80 -7
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_model_config.py +87 -0
- deepagents_cli-0.0.37/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/uv.lock +60 -60
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/DEV.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/Makefile +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/README.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/THREAT_MODEL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/__main__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_ask_user_types.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_cli_context.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_debug.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_env_vars.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_server_config.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_session_stats.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/_testing_models.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/agent.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/app.tcss +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/ask_user.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/built_in_skills/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/clipboard.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/configurable_model.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/default_agent_prompt.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/editor.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/file_ops.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/formatting.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/hooks.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/input.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/integrations/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/integrations/sandbox_provider.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/local_context.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/mcp_tools.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/mcp_trust.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/media_utils.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/non_interactive.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/offload.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/output.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/project_utils.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/py.typed +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/remote_client.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/server.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/server_graph.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/server_manager.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/sessions.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/skills/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/skills/commands.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/skills/invocation.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/skills/load.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/subagents.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/system_prompt.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/textual_adapter.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/theme.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/token_state.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/tool_display.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/tools.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/unicode_security.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/update_check.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/_links.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/approval.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/ask_user.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/autocomplete.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/chat_input.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/diff.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/history.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/loading.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/mcp_viewer.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/message_store.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/messages.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/model_selector.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/status.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/theme_selector.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/thread_selector.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/tool_renderers.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/tool_widgets.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/deepagents_cli/widgets/welcome.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/images/cli.png +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/scripts/check_imports.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/scripts/install.sh +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/README.md +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/conftest.py +0 -0
- {deepagents_cli-0.0.35/tests/unit_tests/tools → deepagents_cli-0.0.37/tests/unit_tests/deploy}/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_app.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_args.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_history.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_links.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_output.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_server.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_status.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_token_tracker.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_version.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_cli-0.0.35 → deepagents_cli-0.0.37}/tests/unit_tests/tools/test_fetch_url.py +0 -0
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.37](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.36...deepagents-cli==0.0.37) (2026-04-10)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* Permissions for `deepagents deploy` ([#2651](https://github.com/langchain-ai/deepagents/issues/2651)) ([5d93b73](https://github.com/langchain-ai/deepagents/commit/5d93b736af6ffb165f33569233d533ced95a6943))
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add missing model provider deps to `deepagents deploy` bundler [closes [#2647](https://github.com/langchain-ai/deepagents/issues/2647)] ([#2660](https://github.com/langchain-ai/deepagents/issues/2660)) ([b710a69](https://github.com/langchain-ai/deepagents/commit/b710a69b12e49479045eaa54dfb709326473500b))
|
|
12
|
+
* `AGENTS.md` in system prompt twice ([#2652](https://github.com/langchain-ai/deepagents/issues/2652)) ([9052be9](https://github.com/langchain-ai/deepagents/commit/9052be98d9f4ef9b11a88c9b1df3fae5e5ac666c))
|
|
13
|
+
* Harden `deepagents deploy` config parsing and add unit tests ([#2636](https://github.com/langchain-ai/deepagents/issues/2636)) ([0469d14](https://github.com/langchain-ai/deepagents/commit/0469d1429d129e604fc1b622263923162f719314))
|
|
14
|
+
* Load `deepagents deploy` project `.env` before deploy/dev config validation ([#2644](https://github.com/langchain-ai/deepagents/issues/2644)) ([8299091](https://github.com/langchain-ai/deepagents/commit/829909166606f8a9d9571b00da725845bad08da7))
|
|
15
|
+
|
|
16
|
+
## [0.0.36](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.35...deepagents-cli==0.0.36) (2026-04-09)
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* `deepagents deploy` ([#2491](https://github.com/langchain-ai/deepagents/issues/2491)) ([01dc60e](https://github.com/langchain-ai/deepagents/commit/01dc60e394ecb56bd5336e447d32caeed8a67ec2))
|
|
21
|
+
* Warn on missing tavily key, add `/notifications` ([#2555](https://github.com/langchain-ai/deepagents/issues/2555)) ([3dff3ed](https://github.com/langchain-ai/deepagents/commit/3dff3ed6835eae9f8b420b8a73c054127faaf7d2))
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* Fail fast on missing provider credentials ([#2554](https://github.com/langchain-ai/deepagents/issues/2554)) ([50fb8ae](https://github.com/langchain-ai/deepagents/commit/50fb8aefe7e3065024e10f1d5ecd11a54d736641))
|
|
26
|
+
* Fix mktemp template in debug script for macOS ([#2603](https://github.com/langchain-ai/deepagents/issues/2603)) ([63fa537](https://github.com/langchain-ai/deepagents/commit/63fa537e9995ca2ead492ee44902227567e9a130))
|
|
27
|
+
|
|
3
28
|
## [0.0.35](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.34...deepagents-cli==0.0.35) (2026-04-07)
|
|
4
29
|
|
|
5
30
|
### Highlights
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.37
|
|
4
4
|
Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
@@ -27,7 +27,7 @@ Classifier: Topic :: Terminals
|
|
|
27
27
|
Requires-Python: <4.0,>=3.11
|
|
28
28
|
Requires-Dist: aiosqlite<1.0.0,>=0.19.0
|
|
29
29
|
Requires-Dist: deepagents-acp>=0.0.4
|
|
30
|
-
Requires-Dist: deepagents==0.5.
|
|
30
|
+
Requires-Dist: deepagents==0.5.2
|
|
31
31
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
32
32
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.0
|
|
33
33
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Version information and lightweight constants for `deepagents-cli`."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.0.
|
|
3
|
+
__version__ = "0.0.37" # x-release-please-version
|
|
4
4
|
|
|
5
5
|
DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/cli"
|
|
6
6
|
"""URL for `deepagents-cli` documentation."""
|
|
@@ -1478,7 +1478,7 @@ class DeepAgentsApp(App):
|
|
|
1478
1478
|
cmd = upgrade_command()
|
|
1479
1479
|
self.notify(
|
|
1480
1480
|
f"Update available: v{latest} (current: v{cli_version}). "
|
|
1481
|
-
f"Run: {cmd}\n"
|
|
1481
|
+
f"Run: {cmd}\n\n"
|
|
1482
1482
|
f"Enable auto-updates: /auto-update",
|
|
1483
1483
|
severity="information",
|
|
1484
1484
|
timeout=15,
|
|
@@ -2626,9 +2626,9 @@ class DeepAgentsApp(App):
|
|
|
2626
2626
|
await self._mount_message(UserMessage(command))
|
|
2627
2627
|
help_body = (
|
|
2628
2628
|
"Commands: /quit, /clear, /offload, /editor, /mcp, "
|
|
2629
|
-
"/model [--model-params JSON] [--default], /
|
|
2630
|
-
"/skill:<name>, /remember, /skill-creator, /theme,
|
|
2631
|
-
"/threads, /trace, "
|
|
2629
|
+
"/model [--model-params JSON] [--default], /notifications, "
|
|
2630
|
+
"/reload, /skill:<name>, /remember, /skill-creator, /theme, "
|
|
2631
|
+
"/tokens, /threads, /trace, "
|
|
2632
2632
|
"/update, /auto-update, /changelog, /docs, /feedback, /help\n\n"
|
|
2633
2633
|
"Interactive Features:\n"
|
|
2634
2634
|
" Enter Submit your message\n"
|
|
@@ -2774,6 +2774,8 @@ class DeepAgentsApp(App):
|
|
|
2774
2774
|
await self._show_mcp_viewer()
|
|
2775
2775
|
elif cmd == "/theme":
|
|
2776
2776
|
await self._show_theme_selector()
|
|
2777
|
+
elif cmd == "/notifications":
|
|
2778
|
+
await self._show_notification_settings()
|
|
2777
2779
|
elif cmd == "/model" or cmd.startswith("/model "):
|
|
2778
2780
|
model_arg = None
|
|
2779
2781
|
set_default = False
|
|
@@ -4552,6 +4554,36 @@ class DeepAgentsApp(App):
|
|
|
4552
4554
|
screen = ThemeSelectorScreen(current_theme=self.theme)
|
|
4553
4555
|
self.push_screen(screen, handle_result)
|
|
4554
4556
|
|
|
4557
|
+
async def _show_notification_settings(self) -> None:
|
|
4558
|
+
"""Show notification settings modal."""
|
|
4559
|
+
from deepagents_cli.model_config import is_warning_suppressed
|
|
4560
|
+
from deepagents_cli.widgets.notification_settings import (
|
|
4561
|
+
WARNING_TOGGLES,
|
|
4562
|
+
NotificationSettingsScreen,
|
|
4563
|
+
)
|
|
4564
|
+
|
|
4565
|
+
suppressed: set[str] = set()
|
|
4566
|
+
try:
|
|
4567
|
+
for key, _ in WARNING_TOGGLES:
|
|
4568
|
+
if await asyncio.to_thread(is_warning_suppressed, key):
|
|
4569
|
+
suppressed.add(key)
|
|
4570
|
+
except Exception:
|
|
4571
|
+
logger.warning("Failed to read notification settings", exc_info=True)
|
|
4572
|
+
suppressed = set()
|
|
4573
|
+
self.notify(
|
|
4574
|
+
"Could not read notification preferences. Showing defaults.",
|
|
4575
|
+
severity="warning",
|
|
4576
|
+
timeout=6,
|
|
4577
|
+
markup=False,
|
|
4578
|
+
)
|
|
4579
|
+
|
|
4580
|
+
def handle_result(_result: None) -> None:
|
|
4581
|
+
if self._chat_input:
|
|
4582
|
+
self._chat_input.focus_input()
|
|
4583
|
+
|
|
4584
|
+
screen = NotificationSettingsScreen(suppressed=suppressed)
|
|
4585
|
+
self.push_screen(screen, handle_result)
|
|
4586
|
+
|
|
4555
4587
|
async def _show_mcp_viewer(self) -> None:
|
|
4556
4588
|
"""Show read-only MCP server/tool viewer as a modal screen."""
|
|
4557
4589
|
from deepagents_cli.widgets.mcp_viewer import MCPViewerScreen
|
|
@@ -77,6 +77,12 @@ COMMANDS: tuple[SlashCommand, ...] = (
|
|
|
77
77
|
description="Switch or configure model (--model-params, --default)",
|
|
78
78
|
bypass_tier=BypassTier.IMMEDIATE_UI,
|
|
79
79
|
),
|
|
80
|
+
SlashCommand(
|
|
81
|
+
name="/notifications",
|
|
82
|
+
description="Configure startup warning preferences",
|
|
83
|
+
bypass_tier=BypassTier.IMMEDIATE_UI,
|
|
84
|
+
hidden_keywords="warnings alerts suppress",
|
|
85
|
+
),
|
|
80
86
|
SlashCommand(
|
|
81
87
|
name="/offload",
|
|
82
88
|
description="Free up context window space by offloading older messages",
|
|
@@ -32,8 +32,8 @@ _bootstrap_done = False
|
|
|
32
32
|
"""Whether `_ensure_bootstrap()` has executed."""
|
|
33
33
|
|
|
34
34
|
_bootstrap_lock = threading.Lock()
|
|
35
|
-
"""Guards `_ensure_bootstrap()` against concurrent access from the main
|
|
36
|
-
|
|
35
|
+
"""Guards `_ensure_bootstrap()` against concurrent access from the main thread
|
|
36
|
+
and the prewarm worker thread."""
|
|
37
37
|
|
|
38
38
|
_singleton_lock = threading.Lock()
|
|
39
39
|
"""Guards lazy singleton construction in `_get_console` / `_get_settings`."""
|
|
@@ -1937,7 +1937,9 @@ def _get_provider_kwargs(
|
|
|
1937
1937
|
result["api_key"] = api_key
|
|
1938
1938
|
|
|
1939
1939
|
if provider == "openrouter":
|
|
1940
|
-
from deepagents.
|
|
1940
|
+
from deepagents.profiles._openrouter import (
|
|
1941
|
+
check_openrouter_version, # noqa: PLC2701
|
|
1942
|
+
)
|
|
1941
1943
|
|
|
1942
1944
|
check_openrouter_version()
|
|
1943
1945
|
_apply_openrouter_defaults(result)
|
|
@@ -2195,7 +2197,14 @@ def create_model(
|
|
|
2195
2197
|
>>> model = create_model("gpt-4o") # Auto-detects openai
|
|
2196
2198
|
>>> model = create_model() # Uses environment defaults
|
|
2197
2199
|
"""
|
|
2198
|
-
from deepagents_cli.model_config import
|
|
2200
|
+
from deepagents_cli.model_config import (
|
|
2201
|
+
IMPLICIT_AUTH_PROVIDERS,
|
|
2202
|
+
ModelConfig,
|
|
2203
|
+
ModelConfigError,
|
|
2204
|
+
ModelSpec,
|
|
2205
|
+
get_credential_env_var,
|
|
2206
|
+
has_provider_credentials,
|
|
2207
|
+
)
|
|
2199
2208
|
|
|
2200
2209
|
if not model_spec:
|
|
2201
2210
|
model_spec = _get_default_model_spec()
|
|
@@ -2225,6 +2234,20 @@ def create_model(
|
|
|
2225
2234
|
model_name = model_spec
|
|
2226
2235
|
provider = detect_provider(model_spec) or ""
|
|
2227
2236
|
|
|
2237
|
+
# Early credential check — fail fast with an actionable message instead of
|
|
2238
|
+
# letting the provider SDK raise an opaque auth error on first invocation.
|
|
2239
|
+
# Providers that support implicit auth (e.g., Vertex AI ADC) are excluded
|
|
2240
|
+
# because their env-var mapping is not a reliable indicator.
|
|
2241
|
+
if provider and provider not in IMPLICIT_AUTH_PROVIDERS:
|
|
2242
|
+
cred_status = has_provider_credentials(provider)
|
|
2243
|
+
if cred_status is False:
|
|
2244
|
+
env_var = get_credential_env_var(provider) or f"<{provider} API key>"
|
|
2245
|
+
msg = (
|
|
2246
|
+
f"No credentials found for provider '{provider}'. "
|
|
2247
|
+
f"Please set the {env_var} environment variable."
|
|
2248
|
+
)
|
|
2249
|
+
raise ModelConfigError(msg)
|
|
2250
|
+
|
|
2228
2251
|
# Provider-specific kwargs (with per-model overrides)
|
|
2229
2252
|
kwargs = _get_provider_kwargs(provider, model_name=model_name)
|
|
2230
2253
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Deploy commands for bundling and shipping deep agents."""
|
|
2
|
+
|
|
3
|
+
from deepagents_cli.deploy.commands import (
|
|
4
|
+
execute_deploy_command,
|
|
5
|
+
execute_dev_command,
|
|
6
|
+
execute_init_command,
|
|
7
|
+
setup_deploy_parsers,
|
|
8
|
+
)
|
|
9
|
+
from deepagents_cli.deploy.config import SandboxProvider, SandboxScope
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"SandboxProvider",
|
|
13
|
+
"SandboxScope",
|
|
14
|
+
"execute_deploy_command",
|
|
15
|
+
"execute_dev_command",
|
|
16
|
+
"execute_init_command",
|
|
17
|
+
"setup_deploy_parsers",
|
|
18
|
+
]
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""Bundle a deepagents project for deployment.
|
|
2
|
+
|
|
3
|
+
Reads the canonical project layout:
|
|
4
|
+
|
|
5
|
+
```txt
|
|
6
|
+
<project>/
|
|
7
|
+
deepagents.toml # required — agent + sandbox config
|
|
8
|
+
AGENTS.md # required — system prompt + seeded memory
|
|
9
|
+
.env # optional — environment variables
|
|
10
|
+
mcp.json # optional — HTTP/SSE MCP servers
|
|
11
|
+
skills/ # optional — auto-seeded into skills namespace
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
...and writes everything `langgraph deploy` needs to a build directory.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
import logging
|
|
21
|
+
import shutil
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from deepagents_cli.deploy.config import (
|
|
25
|
+
AGENTS_MD_FILENAME,
|
|
26
|
+
MCP_FILENAME,
|
|
27
|
+
SKILLS_DIRNAME,
|
|
28
|
+
DeployConfig,
|
|
29
|
+
)
|
|
30
|
+
from deepagents_cli.deploy.templates import (
|
|
31
|
+
DEPLOY_GRAPH_TEMPLATE,
|
|
32
|
+
MCP_TOOLS_TEMPLATE,
|
|
33
|
+
PYPROJECT_TEMPLATE,
|
|
34
|
+
SANDBOX_BLOCKS,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
_MODEL_PROVIDER_DEPS: dict[str, str] = {
|
|
40
|
+
"anthropic": "langchain-anthropic",
|
|
41
|
+
"azure_openai": "langchain-openai",
|
|
42
|
+
"baseten": "langchain-baseten",
|
|
43
|
+
"cohere": "langchain-cohere",
|
|
44
|
+
"deepseek": "langchain-deepseek",
|
|
45
|
+
"fireworks": "langchain-fireworks",
|
|
46
|
+
"google_genai": "langchain-google-genai",
|
|
47
|
+
"google_vertexai": "langchain-google-vertexai",
|
|
48
|
+
"groq": "langchain-groq",
|
|
49
|
+
"mistralai": "langchain-mistralai",
|
|
50
|
+
"nvidia": "langchain-nvidia-ai-endpoints",
|
|
51
|
+
"openai": "langchain-openai",
|
|
52
|
+
"openrouter": "langchain-openrouter",
|
|
53
|
+
"perplexity": "langchain-perplexity",
|
|
54
|
+
"xai": "langchain-xai",
|
|
55
|
+
}
|
|
56
|
+
"""Dependencies inferred from a provider: prefix on the model string."""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def bundle(
|
|
60
|
+
config: DeployConfig,
|
|
61
|
+
project_root: Path,
|
|
62
|
+
build_dir: Path,
|
|
63
|
+
) -> Path:
|
|
64
|
+
"""Create the full deployment bundle in *build_dir*."""
|
|
65
|
+
build_dir.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
|
|
67
|
+
# 1. Read AGENTS.md — the system prompt AND (optionally) seeded memory.
|
|
68
|
+
agents_md_path = project_root / AGENTS_MD_FILENAME
|
|
69
|
+
system_prompt = agents_md_path.read_text(encoding="utf-8")
|
|
70
|
+
|
|
71
|
+
# 2. Build and write the seed payload: memory (AGENTS.md) + skills/.
|
|
72
|
+
seed = _build_seed(config, project_root, system_prompt)
|
|
73
|
+
(build_dir / "_seed.json").write_text(
|
|
74
|
+
json.dumps(seed, indent=2, ensure_ascii=False),
|
|
75
|
+
encoding="utf-8",
|
|
76
|
+
)
|
|
77
|
+
logger.info(
|
|
78
|
+
"Wrote _seed.json (memories: %d, skills: %d)",
|
|
79
|
+
len(seed["memories"]),
|
|
80
|
+
len(seed["skills"]),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# 3. Copy mcp.json if present.
|
|
84
|
+
mcp_present = (project_root / MCP_FILENAME).is_file()
|
|
85
|
+
if mcp_present:
|
|
86
|
+
shutil.copy2(project_root / MCP_FILENAME, build_dir / "_mcp.json")
|
|
87
|
+
logger.info("Copied %s → _mcp.json", MCP_FILENAME)
|
|
88
|
+
|
|
89
|
+
# 3b. Copy .env from the project root if present (alongside
|
|
90
|
+
# deepagents.toml). The bundler skips .env when
|
|
91
|
+
# building the seed payload so secrets never land in _seed.json.
|
|
92
|
+
env_src = project_root / ".env"
|
|
93
|
+
env_present = env_src.is_file()
|
|
94
|
+
if env_present:
|
|
95
|
+
shutil.copy2(env_src, build_dir / ".env")
|
|
96
|
+
logger.info("Copied %s → .env", env_src)
|
|
97
|
+
|
|
98
|
+
# 4. Render deploy_graph.py.
|
|
99
|
+
(build_dir / "deploy_graph.py").write_text(
|
|
100
|
+
_render_deploy_graph(config, mcp_present=mcp_present),
|
|
101
|
+
encoding="utf-8",
|
|
102
|
+
)
|
|
103
|
+
logger.info("Generated deploy_graph.py")
|
|
104
|
+
|
|
105
|
+
# 5. Render langgraph.json.
|
|
106
|
+
(build_dir / "langgraph.json").write_text(
|
|
107
|
+
_render_langgraph_json(env_present=env_present),
|
|
108
|
+
encoding="utf-8",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# 6. Render pyproject.toml.
|
|
112
|
+
(build_dir / "pyproject.toml").write_text(
|
|
113
|
+
_render_pyproject(config, mcp_present=mcp_present),
|
|
114
|
+
encoding="utf-8",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return build_dir
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _build_seed(
|
|
121
|
+
config: DeployConfig, # noqa: ARG001
|
|
122
|
+
project_root: Path,
|
|
123
|
+
system_prompt: str,
|
|
124
|
+
) -> dict[str, dict[str, str]]:
|
|
125
|
+
"""Build the `_seed.json` payload.
|
|
126
|
+
|
|
127
|
+
Layout:
|
|
128
|
+
|
|
129
|
+
```txt
|
|
130
|
+
{
|
|
131
|
+
"memories": { "/AGENTS.md": "..." },
|
|
132
|
+
"skills": { "/<skill>/SKILL.md": "...", ... }
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`memories` always contains `/AGENTS.md` — the middleware loads it at
|
|
137
|
+
startup via `/memories/AGENTS.md`. Agent reads of `/memories/` and
|
|
138
|
+
`/skills/` are denied by `FilesystemPermission` rules.
|
|
139
|
+
|
|
140
|
+
`skills` walks `skills/` if present. Keys are paths relative to the
|
|
141
|
+
skills dir with a leading slash; the runtime namespace handles the
|
|
142
|
+
scoping.
|
|
143
|
+
"""
|
|
144
|
+
# Keys must match what CompositeBackend passes to the mounted
|
|
145
|
+
# StoreBackend after stripping the route prefix: for a read of
|
|
146
|
+
# /memories/AGENTS.md it calls store.read("/AGENTS.md").
|
|
147
|
+
# Seed with the same leading-slash convention.
|
|
148
|
+
memories: dict[str, str] = {f"/{AGENTS_MD_FILENAME}": system_prompt}
|
|
149
|
+
skills: dict[str, str] = {}
|
|
150
|
+
|
|
151
|
+
skills_dir = project_root / SKILLS_DIRNAME
|
|
152
|
+
if skills_dir.is_dir():
|
|
153
|
+
for f in sorted(skills_dir.rglob("*")):
|
|
154
|
+
if f.is_file() and not f.name.startswith("."):
|
|
155
|
+
rel = f.relative_to(skills_dir).as_posix()
|
|
156
|
+
skills[f"/{rel}"] = f.read_text(encoding="utf-8")
|
|
157
|
+
|
|
158
|
+
return {"memories": memories, "skills": skills}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _render_deploy_graph(
|
|
162
|
+
config: DeployConfig,
|
|
163
|
+
*,
|
|
164
|
+
mcp_present: bool,
|
|
165
|
+
) -> str:
|
|
166
|
+
"""Render the generated `deploy_graph.py`."""
|
|
167
|
+
provider = config.sandbox.provider
|
|
168
|
+
if provider not in SANDBOX_BLOCKS:
|
|
169
|
+
msg = f"Unknown sandbox provider {provider!r}. Valid: {sorted(SANDBOX_BLOCKS)}"
|
|
170
|
+
raise ValueError(msg)
|
|
171
|
+
sandbox_block, _ = SANDBOX_BLOCKS[provider]
|
|
172
|
+
|
|
173
|
+
if mcp_present:
|
|
174
|
+
mcp_tools_block = MCP_TOOLS_TEMPLATE
|
|
175
|
+
mcp_tools_load_call = "tools.extend(await _load_mcp_tools())"
|
|
176
|
+
else:
|
|
177
|
+
mcp_tools_block = ""
|
|
178
|
+
mcp_tools_load_call = "pass # no MCP servers configured"
|
|
179
|
+
|
|
180
|
+
return DEPLOY_GRAPH_TEMPLATE.format(
|
|
181
|
+
model=config.agent.model,
|
|
182
|
+
sandbox_template=config.sandbox.template,
|
|
183
|
+
sandbox_image=config.sandbox.image,
|
|
184
|
+
sandbox_scope=config.sandbox.scope,
|
|
185
|
+
sandbox_block=sandbox_block,
|
|
186
|
+
mcp_tools_block=mcp_tools_block,
|
|
187
|
+
mcp_tools_load_call=mcp_tools_load_call,
|
|
188
|
+
default_assistant_id=config.agent.name,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _render_langgraph_json(*, env_present: bool) -> str:
|
|
193
|
+
"""Render `langgraph.json` — adds `"env": ".env"` when a `.env` was copied."""
|
|
194
|
+
data: dict = {
|
|
195
|
+
"dependencies": ["."],
|
|
196
|
+
"graphs": {"agent": "./deploy_graph.py:make_graph"},
|
|
197
|
+
"python_version": "3.12",
|
|
198
|
+
}
|
|
199
|
+
if env_present:
|
|
200
|
+
data["env"] = ".env"
|
|
201
|
+
return json.dumps(data, indent=2) + "\n"
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _render_pyproject(config: DeployConfig, *, mcp_present: bool) -> str:
|
|
205
|
+
"""Render the deployment package's `pyproject.toml`.
|
|
206
|
+
|
|
207
|
+
Deps are inferred — the user never writes them. We add:
|
|
208
|
+
|
|
209
|
+
- the LangChain partner package matching the model provider prefix
|
|
210
|
+
- `langchain-mcp-adapters` if `mcp.json` is present
|
|
211
|
+
- the sandbox partner package (daytona/modal/runloop)
|
|
212
|
+
"""
|
|
213
|
+
deps: list[str] = []
|
|
214
|
+
|
|
215
|
+
provider_prefix = (
|
|
216
|
+
config.agent.model.split(":", 1)[0] if ":" in config.agent.model else ""
|
|
217
|
+
)
|
|
218
|
+
if provider_prefix and provider_prefix in _MODEL_PROVIDER_DEPS:
|
|
219
|
+
deps.append(_MODEL_PROVIDER_DEPS[provider_prefix])
|
|
220
|
+
|
|
221
|
+
if mcp_present:
|
|
222
|
+
deps.append("langchain-mcp-adapters")
|
|
223
|
+
|
|
224
|
+
_, partner_pkg = SANDBOX_BLOCKS.get(config.sandbox.provider, (None, None))
|
|
225
|
+
if partner_pkg:
|
|
226
|
+
deps.append(partner_pkg)
|
|
227
|
+
|
|
228
|
+
extra_deps_lines = "".join(f' "{dep}",\n' for dep in deps)
|
|
229
|
+
|
|
230
|
+
return PYPROJECT_TEMPLATE.format(
|
|
231
|
+
agent_name=config.agent.name,
|
|
232
|
+
extra_deps=extra_deps_lines,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def print_bundle_summary(config: DeployConfig, build_dir: Path) -> None:
|
|
237
|
+
"""Print a human-readable summary of what was bundled."""
|
|
238
|
+
seed_path = build_dir / "_seed.json"
|
|
239
|
+
seed: dict[str, dict[str, str]] = {"memories": {}, "skills": {}}
|
|
240
|
+
if seed_path.exists():
|
|
241
|
+
try:
|
|
242
|
+
seed = json.loads(seed_path.read_text(encoding="utf-8"))
|
|
243
|
+
except (json.JSONDecodeError, OSError) as exc:
|
|
244
|
+
logger.warning(
|
|
245
|
+
"Failed to parse %s; summary may be incomplete: %s",
|
|
246
|
+
seed_path,
|
|
247
|
+
exc,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
print(f"\n Agent: {config.agent.name}")
|
|
251
|
+
print(f" Model: {config.agent.model}")
|
|
252
|
+
|
|
253
|
+
memory_files = sorted(seed.get("memories", {}).keys())
|
|
254
|
+
if memory_files:
|
|
255
|
+
print(f"\n Memory seed ({len(memory_files)} file(s)):")
|
|
256
|
+
for f in memory_files:
|
|
257
|
+
print(f" {f}")
|
|
258
|
+
|
|
259
|
+
skills_files = sorted(seed.get("skills", {}).keys())
|
|
260
|
+
if skills_files:
|
|
261
|
+
print(f"\n Skills seed ({len(skills_files)} file(s)):")
|
|
262
|
+
for f in skills_files:
|
|
263
|
+
print(f" {f}")
|
|
264
|
+
|
|
265
|
+
if (build_dir / "_mcp.json").exists():
|
|
266
|
+
print("\n MCP config: _mcp.json")
|
|
267
|
+
|
|
268
|
+
print(f"\n Sandbox: {config.sandbox.provider}")
|
|
269
|
+
print(f"\n Build directory: {build_dir}")
|
|
270
|
+
generated = sorted(f.name for f in build_dir.iterdir() if f.is_file())
|
|
271
|
+
print(f" Generated files: {', '.join(generated)}")
|
|
272
|
+
print()
|