deepagents-code 0.1.18__tar.gz → 0.1.19__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.18 → deepagents_code-0.1.19}/CHANGELOG.md +13 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/PKG-INFO +1 -1
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_env_vars.py +19 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/app.py +335 -69
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/config.py +53 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/config_manifest.py +72 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/remote_client.py +16 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/auth.py +9 -0
- deepagents_code-0.1.19/deepagents_code/widgets/install_confirm.py +233 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/messages.py +76 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/model_selector.py +173 -29
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/welcome.py +133 -30
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/pyproject.toml +1 -1
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/scripts/install.sh +3 -6
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_app.py +531 -7
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_auth_widgets.py +16 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_config_manifest.py +53 -9
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_install_command.py +127 -17
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_install_confirm.py +61 -1
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_messages.py +137 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_model_selector.py +252 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_remote_client.py +67 -0
- deepagents_code-0.1.19/tests/unit_tests/test_tracing_replicas.py +70 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_welcome.py +170 -12
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/uv.lock +1 -1
- deepagents_code-0.1.18/deepagents_code/widgets/install_confirm.py +0 -120
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/.gitignore +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/AGENTS.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/COMMANDS.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/DEV.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/Makefile +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/README.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/agent.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/auth_commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/config_commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/filesystem_empty_result.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/main.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/model_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/non_interactive.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/server.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/server_manager.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/textual_adapter.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/update_check.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/_links.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/approval.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/chat_input.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/diff.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/history.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/loading.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/message_store.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/status.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/update_available.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/deepagents_code/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/images/tui.png +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/README.md +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_auth_commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_filesystem_empty_result.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_history.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_install_script.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_launch_init.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_links.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_commands.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_status.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_textual_adapter.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_update_progress.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/widgets/__init__.py +0 -0
- {deepagents_code-0.1.18 → deepagents_code-0.1.19}/tests/unit_tests/widgets/test_diff.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.19](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.18...deepagents-code==0.1.19) (2026-06-17)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Add latest frontier models to recommended list ([#4045](https://github.com/langchain-ai/deepagents/issues/4045)) ([1145356](https://github.com/langchain-ai/deepagents/commit/114535637eaee383c64eac5282bc9ac57007c83f))
|
|
10
|
+
* Dual-write agent traces to extra LangSmith projects ([#3998](https://github.com/langchain-ai/deepagents/issues/3998)) ([1b94cf3](https://github.com/langchain-ai/deepagents/commit/1b94cf322949e0cafd6f2bacf343fb0044ec5a8c))
|
|
11
|
+
* Prompt to install provider when selecting an uninstalled model ([#3981](https://github.com/langchain-ai/deepagents/issues/3981)) ([619207c](https://github.com/langchain-ai/deepagents/commit/619207c8d4d4308a9a3ab9d2d039506feeaf8a67))
|
|
12
|
+
* Note minimum OpenAI key permissions in `/auth` ([#4040](https://github.com/langchain-ai/deepagents/issues/4040)) ([14be63d](https://github.com/langchain-ai/deepagents/commit/14be63d476ed8dece75e20fff05016122c258be8))
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* Exclude prompt prefix from `UserMessage` selection ([#4002](https://github.com/langchain-ai/deepagents/issues/4002)) ([8ee6ba6](https://github.com/langchain-ai/deepagents/commit/8ee6ba6e64895d3d36a5957627221ed7667bc1d4))
|
|
17
|
+
|
|
5
18
|
## [0.1.18](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.17...deepagents-code==0.1.18) (2026-06-16)
|
|
6
19
|
|
|
7
20
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.19
|
|
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/
|
|
@@ -122,6 +122,18 @@ KITTY_KEYBOARD = "DEEPAGENTS_CODE_KITTY_KEYBOARD"
|
|
|
122
122
|
LANGSMITH_PROJECT = "DEEPAGENTS_CODE_LANGSMITH_PROJECT"
|
|
123
123
|
"""Override LangSmith project name for agent traces."""
|
|
124
124
|
|
|
125
|
+
LANGSMITH_REPLICA_PROJECTS = "DEEPAGENTS_CODE_LANGSMITH_REPLICA_PROJECTS"
|
|
126
|
+
"""Comma-separated LangSmith project names to *also* write agent traces to.
|
|
127
|
+
|
|
128
|
+
When set (and tracing is active), each agent run is dual-written to the primary
|
|
129
|
+
deepagents-code project *and* one extra project via LangSmith write replicas.
|
|
130
|
+
|
|
131
|
+
Only the first listed project is used: the LangGraph server mirrors a run to a
|
|
132
|
+
single extra project, so any additional entries are dropped (with a warning).
|
|
133
|
+
The value is comma-separated for forward-compatibility, not because multiple
|
|
134
|
+
destinations are written today.
|
|
135
|
+
"""
|
|
136
|
+
|
|
125
137
|
NO_TERMINAL_ESCAPE = "DEEPAGENTS_CODE_NO_TERMINAL_ESCAPE"
|
|
126
138
|
"""Disable all terminal escape/control sequence output when enabled."""
|
|
127
139
|
|
|
@@ -165,6 +177,13 @@ SHELL_ALLOW_LIST = "DEEPAGENTS_CODE_SHELL_ALLOW_LIST"
|
|
|
165
177
|
SHOW_HEADER = "DEEPAGENTS_CODE_SHOW_HEADER"
|
|
166
178
|
"""Show Textual's native header bar at the top of the TUI when enabled."""
|
|
167
179
|
|
|
180
|
+
SHOW_LANGSMITH_REPLICA_TRACING = "DEEPAGENTS_CODE_SHOW_LANGSMITH_REPLICA_TRACING"
|
|
181
|
+
"""Show LangSmith replica project info in the startup splash when enabled.
|
|
182
|
+
|
|
183
|
+
Defaults to enabled; set to a falsy value (`0`, `false`, `no`, `off`, or empty)
|
|
184
|
+
to hide replica tracing details from the splash while leaving tracing active.
|
|
185
|
+
"""
|
|
186
|
+
|
|
168
187
|
THEME = "DEEPAGENTS_CODE_THEME"
|
|
169
188
|
"""Force the CLI to launch with this theme name when set."""
|
|
170
189
|
|
|
@@ -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.19" # 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."""
|
|
@@ -202,6 +202,7 @@ if TYPE_CHECKING:
|
|
|
202
202
|
from deepagents_code.textual_adapter import TextualUIAdapter
|
|
203
203
|
from deepagents_code.widgets.approval import ApprovalMenu
|
|
204
204
|
from deepagents_code.widgets.ask_user import AskUserMenu
|
|
205
|
+
from deepagents_code.widgets.model_selector import ModelSelectorScreen
|
|
205
206
|
from deepagents_code.widgets.notification_center import (
|
|
206
207
|
NotificationSuppressRequested,
|
|
207
208
|
)
|
|
@@ -3984,7 +3985,30 @@ class DeepAgentsApp(App):
|
|
|
3984
3985
|
return
|
|
3985
3986
|
|
|
3986
3987
|
extra = names[0].lower()
|
|
3988
|
+
await self._install_extra(extra, force=force)
|
|
3987
3989
|
|
|
3990
|
+
async def _install_extra(
|
|
3991
|
+
self, extra: str, *, force: bool = False, auto_restart: bool = False
|
|
3992
|
+
) -> bool:
|
|
3993
|
+
"""Install a `deepagents-code` extra, mounting progress and restart offer.
|
|
3994
|
+
|
|
3995
|
+
Shared by the `/install <extra>` command and the model selector's
|
|
3996
|
+
install-on-select flow. Mounts its own status/error messages and offers
|
|
3997
|
+
a one-keypress restart for restart-capable extras.
|
|
3998
|
+
|
|
3999
|
+
Args:
|
|
4000
|
+
extra: The extra name to install (e.g. `"baseten"`, `"quickjs"`).
|
|
4001
|
+
force: Skip the "unknown extra" guard for valid-but-unlisted names.
|
|
4002
|
+
auto_restart: Restart the app-owned server immediately after a
|
|
4003
|
+
restart-capable install. Used only when the user selected a model
|
|
4004
|
+
that cannot load until the server respawns.
|
|
4005
|
+
|
|
4006
|
+
Returns:
|
|
4007
|
+
`True` when the extra installed successfully and, when `auto_restart`
|
|
4008
|
+
was requested, the server was restarted (or a fresh startup will
|
|
4009
|
+
load it); `False` otherwise. The interactive restart offer
|
|
4010
|
+
(non-`auto_restart` path) does not affect the return value.
|
|
4011
|
+
"""
|
|
3988
4012
|
try:
|
|
3989
4013
|
from deepagents_code.config import _is_editable_install
|
|
3990
4014
|
from deepagents_code.extras_info import (
|
|
@@ -4005,7 +4029,7 @@ class DeepAgentsApp(App):
|
|
|
4005
4029
|
await self._mount_message(
|
|
4006
4030
|
ErrorMessage(f"Install failed: {type(exc).__name__}: {exc}"),
|
|
4007
4031
|
)
|
|
4008
|
-
return
|
|
4032
|
+
return False
|
|
4009
4033
|
|
|
4010
4034
|
if not is_valid_extra_name(extra):
|
|
4011
4035
|
await self._mount_message(
|
|
@@ -4014,7 +4038,7 @@ class DeepAgentsApp(App):
|
|
|
4014
4038
|
"alphanumeric with `-`, `_`, or `.` (PEP 508).",
|
|
4015
4039
|
),
|
|
4016
4040
|
)
|
|
4017
|
-
return
|
|
4041
|
+
return False
|
|
4018
4042
|
|
|
4019
4043
|
if await asyncio.to_thread(_is_editable_install):
|
|
4020
4044
|
await self._mount_message(
|
|
@@ -4023,7 +4047,7 @@ class DeepAgentsApp(App):
|
|
|
4023
4047
|
+ editable_extra_hint(extra),
|
|
4024
4048
|
),
|
|
4025
4049
|
)
|
|
4026
|
-
return
|
|
4050
|
+
return False
|
|
4027
4051
|
|
|
4028
4052
|
# KNOWN_EXTRAS is a curated "did you mean" list, not the authoritative
|
|
4029
4053
|
# set (that's pyproject, resolved by uv): defer to --force rather than
|
|
@@ -4036,7 +4060,7 @@ class DeepAgentsApp(App):
|
|
|
4036
4060
|
await self._mount_message(
|
|
4037
4061
|
ErrorMessage(f"Install failed: {type(exc).__name__}: {exc}"),
|
|
4038
4062
|
)
|
|
4039
|
-
return
|
|
4063
|
+
return False
|
|
4040
4064
|
known = ", ".join(sorted(KNOWN_EXTRAS))
|
|
4041
4065
|
await self._mount_message(
|
|
4042
4066
|
AppMessage(
|
|
@@ -4047,7 +4071,7 @@ class DeepAgentsApp(App):
|
|
|
4047
4071
|
f"`/install {extra} --force`",
|
|
4048
4072
|
),
|
|
4049
4073
|
)
|
|
4050
|
-
return
|
|
4074
|
+
return False
|
|
4051
4075
|
|
|
4052
4076
|
log_path = create_update_log_path()
|
|
4053
4077
|
# Load the restart modal before the upgrade rewrites our own package
|
|
@@ -4065,7 +4089,7 @@ class DeepAgentsApp(App):
|
|
|
4065
4089
|
f"Install failed: {type(exc).__name__}: {exc}\nLog: {log_path}",
|
|
4066
4090
|
),
|
|
4067
4091
|
)
|
|
4068
|
-
return
|
|
4092
|
+
return False
|
|
4069
4093
|
try:
|
|
4070
4094
|
success, output = await perform_install_extra(extra, log_path=log_path)
|
|
4071
4095
|
except (OSError, asyncio.CancelledError) as exc:
|
|
@@ -4077,7 +4101,7 @@ class DeepAgentsApp(App):
|
|
|
4077
4101
|
f"Run manually: {manual_cmd}",
|
|
4078
4102
|
),
|
|
4079
4103
|
)
|
|
4080
|
-
return
|
|
4104
|
+
return False
|
|
4081
4105
|
|
|
4082
4106
|
if not success:
|
|
4083
4107
|
# Tail the last 200 chars — uv resolver prints the resolved
|
|
@@ -4090,7 +4114,7 @@ class DeepAgentsApp(App):
|
|
|
4090
4114
|
f"Run manually: {manual_cmd}",
|
|
4091
4115
|
),
|
|
4092
4116
|
)
|
|
4093
|
-
return
|
|
4117
|
+
return False
|
|
4094
4118
|
|
|
4095
4119
|
# Model-provider and sandbox extras are imported by the langgraph
|
|
4096
4120
|
# server subprocess; `/restart` respawns that subprocess and picks
|
|
@@ -4099,16 +4123,60 @@ class DeepAgentsApp(App):
|
|
|
4099
4123
|
# (`verify_interpreter_deps` gates `--interpreter`), so a full
|
|
4100
4124
|
# relaunch is required.
|
|
4101
4125
|
restart_capable = extra in MODEL_PROVIDER_EXTRAS or extra in SANDBOX_EXTRAS
|
|
4102
|
-
if restart_capable:
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4126
|
+
if restart_capable and auto_restart:
|
|
4127
|
+
if self._restart_after_install_is_unneeded():
|
|
4128
|
+
# No running server to respawn; a deferred/errored startup will
|
|
4129
|
+
# import the extra on its first spawn. Acknowledge the install
|
|
4130
|
+
# regardless of whether the config reload below succeeds.
|
|
4131
|
+
await self._mount_message(
|
|
4132
|
+
AppMessage(f"Installed extra '{extra}'."),
|
|
4133
|
+
)
|
|
4134
|
+
return await self._reload_configuration_for_restart()
|
|
4135
|
+
if await self._restart_after_install(extra):
|
|
4136
|
+
return True
|
|
4137
|
+
if self._server_kwargs is None:
|
|
4138
|
+
await self._mount_message(
|
|
4139
|
+
AppMessage(
|
|
4140
|
+
f"Installed extra '{extra}', but this app is connected "
|
|
4141
|
+
"to a remote LangGraph server. Relaunch dcode to load it, "
|
|
4142
|
+
"then select the model again."
|
|
4143
|
+
),
|
|
4144
|
+
)
|
|
4145
|
+
else:
|
|
4146
|
+
await self._mount_message(
|
|
4147
|
+
AppMessage(
|
|
4148
|
+
f"Installed extra '{extra}', but couldn't restart the server "
|
|
4149
|
+
"automatically. Run `/restart` to load it, then select the "
|
|
4150
|
+
"model again."
|
|
4151
|
+
),
|
|
4152
|
+
)
|
|
4153
|
+
return False
|
|
4106
4154
|
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4155
|
+
if not restart_capable:
|
|
4156
|
+
if extra == "quickjs":
|
|
4157
|
+
# `quickjs` only does anything behind `--interpreter`, a
|
|
4158
|
+
# launch-only flag with a startup-time dependency gate, so a
|
|
4159
|
+
# `/restart` (which reuses the original launch settings) can't
|
|
4160
|
+
# enable it — a full relaunch with the flag is required.
|
|
4161
|
+
next_step = (
|
|
4162
|
+
"Exit and relaunch dcode with `--interpreter` to use it — "
|
|
4163
|
+
"see `dcode --help`."
|
|
4164
|
+
)
|
|
4165
|
+
else:
|
|
4166
|
+
next_step = "Exit and relaunch dcode to use the new dependencies."
|
|
4167
|
+
await self._mount_message(
|
|
4168
|
+
AppMessage(f"Installed extra '{extra}'. {next_step}"),
|
|
4169
|
+
)
|
|
4170
|
+
return True
|
|
4171
|
+
|
|
4172
|
+
# Restart-capable extra: announce success, then offer a one-keypress
|
|
4173
|
+
# restart. `_offer_restart_after_install` owns all follow-up messaging
|
|
4174
|
+
# (the prompt's button is the call to action when shown; it mounts a
|
|
4175
|
+
# `/restart`-or-relaunch hint itself when it can't show the prompt), so
|
|
4176
|
+
# a redundant "Run /restart" line is never appended here.
|
|
4177
|
+
await self._mount_message(AppMessage(f"Installed extra '{extra}'."))
|
|
4178
|
+
await self._offer_restart_after_install(extra)
|
|
4179
|
+
return True
|
|
4112
4180
|
|
|
4113
4181
|
async def _handle_install_package(self, package: str, *, force: bool) -> None:
|
|
4114
4182
|
"""Install an arbitrary package into the dcode tool env via `uv --with`.
|
|
@@ -6447,8 +6515,11 @@ class DeepAgentsApp(App):
|
|
|
6447
6515
|
with suppress(Exception):
|
|
6448
6516
|
await queued_widget.remove()
|
|
6449
6517
|
await self._mount_message(UserMessage(command))
|
|
6450
|
-
|
|
6451
|
-
|
|
6518
|
+
msg = Content.assemble(
|
|
6519
|
+
f"Opening tracing project {project_name!r}:\n",
|
|
6520
|
+
(url, TStyle(dim=True, italic=True, link=url)),
|
|
6521
|
+
)
|
|
6522
|
+
await self._mount_message(AppMessage(msg))
|
|
6452
6523
|
|
|
6453
6524
|
# Append directly — no dedup; each /trace invocation gets its own output.
|
|
6454
6525
|
self._deferred_actions.append(
|
|
@@ -6457,8 +6528,11 @@ class DeepAgentsApp(App):
|
|
|
6457
6528
|
return
|
|
6458
6529
|
|
|
6459
6530
|
await self._mount_message(UserMessage(command))
|
|
6460
|
-
|
|
6461
|
-
|
|
6531
|
+
msg = Content.assemble(
|
|
6532
|
+
f"Opening tracing project {project_name!r}:\n",
|
|
6533
|
+
(url, TStyle(dim=True, italic=True, link=url)),
|
|
6534
|
+
)
|
|
6535
|
+
await self._mount_message(AppMessage(msg))
|
|
6462
6536
|
|
|
6463
6537
|
async def _handle_command(self, command: str) -> None:
|
|
6464
6538
|
"""Handle a slash command.
|
|
@@ -8785,7 +8859,7 @@ class DeepAgentsApp(App):
|
|
|
8785
8859
|
*,
|
|
8786
8860
|
curated: bool = False,
|
|
8787
8861
|
result_callback: Callable[[tuple[str, str] | None], None] | None = None,
|
|
8788
|
-
) ->
|
|
8862
|
+
) -> ModelSelectorScreen:
|
|
8789
8863
|
"""Build the model selector screen with current app model state.
|
|
8790
8864
|
|
|
8791
8865
|
Args:
|
|
@@ -8824,35 +8898,10 @@ class DeepAgentsApp(App):
|
|
|
8824
8898
|
Args:
|
|
8825
8899
|
extra_kwargs: Extra constructor kwargs from `--model-params`.
|
|
8826
8900
|
"""
|
|
8827
|
-
from functools import partial
|
|
8828
8901
|
|
|
8829
8902
|
def handle_result(result: tuple[str, str] | None) -> None:
|
|
8830
8903
|
"""Handle the model selector result."""
|
|
8831
|
-
|
|
8832
|
-
model_spec, _ = result
|
|
8833
|
-
if self._agent_running or self._shell_running or self._connecting:
|
|
8834
|
-
self._defer_action(
|
|
8835
|
-
DeferredAction(
|
|
8836
|
-
kind="model_switch",
|
|
8837
|
-
execute=partial(
|
|
8838
|
-
self._switch_model,
|
|
8839
|
-
model_spec,
|
|
8840
|
-
extra_kwargs=extra_kwargs,
|
|
8841
|
-
),
|
|
8842
|
-
),
|
|
8843
|
-
)
|
|
8844
|
-
self.notify(
|
|
8845
|
-
"Model will switch after current task completes.",
|
|
8846
|
-
timeout=3,
|
|
8847
|
-
)
|
|
8848
|
-
else:
|
|
8849
|
-
self.call_later(
|
|
8850
|
-
partial(
|
|
8851
|
-
self._switch_model,
|
|
8852
|
-
model_spec,
|
|
8853
|
-
extra_kwargs=extra_kwargs,
|
|
8854
|
-
),
|
|
8855
|
-
)
|
|
8904
|
+
self._handle_model_selection(screen, result, extra_kwargs=extra_kwargs)
|
|
8856
8905
|
# Refocus input after modal closes
|
|
8857
8906
|
if self._chat_input:
|
|
8858
8907
|
self._chat_input.focus_input()
|
|
@@ -8860,6 +8909,155 @@ class DeepAgentsApp(App):
|
|
|
8860
8909
|
screen = self._build_model_selector_screen()
|
|
8861
8910
|
self.push_screen(screen, handle_result)
|
|
8862
8911
|
|
|
8912
|
+
def _handle_model_selection(
|
|
8913
|
+
self,
|
|
8914
|
+
screen: ModelSelectorScreen,
|
|
8915
|
+
result: tuple[str, str] | None,
|
|
8916
|
+
*,
|
|
8917
|
+
extra_kwargs: dict[str, Any] | None = None,
|
|
8918
|
+
) -> None:
|
|
8919
|
+
"""Route a model-selector result to install-then-switch or a switch.
|
|
8920
|
+
|
|
8921
|
+
Args:
|
|
8922
|
+
screen: The dismissed selector, read for a confirmed install extra.
|
|
8923
|
+
result: The `(model_spec, provider)` pair, or `None` if cancelled.
|
|
8924
|
+
extra_kwargs: Extra constructor kwargs from `--model-params`.
|
|
8925
|
+
"""
|
|
8926
|
+
if result is None:
|
|
8927
|
+
return
|
|
8928
|
+
model_spec, _ = result
|
|
8929
|
+
# When the selector confirmed installing a missing provider's extra,
|
|
8930
|
+
# install it first (with restart offer) before switching.
|
|
8931
|
+
extra = screen.pending_install_extra
|
|
8932
|
+
if extra:
|
|
8933
|
+
from functools import partial
|
|
8934
|
+
|
|
8935
|
+
self.call_later(
|
|
8936
|
+
partial(
|
|
8937
|
+
self._install_extra_then_switch,
|
|
8938
|
+
extra,
|
|
8939
|
+
model_spec,
|
|
8940
|
+
extra_kwargs=extra_kwargs,
|
|
8941
|
+
),
|
|
8942
|
+
)
|
|
8943
|
+
else:
|
|
8944
|
+
self._dispatch_model_switch(model_spec, extra_kwargs=extra_kwargs)
|
|
8945
|
+
|
|
8946
|
+
def _dispatch_model_switch(
|
|
8947
|
+
self,
|
|
8948
|
+
model_spec: str,
|
|
8949
|
+
*,
|
|
8950
|
+
extra_kwargs: dict[str, Any] | None = None,
|
|
8951
|
+
) -> None:
|
|
8952
|
+
"""Switch to `model_spec` now, or defer until in-flight work finishes.
|
|
8953
|
+
|
|
8954
|
+
Args:
|
|
8955
|
+
model_spec: The `provider:model` spec to switch to.
|
|
8956
|
+
extra_kwargs: Extra constructor kwargs from `--model-params`.
|
|
8957
|
+
"""
|
|
8958
|
+
from functools import partial
|
|
8959
|
+
|
|
8960
|
+
if self._agent_running or self._shell_running or self._connecting:
|
|
8961
|
+
self._defer_action(
|
|
8962
|
+
DeferredAction(
|
|
8963
|
+
kind="model_switch",
|
|
8964
|
+
execute=partial(
|
|
8965
|
+
self._switch_model,
|
|
8966
|
+
model_spec,
|
|
8967
|
+
extra_kwargs=extra_kwargs,
|
|
8968
|
+
),
|
|
8969
|
+
),
|
|
8970
|
+
)
|
|
8971
|
+
self.notify(
|
|
8972
|
+
"Model will switch after current task completes.",
|
|
8973
|
+
timeout=3,
|
|
8974
|
+
)
|
|
8975
|
+
else:
|
|
8976
|
+
self.call_later(
|
|
8977
|
+
partial(
|
|
8978
|
+
self._switch_model,
|
|
8979
|
+
model_spec,
|
|
8980
|
+
extra_kwargs=extra_kwargs,
|
|
8981
|
+
),
|
|
8982
|
+
)
|
|
8983
|
+
|
|
8984
|
+
async def _install_extra_then_switch(
|
|
8985
|
+
self,
|
|
8986
|
+
extra: str,
|
|
8987
|
+
model_spec: str,
|
|
8988
|
+
*,
|
|
8989
|
+
extra_kwargs: dict[str, Any] | None = None,
|
|
8990
|
+
) -> None:
|
|
8991
|
+
"""Install a provider's extra, then switch to its model on success.
|
|
8992
|
+
|
|
8993
|
+
Args:
|
|
8994
|
+
extra: The extra that installs the model's provider integration.
|
|
8995
|
+
model_spec: The `provider:model` spec to switch to once installed.
|
|
8996
|
+
extra_kwargs: Extra constructor kwargs from `--model-params`.
|
|
8997
|
+
"""
|
|
8998
|
+
# `_install_extra` already surfaced the reason on any failure.
|
|
8999
|
+
if not await self._install_extra(extra, auto_restart=True):
|
|
9000
|
+
return
|
|
9001
|
+
# The extra is now installed regardless of what happens next. If the
|
|
9002
|
+
# user dismisses the credential prompt, only the switch is cancelled —
|
|
9003
|
+
# the extra stays installed so they can switch later once a key is set.
|
|
9004
|
+
# The selector is already gone, so confirm the install landed rather
|
|
9005
|
+
# than leaving a silent no-op after a multi-step flow.
|
|
9006
|
+
if not await self._prompt_model_auth_if_needed(model_spec):
|
|
9007
|
+
await self._mount_message(
|
|
9008
|
+
AppMessage(
|
|
9009
|
+
f"Installed '{extra}'. Skipped switching to {model_spec} for "
|
|
9010
|
+
f"now — add credentials with `/auth`, then switch with "
|
|
9011
|
+
f"`/model` anytime.",
|
|
9012
|
+
),
|
|
9013
|
+
)
|
|
9014
|
+
return
|
|
9015
|
+
self._dispatch_model_switch(model_spec, extra_kwargs=extra_kwargs)
|
|
9016
|
+
|
|
9017
|
+
async def _prompt_model_auth_if_needed(self, model_spec: str) -> bool:
|
|
9018
|
+
"""Prompt for missing credentials before switching to `model_spec`.
|
|
9019
|
+
|
|
9020
|
+
Args:
|
|
9021
|
+
model_spec: The `provider:model` spec selected after installation.
|
|
9022
|
+
|
|
9023
|
+
Returns:
|
|
9024
|
+
`True` when switching can continue, or `False` when the user did not
|
|
9025
|
+
save required credentials.
|
|
9026
|
+
"""
|
|
9027
|
+
# This assumes API-key-style providers: it always uses the generic
|
|
9028
|
+
# `AuthPromptScreen` (key / base-url), never the codex OAuth flow that
|
|
9029
|
+
# the selector routes separately. That holds because only providers
|
|
9030
|
+
# with a `_PROVIDER_DEPENDENCIES` extra reach the install-then-switch
|
|
9031
|
+
# path, and the OAuth providers (e.g. `openai_codex`) have no such
|
|
9032
|
+
# entry. If an OAuth provider ever gains an extra, route it to its
|
|
9033
|
+
# dedicated sign-in here rather than the key prompt.
|
|
9034
|
+
from deepagents_code.config import detect_provider
|
|
9035
|
+
from deepagents_code.model_config import (
|
|
9036
|
+
ModelSpec,
|
|
9037
|
+
get_credential_env_var,
|
|
9038
|
+
get_provider_auth_status,
|
|
9039
|
+
)
|
|
9040
|
+
from deepagents_code.widgets.auth import AuthPromptScreen, AuthResult
|
|
9041
|
+
|
|
9042
|
+
parsed = ModelSpec.try_parse(model_spec)
|
|
9043
|
+
provider = parsed.provider if parsed else detect_provider(model_spec)
|
|
9044
|
+
if not provider:
|
|
9045
|
+
return True
|
|
9046
|
+
|
|
9047
|
+
status = get_provider_auth_status(provider)
|
|
9048
|
+
if not status.blocks_start:
|
|
9049
|
+
return True
|
|
9050
|
+
|
|
9051
|
+
env_var = status.env_var or get_credential_env_var(provider)
|
|
9052
|
+
result = await self._push_screen_wait(
|
|
9053
|
+
AuthPromptScreen(
|
|
9054
|
+
provider,
|
|
9055
|
+
env_var,
|
|
9056
|
+
reason=f"Required to use {model_spec}",
|
|
9057
|
+
)
|
|
9058
|
+
)
|
|
9059
|
+
return result is AuthResult.SAVED
|
|
9060
|
+
|
|
8863
9061
|
def _register_custom_themes(self) -> None:
|
|
8864
9062
|
"""Register all custom themes (built-in LC + user-defined) with Textual."""
|
|
8865
9063
|
for name, entry in theme.get_registry().items():
|
|
@@ -10757,37 +10955,56 @@ class DeepAgentsApp(App):
|
|
|
10757
10955
|
app-owned LangGraph server subprocess, so a `/restart` loads them
|
|
10758
10956
|
without exiting the TUI. When dcode owns that subprocess and is idle,
|
|
10759
10957
|
prompt to run the restart immediately instead of making the user type
|
|
10760
|
-
`/restart`.
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10958
|
+
`/restart`.
|
|
10959
|
+
|
|
10960
|
+
Owns all of its own follow-up messaging so the caller never appends a
|
|
10961
|
+
redundant hint:
|
|
10962
|
+
|
|
10963
|
+
- Owned + idle: show the prompt (its button is the call to action). If
|
|
10964
|
+
the prompt can't be shown, fall back to a `/restart` hint.
|
|
10965
|
+
- Owned + busy/connecting: a restart cancels in-flight work, so point
|
|
10966
|
+
at `/restart` for once the current task finishes.
|
|
10967
|
+
- No owned subprocess (remote server): `/restart` can't respawn it, so a
|
|
10968
|
+
full relaunch is the only way to load the package.
|
|
10765
10969
|
|
|
10766
10970
|
Args:
|
|
10767
10971
|
label: Installed extra/package name, surfaced in the prompt title.
|
|
10768
10972
|
"""
|
|
10769
10973
|
if self._server_proc is None or self._server_kwargs is None:
|
|
10974
|
+
await self._mount_message(
|
|
10975
|
+
AppMessage(f"Relaunch dcode to load '{label}'."),
|
|
10976
|
+
)
|
|
10770
10977
|
return
|
|
10771
10978
|
if self._agent_running or self._connecting:
|
|
10979
|
+
await self._mount_message(
|
|
10980
|
+
AppMessage(
|
|
10981
|
+
f"Run `/restart` to load '{label}' once the current task finishes.",
|
|
10982
|
+
),
|
|
10983
|
+
)
|
|
10772
10984
|
return
|
|
10773
10985
|
|
|
10986
|
+
# Owned + idle. A `/restart` respawns the subprocess (same effect as a
|
|
10987
|
+
# relaunch, without exiting), so every couldn't-show-the-prompt path
|
|
10988
|
+
# below degrades to this hint rather than mentioning a relaunch.
|
|
10989
|
+
manual_hint = f"Run `/restart` to load '{label}' now."
|
|
10990
|
+
|
|
10774
10991
|
try:
|
|
10775
10992
|
from deepagents_code.widgets.restart_prompt import RestartPromptScreen
|
|
10776
10993
|
except ModuleNotFoundError:
|
|
10777
10994
|
# `/install` runs `uv tool install -U 'deepagents-code[...]'`, which
|
|
10778
10995
|
# can rewrite deepagents-code's own on-disk package tree mid-session
|
|
10779
10996
|
# (see `_ensure_restart_prompt_loaded`). A first import of the modal
|
|
10780
|
-
# here may then fail with `ModuleNotFoundError`.
|
|
10781
|
-
# `/restart` hint
|
|
10782
|
-
#
|
|
10783
|
-
#
|
|
10784
|
-
# propagates rather than being mistaken for an upgrade race.
|
|
10997
|
+
# here may then fail with `ModuleNotFoundError`. Degrade to the
|
|
10998
|
+
# manual `/restart` hint instead of crashing the TUI. The catch is
|
|
10999
|
+
# deliberately narrow — a genuine `ImportError` from a broken modal
|
|
11000
|
+
# still propagates rather than being mistaken for an upgrade race.
|
|
10785
11001
|
logger.warning(
|
|
10786
|
-
"restart_prompt unavailable after installing %r;
|
|
10787
|
-
"manual /restart hint
|
|
11002
|
+
"restart_prompt unavailable after installing %r; falling back "
|
|
11003
|
+
"to the manual /restart hint",
|
|
10788
11004
|
label,
|
|
10789
11005
|
exc_info=True,
|
|
10790
11006
|
)
|
|
11007
|
+
await self._mount_message(AppMessage(manual_hint))
|
|
10791
11008
|
return
|
|
10792
11009
|
|
|
10793
11010
|
choice: RestartChoice | None
|
|
@@ -10801,25 +11018,74 @@ class DeepAgentsApp(App):
|
|
|
10801
11018
|
)
|
|
10802
11019
|
except TimeoutError:
|
|
10803
11020
|
logger.warning(
|
|
10804
|
-
"Restart prompt after installing %r timed out;
|
|
10805
|
-
"manual /restart hint
|
|
11021
|
+
"Restart prompt after installing %r timed out; falling back to "
|
|
11022
|
+
"the manual /restart hint",
|
|
10806
11023
|
label,
|
|
10807
11024
|
)
|
|
11025
|
+
await self._mount_message(AppMessage(manual_hint))
|
|
10808
11026
|
return
|
|
10809
11027
|
except Exception:
|
|
10810
11028
|
# Modal could not be mounted (e.g. another modal hijacked the
|
|
10811
|
-
# stack).
|
|
11029
|
+
# stack). Fall back to the manual `/restart` hint.
|
|
10812
11030
|
logger.exception(
|
|
10813
11031
|
"Failed to mount restart prompt after installing %r", label
|
|
10814
11032
|
)
|
|
11033
|
+
await self._mount_message(AppMessage(manual_hint))
|
|
10815
11034
|
return
|
|
10816
11035
|
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
11036
|
+
# The pre-prompt guards above ran before the modal await; server state
|
|
11037
|
+
# can flip while the user reads the prompt (e.g. an agent run starts),
|
|
11038
|
+
# tripping `_restart_after_install`'s busy/no-server guards, which only
|
|
11039
|
+
# log. Surface a message so an explicit "restart" choice never looks
|
|
11040
|
+
# like a silent no-op. Mirrors the `auto_restart` path.
|
|
11041
|
+
if choice == "restart" and not await self._restart_after_install(label):
|
|
11042
|
+
await self._mount_message(
|
|
11043
|
+
AppMessage(
|
|
11044
|
+
f"Couldn't restart the server automatically to load "
|
|
11045
|
+
f"'{label}'. Run `/restart` to load it.",
|
|
11046
|
+
),
|
|
11047
|
+
)
|
|
11048
|
+
# Otherwise the prompt was shown and the user made an informed choice;
|
|
11049
|
+
# no further hint is needed.
|
|
11050
|
+
|
|
11051
|
+
def _restart_after_install_is_unneeded(self) -> bool:
|
|
11052
|
+
"""Return whether a fresh startup will load the installed dependency."""
|
|
11053
|
+
return (
|
|
11054
|
+
self._server_proc is None
|
|
11055
|
+
and self._server_kwargs is not None
|
|
11056
|
+
and (
|
|
11057
|
+
self._server_startup_deferred or self._server_startup_error is not None
|
|
11058
|
+
)
|
|
11059
|
+
)
|
|
11060
|
+
|
|
11061
|
+
async def _restart_after_install(self, label: str) -> bool:
|
|
11062
|
+
"""Restart the app-owned server after installing a dependency.
|
|
11063
|
+
|
|
11064
|
+
Args:
|
|
11065
|
+
label: Installed extra/package name, used for logs and fallback copy.
|
|
11066
|
+
|
|
11067
|
+
Returns:
|
|
11068
|
+
`True` when the server restarted successfully; `False` when restart is
|
|
11069
|
+
not currently available or fails.
|
|
11070
|
+
"""
|
|
11071
|
+
if self._server_proc is None or self._server_kwargs is None:
|
|
11072
|
+
logger.info(
|
|
11073
|
+
"Cannot auto-restart after installing %s: no app-owned server", label
|
|
11074
|
+
)
|
|
11075
|
+
return False
|
|
11076
|
+
if self._agent_running or self._connecting:
|
|
11077
|
+
logger.info(
|
|
11078
|
+
"Cannot auto-restart after installing %s: server is busy",
|
|
11079
|
+
label,
|
|
11080
|
+
)
|
|
11081
|
+
return False
|
|
11082
|
+
if not await self._reload_configuration_for_restart():
|
|
11083
|
+
return False
|
|
11084
|
+
await self._mount_message(AppMessage("Restarting server..."))
|
|
11085
|
+
if not await self._restart_server_manual():
|
|
11086
|
+
return False
|
|
11087
|
+
await self._mount_message(AppMessage("Restart complete."))
|
|
11088
|
+
return True
|
|
10823
11089
|
|
|
10824
11090
|
async def _reload_configuration_for_restart(self) -> bool:
|
|
10825
11091
|
"""Reload config state before respawning the owned server.
|