deepagents-code 0.1.30__tar.gz → 0.1.31__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_code-0.1.30 → deepagents_code-0.1.31}/CHANGELOG.md +21 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/Makefile +5 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/PKG-INFO +4 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_env_vars.py +14 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/agent.py +5 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/app.py +223 -77
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/config.py +55 -8
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/config_commands.py +160 -89
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/config_manifest.py +9 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/extras_info.py +5 -4
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/main.py +1 -5
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/model_config.py +29 -0
- deepagents_code-0.1.31/deepagents_code/paste_collapse.py +103 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/reasoning_effort.py +36 -13
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/textual_adapter.py +2 -2
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/tool_display.py +10 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/ui.py +5 -4
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/update_check.py +45 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/auth.py +48 -5
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/chat_input.py +195 -26
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/cwd_switch.py +46 -4
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/install_confirm.py +1 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/message_store.py +8 -3
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/messages.py +234 -38
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/model_selector.py +206 -77
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/status.py +55 -7
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/thread_selector.py +7 -4
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/pyproject.toml +4 -2
- deepagents_code-0.1.31/tests/unit_tests/smoke_tests/conftest.py +28 -0
- deepagents_code-0.1.31/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +537 -0
- deepagents_code-0.1.31/tests/unit_tests/smoke_tests/test_system_prompt.py +199 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_agent.py +39 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_app.py +593 -2
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_auth_widgets.py +29 -5
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_autocomplete.py +7 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_chat_input.py +585 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_config.py +330 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_config_manifest.py +145 -3
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_cwd_switch.py +69 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_message_store.py +35 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_messages.py +424 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_model_config.py +19 -1
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_model_selector.py +351 -10
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_model_switch.py +119 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_reasoning_effort.py +27 -5
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_status.py +115 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_thread_selector.py +128 -7
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_update_check.py +152 -0
- deepagents_code-0.1.31/tests/unit_tests/widgets/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/uv.lock +41 -3
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/.gitignore +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/AGENTS.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/COMMANDS.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/README.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/auth_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/non_interactive.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/remote_client.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/server.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/server_manager.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/tools_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/_links.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/approval.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/diff.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/goal_review.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/history.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/loading.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/subagent_panel.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/update_available.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/deepagents_code/widgets/welcome.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/hatch_build.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/images/tui.png +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/scripts/install.sh +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/README.md +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/test_auto_approve_remote.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.30/tests/unit_tests/tools → deepagents_code-0.1.31/tests/unit_tests/smoke_tests}/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_auth_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_goal_review.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_history.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_install_confirm.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_install_script.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_launch_init.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_links.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_rubric_cli.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_subagent_panel.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_subagent_stream.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_tool_renderers.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_tools_commands.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_update_confirm.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_update_progress.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_code-0.1.30/tests/unit_tests/widgets → deepagents_code-0.1.31/tests/unit_tests/tools}/__init__.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.30 → deepagents_code-0.1.31}/tests/unit_tests/widgets/test_diff.py +0 -0
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.31](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.30...deepagents-code==0.1.31) (2026-07-03)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Collapse large pastes into compact placeholders ([#4447](https://github.com/langchain-ai/deepagents/issues/4447)) ([9ae927d](https://github.com/langchain-ai/deepagents/commit/9ae927d73ebf30ba50bbb7ec0c1076a0937e5cb7))
|
|
10
|
+
* Show model name instead of spec in switcher ([#4460](https://github.com/langchain-ai/deepagents/issues/4460)) ([0059620](https://github.com/langchain-ai/deepagents/commit/005962088ad31b16745c399e4ab2e725e97f7858))
|
|
11
|
+
* Offer abort during resume ([#4188](https://github.com/langchain-ai/deepagents/issues/4188)) ([a4c25cd](https://github.com/langchain-ai/deepagents/commit/a4c25cd74de9902fd0ea9440b5dda2d4248bb3d2))
|
|
12
|
+
* Persistent banner when installation is stale ([#4459](https://github.com/langchain-ai/deepagents/issues/4459)) ([b74c185](https://github.com/langchain-ai/deepagents/commit/b74c18591a8ce9a49a5fee43b07e602ca9fbf68a))
|
|
13
|
+
* Show `"Took <duration>"` after `execute` finishes ([#4301](https://github.com/langchain-ai/deepagents/issues/4301)) ([a5240eb](https://github.com/langchain-ai/deepagents/commit/a5240ebe3654e72fa5beb4070224f52f944768c8))
|
|
14
|
+
* Unify `config show`/`list` around effective values ([#4174](https://github.com/langchain-ai/deepagents/issues/4174)) ([ccd9d21](https://github.com/langchain-ai/deepagents/commit/ccd9d216e77855a28b88850beb525f47ce8b686a))
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* Make execute command expandable in code TUI transcript ([#4428](https://github.com/langchain-ai/deepagents/issues/4428)) ([d999181](https://github.com/langchain-ai/deepagents/commit/d999181e8424498681f1e442c71380bf6b82b0aa))
|
|
19
|
+
* Allow suppressing LangSmith key override warning ([#4436](https://github.com/langchain-ai/deepagents/issues/4436)) ([ddcae5e](https://github.com/langchain-ai/deepagents/commit/ddcae5e0bd9aebc946be1d9fb3f5e35eeb690fa6))
|
|
20
|
+
* Ensure unique message widget IDs on history load ([#4454](https://github.com/langchain-ai/deepagents/issues/4454)) ([de2f7d2](https://github.com/langchain-ai/deepagents/commit/de2f7d2835485df905772e1c96e33d2c239d8e22))
|
|
21
|
+
* Resolve `/threads` header link on mount, not after load ([#4453](https://github.com/langchain-ai/deepagents/issues/4453)) ([4cba728](https://github.com/langchain-ai/deepagents/commit/4cba72893fc4aae5b429d8c573c1a513d97ddf8a))
|
|
22
|
+
* Restore caller's LangSmith API key in shell subprocess env ([#4458](https://github.com/langchain-ai/deepagents/issues/4458)) ([9293b19](https://github.com/langchain-ai/deepagents/commit/9293b190170a872b73d0d94e66479bcc5f7962c7))
|
|
23
|
+
* Route Anthropic effort through output config ([#4446](https://github.com/langchain-ai/deepagents/issues/4446)) ([1e8ed81](https://github.com/langchain-ai/deepagents/commit/1e8ed81940a862dde44f704826b61650336367e0))
|
|
24
|
+
* Show loading state during model switch ([#4209](https://github.com/langchain-ai/deepagents/issues/4209)) ([7cc4e9f](https://github.com/langchain-ai/deepagents/commit/7cc4e9f9bda5a8ae42bb072b82b634ad8c39ade1))
|
|
25
|
+
|
|
5
26
|
## [0.1.30](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.29...deepagents-code==0.1.30) (2026-07-02)
|
|
6
27
|
|
|
7
28
|
### Features
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.PHONY: format lint type typecheck test tests integration_test integration_tests test_watch benchmark bench bench-memory help run lint_package lint_tests check_imports coverage commands-catalog commands-catalog-check check bootstrap
|
|
1
|
+
.PHONY: format lint type typecheck test tests integration_test integration_tests test_watch benchmark bench bench-memory help run lint_package lint_tests check_imports coverage commands-catalog commands-catalog-check check bootstrap update-snapshots
|
|
2
2
|
|
|
3
3
|
.DEFAULT_GOAL := help
|
|
4
4
|
|
|
@@ -16,8 +16,12 @@ TEST_FILE ?= tests/unit_tests/
|
|
|
16
16
|
integration_test integration_tests: TEST_FILE=tests/integration_tests/
|
|
17
17
|
|
|
18
18
|
COV_ARGS ?= --cov=deepagents_code --cov-report=term-missing
|
|
19
|
+
SMOKE_TESTS ?= tests/unit_tests/smoke_tests/
|
|
19
20
|
PYTEST_EXTRA ?=
|
|
20
21
|
|
|
22
|
+
update-snapshots: ## Update smoke test snapshots
|
|
23
|
+
uv run --group test pytest -vvv --disable-socket --allow-unix-socket --update-snapshots $(SMOKE_TESTS)
|
|
24
|
+
|
|
21
25
|
test: ## Run unit tests
|
|
22
26
|
test tests:
|
|
23
27
|
uv run --group test pytest -n auto --benchmark-disable --disable-socket --allow-unix-socket $(PYTEST_EXTRA) $(TEST_FILE) \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.31
|
|
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/
|
|
@@ -111,6 +111,9 @@ Provides-Extra: ibm
|
|
|
111
111
|
Requires-Dist: langchain-ibm<2.0.0,>=1.1.0; extra == 'ibm'
|
|
112
112
|
Provides-Extra: litellm
|
|
113
113
|
Requires-Dist: langchain-litellm<2.0.0,>=0.7.0; extra == 'litellm'
|
|
114
|
+
Provides-Extra: media
|
|
115
|
+
Requires-Dist: av<18.0.0,>=17.0.0; extra == 'media'
|
|
116
|
+
Requires-Dist: pillow<13.0.0,>=12.2.0; extra == 'media'
|
|
114
117
|
Provides-Extra: mistralai
|
|
115
118
|
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.5; extra == 'mistralai'
|
|
116
119
|
Provides-Extra: modal
|
|
@@ -225,6 +225,20 @@ Defaults to enabled; set to a falsy value (`0`, `false`, `no`, `off`, or empty)
|
|
|
225
225
|
to suppress the success toast while still opening URLs normally.
|
|
226
226
|
"""
|
|
227
227
|
|
|
228
|
+
SUPPRESS_ENV_OVERRIDE_WARNING = "DEEPAGENTS_CODE_SUPPRESS_ENV_OVERRIDE_WARNING"
|
|
229
|
+
"""Silence the startup warning emitted when a `DEEPAGENTS_CODE_`-prefixed
|
|
230
|
+
LangSmith variable overrides its canonical counterpart (e.g. both
|
|
231
|
+
`LANGSMITH_API_KEY` and `DEEPAGENTS_CODE_LANGSMITH_API_KEY` are set to
|
|
232
|
+
different values).
|
|
233
|
+
|
|
234
|
+
The override is intentional: the prefixed value overwrites the canonical
|
|
235
|
+
variable inside the Deep Agents Code process (so the LangSmith SDK, which
|
|
236
|
+
only reads canonical names, picks it up). The value you exported in your own
|
|
237
|
+
shell is unaffected, since a process cannot change its parent's environment.
|
|
238
|
+
Off by default; set to a truthy value (`1`, `true`, `yes`, `on`) to suppress
|
|
239
|
+
the warning when this coexistence is expected. Parsed by `is_env_truthy`.
|
|
240
|
+
"""
|
|
241
|
+
|
|
228
242
|
THEME = "DEEPAGENTS_CODE_THEME"
|
|
229
243
|
"""Force the CLI to launch with this theme name when set."""
|
|
230
244
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Keep the `x-release-please-version` annotation — release-please uses it to
|
|
4
4
|
# bump `__version__` in sync with `pyproject.toml` on every release PR.
|
|
5
|
-
__version__ = "0.1.
|
|
5
|
+
__version__ = "0.1.31" # x-release-please-version
|
|
6
6
|
|
|
7
7
|
DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/code"
|
|
8
8
|
"""URL for `deepagents-code` documentation."""
|
|
@@ -74,6 +74,7 @@ from deepagents_code.config import (
|
|
|
74
74
|
get_default_coding_instructions,
|
|
75
75
|
get_glyphs,
|
|
76
76
|
get_langsmith_project_name,
|
|
77
|
+
restore_user_tracing_api_keys,
|
|
77
78
|
restore_user_tracing_env,
|
|
78
79
|
settings,
|
|
79
80
|
)
|
|
@@ -1663,6 +1664,7 @@ def create_cli_agent(
|
|
|
1663
1664
|
else:
|
|
1664
1665
|
shell_env.pop("LANGSMITH_PROJECT", None)
|
|
1665
1666
|
restore_user_tracing_env(shell_env)
|
|
1667
|
+
restore_user_tracing_api_keys(shell_env)
|
|
1666
1668
|
# Re-apply a launch-time PYTHONPATH that was stripped from the server
|
|
1667
1669
|
# interpreter but relayed for approval-gated `execute` commands.
|
|
1668
1670
|
_apply_inherited_pythonpath(shell_env)
|
|
@@ -1673,6 +1675,9 @@ def create_cli_agent(
|
|
|
1673
1675
|
# `inherit_env=False`: `shell_env` is already a complete, curated
|
|
1674
1676
|
# copy of `os.environ`. Inheriting again would re-copy `os.environ`
|
|
1675
1677
|
# and resurrect the popped carrier var, leaking it into `execute`.
|
|
1678
|
+
# `restore_user_tracing_api_keys` above depends on this too: flipping
|
|
1679
|
+
# to `inherit_env=True` would re-copy the agent's overridden
|
|
1680
|
+
# `LANGSMITH_API_KEY` and undo the restore, leaking it into `execute`.
|
|
1676
1681
|
backend = LocalShellBackend(
|
|
1677
1682
|
root_dir=root_dir,
|
|
1678
1683
|
virtual_mode=False,
|
|
@@ -1985,7 +1985,8 @@ class DeepAgentsApp(App):
|
|
|
1985
1985
|
defer_server_start: Whether to keep app-owned server startup paused
|
|
1986
1986
|
until the user configures credentials or explicitly picks a model.
|
|
1987
1987
|
title: Override the Textual `App.title` shown in the optional
|
|
1988
|
-
header bar
|
|
1988
|
+
header bar (shown when `DEEPAGENTS_CODE_SHOW_HEADER` is set or
|
|
1989
|
+
the installation is stale).
|
|
1989
1990
|
|
|
1990
1991
|
When `None`, the class-level `TITLE` is used.
|
|
1991
1992
|
|
|
@@ -1993,7 +1994,8 @@ class DeepAgentsApp(App):
|
|
|
1993
1994
|
sub_title: Override the Textual `App.sub_title` shown in the
|
|
1994
1995
|
optional header bar.
|
|
1995
1996
|
|
|
1996
|
-
When `None`,
|
|
1997
|
+
When `None`, a sandbox label or a stale-install advisory may be
|
|
1998
|
+
substituted; otherwise the parent default is used.
|
|
1997
1999
|
|
|
1998
2000
|
Reassigning `app.sub_title` at runtime updates the header live.
|
|
1999
2001
|
**kwargs: Additional arguments passed to parent
|
|
@@ -2263,6 +2265,34 @@ class DeepAgentsApp(App):
|
|
|
2263
2265
|
)
|
|
2264
2266
|
self.sub_title = f"Sandbox: {display}"
|
|
2265
2267
|
|
|
2268
|
+
from deepagents_code.update_check import (
|
|
2269
|
+
installed_days_old,
|
|
2270
|
+
is_installation_stale,
|
|
2271
|
+
)
|
|
2272
|
+
|
|
2273
|
+
self._installation_stale: bool = sub_title is None and is_installation_stale()
|
|
2274
|
+
"""Whether the installed version is old enough to force the header banner.
|
|
2275
|
+
|
|
2276
|
+
Set once at construction from the cache-only install-age check. When
|
|
2277
|
+
`True`, `compose` renders the header even without `DEEPAGENTS_CODE_SHOW_HEADER`
|
|
2278
|
+
and the subtitle carries the advisory below — overriding the sandbox
|
|
2279
|
+
subtitle by design.
|
|
2280
|
+
"""
|
|
2281
|
+
|
|
2282
|
+
if self._installation_stale:
|
|
2283
|
+
days = installed_days_old()
|
|
2284
|
+
if days is None:
|
|
2285
|
+
# The cache changed between the staleness gate and this read
|
|
2286
|
+
# (e.g. a concurrent `dcode` process). Drop the banner rather
|
|
2287
|
+
# than render "installed version is None days old".
|
|
2288
|
+
self._installation_stale = False
|
|
2289
|
+
else:
|
|
2290
|
+
unit = "day" if days == 1 else "days"
|
|
2291
|
+
self.sub_title = (
|
|
2292
|
+
f"Update available \u2014 installed version is "
|
|
2293
|
+
f"{days} {unit} old (run /update)"
|
|
2294
|
+
)
|
|
2295
|
+
|
|
2266
2296
|
# Per-turn model overrides
|
|
2267
2297
|
self._model_override: str | None = None
|
|
2268
2298
|
"""Per-turn model override set via `/model`; `None` uses session default."""
|
|
@@ -2770,7 +2800,7 @@ class DeepAgentsApp(App):
|
|
|
2770
2800
|
"""
|
|
2771
2801
|
from deepagents_code._env_vars import SHOW_HEADER, is_env_truthy
|
|
2772
2802
|
|
|
2773
|
-
if is_env_truthy(SHOW_HEADER):
|
|
2803
|
+
if is_env_truthy(SHOW_HEADER) or self._installation_stale:
|
|
2774
2804
|
yield _StaticHeader(id="app-header")
|
|
2775
2805
|
# Main chat area with scrollable messages
|
|
2776
2806
|
# VerticalScroll tracks user scroll intent for better auto-scroll behavior.
|
|
@@ -3525,7 +3555,10 @@ class DeepAgentsApp(App):
|
|
|
3525
3555
|
"""Resolve a `-r` resume intent into a concrete thread ID.
|
|
3526
3556
|
|
|
3527
3557
|
Consumes `self._resume_thread_intent` and resolves it into a concrete
|
|
3528
|
-
thread ID.
|
|
3558
|
+
thread ID. When the intent resolves to an existing thread whose cwd
|
|
3559
|
+
differs from the current one, the cwd-switch prompt is shown with an
|
|
3560
|
+
extra "abort" option; choosing it starts a fresh thread instead of
|
|
3561
|
+
resuming. Mutates `self._lc_thread_id` and optionally
|
|
3529
3562
|
`self._assistant_id` / `self._server_kwargs`. Does NOT touch
|
|
3530
3563
|
`self._default_assistant_id` — a one-off resume should not redefine
|
|
3531
3564
|
the user's persisted default agent. Falls back to a fresh thread on
|
|
@@ -3539,7 +3572,6 @@ class DeepAgentsApp(App):
|
|
|
3539
3572
|
thread_exists,
|
|
3540
3573
|
)
|
|
3541
3574
|
|
|
3542
|
-
resumed_thread_id: str | None = None
|
|
3543
3575
|
try:
|
|
3544
3576
|
resume = self._resume_thread_intent
|
|
3545
3577
|
self._resume_thread_intent = None # consumed
|
|
@@ -3549,81 +3581,118 @@ class DeepAgentsApp(App):
|
|
|
3549
3581
|
|
|
3550
3582
|
default_agent = DEFAULT_ASSISTANT_ID
|
|
3551
3583
|
|
|
3552
|
-
|
|
3584
|
+
# Resolve the candidate thread id before any agent/model mutation,
|
|
3585
|
+
# so an abort only needs to reset the thread id (no rollback).
|
|
3586
|
+
via_most_recent = resume == "__MOST_RECENT__"
|
|
3587
|
+
if via_most_recent:
|
|
3553
3588
|
agent_filter = (
|
|
3554
3589
|
self._assistant_id if self._assistant_id != default_agent else None
|
|
3555
3590
|
)
|
|
3556
|
-
|
|
3557
|
-
if
|
|
3558
|
-
agent_name = await get_thread_agent(thread_id)
|
|
3559
|
-
if agent_name:
|
|
3560
|
-
self._assistant_id = agent_name
|
|
3561
|
-
if self._server_kwargs:
|
|
3562
|
-
self._server_kwargs["assistant_id"] = agent_name
|
|
3563
|
-
self._lc_thread_id = thread_id
|
|
3564
|
-
resumed_thread_id = thread_id
|
|
3565
|
-
self._should_adopt_resumed_model = not self._model_explicitly_set
|
|
3566
|
-
else:
|
|
3591
|
+
candidate = await get_most_recent(agent_filter)
|
|
3592
|
+
if not candidate:
|
|
3567
3593
|
self._lc_thread_id = generate_thread_id()
|
|
3594
|
+
self._resuming = False
|
|
3595
|
+
self._sync_status_connection()
|
|
3568
3596
|
if agent_filter:
|
|
3569
3597
|
msg = f"No previous threads for '{agent_filter}', starting new."
|
|
3570
3598
|
else:
|
|
3571
3599
|
msg = "No previous threads, starting new."
|
|
3572
3600
|
self.notify(msg, severity="warning", markup=False)
|
|
3601
|
+
return
|
|
3573
3602
|
elif await thread_exists(resume):
|
|
3574
|
-
|
|
3575
|
-
resumed_thread_id = resume
|
|
3576
|
-
self._should_adopt_resumed_model = not self._model_explicitly_set
|
|
3577
|
-
if self._assistant_id == default_agent:
|
|
3578
|
-
agent_name = await get_thread_agent(resume)
|
|
3579
|
-
if agent_name:
|
|
3580
|
-
self._assistant_id = agent_name
|
|
3581
|
-
if self._server_kwargs:
|
|
3582
|
-
self._server_kwargs["assistant_id"] = agent_name
|
|
3603
|
+
candidate = resume
|
|
3583
3604
|
else:
|
|
3584
3605
|
# Thread not found — notify + fall back to new thread
|
|
3585
3606
|
self._lc_thread_id = generate_thread_id()
|
|
3607
|
+
self._resuming = False
|
|
3608
|
+
self._sync_status_connection()
|
|
3586
3609
|
similar = await find_similar_threads(resume)
|
|
3587
3610
|
hint = f"Thread '{resume}' not found."
|
|
3588
3611
|
if similar:
|
|
3589
3612
|
hint += f" Did you mean: {', '.join(str(t) for t in similar)}?"
|
|
3590
3613
|
self.notify(hint, severity="warning", timeout=6, markup=False)
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3614
|
+
return
|
|
3615
|
+
|
|
3616
|
+
# Commit the resolved thread before the cwd-switch offer so a
|
|
3617
|
+
# failure in that offer leaves the thread resolved (see the
|
|
3618
|
+
# isolation guard below) rather than falling through to the
|
|
3619
|
+
# resume-resolution handler.
|
|
3620
|
+
self._lc_thread_id = candidate
|
|
3621
|
+
|
|
3622
|
+
# The cwd-switch prompt doubles as the resume confirmation: at
|
|
3623
|
+
# launch it carries an extra "abort" option that starts a fresh
|
|
3624
|
+
# session instead of resuming. Isolate its failures so they can't
|
|
3625
|
+
# fall into the resume-resolution handler below, which would
|
|
3626
|
+
# discard the already-resolved thread and misleadingly report
|
|
3627
|
+
# "Could not look up thread history."
|
|
3628
|
+
try:
|
|
3629
|
+
cwd_choice = await self._offer_thread_cwd_switch(
|
|
3630
|
+
candidate,
|
|
3631
|
+
restart_server=False,
|
|
3632
|
+
allow_abort=True,
|
|
3633
|
+
)
|
|
3634
|
+
except Exception:
|
|
3635
|
+
logger.exception(
|
|
3636
|
+
"cwd switch offer failed for resumed thread %s",
|
|
3637
|
+
candidate,
|
|
3638
|
+
)
|
|
3639
|
+
self.notify(
|
|
3640
|
+
"Resumed the thread, but could not check its working "
|
|
3641
|
+
"directory. Local context may be stale.",
|
|
3642
|
+
severity="warning",
|
|
3643
|
+
markup=False,
|
|
3644
|
+
)
|
|
3645
|
+
cwd_choice = "continue"
|
|
3646
|
+
|
|
3647
|
+
if cwd_choice == "abort":
|
|
3648
|
+
# User declined the resume: start a fresh session and skip the
|
|
3649
|
+
# agent/model adoption below so it inherits the launch default.
|
|
3650
|
+
self._lc_thread_id = generate_thread_id()
|
|
3651
|
+
self._resuming = False
|
|
3652
|
+
self._sync_status_connection()
|
|
3653
|
+
self.notify(
|
|
3654
|
+
"Starting a new session.",
|
|
3655
|
+
severity="information",
|
|
3656
|
+
markup=False,
|
|
3657
|
+
)
|
|
3658
|
+
return
|
|
3659
|
+
|
|
3660
|
+
# Confirmed: adopt the thread's agent for this session — always when
|
|
3661
|
+
# resuming the most recent thread (bare `-r`, even over an
|
|
3662
|
+
# explicitly pinned `-a`), and for an explicit `-r <id>` only when
|
|
3663
|
+
# the user hasn't pinned a non-default agent — plus its persisted
|
|
3664
|
+
# model.
|
|
3665
|
+
self._should_adopt_resumed_model = not self._model_explicitly_set
|
|
3666
|
+
if via_most_recent or self._assistant_id == default_agent:
|
|
3667
|
+
agent_name = await get_thread_agent(candidate)
|
|
3668
|
+
if agent_name:
|
|
3669
|
+
self._assistant_id = agent_name
|
|
3670
|
+
if self._server_kwargs:
|
|
3671
|
+
self._server_kwargs["assistant_id"] = agent_name
|
|
3612
3672
|
except Exception:
|
|
3613
3673
|
logger.exception("Failed to resolve resume thread %r", resume)
|
|
3614
3674
|
self._lc_thread_id = generate_thread_id()
|
|
3675
|
+
self._resuming = False
|
|
3676
|
+
self._sync_status_connection()
|
|
3615
3677
|
self.notify(
|
|
3616
3678
|
"Could not look up thread history. Starting new session.",
|
|
3617
3679
|
severity="warning",
|
|
3618
3680
|
)
|
|
3619
3681
|
finally:
|
|
3682
|
+
# Sync the resolved (or fresh) thread id into session state before
|
|
3683
|
+
# signaling completion. This must run in `finally` so an early
|
|
3684
|
+
# return — a fallback to a new thread, or the user aborting the
|
|
3685
|
+
# resume — can't leave `session_state.thread_id` pointing at a
|
|
3686
|
+
# thread that was never adopted. `_init_session_state` may run
|
|
3687
|
+
# concurrently and capture a not-yet-final id mid-prompt; this
|
|
3688
|
+
# reconciles it whenever session state already exists. If session
|
|
3689
|
+
# state hasn't been assigned yet, correctness instead relies on
|
|
3690
|
+
# `_init_session_state` reading the now-final `_lc_thread_id` when
|
|
3691
|
+
# it constructs the state.
|
|
3692
|
+
if self._session_state:
|
|
3693
|
+
self._session_state.thread_id = self._lc_thread_id
|
|
3620
3694
|
self._resume_thread_resolved_event.set()
|
|
3621
3695
|
|
|
3622
|
-
# Update session state if ready (may still be initializing in a
|
|
3623
|
-
# concurrent worker)
|
|
3624
|
-
if self._session_state:
|
|
3625
|
-
self._session_state.thread_id = self._lc_thread_id
|
|
3626
|
-
|
|
3627
3696
|
async def _start_server_background(self) -> None:
|
|
3628
3697
|
"""Background worker: resolve resume-thread intent, start server + MCP preload.
|
|
3629
3698
|
|
|
@@ -7742,8 +7811,7 @@ class DeepAgentsApp(App):
|
|
|
7742
7811
|
await self._mount_message(
|
|
7743
7812
|
AppMessage(
|
|
7744
7813
|
"LangSmith tracing is not configured. "
|
|
7745
|
-
"Run `/auth` and select LangSmith to enable tracing,
|
|
7746
|
-
"LANGSMITH_API_KEY and LANGSMITH_TRACING=true.",
|
|
7814
|
+
"Run `/auth` and select LangSmith to enable tracing.",
|
|
7747
7815
|
),
|
|
7748
7816
|
)
|
|
7749
7817
|
return
|
|
@@ -10757,32 +10825,86 @@ class DeepAgentsApp(App):
|
|
|
10757
10825
|
if payload.context_tokens > 0:
|
|
10758
10826
|
self._on_tokens_update(payload.context_tokens)
|
|
10759
10827
|
|
|
10760
|
-
#
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
# 5. Cache container ref (single query)
|
|
10828
|
+
# 5. Cache container ref (single query). Queried before the store
|
|
10829
|
+
# load so history can be reconciled against widgets already in the
|
|
10830
|
+
# DOM (see below).
|
|
10764
10831
|
try:
|
|
10765
10832
|
messages_container = self.query_one("#messages", Container)
|
|
10766
10833
|
except NoMatches:
|
|
10767
10834
|
return
|
|
10768
10835
|
|
|
10769
|
-
#
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10836
|
+
# 3. Reconcile against existing state before loading the store.
|
|
10837
|
+
# Mounting a widget whose ID already exists raises `DuplicateIds`,
|
|
10838
|
+
# which would abort the entire history load. Widened message IDs
|
|
10839
|
+
# make natural collisions vanishingly unlikely, but a re-entrant
|
|
10840
|
+
# load (e.g. a server respawn that re-runs the startup sequence
|
|
10841
|
+
# over a non-cleared store and its surviving widgets) can still
|
|
10842
|
+
# reintroduce an already-present ID. Two guards keep this safe:
|
|
10843
|
+
#
|
|
10844
|
+
# a) Drop payload messages whose ID is already in the store (or
|
|
10845
|
+
# repeated within the payload) before `bulk_load`. Otherwise
|
|
10846
|
+
# `bulk_load` would append duplicate entries to `_messages`,
|
|
10847
|
+
# desyncing the visible window from the DOM and tripping up
|
|
10848
|
+
# later pruning/hydration.
|
|
10849
|
+
# b) Skip mounting any visible message whose ID is already in the
|
|
10850
|
+
# DOM. `bulk_load` returns a window over the *whole* store, so
|
|
10851
|
+
# a surviving pre-existing entry can still surface as a mount
|
|
10852
|
+
# candidate even after (a); its widget already exists.
|
|
10853
|
+
seen: set[str] = set()
|
|
10854
|
+
deduped: list[MessageData] = []
|
|
10855
|
+
for msg_data in payload.messages:
|
|
10856
|
+
if (
|
|
10857
|
+
msg_data.id in seen
|
|
10858
|
+
or self._message_store.get_message(msg_data.id) is not None
|
|
10859
|
+
):
|
|
10860
|
+
continue
|
|
10861
|
+
seen.add(msg_data.id)
|
|
10862
|
+
deduped.append(msg_data)
|
|
10863
|
+
dropped = len(payload.messages) - len(deduped)
|
|
10864
|
+
if dropped:
|
|
10865
|
+
logger.warning(
|
|
10866
|
+
"Dropped %d duplicate history message(s) for thread %s: "
|
|
10867
|
+
"IDs were already in the store or repeated in the payload",
|
|
10868
|
+
dropped,
|
|
10869
|
+
history_thread_id,
|
|
10870
|
+
)
|
|
10871
|
+
|
|
10872
|
+
# Bulk load into store (sets visible window over the deduped set).
|
|
10873
|
+
_archived, visible = self._message_store.bulk_load(deduped)
|
|
10874
|
+
|
|
10875
|
+
# 6-7. Create and mount the visible widgets (max WINDOW_SIZE),
|
|
10876
|
+
# skipping any whose ID is already mounted (guard (b) above).
|
|
10877
|
+
# `existing_ids` includes footer node IDs, which never collide with
|
|
10878
|
+
# the `msg-`/`asst-` message IDs checked here.
|
|
10879
|
+
existing_ids = {
|
|
10880
|
+
node.id for node in messages_container.children if node.id is not None
|
|
10881
|
+
}
|
|
10882
|
+
mounted: list[tuple[Widget, MessageData]] = []
|
|
10883
|
+
nodes: list[Widget] = []
|
|
10884
|
+
for msg_data in visible:
|
|
10885
|
+
if msg_data.id in existing_ids:
|
|
10886
|
+
logger.debug(
|
|
10887
|
+
"Skipping already-mounted history widget %s in thread %s",
|
|
10888
|
+
msg_data.id,
|
|
10889
|
+
history_thread_id,
|
|
10777
10890
|
)
|
|
10778
|
-
|
|
10779
|
-
|
|
10891
|
+
continue
|
|
10892
|
+
existing_ids.add(msg_data.id)
|
|
10893
|
+
widget = msg_data.to_widget()
|
|
10894
|
+
mounted.append((widget, msg_data))
|
|
10895
|
+
nodes.append(widget)
|
|
10896
|
+
footer = self._build_message_timestamp_footer(
|
|
10897
|
+
msg_data, visible=self._message_timestamps_visible
|
|
10898
|
+
)
|
|
10899
|
+
if footer is not None:
|
|
10900
|
+
nodes.append(footer)
|
|
10901
|
+
if nodes:
|
|
10780
10902
|
await messages_container.mount(*nodes)
|
|
10781
10903
|
|
|
10782
10904
|
# 8. Render content for AssistantMessage after mount
|
|
10783
10905
|
assistant_updates = [
|
|
10784
10906
|
widget.set_content(msg_data.content)
|
|
10785
|
-
for widget, msg_data in
|
|
10907
|
+
for widget, msg_data in mounted
|
|
10786
10908
|
if isinstance(widget, AssistantMessage) and msg_data.content
|
|
10787
10909
|
]
|
|
10788
10910
|
if assistant_updates:
|
|
@@ -12033,12 +12155,17 @@ class DeepAgentsApp(App):
|
|
|
12033
12155
|
child.toggle_body()
|
|
12034
12156
|
return
|
|
12035
12157
|
if isinstance(child, ToolCallMessage) and not child.has_class("-grouped"):
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12158
|
+
# Prefer the collapsible command/code block when the row has one,
|
|
12159
|
+
# so Ctrl+O matches the "click or Ctrl+O to show command/code"
|
|
12160
|
+
# hint rendered beside it. The output stays reachable by clicking
|
|
12161
|
+
# its own region (see `ToolCallMessage.on_click`); rows without an
|
|
12162
|
+
# expandable command/code block fall through to the output.
|
|
12039
12163
|
if child.has_expandable_args:
|
|
12040
12164
|
child.toggle_args()
|
|
12041
12165
|
return
|
|
12166
|
+
if child.has_output and child.has_expandable_output:
|
|
12167
|
+
child.toggle_output()
|
|
12168
|
+
return
|
|
12042
12169
|
if child.has_output:
|
|
12043
12170
|
child.toggle_output()
|
|
12044
12171
|
return
|
|
@@ -15458,6 +15585,7 @@ class DeepAgentsApp(App):
|
|
|
15458
15585
|
thread_id: str,
|
|
15459
15586
|
*,
|
|
15460
15587
|
restart_server: bool,
|
|
15588
|
+
allow_abort: bool = False,
|
|
15461
15589
|
) -> Literal["continue", "abort"]:
|
|
15462
15590
|
"""Offer to switch to a resumed thread's cwd when it differs.
|
|
15463
15591
|
|
|
@@ -15467,11 +15595,16 @@ class DeepAgentsApp(App):
|
|
|
15467
15595
|
switch replaces the app-owned server so the backend runs in the
|
|
15468
15596
|
new cwd. When False (launch-time resume), the server has not
|
|
15469
15597
|
started yet, so only the process cwd is changed.
|
|
15598
|
+
allow_abort: When True (launch-time `-r` resume), the prompt offers a
|
|
15599
|
+
third "abort" option that declines the resume entirely.
|
|
15470
15600
|
|
|
15471
15601
|
Returns:
|
|
15472
|
-
`"continue"` when resume may proceed, or `"abort"` when
|
|
15473
|
-
|
|
15474
|
-
the resume).
|
|
15602
|
+
`"continue"` when resume may proceed, or `"abort"` when the user
|
|
15603
|
+
declined the resume or a requested switch was accepted but
|
|
15604
|
+
failed (the caller should stop the resume). The two abort
|
|
15605
|
+
sources are mode-exclusive: the user-declined abort fires only
|
|
15606
|
+
when `allow_abort` is True, and the switch-failed abort only
|
|
15607
|
+
when `restart_server` is True.
|
|
15475
15608
|
"""
|
|
15476
15609
|
target = await self._thread_cwd_mismatch(thread_id)
|
|
15477
15610
|
if target is None:
|
|
@@ -15487,8 +15620,11 @@ class DeepAgentsApp(App):
|
|
|
15487
15620
|
current_cwd=self._cwd,
|
|
15488
15621
|
thread_cwd=str(target),
|
|
15489
15622
|
project_settings_change_detected=project_settings_change_detected,
|
|
15623
|
+
allow_abort=allow_abort,
|
|
15490
15624
|
)
|
|
15491
15625
|
)
|
|
15626
|
+
if choice == "abort":
|
|
15627
|
+
return "abort"
|
|
15492
15628
|
if choice == "switch":
|
|
15493
15629
|
if restart_server:
|
|
15494
15630
|
return await self._replace_server_after_cwd_switch(target)
|
|
@@ -15888,6 +16024,12 @@ class DeepAgentsApp(App):
|
|
|
15888
16024
|
if provider and not parsed:
|
|
15889
16025
|
display = f"{provider}:{model_name}"
|
|
15890
16026
|
|
|
16027
|
+
# Provider package imports (e.g. langchain_google_genai) can take a
|
|
16028
|
+
# noticeable moment; show an animated busy indicator so it doesn't look
|
|
16029
|
+
# frozen. The work itself already runs off the event loop via
|
|
16030
|
+
# `asyncio.to_thread`, so the UI stays responsive meanwhile.
|
|
16031
|
+
if self._status_bar:
|
|
16032
|
+
self._status_bar.set_busy("Switching model")
|
|
15891
16033
|
try:
|
|
15892
16034
|
result = await asyncio.to_thread(
|
|
15893
16035
|
_create_model_with_deepagents_import_lock,
|
|
@@ -15907,6 +16049,9 @@ class DeepAgentsApp(App):
|
|
|
15907
16049
|
ErrorMessage(_build_model_switch_error_body(exc)),
|
|
15908
16050
|
)
|
|
15909
16051
|
return
|
|
16052
|
+
finally:
|
|
16053
|
+
if self._status_bar:
|
|
16054
|
+
self._status_bar.set_busy("")
|
|
15910
16055
|
|
|
15911
16056
|
# Set the model override for ConfigurableModelMiddleware.
|
|
15912
16057
|
# The next stream call passes CLIContext via context= and the
|
|
@@ -16228,8 +16373,9 @@ async def run_textual_app(
|
|
|
16228
16373
|
defer_server_start: Whether to keep app-owned server startup paused
|
|
16229
16374
|
until credentials or a model are configured from inside the TUI.
|
|
16230
16375
|
title: Override the Textual `App.title` shown in the optional header
|
|
16231
|
-
bar (gated on `DEEPAGENTS_CODE_SHOW_HEADER
|
|
16232
|
-
|
|
16376
|
+
bar (gated on `DEEPAGENTS_CODE_SHOW_HEADER`, or shown automatically
|
|
16377
|
+
when the installation is stale). When `None`, the default
|
|
16378
|
+
`"Deep Agents"` is used.
|
|
16233
16379
|
sub_title: Override the Textual `App.sub_title` shown in the optional
|
|
16234
16380
|
header bar.
|
|
16235
16381
|
|