deepagents-code 0.1.22__tar.gz → 0.1.23__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.22 → deepagents_code-0.1.23}/.gitignore +3 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/AGENTS.md +1 -1
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/CHANGELOG.md +16 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/Makefile +1 -1
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/PKG-INFO +2 -2
- deepagents_code-0.1.23/deepagents_code/_build_info.py +3 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/agent.py +0 -2
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/app.py +99 -12
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/config.py +9 -2
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/doctor.py +36 -2
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/main.py +1 -1
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/update_check.py +109 -43
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/auth.py +61 -15
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/launch_init.py +1 -1
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/model_selector.py +2 -0
- deepagents_code-0.1.23/hatch_build.py +67 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/pyproject.toml +8 -2
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/scripts/install.sh +2 -2
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/conftest.py +18 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_app.py +305 -5
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_auth_widgets.py +162 -8
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_config.py +42 -3
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_doctor.py +58 -0
- deepagents_code-0.1.23/tests/unit_tests/test_hatch_build.py +159 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_update_check.py +314 -12
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/uv.lock +27 -1
- deepagents_code-0.1.22/deepagents_code/filesystem_empty_result.py +0 -99
- deepagents_code-0.1.22/tests/unit_tests/test_filesystem_empty_result.py +0 -160
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/COMMANDS.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/README.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_env_vars.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/auth_commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/config_commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/config_manifest.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/model_config.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/non_interactive.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/remote_client.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/server.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/server_manager.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/textual_adapter.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/_links.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/approval.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/chat_input.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/diff.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/history.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/install_confirm.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/loading.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/message_store.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/messages.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/status.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/update_available.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/deepagents_code/widgets/welcome.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/images/tui.png +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/README.md +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_auth_commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_config_manifest.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_history.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_install_confirm.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_install_script.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_launch_init.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_links.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_commands.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_status.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_update_confirm.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_update_progress.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/widgets/__init__.py +0 -0
- {deepagents_code-0.1.22 → deepagents_code-0.1.23}/tests/unit_tests/widgets/test_diff.py +0 -0
|
@@ -69,7 +69,7 @@ Casts are acceptable when the type violation is the point of the test (for examp
|
|
|
69
69
|
|
|
70
70
|
## SDK dependency pin
|
|
71
71
|
|
|
72
|
-
`deepagents-code` pins an exact `deepagents==X.Y.Z` version in `pyproject.toml`. When developing features that depend on new SDK functionality, bump this pin as part of the same PR. A CI check verifies the pin
|
|
72
|
+
`deepagents-code` pins an exact `deepagents==X.Y.Z` version in `pyproject.toml`. When developing features that depend on new SDK functionality, bump this pin as part of the same PR. A CI check verifies the pin is not older than the current SDK version at release time (unless bypassed with `dangerous-skip-sdk-pin-check`); pins ahead of the workspace SDK are allowed for intentional prerelease coordination.
|
|
73
73
|
|
|
74
74
|
For a persistent editable `dcode-dev` install that stays separate from a released install, see [Local dev installs](./DEVELOPMENT.md#local-dev-installs) in the development guide.
|
|
75
75
|
|
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.23](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.22...deepagents-code==0.1.23) (2026-06-25)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Collect Tavily key during onboarding ([#4233](https://github.com/langchain-ai/deepagents/issues/4233)) ([e321cba](https://github.com/langchain-ai/deepagents/commit/e321cba5701313e974f979069186680f1a39587c))
|
|
10
|
+
* Surface `/auth` in `/trace not-configured` hint ([#4206](https://github.com/langchain-ai/deepagents/issues/4206)) ([392e410](https://github.com/langchain-ai/deepagents/commit/392e410e48639a56fda5e35b6f7f85a5215cce9c))
|
|
11
|
+
* Add Opus 4.8 to recommended models ([#4204](https://github.com/langchain-ai/deepagents/issues/4204)) ([8faf2b0](https://github.com/langchain-ai/deepagents/commit/8faf2b025f8429481a41a3e65544d26614e53589))
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* `--reinstall` on `/install` so upgrades rebuild a clean env ([#4196](https://github.com/langchain-ai/deepagents/issues/4196)) ([5e152ac](https://github.com/langchain-ai/deepagents/commit/5e152ac0256d64376f96b293f8844bc8acc993ec))
|
|
16
|
+
* Suppress auto-update migration notice on fresh installs ([#4224](https://github.com/langchain-ai/deepagents/issues/4224)) ([eb8ff80](https://github.com/langchain-ai/deepagents/commit/eb8ff809a1b3130a261083c66a193e532095c6db))
|
|
17
|
+
* Bake release commit into `dcode doctor` ([#4225](https://github.com/langchain-ai/deepagents/issues/4225)) ([6dc0246](https://github.com/langchain-ai/deepagents/commit/6dc0246f5c6e9170e05191e1c82fad6975ac945c))
|
|
18
|
+
* Drop redundant version from "already up to date" message ([#4223](https://github.com/langchain-ai/deepagents/issues/4223)) ([5d080df](https://github.com/langchain-ai/deepagents/commit/5d080df2776d380214bf20ae31266b9628e4e5b0))
|
|
19
|
+
* Note subscription plans unusable for Anthropic in `/auth` ([#4207](https://github.com/langchain-ai/deepagents/issues/4207)) ([28cd19d](https://github.com/langchain-ai/deepagents/commit/28cd19db08bacf981ab2c91195638e66072816fe))
|
|
20
|
+
|
|
5
21
|
## [0.1.22](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.21...deepagents-code==0.1.22) (2026-06-24)
|
|
6
22
|
|
|
7
23
|
### Features
|
|
@@ -108,7 +108,7 @@ check: lint check_imports test
|
|
|
108
108
|
uv lock --check
|
|
109
109
|
@echo "🔗 Checking SDK pin against workspace SDK (advisory)..."
|
|
110
110
|
@uv run --all-groups python "$(REPO_ROOT)/.github/scripts/check_sdk_pin.py" || \
|
|
111
|
-
{ rc=$$?; [ $$rc -eq 1 ] && echo "⚠️ SDK pin
|
|
111
|
+
{ rc=$$?; [ $$rc -eq 1 ] && echo "⚠️ Stale SDK pin (advisory, non-fatal)." || exit $$rc; }
|
|
112
112
|
@echo "✅ All local CI checks passed!"
|
|
113
113
|
|
|
114
114
|
######################
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.23
|
|
4
4
|
Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
@@ -27,7 +27,7 @@ Classifier: Topic :: Terminals
|
|
|
27
27
|
Requires-Python: <4.0,>=3.11
|
|
28
28
|
Requires-Dist: aiosqlite<1.0.0,>=0.22.1
|
|
29
29
|
Requires-Dist: deepagents-acp<1.0.0,>=0.0.8
|
|
30
|
-
Requires-Dist: deepagents==0.
|
|
30
|
+
Requires-Dist: deepagents==0.7.0a2
|
|
31
31
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
32
32
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.7
|
|
33
33
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.5
|
|
@@ -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.23" # 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."""
|
|
@@ -67,7 +67,6 @@ from deepagents_code.config import (
|
|
|
67
67
|
settings,
|
|
68
68
|
)
|
|
69
69
|
from deepagents_code.configurable_model import ConfigurableModelMiddleware
|
|
70
|
-
from deepagents_code.filesystem_empty_result import _FilesystemEmptyResultMiddleware
|
|
71
70
|
from deepagents_code.integrations.sandbox_factory import get_default_working_dir
|
|
72
71
|
from deepagents_code.local_context import (
|
|
73
72
|
LocalContextMiddleware,
|
|
@@ -1420,7 +1419,6 @@ def create_cli_agent(
|
|
|
1420
1419
|
# Build middleware stack based on enabled features
|
|
1421
1420
|
agent_middleware: list[AgentMiddleware[Any, Any]] = [
|
|
1422
1421
|
ConfigurableModelMiddleware(),
|
|
1423
|
-
_FilesystemEmptyResultMiddleware(),
|
|
1424
1422
|
]
|
|
1425
1423
|
|
|
1426
1424
|
# Resume state: declares the `_context_tokens` and `_model_spec` channels
|
|
@@ -1749,6 +1749,22 @@ class DeepAgentsApp(App):
|
|
|
1749
1749
|
self._launch_init_requested = launch_init
|
|
1750
1750
|
"""Whether startup should show onboarding during the initial paint."""
|
|
1751
1751
|
|
|
1752
|
+
self._onboarding_session = launch_init
|
|
1753
|
+
"""Whether onboarding runs this session (constant for the session).
|
|
1754
|
+
|
|
1755
|
+
Unlike `_launch_init_requested`, which is cleared once the flow starts,
|
|
1756
|
+
this stays set so background workers (e.g. the optional-tools check)
|
|
1757
|
+
can register missing-dependency notices silently instead of toasting
|
|
1758
|
+
over the onboarding modals.
|
|
1759
|
+
|
|
1760
|
+
Intentionally never reset, including on onboarding completion: the
|
|
1761
|
+
optional-tools check is scheduled once at startup and may not have run
|
|
1762
|
+
by the time the flow finishes, so clearing this would let that check
|
|
1763
|
+
toast the very "Web search disabled" notice onboarding means to defer.
|
|
1764
|
+
Leaving it set for the whole session is harmless because the check runs
|
|
1765
|
+
exactly once.
|
|
1766
|
+
"""
|
|
1767
|
+
|
|
1752
1768
|
self._launch_init_running = False
|
|
1753
1769
|
"""Re-entry guard for launch init modals."""
|
|
1754
1770
|
|
|
@@ -2909,7 +2925,13 @@ class DeepAgentsApp(App):
|
|
|
2909
2925
|
# update (already notified within CACHE_TTL) does not open the
|
|
2910
2926
|
# modal, so toasts must still fire or returning users never
|
|
2911
2927
|
# see the warning.
|
|
2912
|
-
|
|
2928
|
+
# Onboarding suppresses too: the flow covers integrations (and
|
|
2929
|
+
# prompts for a Tavily key) itself, so a "Web search disabled"
|
|
2930
|
+
# toast over the onboarding modals is noise. Entries stay
|
|
2931
|
+
# reachable via ctrl+n.
|
|
2932
|
+
suppress_toasts = (
|
|
2933
|
+
self._update_modal_pending.is_set() or self._onboarding_session
|
|
2934
|
+
)
|
|
2913
2935
|
|
|
2914
2936
|
for tool in missing:
|
|
2915
2937
|
notification = build_missing_tool_notification(tool)
|
|
@@ -3461,11 +3483,18 @@ class DeepAgentsApp(App):
|
|
|
3461
3483
|
)
|
|
3462
3484
|
else:
|
|
3463
3485
|
from deepagents_code.extras_info import ExtrasIntrospectionError
|
|
3464
|
-
from deepagents_code.update_check import
|
|
3486
|
+
from deepagents_code.update_check import (
|
|
3487
|
+
ToolRequirementIntrospectionError,
|
|
3488
|
+
install_package_command,
|
|
3489
|
+
)
|
|
3465
3490
|
|
|
3466
3491
|
try:
|
|
3467
3492
|
install_cmd = install_package_command(missing.package)
|
|
3468
|
-
except (
|
|
3493
|
+
except (
|
|
3494
|
+
ValueError,
|
|
3495
|
+
ExtrasIntrospectionError,
|
|
3496
|
+
ToolRequirementIntrospectionError,
|
|
3497
|
+
) as exc:
|
|
3469
3498
|
logger.debug(
|
|
3470
3499
|
"install_package_command failed; falling back to "
|
|
3471
3500
|
"manual hint: %s",
|
|
@@ -4313,7 +4342,8 @@ class DeepAgentsApp(App):
|
|
|
4313
4342
|
"""Handle the `/install <extra>` slash command.
|
|
4314
4343
|
|
|
4315
4344
|
Adds an optional extra (e.g. `quickjs`, `daytona`) to the installed
|
|
4316
|
-
dcode tool by re-running
|
|
4345
|
+
dcode tool by re-running
|
|
4346
|
+
`uv tool install --reinstall -U 'deepagents-code[<extra>]'`.
|
|
4317
4347
|
Refuses unknown extras unless the user passes a `--force` token.
|
|
4318
4348
|
|
|
4319
4349
|
Args:
|
|
@@ -6102,6 +6132,7 @@ class DeepAgentsApp(App):
|
|
|
6102
6132
|
return
|
|
6103
6133
|
|
|
6104
6134
|
model_spec, provider = result
|
|
6135
|
+
await self._prompt_launch_tavily()
|
|
6105
6136
|
if self._connecting:
|
|
6106
6137
|
# Bound the wait so a stuck server never traps onboarding.
|
|
6107
6138
|
# Server startup typically completes in seconds; a minute is
|
|
@@ -6186,6 +6217,59 @@ class DeepAgentsApp(App):
|
|
|
6186
6217
|
return
|
|
6187
6218
|
await self._switch_model(model_spec, announce_unchanged=False)
|
|
6188
6219
|
|
|
6220
|
+
async def _prompt_launch_tavily(self) -> None:
|
|
6221
|
+
"""Optionally collect and store a Tavily web-search key during onboarding.
|
|
6222
|
+
|
|
6223
|
+
Skipped when a Tavily key is already configured (env or stored). A
|
|
6224
|
+
blank submission or Escape stores nothing; a non-empty key is persisted
|
|
6225
|
+
via the same `auth_store` path `/auth` uses. The key is also exported to
|
|
6226
|
+
the process environment (`apply_stored_service_credentials`) so a server
|
|
6227
|
+
respawn this session picks it up; the already-running server keeps its
|
|
6228
|
+
spawn-time tools, so web search takes full effect on the next launch (or
|
|
6229
|
+
after a restart).
|
|
6230
|
+
"""
|
|
6231
|
+
from deepagents_code.config import settings
|
|
6232
|
+
|
|
6233
|
+
if settings.has_tavily:
|
|
6234
|
+
return
|
|
6235
|
+
|
|
6236
|
+
from deepagents_code.widgets.auth import AuthPromptScreen, AuthResult
|
|
6237
|
+
|
|
6238
|
+
result = await self._push_screen_wait(
|
|
6239
|
+
AuthPromptScreen(
|
|
6240
|
+
"tavily",
|
|
6241
|
+
"TAVILY_API_KEY",
|
|
6242
|
+
reason=(
|
|
6243
|
+
"Web search is optional but strongly recommended to enhance "
|
|
6244
|
+
"your agent's capabilities."
|
|
6245
|
+
),
|
|
6246
|
+
allow_empty_submit=True,
|
|
6247
|
+
input_placeholder="Tavily API key (optional)",
|
|
6248
|
+
submit_label="Enter save/skip",
|
|
6249
|
+
)
|
|
6250
|
+
)
|
|
6251
|
+
if result is not AuthResult.SAVED:
|
|
6252
|
+
return
|
|
6253
|
+
|
|
6254
|
+
from deepagents_code.model_config import apply_stored_service_credentials
|
|
6255
|
+
|
|
6256
|
+
apply_stored_service_credentials()
|
|
6257
|
+
|
|
6258
|
+
# `apply_stored_service_credentials` is best-effort: it swallows a
|
|
6259
|
+
# corrupt-store read with only a `logger.warning`, which is invisible
|
|
6260
|
+
# inside a Textual session. The user just saw the key accepted, so
|
|
6261
|
+
# confirm it actually reached the environment; if not, say so rather
|
|
6262
|
+
# than letting web search silently stay disabled. Reaching this branch
|
|
6263
|
+
# means `has_tavily` was False at bootstrap, so a populated
|
|
6264
|
+
# `TAVILY_API_KEY` here can only come from the export above.
|
|
6265
|
+
if not os.environ.get("TAVILY_API_KEY"):
|
|
6266
|
+
self.notify(
|
|
6267
|
+
"Saved your Tavily key, but couldn't activate it this "
|
|
6268
|
+
"session. Restart Deep Agents Code, or re-add it with /auth.",
|
|
6269
|
+
severity="warning",
|
|
6270
|
+
markup=False,
|
|
6271
|
+
)
|
|
6272
|
+
|
|
6189
6273
|
async def _finish_launch_init(self, *, name: str | None) -> None:
|
|
6190
6274
|
"""Persist onboarding completion and, when given, mount the welcome.
|
|
6191
6275
|
|
|
@@ -6956,7 +7040,8 @@ class DeepAgentsApp(App):
|
|
|
6956
7040
|
await self._mount_message(
|
|
6957
7041
|
AppMessage(
|
|
6958
7042
|
"LangSmith tracing is not configured. "
|
|
6959
|
-
"
|
|
7043
|
+
"Run `/auth` and select LangSmith to enable tracing, or set "
|
|
7044
|
+
"LANGSMITH_API_KEY and LANGSMITH_TRACING=true.",
|
|
6960
7045
|
),
|
|
6961
7046
|
)
|
|
6962
7047
|
return
|
|
@@ -6974,7 +7059,8 @@ class DeepAgentsApp(App):
|
|
|
6974
7059
|
AppMessage(
|
|
6975
7060
|
"The `langsmith` package is not installed. "
|
|
6976
7061
|
"Install it with "
|
|
6977
|
-
"`uv tool install -U deepagents-code
|
|
7062
|
+
"`uv tool install --reinstall -U deepagents-code "
|
|
7063
|
+
"--with langsmith` "
|
|
6978
7064
|
"to enable `/trace`.",
|
|
6979
7065
|
),
|
|
6980
7066
|
)
|
|
@@ -11798,7 +11884,7 @@ class DeepAgentsApp(App):
|
|
|
11798
11884
|
def _ensure_restart_prompt_loaded() -> None:
|
|
11799
11885
|
"""Load the restart-prompt modal before any in-place self-upgrade.
|
|
11800
11886
|
|
|
11801
|
-
`/install` runs `uv tool install -U 'deepagents-code[...]'`, which
|
|
11887
|
+
`/install` runs `uv tool install --reinstall -U 'deepagents-code[...]'`, which
|
|
11802
11888
|
rewrites deepagents-code's own on-disk package tree while this process
|
|
11803
11889
|
is running. Modules already in `sys.modules` keep working from memory,
|
|
11804
11890
|
but a *first* import after the rewrite reads the mutated (or
|
|
@@ -11835,11 +11921,11 @@ class DeepAgentsApp(App):
|
|
|
11835
11921
|
redundant hint:
|
|
11836
11922
|
|
|
11837
11923
|
- Owned + idle: show the prompt (its button is the call to action). If
|
|
11838
|
-
|
|
11924
|
+
the prompt can't be shown, fall back to a `/restart` hint.
|
|
11839
11925
|
- Owned + busy/connecting: a restart cancels in-flight work, so point
|
|
11840
|
-
|
|
11926
|
+
at `/restart` for once the current task finishes.
|
|
11841
11927
|
- No owned subprocess (remote server): `/restart` can't respawn it, so a
|
|
11842
|
-
|
|
11928
|
+
full relaunch is the only way to load the package.
|
|
11843
11929
|
|
|
11844
11930
|
Args:
|
|
11845
11931
|
label: Installed extra/package name, surfaced in the prompt title.
|
|
@@ -11865,8 +11951,9 @@ class DeepAgentsApp(App):
|
|
|
11865
11951
|
try:
|
|
11866
11952
|
from deepagents_code.widgets.restart_prompt import RestartPromptScreen
|
|
11867
11953
|
except ModuleNotFoundError:
|
|
11868
|
-
# `/install` runs `uv tool install -U
|
|
11869
|
-
# can rewrite deepagents-code's own
|
|
11954
|
+
# `/install` runs `uv tool install --reinstall -U
|
|
11955
|
+
# 'deepagents-code[...]'`, which can rewrite deepagents-code's own
|
|
11956
|
+
# on-disk package tree mid-session
|
|
11870
11957
|
# (see `_ensure_restart_prompt_loaded`). A first import of the modal
|
|
11871
11958
|
# here may then fail with `ModuleNotFoundError`. Degrade to the
|
|
11872
11959
|
# manual `/restart` hint instead of crashing the TUI. The catch is
|
|
@@ -3426,11 +3426,18 @@ def _create_model_via_init(
|
|
|
3426
3426
|
)
|
|
3427
3427
|
else:
|
|
3428
3428
|
from deepagents_code.extras_info import ExtrasIntrospectionError
|
|
3429
|
-
from deepagents_code.update_check import
|
|
3429
|
+
from deepagents_code.update_check import (
|
|
3430
|
+
ToolRequirementIntrospectionError,
|
|
3431
|
+
install_package_command,
|
|
3432
|
+
)
|
|
3430
3433
|
|
|
3431
3434
|
try:
|
|
3432
3435
|
install_cmd = install_package_command(package)
|
|
3433
|
-
except (
|
|
3436
|
+
except (
|
|
3437
|
+
ValueError,
|
|
3438
|
+
ExtrasIntrospectionError,
|
|
3439
|
+
ToolRequirementIntrospectionError,
|
|
3440
|
+
) as exc:
|
|
3434
3441
|
logger.debug(
|
|
3435
3442
|
"install_package_command failed; falling back to "
|
|
3436
3443
|
"manual hint: %s",
|
|
@@ -75,15 +75,49 @@ def _sdk_version() -> tuple[str, bool]:
|
|
|
75
75
|
return "unknown", False
|
|
76
76
|
|
|
77
77
|
|
|
78
|
+
def _build_commit() -> str | None:
|
|
79
|
+
"""Return the commit stamped into the package at build time, if present.
|
|
80
|
+
|
|
81
|
+
Released wheels carry a generated `_build_info.py` (see `hatch_build.py`);
|
|
82
|
+
editable and local installs do not, so this returns `None` for them.
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
from deepagents_code._build_info import ( # ty: ignore[unresolved-import] # generated at build time
|
|
86
|
+
BUILD_COMMIT,
|
|
87
|
+
)
|
|
88
|
+
except ImportError:
|
|
89
|
+
return None
|
|
90
|
+
except Exception: # a corrupt stamp must never crash `doctor`
|
|
91
|
+
logger.debug("Build-info module present but failed to import", exc_info=True)
|
|
92
|
+
return None
|
|
93
|
+
commit = (BUILD_COMMIT or "").strip()
|
|
94
|
+
return commit or None
|
|
95
|
+
|
|
96
|
+
|
|
78
97
|
def _commit_hash(path: str) -> str:
|
|
79
|
-
"""Return the short git commit hash for
|
|
98
|
+
"""Return the short git commit hash for the install, if available.
|
|
99
|
+
|
|
100
|
+
Prefers the commit stamped into a released wheel at build time, but only for
|
|
101
|
+
non-editable installs: an editable install may carry a stale stamp from a
|
|
102
|
+
prior local build (the generated file is gitignored and survives a failed
|
|
103
|
+
build), so it always probes the live git working tree, which reflects local
|
|
104
|
+
changes.
|
|
80
105
|
|
|
81
106
|
Args:
|
|
82
107
|
path: Directory used as the git command working directory.
|
|
83
108
|
|
|
84
109
|
Returns:
|
|
85
|
-
The short commit hash, or `unknown` when
|
|
110
|
+
The short commit hash, or `unknown` when no commit can be determined.
|
|
86
111
|
"""
|
|
112
|
+
baked = _build_commit()
|
|
113
|
+
if baked:
|
|
114
|
+
from deepagents_code.config import _is_editable_install
|
|
115
|
+
|
|
116
|
+
# A baked commit only describes a built wheel; ignore it for editable
|
|
117
|
+
# installs so a stale stamp can't mask the live working-tree commit.
|
|
118
|
+
if not _is_editable_install():
|
|
119
|
+
return baked
|
|
120
|
+
|
|
87
121
|
import shutil
|
|
88
122
|
import subprocess # noqa: S404 # fixed-argv git metadata probe
|
|
89
123
|
from pathlib import Path
|
|
@@ -2372,7 +2372,7 @@ def cli_main() -> None:
|
|
|
2372
2372
|
except ImportError as exc:
|
|
2373
2373
|
msg = (
|
|
2374
2374
|
f"ACP dependencies not available: {exc}\n"
|
|
2375
|
-
"Install with: uv tool install -U deepagents-code "
|
|
2375
|
+
"Install with: uv tool install --reinstall -U deepagents-code "
|
|
2376
2376
|
"--with deepagents-acp\n"
|
|
2377
2377
|
)
|
|
2378
2378
|
sys.stderr.write(msg)
|
|
@@ -291,7 +291,8 @@ def get_latest_version(
|
|
|
291
291
|
except ImportError:
|
|
292
292
|
logger.warning(
|
|
293
293
|
"requests package not installed — update checks disabled. "
|
|
294
|
-
"Install with: uv tool install -U deepagents-code
|
|
294
|
+
"Install with: uv tool install --reinstall -U deepagents-code "
|
|
295
|
+
"--with requests"
|
|
295
296
|
)
|
|
296
297
|
return cached_version
|
|
297
298
|
|
|
@@ -1876,6 +1877,8 @@ def _uv_tool_install_command(
|
|
|
1876
1877
|
include_prereleases: bool | None,
|
|
1877
1878
|
distribution_name: str,
|
|
1878
1879
|
extras_to_add: Iterable[str] = (),
|
|
1880
|
+
with_packages_to_add: Iterable[str] = (),
|
|
1881
|
+
reinstall: bool = False,
|
|
1879
1882
|
) -> str:
|
|
1880
1883
|
"""Return the receipt-preserving `uv tool install -U` command.
|
|
1881
1884
|
|
|
@@ -1885,6 +1888,19 @@ def _uv_tool_install_command(
|
|
|
1885
1888
|
`None`, follows the installed version's channel.
|
|
1886
1889
|
distribution_name: Name of the installed distribution to inspect.
|
|
1887
1890
|
extras_to_add: Extra names to merge with already-installed extras.
|
|
1891
|
+
with_packages_to_add: Package names to merge with the receipt's existing
|
|
1892
|
+
`--with` packages. Names already present (compared canonically) are
|
|
1893
|
+
not duplicated; genuinely new names are appended after the preserved
|
|
1894
|
+
ones. Callers must validate these names before passing them — the
|
|
1895
|
+
builder only `shlex.quote`-s them.
|
|
1896
|
+
reinstall: When `True`, add `--reinstall` so uv rebuilds the tool
|
|
1897
|
+
environment from scratch instead of patching it in place. An
|
|
1898
|
+
in-place `-U` upgrade can leave stale files behind (e.g. an old
|
|
1899
|
+
`tools.py` or its cached bytecode), which has been observed to
|
|
1900
|
+
produce a half-updated env that crashes the next server start with
|
|
1901
|
+
an `ImportError`; the preserved `--python` interpreter and `--with`
|
|
1902
|
+
packages still apply, so the rebuild keeps the existing tool
|
|
1903
|
+
context.
|
|
1888
1904
|
|
|
1889
1905
|
Raises:
|
|
1890
1906
|
ExtrasIntrospectionError: If a metadata-sourced extra name fails PEP 508
|
|
@@ -1906,12 +1922,17 @@ def _uv_tool_install_command(
|
|
|
1906
1922
|
except ValueError as exc:
|
|
1907
1923
|
msg = f"Distribution metadata yielded an invalid extra name: {exc}"
|
|
1908
1924
|
raise ExtrasIntrospectionError(msg) from exc
|
|
1909
|
-
cmd = "uv tool install -U"
|
|
1925
|
+
cmd = "uv tool install --reinstall -U" if reinstall else "uv tool install -U"
|
|
1910
1926
|
python = _uv_tool_python()
|
|
1911
1927
|
if python is not None:
|
|
1912
1928
|
cmd += f" --python {shlex.quote(python)}"
|
|
1913
1929
|
cmd += f" {requirement}"
|
|
1914
|
-
with_packages = _uv_tool_with_packages(distribution_name=distribution_name)
|
|
1930
|
+
with_packages = list(_uv_tool_with_packages(distribution_name=distribution_name))
|
|
1931
|
+
known = {canonicalize_name(package) for package in with_packages}
|
|
1932
|
+
for package in with_packages_to_add:
|
|
1933
|
+
if canonicalize_name(package) not in known:
|
|
1934
|
+
with_packages.append(package)
|
|
1935
|
+
known.add(canonicalize_name(package))
|
|
1915
1936
|
for package in with_packages:
|
|
1916
1937
|
cmd += f" --with {shlex.quote(package)}"
|
|
1917
1938
|
if _resolve_include_prereleases(include_prereleases):
|
|
@@ -2047,30 +2068,42 @@ def install_package_command(
|
|
|
2047
2068
|
|
|
2048
2069
|
The result is built for *execution* (via `perform_install_package`), not for
|
|
2049
2070
|
display — surfacing raw `uv tool` invocations to the user is intentionally
|
|
2050
|
-
avoided. `package` is validated
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2071
|
+
avoided. `package` is validated here against PEP 508 grammar and then
|
|
2072
|
+
`shlex.quote`-d by the shared builder: the validation already blocks shell
|
|
2073
|
+
metacharacters, so the quoting is defense in depth that keeps the command
|
|
2074
|
+
safe even if the pattern is later loosened.
|
|
2075
|
+
|
|
2076
|
+
Delegates to `_uv_tool_install_command` (the same builder the extras path
|
|
2077
|
+
uses), passing the new package as a `--with` requirement. That builder folds
|
|
2078
|
+
already-installed extras into the `deepagents-code[...]` requirement, and
|
|
2079
|
+
preserves the uv-managed Python interpreter, the receipt's existing `--with`
|
|
2080
|
+
packages, and the installed pre-release channel. Without this, reinstalling
|
|
2081
|
+
to add a second package would replace the tool with a plain `deepagents-code`
|
|
2082
|
+
(dropping extras the user added through `/install <extra>`), rebuild with
|
|
2083
|
+
only the newest `--with` package (dropping previously configured custom
|
|
2084
|
+
providers), or silently downgrade a pre-release install to the latest stable.
|
|
2085
|
+
|
|
2086
|
+
Like the extras path (`_install_extra_uv_tool_command`), passes
|
|
2087
|
+
`reinstall=True` so the upgrade rebuilds the tool environment cleanly; see
|
|
2088
|
+
`_uv_tool_install_command`'s `reinstall` parameter for why an in-place
|
|
2089
|
+
upgrade is unsafe.
|
|
2059
2090
|
|
|
2060
2091
|
Args:
|
|
2061
2092
|
package: Package name to install into the existing tool environment.
|
|
2062
2093
|
distribution_name: Name of the installed distribution to inspect for
|
|
2063
|
-
already-installed extras.
|
|
2094
|
+
already-installed extras and uv receipt requirements.
|
|
2064
2095
|
|
|
2065
2096
|
Returns:
|
|
2066
2097
|
Shell command string suitable for execution via the shell.
|
|
2067
2098
|
|
|
2068
2099
|
Raises:
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2100
|
+
ValueError: If `package` fails PEP 508 validation.
|
|
2101
|
+
|
|
2102
|
+
Propagates `ExtrasIntrospectionError` if installed extras cannot be
|
|
2103
|
+
determined safely from distribution metadata (or a metadata-sourced extra
|
|
2104
|
+
name fails PEP 508 validation), and `ToolRequirementIntrospectionError` if
|
|
2105
|
+
the uv tool receipt's interpreter or `--with` packages cannot be determined
|
|
2106
|
+
safely.
|
|
2074
2107
|
"""
|
|
2075
2108
|
if not _PACKAGE_NAME_RE.fullmatch(package):
|
|
2076
2109
|
msg = (
|
|
@@ -2078,19 +2111,14 @@ def install_package_command(
|
|
|
2078
2111
|
f"({_PACKAGE_NAME_RE.pattern})"
|
|
2079
2112
|
)
|
|
2080
2113
|
raise ValueError(msg)
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2114
|
+
return _uv_tool_install_command(
|
|
2115
|
+
version=None,
|
|
2116
|
+
include_prereleases=None,
|
|
2117
|
+
distribution_name=distribution_name,
|
|
2118
|
+
with_packages_to_add=(package,),
|
|
2119
|
+
reinstall=True,
|
|
2084
2120
|
)
|
|
2085
2121
|
|
|
2086
|
-
try:
|
|
2087
|
-
extras = installed_extra_names(distribution_name, strict=True)
|
|
2088
|
-
except ExtrasIntrospectionError as exc:
|
|
2089
|
-
msg = str(exc)
|
|
2090
|
-
raise ExtrasIntrospectionError(msg) from exc
|
|
2091
|
-
requirement = _dcode_extras_requirement(extras)
|
|
2092
|
-
return f"uv tool install -U {requirement} --with {shlex.quote(package)}"
|
|
2093
|
-
|
|
2094
2122
|
|
|
2095
2123
|
def install_extras_command(extras: Iterable[str]) -> str:
|
|
2096
2124
|
"""Return the install-script command that installs dcode extras.
|
|
@@ -2183,6 +2211,10 @@ def _install_extra_uv_tool_command(
|
|
|
2183
2211
|
) -> str:
|
|
2184
2212
|
"""Return the receipt-preserving uv command that installs one dcode extra.
|
|
2185
2213
|
|
|
2214
|
+
Passes `reinstall=True` so the upgrade rebuilds the tool environment from
|
|
2215
|
+
scratch rather than patching it in place; see `_uv_tool_install_command`'s
|
|
2216
|
+
`reinstall` parameter for why an in-place upgrade is unsafe.
|
|
2217
|
+
|
|
2186
2218
|
Args:
|
|
2187
2219
|
extra: The extra name to add. Validated against PEP 508 grammar before
|
|
2188
2220
|
interpolation into the shell command.
|
|
@@ -2208,6 +2240,7 @@ def _install_extra_uv_tool_command(
|
|
|
2208
2240
|
include_prereleases=None,
|
|
2209
2241
|
distribution_name=distribution_name,
|
|
2210
2242
|
extras_to_add=(extra,),
|
|
2243
|
+
reinstall=True,
|
|
2211
2244
|
)
|
|
2212
2245
|
|
|
2213
2246
|
|
|
@@ -2248,11 +2281,11 @@ async def perform_install_extra(
|
|
|
2248
2281
|
) -> tuple[bool, str]:
|
|
2249
2282
|
"""Add `extra` to the installed dcode tool environment.
|
|
2250
2283
|
|
|
2251
|
-
Runs `uv tool install -U 'deepagents-code[<extras>]'`,
|
|
2252
|
-
extras that are already installed. Editable installs are
|
|
2253
|
-
caller should rerun their `uv tool install --editable` command
|
|
2254
|
-
'deepagents-code[<extra>]'` added so the extra is resolved
|
|
2255
|
-
editable source.
|
|
2284
|
+
Runs `uv tool install --reinstall -U 'deepagents-code[<extras>]'`,
|
|
2285
|
+
preserving any extras that are already installed. Editable installs are
|
|
2286
|
+
refused — the caller should rerun their `uv tool install --editable` command
|
|
2287
|
+
with `--with 'deepagents-code[<extra>]'` added so the extra is resolved
|
|
2288
|
+
against the editable source.
|
|
2256
2289
|
|
|
2257
2290
|
Args:
|
|
2258
2291
|
extra: The extra name to install. Must satisfy `is_valid_extra_name`;
|
|
@@ -2319,10 +2352,11 @@ async def perform_install_package(
|
|
|
2319
2352
|
) -> tuple[bool, str]:
|
|
2320
2353
|
"""Add an arbitrary `package` to the installed dcode tool environment.
|
|
2321
2354
|
|
|
2322
|
-
Runs `uv tool install -U 'deepagents-code[<extras>]' --with
|
|
2323
|
-
escape hatch for a provider whose package is not a
|
|
2324
|
-
(e.g. a custom or in-house `class_path` model).
|
|
2325
|
-
preserved so the reinstall does not drop them.
|
|
2355
|
+
Runs `uv tool install --reinstall -U 'deepagents-code[<extras>]' --with
|
|
2356
|
+
<package>`, the escape hatch for a provider whose package is not a
|
|
2357
|
+
`deepagents-code` extra (e.g. a custom or in-house `class_path` model).
|
|
2358
|
+
Already-installed extras are preserved so the reinstall does not drop them.
|
|
2359
|
+
Editable installs are refused
|
|
2326
2360
|
— the caller should rerun their `uv tool install --editable` command with
|
|
2327
2361
|
`--with <package>` added so it resolves against the editable source.
|
|
2328
2362
|
|
|
@@ -2378,12 +2412,14 @@ async def perform_install_package(
|
|
|
2378
2412
|
cmd = install_package_command(package)
|
|
2379
2413
|
except ValueError as exc:
|
|
2380
2414
|
return False, f"{type(exc).__name__}: {exc}"
|
|
2381
|
-
except ExtrasIntrospectionError as exc:
|
|
2415
|
+
except (ExtrasIntrospectionError, ToolRequirementIntrospectionError) as exc:
|
|
2382
2416
|
# Distinct from a malformed package name: the running distribution's own
|
|
2383
|
-
# metadata could not be read or parsed. Leave a
|
|
2384
|
-
# is recoverable from logs, even though the user
|
|
2417
|
+
# metadata, or the uv tool receipt, could not be read or parsed. Leave a
|
|
2418
|
+
# breadcrumb so the cause is recoverable from logs, even though the user
|
|
2419
|
+
# message is unchanged.
|
|
2385
2420
|
logger.warning(
|
|
2386
|
-
"Could not introspect installed extras for package
|
|
2421
|
+
"Could not introspect installed extras or uv receipt for package "
|
|
2422
|
+
"install of %r",
|
|
2387
2423
|
package,
|
|
2388
2424
|
exc_info=True,
|
|
2389
2425
|
)
|
|
@@ -2583,6 +2619,32 @@ def mark_auto_update_default_acknowledged() -> bool:
|
|
|
2583
2619
|
return _write_update_state({"auto_update_default_acknowledged": True})
|
|
2584
2620
|
|
|
2585
2621
|
|
|
2622
|
+
def _note_install_baseline() -> None:
|
|
2623
|
+
"""Pre-acknowledge the auto-update default notice for a fresh install.
|
|
2624
|
+
|
|
2625
|
+
The migration notice (`should_announce_auto_update_default`) is intended to
|
|
2626
|
+
warn users who ran dcode *before* auto-update became the opt-out default; a
|
|
2627
|
+
brand-new install never experienced the old behavior, so the notice is
|
|
2628
|
+
meaningless to it. Call this on the first launch ever (see
|
|
2629
|
+
`should_show_whats_new`) so the notice never leaks into a new install — the
|
|
2630
|
+
notice itself fires pre-TUI in `_run_startup_auto_update`.
|
|
2631
|
+
|
|
2632
|
+
Writes nothing when the user already set an explicit preference.
|
|
2633
|
+
"""
|
|
2634
|
+
if is_auto_update_explicitly_set():
|
|
2635
|
+
return
|
|
2636
|
+
if not mark_auto_update_default_acknowledged():
|
|
2637
|
+
# Fail-soft: the same unwritable state dir also drops the adjacent
|
|
2638
|
+
# `seen_version` write, so the install stays "first run ever" and the
|
|
2639
|
+
# stamp is retried next launch. Log the operation for context — the
|
|
2640
|
+
# generic write warning in `_write_update_state` can't say which write
|
|
2641
|
+
# failed when both fire back-to-back.
|
|
2642
|
+
logger.debug(
|
|
2643
|
+
"Could not stamp install baseline; the auto-update default notice "
|
|
2644
|
+
"will be re-evaluated on the next launch",
|
|
2645
|
+
)
|
|
2646
|
+
|
|
2647
|
+
|
|
2586
2648
|
# ---------------------------------------------------------------------------
|
|
2587
2649
|
# "What's new" tracking
|
|
2588
2650
|
# ---------------------------------------------------------------------------
|
|
@@ -2603,7 +2665,11 @@ def should_show_whats_new() -> bool:
|
|
|
2603
2665
|
"""Return `True` if this is the first launch on a newer version."""
|
|
2604
2666
|
seen = get_seen_version()
|
|
2605
2667
|
if seen is None:
|
|
2606
|
-
# First run ever — mark current as seen, don't show banner.
|
|
2668
|
+
# First run ever — mark current as seen, don't show banner. This is the
|
|
2669
|
+
# canonical fresh-install signal, so also pre-acknowledge the
|
|
2670
|
+
# auto-update default migration notice (which only applies to users who
|
|
2671
|
+
# predate the opt-out default) before it can fire on a later launch.
|
|
2672
|
+
_note_install_baseline()
|
|
2607
2673
|
mark_version_seen(__version__)
|
|
2608
2674
|
return False
|
|
2609
2675
|
try:
|