deepagents-cli 0.0.36__tar.gz → 0.0.38__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.36 → deepagents_cli-0.0.38}/.gitignore +3 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/CHANGELOG.md +30 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/PKG-INFO +2 -2
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_version.py +1 -1
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/app.py +8 -4
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/config.py +3 -1
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/deploy/__init__.py +3 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/deploy/bundler.py +76 -34
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/deploy/commands.py +61 -48
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/deploy/config.py +61 -30
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/deploy/templates.py +146 -69
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/integrations/sandbox_factory.py +5 -2
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/model_config.py +2 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/message_store.py +34 -10
- deepagents_cli-0.0.38/examples/deploy-content-writer/.env.example +2 -0
- deepagents_cli-0.0.38/examples/deploy-content-writer/skills/blog-post/SKILL.md +15 -0
- deepagents_cli-0.0.38/examples/deploy-content-writer/skills/social-media/SKILL.md +15 -0
- deepagents_cli-0.0.38/examples/deploy-content-writer/user/context.md +15 -0
- deepagents_cli-0.0.38/examples/deploy-content-writer/user/preferences.md +11 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/pyproject.toml +2 -2
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/test_compact_resume.py +6 -11
- deepagents_cli-0.0.38/tests/unit_tests/deploy/test_bundler.py +350 -0
- deepagents_cli-0.0.38/tests/unit_tests/deploy/test_commands.py +75 -0
- deepagents_cli-0.0.38/tests/unit_tests/deploy/test_config.py +302 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_config.py +4 -4
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_message_store.py +71 -0
- deepagents_cli-0.0.38/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/uv.lock +92 -92
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/DEV.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/Makefile +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/README.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/THREAT_MODEL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/__main__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_ask_user_types.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_cli_context.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_debug.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_env_vars.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_server_config.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_session_stats.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/_testing_models.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/agent.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/app.tcss +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/ask_user.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/built_in_skills/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/clipboard.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/command_registry.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/configurable_model.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/default_agent_prompt.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/editor.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/file_ops.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/formatting.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/hooks.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/input.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/integrations/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/integrations/sandbox_provider.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/local_context.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/main.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/mcp_tools.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/mcp_trust.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/media_utils.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/non_interactive.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/offload.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/output.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/project_utils.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/py.typed +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/remote_client.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/server.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/server_graph.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/server_manager.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/sessions.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/skills/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/skills/commands.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/skills/invocation.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/skills/load.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/subagents.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/system_prompt.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/textual_adapter.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/theme.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/token_state.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/tool_display.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/tools.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/ui.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/unicode_security.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/update_check.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/_links.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/approval.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/ask_user.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/autocomplete.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/chat_input.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/diff.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/history.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/loading.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/mcp_viewer.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/messages.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/model_selector.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/notification_settings.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/status.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/theme_selector.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/thread_selector.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/tool_renderers.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/tool_widgets.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/deepagents_cli/widgets/welcome.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/images/cli.png +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/scripts/check_imports.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/scripts/debug_server.sh +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/scripts/install.sh +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/README.md +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/conftest.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/conftest.py +0 -0
- {deepagents_cli-0.0.36/tests/unit_tests/tools → deepagents_cli-0.0.38/tests/unit_tests/deploy}/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_app.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_args.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_history.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_links.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_main.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_output.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_server.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_status.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_token_tracker.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_version.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_cli-0.0.36 → deepagents_cli-0.0.38}/tests/unit_tests/tools/test_fetch_url.py +0 -0
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.38](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.37...deepagents-cli==0.0.38) (2026-04-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **cli:** user scoped memory ([#2708](https://github.com/langchain-ai/deepagents/issues/2708)) ([23bfca6](https://github.com/langchain-ai/deepagents/commit/23bfca6e46e6f3e4fba6657d858ddd5a0b06626f))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deepagents:** remove old integration tests ([#2728](https://github.com/langchain-ai/deepagents/issues/2728)) ([6653197](https://github.com/langchain-ai/deepagents/commit/6653197b6cbec6dd1ca23d9f90bc1439ca26e6e5))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Performance Improvements
|
|
17
|
+
|
|
18
|
+
* **cli:** `O(1)` message lookups in `MessageStore` ([#2350](https://github.com/langchain-ai/deepagents/issues/2350)) ([d39fd5d](https://github.com/langchain-ai/deepagents/commit/d39fd5d3651fd87d1eea8c02cbef2c2f62449e67))
|
|
19
|
+
|
|
20
|
+
## [0.0.37](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.36...deepagents-cli==0.0.37) (2026-04-10)
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* Permissions for `deepagents deploy` ([#2651](https://github.com/langchain-ai/deepagents/issues/2651)) ([5d93b73](https://github.com/langchain-ai/deepagents/commit/5d93b736af6ffb165f33569233d533ced95a6943))
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* 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))
|
|
29
|
+
* `AGENTS.md` in system prompt twice ([#2652](https://github.com/langchain-ai/deepagents/issues/2652)) ([9052be9](https://github.com/langchain-ai/deepagents/commit/9052be98d9f4ef9b11a88c9b1df3fae5e5ac666c))
|
|
30
|
+
* 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))
|
|
31
|
+
* 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))
|
|
32
|
+
|
|
3
33
|
## [0.0.36](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.35...deepagents-cli==0.0.36) (2026-04-09)
|
|
4
34
|
|
|
5
35
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.38
|
|
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.3
|
|
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.38" # 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,
|
|
@@ -1505,11 +1505,15 @@ class DeepAgentsApp(App):
|
|
|
1505
1505
|
|
|
1506
1506
|
try:
|
|
1507
1507
|
from deepagents_cli._version import __version__ as cli_version
|
|
1508
|
+
from deepagents_cli.config import _is_editable_install
|
|
1509
|
+
|
|
1510
|
+
if await asyncio.to_thread(_is_editable_install):
|
|
1511
|
+
heading = f"Now running v{cli_version}"
|
|
1512
|
+
else:
|
|
1513
|
+
heading = f"Updated to v{cli_version}"
|
|
1508
1514
|
|
|
1509
1515
|
await self._mount_message(
|
|
1510
|
-
AppMessage(
|
|
1511
|
-
f"Updated to v{cli_version}\nSee what's new: {CHANGELOG_URL}"
|
|
1512
|
-
)
|
|
1516
|
+
AppMessage(f"{heading}\nSee what's new: {CHANGELOG_URL}")
|
|
1513
1517
|
)
|
|
1514
1518
|
except Exception:
|
|
1515
1519
|
logger.debug("What's new banner display failed", exc_info=True)
|
|
@@ -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)
|
|
@@ -6,8 +6,11 @@ from deepagents_cli.deploy.commands import (
|
|
|
6
6
|
execute_init_command,
|
|
7
7
|
setup_deploy_parsers,
|
|
8
8
|
)
|
|
9
|
+
from deepagents_cli.deploy.config import SandboxProvider, SandboxScope
|
|
9
10
|
|
|
10
11
|
__all__ = [
|
|
12
|
+
"SandboxProvider",
|
|
13
|
+
"SandboxScope",
|
|
11
14
|
"execute_deploy_command",
|
|
12
15
|
"execute_dev_command",
|
|
13
16
|
"execute_init_command",
|
|
@@ -3,14 +3,22 @@
|
|
|
3
3
|
Reads the canonical project layout:
|
|
4
4
|
|
|
5
5
|
```txt
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
+
user/ # optional — per-user writable memory
|
|
13
|
+
AGENTS.md # optional — seeded as empty if not provided
|
|
11
14
|
```
|
|
12
15
|
|
|
13
16
|
...and writes everything `langgraph deploy` needs to a build directory.
|
|
17
|
+
|
|
18
|
+
AGENTS.md and skills are read-only at runtime. When a ``user/``
|
|
19
|
+
directory is present, a per-user ``AGENTS.md`` is seeded (from
|
|
20
|
+
``user/AGENTS.md`` if provided, otherwise empty) and is writable
|
|
21
|
+
at runtime.
|
|
14
22
|
"""
|
|
15
23
|
|
|
16
24
|
from __future__ import annotations
|
|
@@ -24,6 +32,7 @@ from deepagents_cli.deploy.config import (
|
|
|
24
32
|
AGENTS_MD_FILENAME,
|
|
25
33
|
MCP_FILENAME,
|
|
26
34
|
SKILLS_DIRNAME,
|
|
35
|
+
USER_DIRNAME,
|
|
27
36
|
DeployConfig,
|
|
28
37
|
)
|
|
29
38
|
from deepagents_cli.deploy.templates import (
|
|
@@ -35,13 +44,22 @@ from deepagents_cli.deploy.templates import (
|
|
|
35
44
|
|
|
36
45
|
logger = logging.getLogger(__name__)
|
|
37
46
|
|
|
38
|
-
_MODEL_PROVIDER_DEPS = {
|
|
47
|
+
_MODEL_PROVIDER_DEPS: dict[str, str] = {
|
|
39
48
|
"anthropic": "langchain-anthropic",
|
|
40
|
-
"
|
|
49
|
+
"azure_openai": "langchain-openai",
|
|
50
|
+
"baseten": "langchain-baseten",
|
|
51
|
+
"cohere": "langchain-cohere",
|
|
52
|
+
"deepseek": "langchain-deepseek",
|
|
53
|
+
"fireworks": "langchain-fireworks",
|
|
41
54
|
"google_genai": "langchain-google-genai",
|
|
42
55
|
"google_vertexai": "langchain-google-vertexai",
|
|
43
56
|
"groq": "langchain-groq",
|
|
44
57
|
"mistralai": "langchain-mistralai",
|
|
58
|
+
"nvidia": "langchain-nvidia-ai-endpoints",
|
|
59
|
+
"openai": "langchain-openai",
|
|
60
|
+
"openrouter": "langchain-openrouter",
|
|
61
|
+
"perplexity": "langchain-perplexity",
|
|
62
|
+
"xai": "langchain-xai",
|
|
45
63
|
}
|
|
46
64
|
"""Dependencies inferred from a provider: prefix on the model string."""
|
|
47
65
|
|
|
@@ -65,9 +83,10 @@ def bundle(
|
|
|
65
83
|
encoding="utf-8",
|
|
66
84
|
)
|
|
67
85
|
logger.info(
|
|
68
|
-
"Wrote _seed.json (memories: %d, skills: %d)",
|
|
86
|
+
"Wrote _seed.json (memories: %d, skills: %d, user_memories: %d)",
|
|
69
87
|
len(seed["memories"]),
|
|
70
88
|
len(seed["skills"]),
|
|
89
|
+
len(seed.get("user_memories", {})),
|
|
71
90
|
)
|
|
72
91
|
|
|
73
92
|
# 3. Copy mcp.json if present.
|
|
@@ -76,8 +95,8 @@ def bundle(
|
|
|
76
95
|
shutil.copy2(project_root / MCP_FILENAME, build_dir / "_mcp.json")
|
|
77
96
|
logger.info("Copied %s → _mcp.json", MCP_FILENAME)
|
|
78
97
|
|
|
79
|
-
# 3b. Copy .env from the project root if present (
|
|
80
|
-
# deepagents.toml
|
|
98
|
+
# 3b. Copy .env from the project root if present (alongside
|
|
99
|
+
# deepagents.toml). The bundler skips .env when
|
|
81
100
|
# building the seed payload so secrets never land in _seed.json.
|
|
82
101
|
env_src = project_root / ".env"
|
|
83
102
|
env_present = env_src.is_file()
|
|
@@ -86,8 +105,13 @@ def bundle(
|
|
|
86
105
|
logger.info("Copied %s → .env", env_src)
|
|
87
106
|
|
|
88
107
|
# 4. Render deploy_graph.py.
|
|
108
|
+
has_user_memories = (project_root / USER_DIRNAME).is_dir()
|
|
89
109
|
(build_dir / "deploy_graph.py").write_text(
|
|
90
|
-
_render_deploy_graph(
|
|
110
|
+
_render_deploy_graph(
|
|
111
|
+
config,
|
|
112
|
+
mcp_present=mcp_present,
|
|
113
|
+
has_user_memories=has_user_memories,
|
|
114
|
+
),
|
|
91
115
|
encoding="utf-8",
|
|
92
116
|
)
|
|
93
117
|
logger.info("Generated deploy_graph.py")
|
|
@@ -111,31 +135,25 @@ def _build_seed(
|
|
|
111
135
|
config: DeployConfig, # noqa: ARG001
|
|
112
136
|
project_root: Path,
|
|
113
137
|
system_prompt: str,
|
|
114
|
-
) -> dict
|
|
138
|
+
) -> dict:
|
|
115
139
|
"""Build the `_seed.json` payload.
|
|
116
140
|
|
|
117
|
-
Layout
|
|
118
|
-
|
|
119
|
-
```txt
|
|
120
|
-
{
|
|
121
|
-
"memories": { "AGENTS.md": "..." },
|
|
122
|
-
"skills": { "<skill>/SKILL.md": "...", ... }
|
|
123
|
-
}
|
|
124
|
-
```
|
|
141
|
+
Layout::
|
|
125
142
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
143
|
+
{
|
|
144
|
+
"memories": { "/AGENTS.md": "..." },
|
|
145
|
+
"skills": { "/<skill>/SKILL.md": "...", ... },
|
|
146
|
+
"user_memories": { "/AGENTS.md": "..." }
|
|
147
|
+
}
|
|
129
148
|
|
|
130
|
-
|
|
131
|
-
|
|
149
|
+
``memories`` and ``skills`` are read-only at runtime.
|
|
150
|
+
``user_memories`` contains a single writable ``AGENTS.md`` mounted at
|
|
151
|
+
``/memories/user/``, namespaced per user_id. If the project has a
|
|
152
|
+
``user/`` directory (even if empty), an ``AGENTS.md`` is always seeded.
|
|
132
153
|
"""
|
|
133
|
-
# Keys must match what CompositeBackend passes to the mounted
|
|
134
|
-
# StoreBackend after stripping the route prefix: for a read of
|
|
135
|
-
# /memories/AGENTS.md it calls store.read("/AGENTS.md").
|
|
136
|
-
# Seed with the same leading-slash convention.
|
|
137
154
|
memories: dict[str, str] = {f"/{AGENTS_MD_FILENAME}": system_prompt}
|
|
138
155
|
skills: dict[str, str] = {}
|
|
156
|
+
user_memories: dict[str, str] = {}
|
|
139
157
|
|
|
140
158
|
skills_dir = project_root / SKILLS_DIRNAME
|
|
141
159
|
if skills_dir.is_dir():
|
|
@@ -144,14 +162,28 @@ def _build_seed(
|
|
|
144
162
|
rel = f.relative_to(skills_dir).as_posix()
|
|
145
163
|
skills[f"/{rel}"] = f.read_text(encoding="utf-8")
|
|
146
164
|
|
|
147
|
-
|
|
165
|
+
user_dir = project_root / USER_DIRNAME
|
|
166
|
+
if user_dir.is_dir():
|
|
167
|
+
user_agents_md = user_dir / AGENTS_MD_FILENAME
|
|
168
|
+
content = (
|
|
169
|
+
user_agents_md.read_text(encoding="utf-8")
|
|
170
|
+
if user_agents_md.is_file()
|
|
171
|
+
else ""
|
|
172
|
+
)
|
|
173
|
+
user_memories[f"/{AGENTS_MD_FILENAME}"] = content
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
"memories": memories,
|
|
177
|
+
"skills": skills,
|
|
178
|
+
"user_memories": user_memories,
|
|
179
|
+
}
|
|
148
180
|
|
|
149
181
|
|
|
150
182
|
def _render_deploy_graph(
|
|
151
183
|
config: DeployConfig,
|
|
152
|
-
system_prompt: str,
|
|
153
184
|
*,
|
|
154
185
|
mcp_present: bool,
|
|
186
|
+
has_user_memories: bool = False,
|
|
155
187
|
) -> str:
|
|
156
188
|
"""Render the generated `deploy_graph.py`."""
|
|
157
189
|
provider = config.sandbox.provider
|
|
@@ -169,7 +201,6 @@ def _render_deploy_graph(
|
|
|
169
201
|
|
|
170
202
|
return DEPLOY_GRAPH_TEMPLATE.format(
|
|
171
203
|
model=config.agent.model,
|
|
172
|
-
system_prompt=system_prompt,
|
|
173
204
|
sandbox_template=config.sandbox.template,
|
|
174
205
|
sandbox_image=config.sandbox.image,
|
|
175
206
|
sandbox_scope=config.sandbox.scope,
|
|
@@ -177,6 +208,7 @@ def _render_deploy_graph(
|
|
|
177
208
|
mcp_tools_block=mcp_tools_block,
|
|
178
209
|
mcp_tools_load_call=mcp_tools_load_call,
|
|
179
210
|
default_assistant_id=config.agent.name,
|
|
211
|
+
has_user_memories=has_user_memories,
|
|
180
212
|
)
|
|
181
213
|
|
|
182
214
|
|
|
@@ -231,8 +263,12 @@ def print_bundle_summary(config: DeployConfig, build_dir: Path) -> None:
|
|
|
231
263
|
if seed_path.exists():
|
|
232
264
|
try:
|
|
233
265
|
seed = json.loads(seed_path.read_text(encoding="utf-8"))
|
|
234
|
-
except
|
|
235
|
-
|
|
266
|
+
except (json.JSONDecodeError, OSError) as exc:
|
|
267
|
+
logger.warning(
|
|
268
|
+
"Failed to parse %s; summary may be incomplete: %s",
|
|
269
|
+
seed_path,
|
|
270
|
+
exc,
|
|
271
|
+
)
|
|
236
272
|
|
|
237
273
|
print(f"\n Agent: {config.agent.name}")
|
|
238
274
|
print(f" Model: {config.agent.model}")
|
|
@@ -243,6 +279,12 @@ def print_bundle_summary(config: DeployConfig, build_dir: Path) -> None:
|
|
|
243
279
|
for f in memory_files:
|
|
244
280
|
print(f" {f}")
|
|
245
281
|
|
|
282
|
+
user_memory_files = sorted(seed.get("user_memories", {}).keys())
|
|
283
|
+
if user_memory_files:
|
|
284
|
+
print(f"\n User memory seed ({len(user_memory_files)} file(s)):")
|
|
285
|
+
for f in user_memory_files:
|
|
286
|
+
print(f" {f}")
|
|
287
|
+
|
|
246
288
|
skills_files = sorted(seed.get("skills", {}).keys())
|
|
247
289
|
if skills_files:
|
|
248
290
|
print(f"\n Skills seed ({len(skills_files)} file(s)):")
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
"""CLI commands for `deepagents deploy`.
|
|
1
|
+
"""CLI commands for `deepagents init`, `dev`, and `deploy`.
|
|
2
2
|
|
|
3
|
-
Registered with the CLI via `
|
|
4
|
-
|
|
5
|
-
Commands:
|
|
6
|
-
- `deepagents deploy` — Bundle and deploy to LangGraph Platform
|
|
7
|
-
- `deepagents deploy --dry-run` — Show what would be generated
|
|
8
|
-
- `deepagents init [NAME]` — Scaffold a new deploy project folder
|
|
3
|
+
Registered with the CLI via `setup_deploy_parsers` in `main.py`.
|
|
9
4
|
"""
|
|
10
5
|
|
|
11
6
|
from __future__ import annotations
|
|
@@ -70,7 +65,7 @@ def setup_deploy_parsers(
|
|
|
70
65
|
"--config",
|
|
71
66
|
type=str,
|
|
72
67
|
default=None,
|
|
73
|
-
help="Path to deepagents.toml (default: auto-discovered from cwd
|
|
68
|
+
help="Path to deepagents.toml (default: auto-discovered from cwd)",
|
|
74
69
|
)
|
|
75
70
|
dev_parser.add_argument(
|
|
76
71
|
"--port",
|
|
@@ -100,7 +95,7 @@ def setup_deploy_parsers(
|
|
|
100
95
|
"--config",
|
|
101
96
|
type=str,
|
|
102
97
|
default=None,
|
|
103
|
-
help="Path to deepagents.toml (default: auto-discovered from cwd
|
|
98
|
+
help="Path to deepagents.toml (default: auto-discovered from cwd)",
|
|
104
99
|
)
|
|
105
100
|
deploy_parser.add_argument(
|
|
106
101
|
"--dry-run",
|
|
@@ -197,14 +192,16 @@ def _init_project(*, name: str, force: bool = False) -> None:
|
|
|
197
192
|
]
|
|
198
193
|
|
|
199
194
|
for filename, content in files:
|
|
200
|
-
(project_dir / filename).write_text(content)
|
|
195
|
+
(project_dir / filename).write_text(content, encoding="utf-8")
|
|
201
196
|
|
|
202
197
|
# Create skills/ directory with a starter skill.
|
|
203
198
|
skills_dir = project_dir / SKILLS_DIRNAME
|
|
204
199
|
skills_dir.mkdir(exist_ok=True)
|
|
205
200
|
starter_skill_dir = skills_dir / STARTER_SKILL_NAME
|
|
206
201
|
starter_skill_dir.mkdir(exist_ok=True)
|
|
207
|
-
(starter_skill_dir / "SKILL.md").write_text(
|
|
202
|
+
(starter_skill_dir / "SKILL.md").write_text(
|
|
203
|
+
generate_starter_skill_md(), encoding="utf-8"
|
|
204
|
+
)
|
|
208
205
|
|
|
209
206
|
print(f"Created {name}/ with:")
|
|
210
207
|
for filename, _ in files:
|
|
@@ -227,6 +224,7 @@ def _deploy(
|
|
|
227
224
|
config_path: Path to config file, or `None` for default.
|
|
228
225
|
dry_run: If `True`, generate artifacts but don't deploy.
|
|
229
226
|
"""
|
|
227
|
+
from deepagents_cli.config import _load_dotenv
|
|
230
228
|
from deepagents_cli.deploy.bundler import bundle, print_bundle_summary
|
|
231
229
|
from deepagents_cli.deploy.config import (
|
|
232
230
|
DEFAULT_CONFIG_FILENAME,
|
|
@@ -242,6 +240,11 @@ def _deploy(
|
|
|
242
240
|
cfg_path = discovered or Path.cwd() / DEFAULT_CONFIG_FILENAME
|
|
243
241
|
|
|
244
242
|
project_root = cfg_path.parent
|
|
243
|
+
# Ensure the project .env is loaded into os.environ before validation.
|
|
244
|
+
# The main CLI bootstrap loads .env lazily (on first `settings` access),
|
|
245
|
+
# but deploy/dev commands may never touch `settings`, so the project
|
|
246
|
+
# .env would be missing when _validate_model_credentials checks os.environ.
|
|
247
|
+
_load_dotenv(start_path=project_root)
|
|
245
248
|
|
|
246
249
|
# Load and validate config
|
|
247
250
|
try:
|
|
@@ -262,10 +265,7 @@ def _deploy(
|
|
|
262
265
|
raise SystemExit(1)
|
|
263
266
|
|
|
264
267
|
# Bundle
|
|
265
|
-
|
|
266
|
-
build_dir = Path(tempfile.mkdtemp(prefix="deepagents-deploy-"))
|
|
267
|
-
else:
|
|
268
|
-
build_dir = Path(tempfile.mkdtemp(prefix="deepagents-deploy-"))
|
|
268
|
+
build_dir = Path(tempfile.mkdtemp(prefix="deepagents-deploy-"))
|
|
269
269
|
|
|
270
270
|
try:
|
|
271
271
|
bundle(config, project_root, build_dir)
|
|
@@ -276,14 +276,13 @@ def _deploy(
|
|
|
276
276
|
print(f"Inspect the build directory: {build_dir}")
|
|
277
277
|
return
|
|
278
278
|
|
|
279
|
-
# Deploy via langgraph CLI
|
|
279
|
+
# Deploy via langgraph CLI.
|
|
280
280
|
_run_langgraph_deploy(build_dir, name=config.agent.name)
|
|
281
|
+
finally:
|
|
282
|
+
if not dry_run:
|
|
283
|
+
import shutil
|
|
281
284
|
|
|
282
|
-
|
|
283
|
-
if dry_run:
|
|
284
|
-
# Keep build dir for inspection on dry run
|
|
285
|
-
raise
|
|
286
|
-
raise
|
|
285
|
+
shutil.rmtree(build_dir, ignore_errors=True)
|
|
287
286
|
|
|
288
287
|
|
|
289
288
|
def _dev(
|
|
@@ -298,7 +297,7 @@ def _dev(
|
|
|
298
297
|
served locally instead of pushed to LangGraph Platform. Hot-reloading
|
|
299
298
|
is provided by `langgraph dev` itself watching the build directory;
|
|
300
299
|
edits to the source project (`deepagents.toml`, skills, `AGENTS.md`)
|
|
301
|
-
require re-running `deepagents
|
|
300
|
+
require re-running `deepagents dev` to re-bundle.
|
|
302
301
|
|
|
303
302
|
Args:
|
|
304
303
|
config_path: Path to `deepagents.toml`, or `None` for default.
|
|
@@ -309,6 +308,7 @@ def _dev(
|
|
|
309
308
|
"""
|
|
310
309
|
import shutil
|
|
311
310
|
|
|
311
|
+
from deepagents_cli.config import _load_dotenv
|
|
312
312
|
from deepagents_cli.deploy.bundler import bundle, print_bundle_summary
|
|
313
313
|
from deepagents_cli.deploy.config import (
|
|
314
314
|
DEFAULT_CONFIG_FILENAME,
|
|
@@ -322,12 +322,17 @@ def _dev(
|
|
|
322
322
|
discovered = find_config()
|
|
323
323
|
cfg_path = discovered or Path.cwd() / DEFAULT_CONFIG_FILENAME
|
|
324
324
|
project_root = cfg_path.parent
|
|
325
|
+
# Ensure the project .env is loaded before validation (see _deploy).
|
|
326
|
+
_load_dotenv(start_path=project_root)
|
|
325
327
|
|
|
326
328
|
try:
|
|
327
329
|
config = load_config(cfg_path)
|
|
328
330
|
except FileNotFoundError:
|
|
329
331
|
print(f"Error: Config file not found: {cfg_path}")
|
|
330
332
|
raise SystemExit(1) from None
|
|
333
|
+
except ValueError as e:
|
|
334
|
+
print(f"Error: Invalid config: {e}")
|
|
335
|
+
raise SystemExit(1) from None
|
|
331
336
|
|
|
332
337
|
errors = config.validate(project_root)
|
|
333
338
|
if errors:
|
|
@@ -337,35 +342,43 @@ def _dev(
|
|
|
337
342
|
raise SystemExit(1)
|
|
338
343
|
|
|
339
344
|
build_dir = Path(tempfile.mkdtemp(prefix="deepagents-dev-"))
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if shutil.which("langgraph") is None:
|
|
344
|
-
print(
|
|
345
|
-
"Error: `langgraph` CLI not found. Install it with:\n"
|
|
346
|
-
" pip install 'langgraph-cli[inmem]'"
|
|
347
|
-
)
|
|
348
|
-
raise SystemExit(1)
|
|
345
|
+
try:
|
|
346
|
+
bundle(config, project_root, build_dir)
|
|
347
|
+
print_bundle_summary(config, build_dir)
|
|
349
348
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
]
|
|
357
|
-
if allow_blocking:
|
|
358
|
-
cmd.append("--allow-blocking")
|
|
349
|
+
if shutil.which("langgraph") is None:
|
|
350
|
+
print(
|
|
351
|
+
"Error: `langgraph` CLI not found. Install it with:\n"
|
|
352
|
+
" pip install 'langgraph-cli[inmem]'"
|
|
353
|
+
)
|
|
354
|
+
raise SystemExit(1)
|
|
359
355
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
356
|
+
cmd = [
|
|
357
|
+
"langgraph",
|
|
358
|
+
"dev",
|
|
359
|
+
"--no-browser",
|
|
360
|
+
"--port",
|
|
361
|
+
str(port),
|
|
362
|
+
]
|
|
363
|
+
if allow_blocking:
|
|
364
|
+
cmd.append("--allow-blocking")
|
|
365
|
+
|
|
366
|
+
print(f"\nStarting langgraph dev on http://localhost:{port}")
|
|
367
|
+
print(f"Build directory: {build_dir}")
|
|
368
|
+
print(f"Running: {' '.join(cmd)}\n")
|
|
369
|
+
|
|
370
|
+
# Pass through stdout/stderr so the user sees dev server logs live.
|
|
371
|
+
try:
|
|
372
|
+
result = subprocess.run(cmd, cwd=str(build_dir), check=False)
|
|
373
|
+
except KeyboardInterrupt:
|
|
374
|
+
print("\nShutting down.")
|
|
375
|
+
return
|
|
363
376
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
377
|
+
if result.returncode != 0:
|
|
378
|
+
print(f"\nDev server exited with error (exit code {result.returncode}).")
|
|
379
|
+
raise SystemExit(result.returncode)
|
|
380
|
+
finally:
|
|
381
|
+
shutil.rmtree(build_dir, ignore_errors=True)
|
|
369
382
|
|
|
370
383
|
|
|
371
384
|
def _run_langgraph_deploy(build_dir: Path, *, name: str) -> None:
|