deepagents-cli 0.0.43__tar.gz → 0.0.44__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.43 → deepagents_cli-0.0.44}/CHANGELOG.md +7 -2
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/PKG-INFO +50 -50
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/README.md +1 -1
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_version.py +1 -1
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/app.py +70 -1
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/pyproject.toml +27 -27
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_app.py +185 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/uv.lock +169 -93
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/.gitignore +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/DEV.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/Makefile +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/THREAT_MODEL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/__main__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_ask_user_types.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_cli_context.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_debug.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_env_vars.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_git.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_server_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_session_stats.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_testing_models.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/_textual_patches.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/agent.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/app.tcss +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/ask_user.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/built_in_skills/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/clipboard.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/command_registry.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/configurable_model.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/default_agent_prompt.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/bundler.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/commands.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/index.html +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/logo-dark.svg +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/frontend_dist/logo-light.svg +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/deploy/templates.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/editor.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/extras_info.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/file_ops.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/formatting.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/hooks.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/input.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/integrations/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/integrations/sandbox_factory.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/integrations/sandbox_provider.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/local_context.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/main.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/mcp_tools.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/mcp_trust.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/media_utils.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/model_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/non_interactive.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/notifications.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/offload.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/output.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/project_utils.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/py.typed +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/remote_client.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/server.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/server_graph.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/server_manager.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/sessions.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/skills/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/skills/commands.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/skills/invocation.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/skills/load.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/subagents.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/system_prompt.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/terminal_capabilities.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/textual_adapter.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/theme.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/token_state.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/tool_display.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/tools.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/ui.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/unicode_security.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/update_check.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/_links.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/agent_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/approval.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/ask_user.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/autocomplete.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/chat_input.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/diff.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/history.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/loading.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/mcp_viewer.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/message_store.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/messages.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/model_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/notification_center.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/notification_detail.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/notification_settings.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/status.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/theme_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/thread_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/tool_renderers.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/tool_widgets.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/update_available.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/deepagents_cli/widgets/welcome.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/deploy-content-writer/.env.example +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/deploy-content-writer/user/context.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/deploy-content-writer/user/preferences.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/.nvmrc +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/index.html +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/package-lock.json +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/package.json +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/postcss.config.js +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/public/logo-dark.svg +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/public/logo-light.svg +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/App.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/ThemeProvider.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/auth/anonymous.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/auth/clerk.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/auth/loader.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/auth/supabase.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/auth/types.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/AppHeader.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/FilePanels.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/MessageList.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/SubagentActivity.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/ThreadPicker.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/TodosPanel.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/ToolCallCard.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/toolcalls/FileToolCard.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/toolcalls/SearchCard.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/toolcalls/ThinkCard.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/toolcalls/TodosCard.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/components/toolcalls/index.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/constants.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/index.css +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/main.tsx +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/runtimeConfig.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/types.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/src/vite-env.d.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/tsconfig.json +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/frontend/vite.config.ts +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/images/cli.png +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/scripts/check_imports.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/scripts/debug_server.sh +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/scripts/install.sh +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/README.md +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/conftest.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/conftest.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/deploy/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/deploy/test_bundler.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/deploy/test_commands.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/deploy/test_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/deploy/test_frontend_bundle.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/deploy/test_frontend_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_args.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_git.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_history.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_links.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_main.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_output.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_server.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_status.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_token_tracker.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_version.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_cli-0.0.43 → deepagents_cli-0.0.44}/tests/unit_tests/tools/test_fetch_url.py +0 -0
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.0.
|
|
3
|
+
## [0.0.44](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.43...deepagents-cli==0.0.44) (2026-04-29)
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
4
6
|
|
|
7
|
+
* Startup import deadlock ([#3017](https://github.com/langchain-ai/deepagents/issues/3017)) ([d40ab57](https://github.com/langchain-ai/deepagents/commit/d40ab57800a6ad12b0c9a5e249753702ec0832c8))
|
|
8
|
+
|
|
9
|
+
## [0.0.43](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.42...deepagents-cli==0.0.43) (2026-04-29)
|
|
5
10
|
|
|
6
11
|
### Features
|
|
7
12
|
|
|
8
|
-
*
|
|
13
|
+
* Bundled chat frontend for deepagent deploy ([#2940](https://github.com/langchain-ai/deepagents/issues/2940)) ([9bde0c7](https://github.com/langchain-ai/deepagents/commit/9bde0c7835ded20e80466d8361f40784141d68d8))
|
|
9
14
|
|
|
10
15
|
## [0.0.42](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.41...deepagents-cli==0.0.42) (2026-04-29)
|
|
11
16
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.44
|
|
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/
|
|
7
7
|
Project-URL: Repository, https://github.com/langchain-ai/deepagents
|
|
8
8
|
Project-URL: Issues, https://github.com/langchain-ai/deepagents/issues
|
|
9
9
|
Project-URL: Changelog, https://github.com/langchain-ai/deepagents/blob/main/libs/cli/CHANGELOG.md
|
|
10
|
-
Project-URL: Twitter, https://x.com/
|
|
10
|
+
Project-URL: Twitter, https://x.com/langchain_oss
|
|
11
11
|
Project-URL: Slack, https://www.langchain.com/join-community
|
|
12
12
|
Project-URL: Reddit, https://www.reddit.com/r/LangChain/
|
|
13
13
|
License: MIT
|
|
@@ -30,9 +30,9 @@ Requires-Dist: deepagents-acp>=0.0.4
|
|
|
30
30
|
Requires-Dist: deepagents==0.5.4
|
|
31
31
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
32
32
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2
|
|
33
|
-
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.
|
|
34
|
-
Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.2.
|
|
35
|
-
Requires-Dist: langchain-openai<2.0.0,>=1.1
|
|
33
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.2
|
|
34
|
+
Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.2.2
|
|
35
|
+
Requires-Dist: langchain-openai<2.0.0,>=1.2.1
|
|
36
36
|
Requires-Dist: langchain<2.0.0,>=1.2.15
|
|
37
37
|
Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.0.0
|
|
38
38
|
Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.15
|
|
@@ -55,76 +55,76 @@ Requires-Dist: textual<9.0.0,>=8.0.0
|
|
|
55
55
|
Requires-Dist: tomli-w<2.0.0,>=1.0.0
|
|
56
56
|
Requires-Dist: uuid-utils<1.0.0,>=0.10.0
|
|
57
57
|
Provides-Extra: agentcore
|
|
58
|
-
Requires-Dist: langchain-agentcore-codeinterpreter>=0.0.
|
|
58
|
+
Requires-Dist: langchain-agentcore-codeinterpreter>=0.0.2; extra == 'agentcore'
|
|
59
59
|
Provides-Extra: all-providers
|
|
60
60
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2; extra == 'all-providers'
|
|
61
|
-
Requires-Dist: langchain-aws<2.0.0,>=1.
|
|
62
|
-
Requires-Dist: langchain-baseten<1.0.0,>=0.
|
|
63
|
-
Requires-Dist: langchain-cohere<1.0.0,>=0.5.
|
|
64
|
-
Requires-Dist: langchain-deepseek<2.0.0,>=1.0.
|
|
65
|
-
Requires-Dist: langchain-fireworks<2.0.0,>=1.
|
|
66
|
-
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.
|
|
67
|
-
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.
|
|
68
|
-
Requires-Dist: langchain-groq<2.0.0,>=1.
|
|
69
|
-
Requires-Dist: langchain-huggingface<2.0.0,>=1.
|
|
70
|
-
Requires-Dist: langchain-ibm<2.0.0,>=1.0.
|
|
71
|
-
Requires-Dist: langchain-litellm<2.0.0,>=0.6.
|
|
72
|
-
Requires-Dist: langchain-mistralai<2.0.0,>=1.
|
|
73
|
-
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.
|
|
74
|
-
Requires-Dist: langchain-ollama<2.0.0,>=1.
|
|
75
|
-
Requires-Dist: langchain-openai<2.0.0,>=1.1
|
|
76
|
-
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.
|
|
77
|
-
Requires-Dist: langchain-perplexity<2.0.0,>=1.
|
|
78
|
-
Requires-Dist: langchain-xai<2.0.0,>=1.
|
|
61
|
+
Requires-Dist: langchain-aws<2.0.0,>=1.4.5; extra == 'all-providers'
|
|
62
|
+
Requires-Dist: langchain-baseten<1.0.0,>=0.2.0; extra == 'all-providers'
|
|
63
|
+
Requires-Dist: langchain-cohere<1.0.0,>=0.5.1; extra == 'all-providers'
|
|
64
|
+
Requires-Dist: langchain-deepseek<2.0.0,>=1.0.1; extra == 'all-providers'
|
|
65
|
+
Requires-Dist: langchain-fireworks<2.0.0,>=1.2.0; extra == 'all-providers'
|
|
66
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.2; extra == 'all-providers'
|
|
67
|
+
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.2; extra == 'all-providers'
|
|
68
|
+
Requires-Dist: langchain-groq<2.0.0,>=1.1.2; extra == 'all-providers'
|
|
69
|
+
Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
70
|
+
Requires-Dist: langchain-ibm<2.0.0,>=1.0.7; extra == 'all-providers'
|
|
71
|
+
Requires-Dist: langchain-litellm<2.0.0,>=0.6.4; extra == 'all-providers'
|
|
72
|
+
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.2; extra == 'all-providers'
|
|
73
|
+
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.2.1; extra == 'all-providers'
|
|
74
|
+
Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
75
|
+
Requires-Dist: langchain-openai<2.0.0,>=1.2.1; extra == 'all-providers'
|
|
76
|
+
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.1; extra == 'all-providers'
|
|
77
|
+
Requires-Dist: langchain-perplexity<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
78
|
+
Requires-Dist: langchain-xai<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
79
79
|
Provides-Extra: all-sandboxes
|
|
80
|
-
Requires-Dist: langchain-agentcore-codeinterpreter>=0.0.
|
|
81
|
-
Requires-Dist: langchain-daytona>=0.0.
|
|
82
|
-
Requires-Dist: langchain-modal>=0.0.
|
|
83
|
-
Requires-Dist: langchain-runloop>=0.0.
|
|
80
|
+
Requires-Dist: langchain-agentcore-codeinterpreter>=0.0.2; extra == 'all-sandboxes'
|
|
81
|
+
Requires-Dist: langchain-daytona>=0.0.5; extra == 'all-sandboxes'
|
|
82
|
+
Requires-Dist: langchain-modal>=0.0.3; extra == 'all-sandboxes'
|
|
83
|
+
Requires-Dist: langchain-runloop>=0.0.4; extra == 'all-sandboxes'
|
|
84
84
|
Provides-Extra: anthropic
|
|
85
85
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2; extra == 'anthropic'
|
|
86
86
|
Provides-Extra: baseten
|
|
87
|
-
Requires-Dist: langchain-baseten<1.0.0,>=0.
|
|
87
|
+
Requires-Dist: langchain-baseten<1.0.0,>=0.2.0; extra == 'baseten'
|
|
88
88
|
Provides-Extra: bedrock
|
|
89
|
-
Requires-Dist: langchain-aws<2.0.0,>=1.
|
|
89
|
+
Requires-Dist: langchain-aws<2.0.0,>=1.4.5; extra == 'bedrock'
|
|
90
90
|
Provides-Extra: cohere
|
|
91
|
-
Requires-Dist: langchain-cohere<1.0.0,>=0.5.
|
|
91
|
+
Requires-Dist: langchain-cohere<1.0.0,>=0.5.1; extra == 'cohere'
|
|
92
92
|
Provides-Extra: daytona
|
|
93
|
-
Requires-Dist: langchain-daytona>=0.0.
|
|
93
|
+
Requires-Dist: langchain-daytona>=0.0.5; extra == 'daytona'
|
|
94
94
|
Provides-Extra: deepseek
|
|
95
|
-
Requires-Dist: langchain-deepseek<2.0.0,>=1.0.
|
|
95
|
+
Requires-Dist: langchain-deepseek<2.0.0,>=1.0.1; extra == 'deepseek'
|
|
96
96
|
Provides-Extra: fireworks
|
|
97
|
-
Requires-Dist: langchain-fireworks<2.0.0,>=1.
|
|
97
|
+
Requires-Dist: langchain-fireworks<2.0.0,>=1.2.0; extra == 'fireworks'
|
|
98
98
|
Provides-Extra: google-genai
|
|
99
|
-
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.
|
|
99
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.2; extra == 'google-genai'
|
|
100
100
|
Provides-Extra: groq
|
|
101
|
-
Requires-Dist: langchain-groq<2.0.0,>=1.
|
|
101
|
+
Requires-Dist: langchain-groq<2.0.0,>=1.1.2; extra == 'groq'
|
|
102
102
|
Provides-Extra: huggingface
|
|
103
|
-
Requires-Dist: langchain-huggingface<2.0.0,>=1.
|
|
103
|
+
Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'huggingface'
|
|
104
104
|
Provides-Extra: ibm
|
|
105
|
-
Requires-Dist: langchain-ibm<2.0.0,>=1.0.
|
|
105
|
+
Requires-Dist: langchain-ibm<2.0.0,>=1.0.7; extra == 'ibm'
|
|
106
106
|
Provides-Extra: litellm
|
|
107
|
-
Requires-Dist: langchain-litellm<2.0.0,>=0.6.
|
|
107
|
+
Requires-Dist: langchain-litellm<2.0.0,>=0.6.4; extra == 'litellm'
|
|
108
108
|
Provides-Extra: mistralai
|
|
109
|
-
Requires-Dist: langchain-mistralai<2.0.0,>=1.
|
|
109
|
+
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.2; extra == 'mistralai'
|
|
110
110
|
Provides-Extra: modal
|
|
111
|
-
Requires-Dist: langchain-modal>=0.0.
|
|
111
|
+
Requires-Dist: langchain-modal>=0.0.3; extra == 'modal'
|
|
112
112
|
Provides-Extra: nvidia
|
|
113
|
-
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.
|
|
113
|
+
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.2.1; extra == 'nvidia'
|
|
114
114
|
Provides-Extra: ollama
|
|
115
|
-
Requires-Dist: langchain-ollama<2.0.0,>=1.
|
|
115
|
+
Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'ollama'
|
|
116
116
|
Provides-Extra: openai
|
|
117
|
-
Requires-Dist: langchain-openai<2.0.0,>=1.1
|
|
117
|
+
Requires-Dist: langchain-openai<2.0.0,>=1.2.1; extra == 'openai'
|
|
118
118
|
Provides-Extra: openrouter
|
|
119
|
-
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.
|
|
119
|
+
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.1; extra == 'openrouter'
|
|
120
120
|
Provides-Extra: perplexity
|
|
121
|
-
Requires-Dist: langchain-perplexity<2.0.0,>=1.
|
|
121
|
+
Requires-Dist: langchain-perplexity<2.0.0,>=1.1.0; extra == 'perplexity'
|
|
122
122
|
Provides-Extra: runloop
|
|
123
|
-
Requires-Dist: langchain-runloop>=0.0.
|
|
123
|
+
Requires-Dist: langchain-runloop>=0.0.4; extra == 'runloop'
|
|
124
124
|
Provides-Extra: vertexai
|
|
125
|
-
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.
|
|
125
|
+
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.2; extra == 'vertexai'
|
|
126
126
|
Provides-Extra: xai
|
|
127
|
-
Requires-Dist: langchain-xai<2.0.0,>=1.
|
|
127
|
+
Requires-Dist: langchain-xai<2.0.0,>=1.2.2; extra == 'xai'
|
|
128
128
|
Description-Content-Type: text/markdown
|
|
129
129
|
|
|
130
130
|
# 🧠🤖 Deep Agents CLI
|
|
@@ -132,7 +132,7 @@ Description-Content-Type: text/markdown
|
|
|
132
132
|
[](https://pypi.org/project/deepagents-cli/#history)
|
|
133
133
|
[](https://opensource.org/licenses/MIT)
|
|
134
134
|
[](https://pypistats.org/packages/deepagents-cli)
|
|
135
|
-
[](https://x.com/langchain_oss)
|
|
136
136
|
|
|
137
137
|
<p align="center">
|
|
138
138
|
<img src="https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/images/cli.png" alt="Deep Agents CLI" width="600"/>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://pypi.org/project/deepagents-cli/#history)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://pypistats.org/packages/deepagents-cli)
|
|
6
|
-
[](https://x.com/langchain_oss)
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<img src="https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/images/cli.png" alt="Deep Agents CLI" width="600"/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Version information and lightweight constants for `deepagents-cli`."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.0.
|
|
3
|
+
__version__ = "0.0.44" # 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."""
|
|
@@ -849,6 +849,13 @@ class DeepAgentsApp(App):
|
|
|
849
849
|
self._shell_running = False
|
|
850
850
|
"""True while a `!` shell command is executing."""
|
|
851
851
|
|
|
852
|
+
self._prewarm_worker: Worker[None] | None = None
|
|
853
|
+
"""Background worker that prewarms `deepagents`/LangChain imports.
|
|
854
|
+
|
|
855
|
+
Awaited via `_await_prewarm_imports` before any caller on the event
|
|
856
|
+
loop re-enters the same module graph (see that method for why).
|
|
857
|
+
"""
|
|
858
|
+
|
|
852
859
|
# Lifecycle flags & re-entry guards
|
|
853
860
|
self._connecting = server_kwargs is not None
|
|
854
861
|
"""True while the backing server is being started or restarted.
|
|
@@ -1038,6 +1045,39 @@ class DeepAgentsApp(App):
|
|
|
1038
1045
|
colors = theme.get_theme_colors(self)
|
|
1039
1046
|
return theme.get_css_variable_defaults(colors=colors)
|
|
1040
1047
|
|
|
1048
|
+
def _fatal_error(self) -> None:
|
|
1049
|
+
"""Render an unhandled-exception traceback without leaking secrets.
|
|
1050
|
+
|
|
1051
|
+
Textual's default `_fatal_error` renders with `show_locals=True`,
|
|
1052
|
+
which prints local variables — including resolved API keys carried
|
|
1053
|
+
in `kwargs` dicts on the call path through `create_model`. Locals
|
|
1054
|
+
are only re-enabled when `DEEPAGENTS_CLI_DEBUG` matches a truthy
|
|
1055
|
+
token (`"1"`, `"true"`, `"yes"`); any other value, including `"0"`
|
|
1056
|
+
and `"false"`, leaves them disabled.
|
|
1057
|
+
"""
|
|
1058
|
+
try:
|
|
1059
|
+
import rich
|
|
1060
|
+
from rich.segment import Segments
|
|
1061
|
+
from rich.traceback import Traceback
|
|
1062
|
+
|
|
1063
|
+
from deepagents_cli._env_vars import DEBUG
|
|
1064
|
+
except Exception: # noqa: BLE001 # mid-teardown import errors fall through to Textual's default rather than double-fault and swallow the original crash
|
|
1065
|
+
super()._fatal_error()
|
|
1066
|
+
return
|
|
1067
|
+
|
|
1068
|
+
self.bell()
|
|
1069
|
+
show_locals = os.environ.get(DEBUG, "").lower() in {"1", "true", "yes"}
|
|
1070
|
+
traceback = Traceback(
|
|
1071
|
+
show_locals=show_locals,
|
|
1072
|
+
width=None,
|
|
1073
|
+
locals_max_length=5,
|
|
1074
|
+
suppress=[rich],
|
|
1075
|
+
)
|
|
1076
|
+
self._exit_renderables.append(
|
|
1077
|
+
Segments(self.console.render(traceback, self.console.options))
|
|
1078
|
+
)
|
|
1079
|
+
self._close_messages_no_wait()
|
|
1080
|
+
|
|
1041
1081
|
def compose(self) -> ComposeResult:
|
|
1042
1082
|
"""Compose the application layout.
|
|
1043
1083
|
|
|
@@ -1108,7 +1148,8 @@ class DeepAgentsApp(App):
|
|
|
1108
1148
|
# Prewarm heavy imports in a thread while the first frame renders.
|
|
1109
1149
|
# The user can't type yet, so GIL contention is harmless. By the
|
|
1110
1150
|
# time _post_paint_init fires its inline imports are dict lookups.
|
|
1111
|
-
|
|
1151
|
+
# Handle is captured so `_await_prewarm_imports` can block on it.
|
|
1152
|
+
self._prewarm_worker = self.run_worker(
|
|
1112
1153
|
asyncio.to_thread(self._prewarm_deferred_imports),
|
|
1113
1154
|
exclusive=True,
|
|
1114
1155
|
group="startup-import-prewarm",
|
|
@@ -1580,6 +1621,10 @@ class DeepAgentsApp(App):
|
|
|
1580
1621
|
# does the heavy langchain import + SDK init and may refine them
|
|
1581
1622
|
# (e.g., context_limit from the model profile).
|
|
1582
1623
|
if self._model_kwargs is not None:
|
|
1624
|
+
# Block on prewarm before re-entering the import graph; see
|
|
1625
|
+
# `_await_prewarm_imports` for the deadlock rationale.
|
|
1626
|
+
await self._await_prewarm_imports()
|
|
1627
|
+
|
|
1583
1628
|
from deepagents_cli.config import create_model
|
|
1584
1629
|
from deepagents_cli.model_config import ModelConfigError, save_recent_model
|
|
1585
1630
|
|
|
@@ -1719,6 +1764,30 @@ class DeepAgentsApp(App):
|
|
|
1719
1764
|
self._queued_widgets.clear()
|
|
1720
1765
|
self._deferred_actions.clear()
|
|
1721
1766
|
|
|
1767
|
+
async def _await_prewarm_imports(self) -> None:
|
|
1768
|
+
"""Wait for prewarm imports before re-entering their module graph.
|
|
1769
|
+
|
|
1770
|
+
Prevents a multi-threaded import deadlock: the prewarm worker runs in
|
|
1771
|
+
`asyncio.to_thread`, and any caller that imports `deepagents` or
|
|
1772
|
+
LangChain from the event-loop thread while it's still running can
|
|
1773
|
+
race on partially-initialized module locks.
|
|
1774
|
+
|
|
1775
|
+
`CancelledError` propagates so app shutdown isn't silently absorbed.
|
|
1776
|
+
"""
|
|
1777
|
+
from textual.worker import WorkerFailed
|
|
1778
|
+
|
|
1779
|
+
worker = self._prewarm_worker
|
|
1780
|
+
if worker is None:
|
|
1781
|
+
return
|
|
1782
|
+
try:
|
|
1783
|
+
await worker.wait()
|
|
1784
|
+
except WorkerFailed:
|
|
1785
|
+
# Prewarm body best-efforts third-party imports and already
|
|
1786
|
+
# warns; logging at WARNING here surfaces unexpected failures
|
|
1787
|
+
# (e.g. a regression that breaks a non-optional import) that
|
|
1788
|
+
# the body itself didn't catch.
|
|
1789
|
+
logger.warning("Import prewarm worker failed", exc_info=True)
|
|
1790
|
+
|
|
1722
1791
|
@staticmethod
|
|
1723
1792
|
def _prewarm_deferred_imports() -> None:
|
|
1724
1793
|
"""Background-load modules deferred from the startup path.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deepagents-cli"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.44"
|
|
8
8
|
description = "Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -38,8 +38,8 @@ dependencies = [
|
|
|
38
38
|
|
|
39
39
|
# Core model providers - others are added as optional
|
|
40
40
|
"langchain-anthropic>=1.4.2,<2.0.0",
|
|
41
|
-
"langchain-google-genai>=4.2.
|
|
42
|
-
"langchain-openai>=1.1
|
|
41
|
+
"langchain-google-genai>=4.2.2,<5.0.0",
|
|
42
|
+
"langchain-openai>=1.2.1,<2.0.0",
|
|
43
43
|
|
|
44
44
|
# UI/Terminal
|
|
45
45
|
# Workaround for Textualize/textual#6378 lives in `_textual_patches.py`.
|
|
@@ -74,7 +74,7 @@ dependencies = [
|
|
|
74
74
|
"tomli-w>=1.0.0,<2.0.0",
|
|
75
75
|
|
|
76
76
|
# MCP
|
|
77
|
-
"langchain-mcp-adapters>=0.2.
|
|
77
|
+
"langchain-mcp-adapters>=0.2.2,<1.0.0",
|
|
78
78
|
|
|
79
79
|
# ACP
|
|
80
80
|
"deepagents-acp>=0.0.4",
|
|
@@ -83,33 +83,33 @@ dependencies = [
|
|
|
83
83
|
[project.optional-dependencies]
|
|
84
84
|
# Model providers
|
|
85
85
|
anthropic = ["langchain-anthropic>=1.4.2,<2.0.0"]
|
|
86
|
-
baseten = ["langchain-baseten>=0.
|
|
87
|
-
bedrock = ["langchain-aws>=1.
|
|
88
|
-
cohere = ["langchain-cohere>=0.5.
|
|
89
|
-
deepseek = ["langchain-deepseek>=1.0.
|
|
90
|
-
fireworks = ["langchain-fireworks>=1.
|
|
91
|
-
google-genai = ["langchain-google-genai>=4.2.
|
|
92
|
-
groq = ["langchain-groq>=1.
|
|
93
|
-
huggingface = ["langchain-huggingface>=1.
|
|
94
|
-
ibm = ["langchain-ibm>=1.0.
|
|
95
|
-
litellm = ["langchain-litellm>=0.6.
|
|
96
|
-
mistralai = ["langchain-mistralai>=1.
|
|
97
|
-
nvidia = ["langchain-nvidia-ai-endpoints>=1.
|
|
98
|
-
ollama = ["langchain-ollama>=1.
|
|
99
|
-
openai = ["langchain-openai>=1.1
|
|
100
|
-
openrouter = ["langchain-openrouter>=0.2.
|
|
101
|
-
perplexity = ["langchain-perplexity>=1.
|
|
102
|
-
vertexai = ["langchain-google-vertexai>=3.
|
|
103
|
-
xai = ["langchain-xai>=1.
|
|
86
|
+
baseten = ["langchain-baseten>=0.2.0,<1.0.0"]
|
|
87
|
+
bedrock = ["langchain-aws>=1.4.5,<2.0.0"]
|
|
88
|
+
cohere = ["langchain-cohere>=0.5.1,<1.0.0"]
|
|
89
|
+
deepseek = ["langchain-deepseek>=1.0.1,<2.0.0"]
|
|
90
|
+
fireworks = ["langchain-fireworks>=1.2.0,<2.0.0"]
|
|
91
|
+
google-genai = ["langchain-google-genai>=4.2.2,<5.0.0"]
|
|
92
|
+
groq = ["langchain-groq>=1.1.2,<2.0.0"]
|
|
93
|
+
huggingface = ["langchain-huggingface>=1.2.2,<2.0.0"]
|
|
94
|
+
ibm = ["langchain-ibm>=1.0.7,<2.0.0"]
|
|
95
|
+
litellm = ["langchain-litellm>=0.6.4,<2.0.0"]
|
|
96
|
+
mistralai = ["langchain-mistralai>=1.1.2,<2.0.0"]
|
|
97
|
+
nvidia = ["langchain-nvidia-ai-endpoints>=1.2.1,<2.0.0"]
|
|
98
|
+
ollama = ["langchain-ollama>=1.1.0,<2.0.0"]
|
|
99
|
+
openai = ["langchain-openai>=1.2.1,<2.0.0"]
|
|
100
|
+
openrouter = ["langchain-openrouter>=0.2.1,<2.0.0"]
|
|
101
|
+
perplexity = ["langchain-perplexity>=1.1.0,<2.0.0"]
|
|
102
|
+
vertexai = ["langchain-google-vertexai>=3.2.2,<4.0.0"]
|
|
103
|
+
xai = ["langchain-xai>=1.2.2,<2.0.0"]
|
|
104
104
|
all-providers = [
|
|
105
105
|
"deepagents-cli[anthropic,baseten,bedrock,cohere,deepseek,fireworks,google-genai,groq,huggingface,ibm,litellm,mistralai,nvidia,ollama,openai,openrouter,perplexity,vertexai,xai]",
|
|
106
106
|
]
|
|
107
107
|
|
|
108
108
|
# Sandbox providers
|
|
109
|
-
agentcore = ["langchain-agentcore-codeinterpreter>=0.0.
|
|
110
|
-
daytona = ["langchain-daytona>=0.0.
|
|
111
|
-
modal = ["langchain-modal>=0.0.
|
|
112
|
-
runloop = ["langchain-runloop>=0.0.
|
|
109
|
+
agentcore = ["langchain-agentcore-codeinterpreter>=0.0.2"]
|
|
110
|
+
daytona = ["langchain-daytona>=0.0.5"]
|
|
111
|
+
modal = ["langchain-modal>=0.0.3"]
|
|
112
|
+
runloop = ["langchain-runloop>=0.0.4"]
|
|
113
113
|
all-sandboxes = [
|
|
114
114
|
"deepagents-cli[agentcore,daytona,modal,runloop]",
|
|
115
115
|
]
|
|
@@ -125,7 +125,7 @@ Documentation = "https://reference.langchain.com/python/deepagents/"
|
|
|
125
125
|
Repository = "https://github.com/langchain-ai/deepagents"
|
|
126
126
|
Issues = "https://github.com/langchain-ai/deepagents/issues"
|
|
127
127
|
Changelog = "https://github.com/langchain-ai/deepagents/blob/main/libs/cli/CHANGELOG.md"
|
|
128
|
-
Twitter = "https://x.com/
|
|
128
|
+
Twitter = "https://x.com/langchain_oss"
|
|
129
129
|
Slack = "https://www.langchain.com/join-community"
|
|
130
130
|
Reddit = "https://www.reddit.com/r/LangChain/"
|
|
131
131
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import contextlib
|
|
6
7
|
import inspect
|
|
7
8
|
import io
|
|
8
9
|
import os
|
|
@@ -5472,3 +5473,187 @@ class TestNotificationCenterIntegration:
|
|
|
5472
5473
|
await pilot.pause()
|
|
5473
5474
|
|
|
5474
5475
|
assert isinstance(app.screen, NotificationCenterScreen)
|
|
5476
|
+
|
|
5477
|
+
|
|
5478
|
+
class TestFatalErrorRedaction:
|
|
5479
|
+
"""`_fatal_error` must not leak local variables (which carry secrets).
|
|
5480
|
+
|
|
5481
|
+
Locals on the `create_model` call path include resolved API keys in a
|
|
5482
|
+
`kwargs` dict. Textual's default rendering uses `show_locals=True`,
|
|
5483
|
+
which would print them. We disable locals unless `DEEPAGENTS_CLI_DEBUG`
|
|
5484
|
+
is set to a truthy token.
|
|
5485
|
+
"""
|
|
5486
|
+
|
|
5487
|
+
@staticmethod
|
|
5488
|
+
def _call_fatal_error(app: DeepAgentsApp) -> MagicMock:
|
|
5489
|
+
"""Run `_fatal_error` with the rendering pipeline patched out.
|
|
5490
|
+
|
|
5491
|
+
Returns the `Traceback` mock so callers can inspect its kwargs.
|
|
5492
|
+
"""
|
|
5493
|
+
with (
|
|
5494
|
+
patch("rich.traceback.Traceback") as mock_traceback,
|
|
5495
|
+
patch("rich.segment.Segments"),
|
|
5496
|
+
patch.object(app, "console", MagicMock()),
|
|
5497
|
+
patch.object(app, "_close_messages_no_wait"),
|
|
5498
|
+
patch.object(app, "bell"),
|
|
5499
|
+
):
|
|
5500
|
+
app._fatal_error()
|
|
5501
|
+
return mock_traceback
|
|
5502
|
+
|
|
5503
|
+
def test_show_locals_disabled_by_default(
|
|
5504
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
5505
|
+
) -> None:
|
|
5506
|
+
"""Default crash rendering hides locals so secrets don't reach stderr."""
|
|
5507
|
+
monkeypatch.delenv("DEEPAGENTS_CLI_DEBUG", raising=False)
|
|
5508
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5509
|
+
|
|
5510
|
+
mock_traceback = self._call_fatal_error(app)
|
|
5511
|
+
|
|
5512
|
+
mock_traceback.assert_called_once()
|
|
5513
|
+
assert mock_traceback.call_args.kwargs["show_locals"] is False
|
|
5514
|
+
|
|
5515
|
+
def test_show_locals_enabled_when_debug_env_truthy(
|
|
5516
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
5517
|
+
) -> None:
|
|
5518
|
+
"""Truthy `DEEPAGENTS_CLI_DEBUG` re-enables locals for debugging."""
|
|
5519
|
+
monkeypatch.setenv("DEEPAGENTS_CLI_DEBUG", "1")
|
|
5520
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5521
|
+
|
|
5522
|
+
mock_traceback = self._call_fatal_error(app)
|
|
5523
|
+
|
|
5524
|
+
assert mock_traceback.call_args.kwargs["show_locals"] is True
|
|
5525
|
+
|
|
5526
|
+
@pytest.mark.parametrize("falsy", ["0", "false", "no", "", "False", " "])
|
|
5527
|
+
def test_show_locals_disabled_for_falsy_strings(
|
|
5528
|
+
self, monkeypatch: pytest.MonkeyPatch, falsy: str
|
|
5529
|
+
) -> None:
|
|
5530
|
+
"""`DEEPAGENTS_CLI_DEBUG=0` (or other falsy strings) MUST NOT enable locals.
|
|
5531
|
+
|
|
5532
|
+
Regression guard: an earlier `bool(os.environ.get(...))` check would
|
|
5533
|
+
have flipped to `True` for any non-empty string, leaking the API key
|
|
5534
|
+
whenever a user set the var to `"0"` or `"false"` thinking they were
|
|
5535
|
+
disabling the flag.
|
|
5536
|
+
"""
|
|
5537
|
+
monkeypatch.setenv("DEEPAGENTS_CLI_DEBUG", falsy)
|
|
5538
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5539
|
+
|
|
5540
|
+
mock_traceback = self._call_fatal_error(app)
|
|
5541
|
+
|
|
5542
|
+
assert mock_traceback.call_args.kwargs["show_locals"] is False
|
|
5543
|
+
|
|
5544
|
+
def test_falls_back_to_super_on_import_failure(
|
|
5545
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
5546
|
+
) -> None:
|
|
5547
|
+
"""If the override's own imports fail, defer to Textual's default.
|
|
5548
|
+
|
|
5549
|
+
Otherwise the user double-faults during a real crash and never sees
|
|
5550
|
+
any traceback at all.
|
|
5551
|
+
"""
|
|
5552
|
+
monkeypatch.delenv("DEEPAGENTS_CLI_DEBUG", raising=False)
|
|
5553
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5554
|
+
|
|
5555
|
+
with (
|
|
5556
|
+
patch.dict("sys.modules", {"rich.traceback": None}),
|
|
5557
|
+
patch("textual.app.App._fatal_error") as super_fatal,
|
|
5558
|
+
):
|
|
5559
|
+
app._fatal_error()
|
|
5560
|
+
|
|
5561
|
+
super_fatal.assert_called_once()
|
|
5562
|
+
|
|
5563
|
+
|
|
5564
|
+
class TestPrewarmAwait:
|
|
5565
|
+
"""`_start_server_background` must wait for the prewarm worker first.
|
|
5566
|
+
|
|
5567
|
+
The prewarm worker imports `deepagents`/LangChain in a separate thread
|
|
5568
|
+
via `asyncio.to_thread`. If `_start_server_background` triggers the
|
|
5569
|
+
same module graph from the event-loop thread before prewarm finishes,
|
|
5570
|
+
Python's per-module locks form a cycle and CPython raises
|
|
5571
|
+
`_DeadlockError` from the import system.
|
|
5572
|
+
"""
|
|
5573
|
+
|
|
5574
|
+
async def test_await_prewarm_imports_no_worker(self) -> None:
|
|
5575
|
+
"""No-op when the prewarm worker handle isn't set."""
|
|
5576
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5577
|
+
assert app._prewarm_worker is None
|
|
5578
|
+
await app._await_prewarm_imports() # must not raise
|
|
5579
|
+
|
|
5580
|
+
async def test_await_prewarm_imports_waits_for_worker(self) -> None:
|
|
5581
|
+
"""Awaits `Worker.wait()` so the import-prewarm thread is fully done."""
|
|
5582
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5583
|
+
worker = MagicMock()
|
|
5584
|
+
worker.wait = AsyncMock()
|
|
5585
|
+
app._prewarm_worker = worker
|
|
5586
|
+
|
|
5587
|
+
await app._await_prewarm_imports()
|
|
5588
|
+
|
|
5589
|
+
worker.wait.assert_awaited_once()
|
|
5590
|
+
|
|
5591
|
+
async def test_await_prewarm_imports_swallows_worker_failure(self) -> None:
|
|
5592
|
+
"""`WorkerFailed` is non-fatal; main path proceeds regardless."""
|
|
5593
|
+
from textual.worker import WorkerFailed
|
|
5594
|
+
|
|
5595
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5596
|
+
worker = MagicMock()
|
|
5597
|
+
worker.wait = AsyncMock(side_effect=WorkerFailed(RuntimeError("boom")))
|
|
5598
|
+
app._prewarm_worker = worker
|
|
5599
|
+
|
|
5600
|
+
await app._await_prewarm_imports() # must not raise
|
|
5601
|
+
|
|
5602
|
+
worker.wait.assert_awaited_once()
|
|
5603
|
+
|
|
5604
|
+
async def test_await_prewarm_imports_propagates_cancellation(self) -> None:
|
|
5605
|
+
"""`CancelledError` MUST propagate so app shutdown isn't absorbed."""
|
|
5606
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5607
|
+
worker = MagicMock()
|
|
5608
|
+
worker.wait = AsyncMock(side_effect=asyncio.CancelledError())
|
|
5609
|
+
app._prewarm_worker = worker
|
|
5610
|
+
|
|
5611
|
+
with pytest.raises(asyncio.CancelledError):
|
|
5612
|
+
await app._await_prewarm_imports()
|
|
5613
|
+
|
|
5614
|
+
async def test_start_server_background_awaits_prewarm_before_create_model(
|
|
5615
|
+
self,
|
|
5616
|
+
) -> None:
|
|
5617
|
+
"""Locks the call-order invariant that fixes the deadlock.
|
|
5618
|
+
|
|
5619
|
+
A future refactor that moves the `await _await_prewarm_imports()`
|
|
5620
|
+
after `create_model` (or drops it) silently re-introduces the
|
|
5621
|
+
production crash. This is the only test that catches that.
|
|
5622
|
+
"""
|
|
5623
|
+
from deepagents_cli import config as cli_config
|
|
5624
|
+
|
|
5625
|
+
call_order: list[str] = []
|
|
5626
|
+
|
|
5627
|
+
app = DeepAgentsApp(agent=MagicMock(), thread_id="t")
|
|
5628
|
+
app._model_kwargs = {"model_spec": "anthropic:claude-opus-4-7"}
|
|
5629
|
+
app._server_kwargs = None
|
|
5630
|
+
app._mcp_preload_kwargs = None
|
|
5631
|
+
app._resume_thread_intent = None
|
|
5632
|
+
app._assistant_id = None
|
|
5633
|
+
|
|
5634
|
+
async def record_prewarm() -> None:
|
|
5635
|
+
call_order.append("prewarm")
|
|
5636
|
+
await asyncio.sleep(0) # yield so any out-of-order calls would land first
|
|
5637
|
+
|
|
5638
|
+
def record_create_model(**_: Any) -> MagicMock:
|
|
5639
|
+
call_order.append("create_model")
|
|
5640
|
+
result = MagicMock()
|
|
5641
|
+
result.apply_to_settings = MagicMock()
|
|
5642
|
+
result.provider = "anthropic"
|
|
5643
|
+
result.model_name = "claude-opus-4-7"
|
|
5644
|
+
return result
|
|
5645
|
+
|
|
5646
|
+
with (
|
|
5647
|
+
patch.object(app, "_await_prewarm_imports", side_effect=record_prewarm),
|
|
5648
|
+
patch.object(cli_config, "create_model", side_effect=record_create_model),
|
|
5649
|
+
patch("deepagents_cli.model_config.save_recent_model"),
|
|
5650
|
+
patch.object(app, "post_message"),
|
|
5651
|
+
# `_start_server_background` continues past `create_model` into
|
|
5652
|
+
# server + MCP setup we don't care about for an ordering test.
|
|
5653
|
+
contextlib.suppress(Exception),
|
|
5654
|
+
):
|
|
5655
|
+
await app._start_server_background()
|
|
5656
|
+
|
|
5657
|
+
assert call_order[:2] == ["prewarm", "create_model"], (
|
|
5658
|
+
f"prewarm must precede create_model; got {call_order}"
|
|
5659
|
+
)
|