deepagents-code 0.1.19__tar.gz → 0.1.20__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.19 → deepagents_code-0.1.20}/.gitignore +1 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/CHANGELOG.md +20 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/PKG-INFO +1 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_constants.py +9 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_session_stats.py +58 -28
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/app.py +182 -14
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/config.py +9 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/config_manifest.py +55 -11
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/main.py +5 -3
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/model_config.py +64 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/non_interactive.py +5 -2
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/notifications.py +3 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/server.py +37 -4
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/server_manager.py +5 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/sessions.py +16 -5
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/textual_adapter.py +22 -9
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/auth.py +149 -13
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/install_confirm.py +24 -9
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/model_selector.py +83 -42
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/thread_selector.py +13 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/update_progress.py +2 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/pyproject.toml +1 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/scripts/install.sh +18 -9
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_app.py +277 -8
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_auth_widgets.py +257 -5
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_config.py +58 -3
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_config_manifest.py +111 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_install_command.py +42 -2
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_install_confirm.py +19 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_install_script.py +77 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_main.py +9 -4
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_model_config.py +103 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_model_selector.py +229 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_non_interactive.py +49 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_server.py +211 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_server_manager.py +36 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_session_stats.py +43 -7
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_sessions.py +91 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_textual_adapter.py +124 -14
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_thread_selector.py +15 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/uv.lock +1 -1
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/AGENTS.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/COMMANDS.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/DEV.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/Makefile +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/README.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_env_vars.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/agent.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/auth_commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/config_commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/filesystem_empty_result.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/remote_client.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/update_check.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/_links.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/approval.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/chat_input.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/diff.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/history.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/loading.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/message_store.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/messages.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/status.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/update_available.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/deepagents_code/widgets/welcome.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/images/tui.png +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/README.md +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_auth_commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_chat_input.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_filesystem_empty_result.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_history.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_launch_init.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_links.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_commands.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_status.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_update_progress.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/widgets/__init__.py +0 -0
- {deepagents_code-0.1.19 → deepagents_code-0.1.20}/tests/unit_tests/widgets/test_diff.py +0 -0
|
@@ -100,6 +100,7 @@ ipython_config.py
|
|
|
100
100
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
101
101
|
# commonly ignored for libraries.
|
|
102
102
|
#uv.lock
|
|
103
|
+
.local_deps/
|
|
103
104
|
|
|
104
105
|
# poetry
|
|
105
106
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.20](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.19...deepagents-code==0.1.20) (2026-06-17)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Manage Tavily web-search API key in `/auth` ([#4062](https://github.com/langchain-ai/deepagents/issues/4062)) ([90cc099](https://github.com/langchain-ai/deepagents/commit/90cc099b0998a9aa55df01e3bc12ad1597c65365))
|
|
10
|
+
* Surface uninstalled known providers in `/auth` menu ([#4059](https://github.com/langchain-ai/deepagents/issues/4059)) ([73db271](https://github.com/langchain-ai/deepagents/commit/73db2719bce5ad3c933ffee643df4a62cfd60e17))
|
|
11
|
+
* Show provider in usage stats table ([#4049](https://github.com/langchain-ai/deepagents/issues/4049)) ([309b054](https://github.com/langchain-ai/deepagents/commit/309b054fdd040adb5086408a3bcb2550ba73439e))
|
|
12
|
+
* Quiet install script's full dependency list ([#4058](https://github.com/langchain-ai/deepagents/issues/4058)) ([de2c9fd](https://github.com/langchain-ai/deepagents/commit/de2c9fd8c7437fdcdfe738599f83808c5423c55c))
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* Read `LANGSMITH_PROJECT` for `tracing.langsmith_project` + show default ([#4054](https://github.com/langchain-ai/deepagents/issues/4054)) ([fec1551](https://github.com/langchain-ai/deepagents/commit/fec1551e901a4fe88bd74ee4833a91ef93b1e93f))
|
|
17
|
+
* Surface recommended models missing from installed provider profiles ([#4057](https://github.com/langchain-ai/deepagents/issues/4057)) ([56e0d31](https://github.com/langchain-ai/deepagents/commit/56e0d31b6c507d5a1e95c3f2058a8d3b9488a4db))
|
|
18
|
+
* Clarify post-update restart semantics ([#4046](https://github.com/langchain-ai/deepagents/issues/4046)) ([6318b81](https://github.com/langchain-ai/deepagents/commit/6318b817399f7dd2f2e6dc07987dca46f1da9886))
|
|
19
|
+
* Hide `[SYSTEM]` interrupt notices from `/threads` prompt ([#3988](https://github.com/langchain-ai/deepagents/issues/3988)) ([68fa0cb](https://github.com/langchain-ai/deepagents/commit/68fa0cb4d48ff3f3e552bbf16f8316433c7b6f34))
|
|
20
|
+
* Keep install-required `/model` rows dimmed after navigation ([#4048](https://github.com/langchain-ai/deepagents/issues/4048)) ([c499634](https://github.com/langchain-ai/deepagents/commit/c499634c530dcab9b18e3126b4573ff0d36c3efa))
|
|
21
|
+
* Rescaffold server workspace on `/restart` when config is missing ([#4050](https://github.com/langchain-ai/deepagents/issues/4050)) ([de51b0e](https://github.com/langchain-ai/deepagents/commit/de51b0e082293f5f795d96d3bf717c82efb9337e))
|
|
22
|
+
* Remove transient `Restarting server...` message after restart ([#4047](https://github.com/langchain-ai/deepagents/issues/4047)) ([87cc504](https://github.com/langchain-ai/deepagents/commit/87cc50428bc96ef11dfb11cee4020bff322a7216))
|
|
23
|
+
* Suppress model-switch defer toast on bare reconnect ([#4060](https://github.com/langchain-ai/deepagents/issues/4060)) ([60b1052](https://github.com/langchain-ai/deepagents/commit/60b10520d24c87b9c8c9d85b94cffae9e3c67c43))
|
|
24
|
+
|
|
5
25
|
## [0.1.19](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.18...deepagents-code==0.1.19) (2026-06-17)
|
|
6
26
|
|
|
7
27
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.20
|
|
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/
|
|
@@ -12,3 +12,12 @@ from typing import Final
|
|
|
12
12
|
|
|
13
13
|
DEFAULT_AGENT_NAME: Final[str] = "agent"
|
|
14
14
|
"""Default agent / assistant identifier when no `-a` flag is given."""
|
|
15
|
+
|
|
16
|
+
SYSTEM_MESSAGE_PREFIX: Final[str] = "[SYSTEM]"
|
|
17
|
+
"""Prefix for synthetic human messages (e.g. interrupt cancellation notices).
|
|
18
|
+
|
|
19
|
+
Such messages are written to the `messages` channel for the agent's benefit on
|
|
20
|
+
resume but are not user-authored, so they are filtered out of both the rendered
|
|
21
|
+
transcript and a thread's initial prompt. Shared here so the single producer
|
|
22
|
+
(`textual_adapter`) and its consumers (`app`, `sessions`) agree on one literal.
|
|
23
|
+
"""
|
|
@@ -17,64 +17,91 @@ SpinnerStatus = Literal["Thinking", "Offloading", "Loading thread"] | None
|
|
|
17
17
|
|
|
18
18
|
@dataclass
|
|
19
19
|
class ModelStats:
|
|
20
|
-
"""Token stats for a single model within a session.
|
|
21
|
-
|
|
22
|
-
Attributes:
|
|
23
|
-
request_count: Number of LLM API requests made to this model.
|
|
24
|
-
input_tokens: Cumulative input tokens sent to this model.
|
|
25
|
-
output_tokens: Cumulative output tokens received from this model.
|
|
26
|
-
"""
|
|
20
|
+
"""Token stats for a single model within a session."""
|
|
27
21
|
|
|
28
22
|
request_count: int = 0
|
|
23
|
+
"""Number of LLM API requests made to this model."""
|
|
24
|
+
|
|
29
25
|
input_tokens: int = 0
|
|
26
|
+
"""Cumulative input tokens sent to this model."""
|
|
27
|
+
|
|
30
28
|
output_tokens: int = 0
|
|
29
|
+
"""Cumulative output tokens received from this model."""
|
|
30
|
+
|
|
31
|
+
provider: str = ""
|
|
32
|
+
"""Provider that served this model (e.g. `openai`), or `""` when unknown."""
|
|
33
|
+
|
|
34
|
+
model_name: str = ""
|
|
35
|
+
"""Model name displayed in usage output."""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
ModelStatsKey = tuple[str, str]
|
|
39
|
+
"""Per-model dict key: the `(provider, model_name)` pair.
|
|
40
|
+
|
|
41
|
+
Pairing the provider with the model name keeps the same model served by
|
|
42
|
+
different providers (e.g. `gpt-5.5` via `openai` vs `azure`) in separate rows
|
|
43
|
+
instead of collapsing them. The key is always built from the same values stored
|
|
44
|
+
on the corresponding `ModelStats`, so key and fields never diverge.
|
|
45
|
+
"""
|
|
31
46
|
|
|
32
47
|
|
|
33
48
|
@dataclass
|
|
34
49
|
class SessionStats:
|
|
35
|
-
"""Stats accumulated over a single agent turn (or full session).
|
|
36
|
-
|
|
37
|
-
Attributes:
|
|
38
|
-
request_count: Total LLM API requests made (each chunk with
|
|
39
|
-
usage_metadata counts as one completed request).
|
|
40
|
-
input_tokens: Cumulative input tokens across all LLM requests.
|
|
41
|
-
output_tokens: Cumulative output tokens across all LLM requests.
|
|
42
|
-
wall_time_seconds: Wall-clock duration from stream start to end.
|
|
43
|
-
per_model: Per-model breakdown keyed by model name.
|
|
44
|
-
Populated only when `record_request` receives a non-empty
|
|
45
|
-
`model_name`. Empty dict means no named-model requests were
|
|
46
|
-
recorded; `print_usage_table` omits the model table in that case and
|
|
47
|
-
shows only the wall-time line (if applicable).
|
|
48
|
-
"""
|
|
50
|
+
"""Stats accumulated over a single agent turn (or full session)."""
|
|
49
51
|
|
|
50
52
|
request_count: int = 0
|
|
53
|
+
"""Total LLM API requests made.
|
|
54
|
+
|
|
55
|
+
Each chunk with `usage_metadata` counts as one completed request.
|
|
56
|
+
"""
|
|
57
|
+
|
|
51
58
|
input_tokens: int = 0
|
|
59
|
+
"""Cumulative input tokens across all LLM requests."""
|
|
60
|
+
|
|
52
61
|
output_tokens: int = 0
|
|
62
|
+
"""Cumulative output tokens across all LLM requests."""
|
|
63
|
+
|
|
53
64
|
wall_time_seconds: float = 0.0
|
|
54
|
-
|
|
65
|
+
"""Wall-clock duration from stream start to end."""
|
|
66
|
+
|
|
67
|
+
per_model: dict[ModelStatsKey, ModelStats] = field(default_factory=dict)
|
|
68
|
+
"""Per-model breakdown keyed by `(provider, model_name)`.
|
|
69
|
+
|
|
70
|
+
Populated only when `record_request` receives a non-empty `model_name`. Empty
|
|
71
|
+
dict means no named-model requests were recorded; `print_usage_table` omits
|
|
72
|
+
the model table in that case and shows only the wall-time line (if applicable).
|
|
73
|
+
"""
|
|
55
74
|
|
|
56
75
|
def record_request(
|
|
57
76
|
self,
|
|
58
77
|
model_name: str,
|
|
59
78
|
input_toks: int,
|
|
60
79
|
output_toks: int,
|
|
80
|
+
provider: str = "",
|
|
61
81
|
) -> None:
|
|
62
82
|
"""Accumulate token counts for one completed LLM request.
|
|
63
83
|
|
|
64
84
|
Updates both the session totals and the per-model breakdown.
|
|
65
85
|
|
|
66
86
|
Args:
|
|
67
|
-
model_name: The model that served this request
|
|
68
|
-
per-model key
|
|
69
|
-
breakdown for this request.
|
|
87
|
+
model_name: The model that served this request. Combined with
|
|
88
|
+
`provider` to form the per-model key. Pass an empty string to
|
|
89
|
+
skip the per-model breakdown for this request.
|
|
70
90
|
input_toks: Input tokens for this request.
|
|
71
91
|
output_toks: Output tokens for this request.
|
|
92
|
+
provider: Provider that served the model (e.g. `openai`). Combined
|
|
93
|
+
with `model_name` to form the per-model key, so the same model
|
|
94
|
+
served by different providers is tracked separately.
|
|
72
95
|
"""
|
|
73
96
|
self.request_count += 1
|
|
74
97
|
self.input_tokens += input_toks
|
|
75
98
|
self.output_tokens += output_toks
|
|
76
99
|
if model_name:
|
|
77
|
-
|
|
100
|
+
key = (provider, model_name)
|
|
101
|
+
entry = self.per_model.setdefault(
|
|
102
|
+
key,
|
|
103
|
+
ModelStats(provider=provider, model_name=model_name),
|
|
104
|
+
)
|
|
78
105
|
entry.request_count += 1
|
|
79
106
|
entry.input_tokens += input_toks
|
|
80
107
|
entry.output_tokens += output_toks
|
|
@@ -91,8 +118,11 @@ class SessionStats:
|
|
|
91
118
|
self.input_tokens += other.input_tokens
|
|
92
119
|
self.output_tokens += other.output_tokens
|
|
93
120
|
self.wall_time_seconds += other.wall_time_seconds
|
|
94
|
-
for
|
|
95
|
-
entry = self.per_model.setdefault(
|
|
121
|
+
for key, ms in other.per_model.items():
|
|
122
|
+
entry = self.per_model.setdefault(
|
|
123
|
+
key,
|
|
124
|
+
ModelStats(provider=ms.provider, model_name=ms.model_name),
|
|
125
|
+
)
|
|
96
126
|
entry.request_count += ms.request_count
|
|
97
127
|
entry.input_tokens += ms.input_tokens
|
|
98
128
|
entry.output_tokens += ms.output_tokens
|
|
@@ -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.20" # 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."""
|
|
@@ -42,7 +42,10 @@ from deepagents_code import (
|
|
|
42
42
|
theme,
|
|
43
43
|
)
|
|
44
44
|
from deepagents_code._cli_context import CLIContext
|
|
45
|
-
from deepagents_code._constants import
|
|
45
|
+
from deepagents_code._constants import (
|
|
46
|
+
DEFAULT_AGENT_NAME as DEFAULT_ASSISTANT_ID,
|
|
47
|
+
SYSTEM_MESSAGE_PREFIX,
|
|
48
|
+
)
|
|
46
49
|
from deepagents_code._git import (
|
|
47
50
|
read_git_branch_from_filesystem,
|
|
48
51
|
read_git_branch_via_subprocess,
|
|
@@ -161,6 +164,32 @@ def _create_model_with_deepagents_import_lock(
|
|
|
161
164
|
)
|
|
162
165
|
|
|
163
166
|
|
|
167
|
+
def _extra_is_ready(extra: str) -> bool | None:
|
|
168
|
+
"""Return whether all dependencies for `extra` are installed.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
`True` when every package declared by `extra` is importable, `False`
|
|
172
|
+
when one or more are missing, or `None` when the extra metadata
|
|
173
|
+
can't be introspected — an unknown state, distinct from a negative
|
|
174
|
+
one, so callers don't treat "couldn't check" as "not installed".
|
|
175
|
+
"""
|
|
176
|
+
from deepagents_code.extras_info import (
|
|
177
|
+
ExtrasIntrospectionError,
|
|
178
|
+
get_optional_dependency_status,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
try:
|
|
182
|
+
statuses = get_optional_dependency_status(strict=True)
|
|
183
|
+
except ExtrasIntrospectionError:
|
|
184
|
+
logger.warning(
|
|
185
|
+
"Could not verify whether extra %r is installed",
|
|
186
|
+
extra,
|
|
187
|
+
exc_info=True,
|
|
188
|
+
)
|
|
189
|
+
return None
|
|
190
|
+
return any(status.name == extra and status.ready for status in statuses)
|
|
191
|
+
|
|
192
|
+
|
|
164
193
|
@dataclass(frozen=True)
|
|
165
194
|
class _ConfigWriteResult:
|
|
166
195
|
"""Result of a config write with TUI-facing failure context."""
|
|
@@ -3684,7 +3713,8 @@ class DeepAgentsApp(App):
|
|
|
3684
3713
|
self.notify(
|
|
3685
3714
|
f"Update available: v{latest}{release_age}. "
|
|
3686
3715
|
f"Currently installed: {cli_version}{installed_age}. "
|
|
3687
|
-
"
|
|
3716
|
+
"Quit and relaunch dcode to install the update "
|
|
3717
|
+
"automatically.",
|
|
3688
3718
|
severity="information",
|
|
3689
3719
|
timeout=12,
|
|
3690
3720
|
markup=False,
|
|
@@ -3924,7 +3954,9 @@ class DeepAgentsApp(App):
|
|
|
3924
3954
|
self._update_available = (False, None)
|
|
3925
3955
|
await self._mount_message(
|
|
3926
3956
|
AppMessage(
|
|
3927
|
-
f"Updated to v{latest}.
|
|
3957
|
+
f"Updated to v{latest}. Quit and relaunch dcode to use "
|
|
3958
|
+
"the new version (`/restart` only restarts the server, "
|
|
3959
|
+
"not the CLI)."
|
|
3928
3960
|
),
|
|
3929
3961
|
)
|
|
3930
3962
|
else:
|
|
@@ -4727,6 +4759,35 @@ class DeepAgentsApp(App):
|
|
|
4727
4759
|
return
|
|
4728
4760
|
await container.mount(widget)
|
|
4729
4761
|
|
|
4762
|
+
async def _mount_transient_app_message(self, content: str) -> AppMessage | None:
|
|
4763
|
+
"""Mount an `AppMessage` that is not tracked by the message store.
|
|
4764
|
+
|
|
4765
|
+
Use for status text that should disappear once the state it describes
|
|
4766
|
+
resolves (e.g. "Restarting server..."). The returned widget can be
|
|
4767
|
+
removed directly; nothing lingers in the store to re-hydrate later.
|
|
4768
|
+
|
|
4769
|
+
Args:
|
|
4770
|
+
content: The message text to display.
|
|
4771
|
+
|
|
4772
|
+
Returns:
|
|
4773
|
+
The mounted widget, or `None` when the messages container is
|
|
4774
|
+
missing or detached.
|
|
4775
|
+
"""
|
|
4776
|
+
try:
|
|
4777
|
+
messages = self.query_one("#messages", Container)
|
|
4778
|
+
except (NoMatches, ScreenStackError):
|
|
4779
|
+
logger.debug(
|
|
4780
|
+
"Messages container unavailable; skipping transient status %r",
|
|
4781
|
+
content,
|
|
4782
|
+
exc_info=True,
|
|
4783
|
+
)
|
|
4784
|
+
return None
|
|
4785
|
+
if not messages.is_attached:
|
|
4786
|
+
return None
|
|
4787
|
+
widget = AppMessage(content)
|
|
4788
|
+
await self._mount_before_queued(messages, widget)
|
|
4789
|
+
return widget
|
|
4790
|
+
|
|
4730
4791
|
def _is_spinner_at_correct_position(self, container: Container) -> bool:
|
|
4731
4792
|
"""Check whether the loading spinner is already correctly positioned.
|
|
4732
4793
|
|
|
@@ -7528,7 +7589,7 @@ class DeepAgentsApp(App):
|
|
|
7528
7589
|
content = (
|
|
7529
7590
|
msg.content if isinstance(msg.content, str) else str(msg.content)
|
|
7530
7591
|
)
|
|
7531
|
-
if content.startswith(
|
|
7592
|
+
if content.startswith(SYSTEM_MESSAGE_PREFIX):
|
|
7532
7593
|
continue
|
|
7533
7594
|
|
|
7534
7595
|
# Detect skill invocations persisted via additional_kwargs
|
|
@@ -8951,6 +9012,13 @@ class DeepAgentsApp(App):
|
|
|
8951
9012
|
) -> None:
|
|
8952
9013
|
"""Switch to `model_spec` now, or defer until in-flight work finishes.
|
|
8953
9014
|
|
|
9015
|
+
The deferral toast is shown only for genuine in-flight user work
|
|
9016
|
+
(`_agent_running`/`_shell_running`). A switch deferred solely because the
|
|
9017
|
+
server is reconnecting (`_connecting` — e.g. the transient restart during
|
|
9018
|
+
install-then-switch) drains automatically once the server is ready and is
|
|
9019
|
+
already confirmed by the following "Switched to ..." message, so the
|
|
9020
|
+
"after current task completes" toast there is misleading noise.
|
|
9021
|
+
|
|
8954
9022
|
Args:
|
|
8955
9023
|
model_spec: The `provider:model` spec to switch to.
|
|
8956
9024
|
extra_kwargs: Extra constructor kwargs from `--model-params`.
|
|
@@ -8968,10 +9036,11 @@ class DeepAgentsApp(App):
|
|
|
8968
9036
|
),
|
|
8969
9037
|
),
|
|
8970
9038
|
)
|
|
8971
|
-
self.
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
9039
|
+
if self._agent_running or self._shell_running:
|
|
9040
|
+
self.notify(
|
|
9041
|
+
"Model will switch after current task completes.",
|
|
9042
|
+
timeout=3,
|
|
9043
|
+
)
|
|
8975
9044
|
else:
|
|
8976
9045
|
self.call_later(
|
|
8977
9046
|
partial(
|
|
@@ -9186,10 +9255,53 @@ class DeepAgentsApp(App):
|
|
|
9186
9255
|
def handle_result(_result: None) -> None:
|
|
9187
9256
|
if self._chat_input:
|
|
9188
9257
|
self._chat_input.focus_input()
|
|
9258
|
+
# When the user selected a greyed-out (uninstalled) provider and
|
|
9259
|
+
# confirmed installing it, install the extra and reopen the manager
|
|
9260
|
+
# so they can add a key against the now-installed provider.
|
|
9261
|
+
extra = screen.pending_install_extra
|
|
9262
|
+
if extra is not None:
|
|
9263
|
+
from functools import partial
|
|
9264
|
+
|
|
9265
|
+
self.call_later(
|
|
9266
|
+
partial(self._install_provider_then_reopen_auth, extra),
|
|
9267
|
+
)
|
|
9268
|
+
return
|
|
9189
9269
|
task = asyncio.create_task(self._maybe_start_deferred_server_from_default())
|
|
9190
9270
|
task.add_done_callback(_log_task_exception)
|
|
9191
9271
|
|
|
9192
|
-
|
|
9272
|
+
screen = AuthManagerScreen()
|
|
9273
|
+
self.push_screen(screen, handle_result)
|
|
9274
|
+
|
|
9275
|
+
async def _install_provider_then_reopen_auth(self, extra: str) -> None:
|
|
9276
|
+
"""Install a provider's extra from `/auth`, then reopen the manager.
|
|
9277
|
+
|
|
9278
|
+
Args:
|
|
9279
|
+
extra: The extra that installs the selected provider's integration.
|
|
9280
|
+
"""
|
|
9281
|
+
if await self._install_extra(extra, auto_restart=True):
|
|
9282
|
+
await self._show_auth_manager()
|
|
9283
|
+
return
|
|
9284
|
+
# `_install_extra` returns `False` both when the install genuinely
|
|
9285
|
+
# failed (it already surfaced the reason) and when the package landed
|
|
9286
|
+
# but the server restart didn't. Adding a key doesn't need the restart,
|
|
9287
|
+
# so reopen whenever the extra is importable; only stay in chat on a
|
|
9288
|
+
# real failure the user has already seen explained.
|
|
9289
|
+
ready = await asyncio.to_thread(_extra_is_ready, extra)
|
|
9290
|
+
if ready:
|
|
9291
|
+
from deepagents_code.model_config import clear_caches
|
|
9292
|
+
|
|
9293
|
+
clear_caches()
|
|
9294
|
+
await self._show_auth_manager()
|
|
9295
|
+
return
|
|
9296
|
+
if ready is None:
|
|
9297
|
+
# Introspection couldn't confirm the state (rare). Don't dead-end
|
|
9298
|
+
# silently after a multi-step flow — point the user back to `/auth`.
|
|
9299
|
+
await self._mount_message(
|
|
9300
|
+
AppMessage(
|
|
9301
|
+
f"Couldn't verify whether '{extra}' finished installing. "
|
|
9302
|
+
"Reopen `/auth` to add a key once it has.",
|
|
9303
|
+
),
|
|
9304
|
+
)
|
|
9193
9305
|
|
|
9194
9306
|
def _switch_agent(self, agent_name: str) -> None:
|
|
9195
9307
|
"""Switch to a different agent and hot-restart the backing server.
|
|
@@ -9982,8 +10094,49 @@ class DeepAgentsApp(App):
|
|
|
9982
10094
|
markup=False,
|
|
9983
10095
|
)
|
|
9984
10096
|
return
|
|
10097
|
+
if action_id == ActionId.ENTER_API_KEY:
|
|
10098
|
+
await self._enter_service_api_key(entry, payload)
|
|
10099
|
+
return
|
|
9985
10100
|
self._log_unknown_action(entry, action_id)
|
|
9986
10101
|
|
|
10102
|
+
async def _enter_service_api_key(
|
|
10103
|
+
self,
|
|
10104
|
+
entry: PendingNotification,
|
|
10105
|
+
payload: MissingDepPayload,
|
|
10106
|
+
) -> None:
|
|
10107
|
+
"""Open the API-key entry prompt (the one `/auth` uses) for a service.
|
|
10108
|
+
|
|
10109
|
+
Lets the user store a service API key inline instead of exporting an
|
|
10110
|
+
env var before launch.
|
|
10111
|
+
|
|
10112
|
+
Args:
|
|
10113
|
+
entry: The missing-dependency notification entry.
|
|
10114
|
+
payload: Typed payload carrying the service (tool) name.
|
|
10115
|
+
"""
|
|
10116
|
+
from deepagents_code.model_config import SERVICE_API_KEY_ENV
|
|
10117
|
+
|
|
10118
|
+
service = payload.tool
|
|
10119
|
+
# `env_var is None` covers any non-service tool, since `is_service` is
|
|
10120
|
+
# exactly membership in `SERVICE_API_KEY_ENV`.
|
|
10121
|
+
env_var = SERVICE_API_KEY_ENV.get(service)
|
|
10122
|
+
if env_var is None:
|
|
10123
|
+
self._log_unknown_action(entry, ActionId.ENTER_API_KEY)
|
|
10124
|
+
return
|
|
10125
|
+
|
|
10126
|
+
from deepagents_code.widgets.auth import AuthPromptScreen, AuthResult
|
|
10127
|
+
|
|
10128
|
+
result = await self._push_screen_wait(
|
|
10129
|
+
AuthPromptScreen(service, env_var),
|
|
10130
|
+
)
|
|
10131
|
+
if result == AuthResult.SAVED:
|
|
10132
|
+
self._notice_registry.remove(entry.key)
|
|
10133
|
+
self.notify(
|
|
10134
|
+
f"Saved {service} API key. Restart to apply.",
|
|
10135
|
+
severity="information",
|
|
10136
|
+
timeout=6,
|
|
10137
|
+
markup=False,
|
|
10138
|
+
)
|
|
10139
|
+
|
|
9987
10140
|
async def _handle_update_action(
|
|
9988
10141
|
self,
|
|
9989
10142
|
entry: PendingNotification,
|
|
@@ -10058,7 +10211,8 @@ class DeepAgentsApp(App):
|
|
|
10058
10211
|
if not progress_modal_visible:
|
|
10059
10212
|
self.notify(
|
|
10060
10213
|
f"Updated to v{payload.latest}. "
|
|
10061
|
-
"
|
|
10214
|
+
"Quit and relaunch dcode to use the new version "
|
|
10215
|
+
"(/restart only restarts the server, not the CLI).",
|
|
10062
10216
|
severity="information",
|
|
10063
10217
|
timeout=10,
|
|
10064
10218
|
markup=False,
|
|
@@ -11081,8 +11235,15 @@ class DeepAgentsApp(App):
|
|
|
11081
11235
|
return False
|
|
11082
11236
|
if not await self._reload_configuration_for_restart():
|
|
11083
11237
|
return False
|
|
11084
|
-
await self.
|
|
11085
|
-
|
|
11238
|
+
restarting = await self._mount_transient_app_message("Restarting server...")
|
|
11239
|
+
restarted = False
|
|
11240
|
+
try:
|
|
11241
|
+
restarted = await self._restart_server_manual()
|
|
11242
|
+
finally:
|
|
11243
|
+
if restarting is not None:
|
|
11244
|
+
with suppress(NoMatches, ScreenStackError):
|
|
11245
|
+
await restarting.remove()
|
|
11246
|
+
if not restarted:
|
|
11086
11247
|
return False
|
|
11087
11248
|
await self._mount_message(AppMessage("Restart complete."))
|
|
11088
11249
|
return True
|
|
@@ -11202,8 +11363,15 @@ class DeepAgentsApp(App):
|
|
|
11202
11363
|
)
|
|
11203
11364
|
return
|
|
11204
11365
|
|
|
11205
|
-
await self.
|
|
11206
|
-
|
|
11366
|
+
restarting = await self._mount_transient_app_message("Restarting server...")
|
|
11367
|
+
restarted = False
|
|
11368
|
+
try:
|
|
11369
|
+
restarted = await self._restart_server_manual()
|
|
11370
|
+
finally:
|
|
11371
|
+
if restarting is not None:
|
|
11372
|
+
with suppress(NoMatches, ScreenStackError):
|
|
11373
|
+
await restarting.remove()
|
|
11374
|
+
if restarted:
|
|
11207
11375
|
await self._mount_message(AppMessage("Restart complete."))
|
|
11208
11376
|
|
|
11209
11377
|
async def _restart_server_manual(self) -> bool:
|
|
@@ -549,6 +549,13 @@ def _ensure_bootstrap() -> None:
|
|
|
549
549
|
# Tracing enabled without a key floods the TUI with 401 ingest
|
|
550
550
|
# errors; disable it before any traced run starts.
|
|
551
551
|
_disable_orphaned_tracing()
|
|
552
|
+
|
|
553
|
+
# Bridge stored service keys (e.g. Tavily web search, entered via
|
|
554
|
+
# `/auth`) onto their canonical env vars before settings detection,
|
|
555
|
+
# so a stored key activates the feature without exporting the var.
|
|
556
|
+
from deepagents_code.model_config import apply_stored_service_credentials
|
|
557
|
+
|
|
558
|
+
apply_stored_service_credentials()
|
|
552
559
|
except Exception:
|
|
553
560
|
logger.exception(
|
|
554
561
|
"Bootstrap failed; .env values and LANGSMITH_PROJECT override "
|
|
@@ -2378,6 +2385,7 @@ def get_langsmith_project_name() -> str | None:
|
|
|
2378
2385
|
Returns:
|
|
2379
2386
|
Project name string when LangSmith tracing is active, None otherwise.
|
|
2380
2387
|
"""
|
|
2388
|
+
from deepagents_code.config_manifest import LANGSMITH_PROJECT_DEFAULT
|
|
2381
2389
|
from deepagents_code.model_config import resolve_env_var
|
|
2382
2390
|
|
|
2383
2391
|
langsmith_key = resolve_env_var("LANGSMITH_API_KEY") or resolve_env_var(
|
|
@@ -2392,7 +2400,7 @@ def get_langsmith_project_name() -> str | None:
|
|
|
2392
2400
|
return (
|
|
2393
2401
|
_get_settings().deepagents_langchain_project
|
|
2394
2402
|
or os.environ.get("LANGSMITH_PROJECT")
|
|
2395
|
-
or
|
|
2403
|
+
or LANGSMITH_PROJECT_DEFAULT
|
|
2396
2404
|
)
|
|
2397
2405
|
|
|
2398
2406
|
|
|
@@ -58,6 +58,12 @@ INTERPRETER_MAX_RESULT_CHARS_DEFAULT = 4000
|
|
|
58
58
|
INTERPRETER_PTC_DEFAULT: str | bool | list[str] = False
|
|
59
59
|
INTERPRETER_PTC_ACKNOWLEDGE_UNSAFE_DEFAULT = False
|
|
60
60
|
|
|
61
|
+
LANGSMITH_PROJECT_DEFAULT = "deepagents-code"
|
|
62
|
+
"""Project agent traces fall back to when no project env var is set.
|
|
63
|
+
|
|
64
|
+
Single source of truth shared by the `tracing.langsmith_project` option and
|
|
65
|
+
`config.get_langsmith_project_name`."""
|
|
66
|
+
|
|
61
67
|
|
|
62
68
|
class OptionKind(Enum):
|
|
63
69
|
"""How an option's raw env/TOML value is coerced to a typed value.
|
|
@@ -163,6 +169,14 @@ class ConfigOption:
|
|
|
163
169
|
`DEEPAGENTS_CODE_` prefix override is applied dynamically at resolution time.
|
|
164
170
|
"""
|
|
165
171
|
|
|
172
|
+
fallback_env_vars: tuple[str, ...] = ()
|
|
173
|
+
"""Secondary env vars read (in order) when `env_var` is unset.
|
|
174
|
+
|
|
175
|
+
Read literally — no `DEEPAGENTS_CODE_` prefix logic — so `config show`/`get`
|
|
176
|
+
mirror runtime fallbacks such as `get_langsmith_project_name` reading bare
|
|
177
|
+
`LANGSMITH_PROJECT`.
|
|
178
|
+
"""
|
|
179
|
+
|
|
166
180
|
toml_keys: tuple[str, ...] | None = None
|
|
167
181
|
"""Section/key path within `config.toml`, or `None`."""
|
|
168
182
|
|
|
@@ -207,9 +221,24 @@ class ConfigOption:
|
|
|
207
221
|
`resolve_scalar`. Catching it here fails the import (and the test suite).
|
|
208
222
|
|
|
209
223
|
Raises:
|
|
210
|
-
TypeError: When `
|
|
211
|
-
|
|
224
|
+
TypeError: When `fallback_env_vars` is not a tuple of non-empty
|
|
225
|
+
strings, `default` is mutable, a `STRUCTURED` option declares a
|
|
226
|
+
default, or a scalar option's default has the wrong type.
|
|
212
227
|
"""
|
|
228
|
+
# Guard `fallback_env_vars` independently of `default` (which has its own
|
|
229
|
+
# early-return path below): like `default`, it is shared by reference
|
|
230
|
+
# through the `get_config_options` `lru_cache`, so a mutable value (a
|
|
231
|
+
# `list`) would reintroduce the aliasing hazard the default guard exists
|
|
232
|
+
# to prevent. Empty names never match any env var, so reject those too.
|
|
233
|
+
if not isinstance(self.fallback_env_vars, tuple) or any(
|
|
234
|
+
not isinstance(name, str) or not name for name in self.fallback_env_vars
|
|
235
|
+
):
|
|
236
|
+
msg = (
|
|
237
|
+
f"{self.key}: fallback_env_vars must be a tuple of non-empty "
|
|
238
|
+
f"strings, got {self.fallback_env_vars!r}"
|
|
239
|
+
)
|
|
240
|
+
raise TypeError(msg)
|
|
241
|
+
|
|
213
242
|
default = self.default
|
|
214
243
|
if default is None:
|
|
215
244
|
if self.invert_toml_bool:
|
|
@@ -498,27 +527,40 @@ def resolve_scalar(
|
|
|
498
527
|
option: The option to resolve.
|
|
499
528
|
toml_data: Parsed `config.toml` mapping (see `load_config_toml`).
|
|
500
529
|
|
|
530
|
+
Resolution order is: the prefixed primary `env_var`, then each
|
|
531
|
+
`fallback_env_vars` name in declaration order, then `config.toml`, then the
|
|
532
|
+
typed `default`.
|
|
533
|
+
|
|
501
534
|
Returns:
|
|
502
535
|
`(value, source)`, where `source` is `env (<name>)`, `config.toml`, or
|
|
503
536
|
`default`. A malformed `int`/`float`/list/PTC value, an unrecognized
|
|
504
537
|
boolean token, or any TOML value of the wrong type is logged and skipped
|
|
505
538
|
so the next layer (or the typed default) applies. An empty env value is
|
|
506
539
|
treated as unset (mirroring `resolve_env_var`), so it falls through to
|
|
507
|
-
`config.toml`/`default
|
|
508
|
-
(`THEME_DELEGATE`) reports its own richer
|
|
540
|
+
the next env var, then `config.toml`/`default`, rather than counting as
|
|
541
|
+
set. Theme resolution (`THEME_DELEGATE`) reports its own richer
|
|
542
|
+
`config.toml [ui.*]` sources.
|
|
509
543
|
"""
|
|
510
544
|
if option.kind is OptionKind.THEME_DELEGATE:
|
|
511
545
|
return _resolve_theme(toml_data)
|
|
512
546
|
|
|
513
|
-
if option.env_var:
|
|
547
|
+
if option.env_var or option.fallback_env_vars:
|
|
514
548
|
from deepagents_code.model_config import resolved_env_var_name
|
|
515
549
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
550
|
+
names: list[str] = []
|
|
551
|
+
if option.env_var:
|
|
552
|
+
names.append(resolved_env_var_name(option.env_var))
|
|
553
|
+
names.extend(option.fallback_env_vars)
|
|
554
|
+
# An empty string counts as unset, matching `resolve_env_var`, so it is
|
|
555
|
+
# skipped and the loop continues to the next name. This keeps
|
|
556
|
+
# `config show`/`get` aligned with what the runtime reads: e.g. an empty
|
|
557
|
+
# prefixed `DEEPAGENTS_CODE_LANGSMITH_PROJECT` falls through to a bare
|
|
558
|
+
# `LANGSMITH_PROJECT`, mirroring `get_langsmith_project_name`. Names are
|
|
559
|
+
# tried in order, so the primary `env_var` wins over any fallback.
|
|
560
|
+
for name in names:
|
|
561
|
+
raw = os.environ.get(name)
|
|
562
|
+
if not raw:
|
|
563
|
+
continue
|
|
522
564
|
value = _coerce_env(option, raw, name)
|
|
523
565
|
if value is not _INVALID:
|
|
524
566
|
return value, f"env ({name})"
|
|
@@ -819,7 +861,9 @@ _STATIC_OPTIONS: tuple[ConfigOption, ...] = (
|
|
|
819
861
|
group="Models",
|
|
820
862
|
summary="LangSmith project name for deepagents agent traces.",
|
|
821
863
|
kind=OptionKind.STR,
|
|
864
|
+
default=LANGSMITH_PROJECT_DEFAULT,
|
|
822
865
|
env_var=_env_vars.LANGSMITH_PROJECT,
|
|
866
|
+
fallback_env_vars=("LANGSMITH_PROJECT",),
|
|
823
867
|
settings_field="deepagents_langchain_project",
|
|
824
868
|
),
|
|
825
869
|
ConfigOption(
|
|
@@ -704,13 +704,15 @@ def build_missing_tool_notification(tool: str) -> "PendingNotification":
|
|
|
704
704
|
key="dep:tavily",
|
|
705
705
|
title="Web search disabled",
|
|
706
706
|
body=(
|
|
707
|
-
"
|
|
708
|
-
"
|
|
707
|
+
"No Tavily API key is set, so web search is disabled.\n\n"
|
|
708
|
+
"Enter a key to store it (takes effect next launch), or get one "
|
|
709
|
+
"at https://tavily.com"
|
|
709
710
|
),
|
|
710
711
|
actions=(
|
|
711
712
|
NotificationAction(
|
|
712
|
-
ActionId.
|
|
713
|
+
ActionId.ENTER_API_KEY, "Enter API key", primary=True
|
|
713
714
|
),
|
|
715
|
+
NotificationAction(ActionId.OPEN_WEBSITE, "Open tavily.com"),
|
|
714
716
|
suppress_action,
|
|
715
717
|
),
|
|
716
718
|
payload=MissingDepPayload(tool="tavily", url="https://tavily.com"),
|