deepagents-code 0.1.53__tar.gz → 0.1.54__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.53 → deepagents_code-0.1.54}/CHANGELOG.md +13 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/PKG-INFO +3 -3
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_constants.py +10 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_textual_patches.py +55 -2
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/app.py +122 -16
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/app.tcss +21 -16
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/non_interactive.py +21 -2
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/config.py +7 -9
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/config_manifest.py +27 -1
- deepagents_code-0.1.54/deepagents_code/diff_utils.py +222 -0
- deepagents_code-0.1.54/deepagents_code/file_ops.py +1062 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/__init__.py +13 -1
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/legacy.py +6 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/loading.py +11 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/migration.py +6 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/server_middleware.py +220 -27
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/model_config.py +37 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/textual_adapter.py +138 -6
- deepagents_code-0.1.54/deepagents_code/tui/widgets/diff.py +686 -0
- deepagents_code-0.1.54/deepagents_code/tui/widgets/install_confirm.py +388 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/message_store.py +90 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/messages.py +447 -77
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/model_selector.py +1 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/tool_renderers.py +101 -10
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/tool_widgets.py +54 -101
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/update_check.py +14 -3
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/pyproject.toml +29 -4
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/scripts/install.sh +548 -56
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_auto_approve_remote.py +2 -1
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/conftest.py +10 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_server_lifecycle.py +101 -1
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_app.py +364 -3
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_charset.py +5 -19
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_config_manifest.py +31 -0
- deepagents_code-0.1.54/tests/unit_tests/test_diff_utils.py +242 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_exception_handling.py +22 -6
- deepagents_code-0.1.54/tests/unit_tests/test_file_ops.py +1136 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_install_script.py +2120 -238
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_model_config.py +76 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_non_interactive.py +97 -4
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_textual_patches.py +95 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/test_textual_adapter.py +829 -59
- deepagents_code-0.1.54/tests/unit_tests/tui/widgets/test_diff.py +766 -0
- deepagents_code-0.1.54/tests/unit_tests/tui/widgets/test_install_confirm.py +395 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_message_store.py +243 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_messages.py +267 -6
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_model_selector.py +1 -0
- deepagents_code-0.1.54/tests/unit_tests/tui/widgets/test_tool_renderers.py +642 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/uv.lock +10 -10
- deepagents_code-0.1.53/deepagents_code/file_ops.py +0 -576
- deepagents_code-0.1.53/deepagents_code/tui/widgets/diff.py +0 -252
- deepagents_code-0.1.53/deepagents_code/tui/widgets/install_confirm.py +0 -248
- deepagents_code-0.1.53/tests/unit_tests/test_file_ops.py +0 -277
- deepagents_code-0.1.53/tests/unit_tests/tui/widgets/test_diff.py +0 -140
- deepagents_code-0.1.53/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -167
- deepagents_code-0.1.53/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -216
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/.gitignore +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/AGENTS.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/COMMANDS.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/HOOKS.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/LICENSE +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/Makefile +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/PRICING.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/README.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_debug_buffer.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_env_vars.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_fake_models.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_glm_5p2_profile.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_invocation.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_markdown.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_repository_bounds.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/_tool_stream.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/agent.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/auto_mode.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/deepagents-thread-inspector/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/deepagents-thread-inspector/scripts/inspect_sessions.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/bundled_prices.README.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/bundled_prices.json +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/commands/auth.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/commands/config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/commands/extras.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/commands/mcp.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/commands/tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/launch/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/launch/server.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/launch/server_manager.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/client/remote_client.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/cost_tracking.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/goal_state_notice.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/capabilities.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/client.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/client_lifecycle.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/context.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/engine.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/env.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/envelope.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/interrupt.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/manager.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/models/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/models/adapters.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/models/config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/models/domain.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/models/transport.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/models/wire.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/permissions.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/presenter.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/projection.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/reducer.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/runner.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/runtime.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/snapshot.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/transcript.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/trust.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/hooks/validate_terminal_sequence.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/json_types.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/main.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/offload_middleware.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/paste_collapse.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/_json.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/adapters/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/adapters/hooks.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/adapters/mcp.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/adapters/skills.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/adapters/skills_middleware.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/commands_cli.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/discovery.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/manifest.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/marketplace.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/models.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/store.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/plugins/substitution.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/reasoning_effort.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/reliable_rubric.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/skills/merge.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/skills/trust.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tool_catalog.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/plugin_manager/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/plugin_manager/content.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/plugin_manager/models.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/plugin_manager/plugin_manager.tcss +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/plugin_manager/state.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/plugin_manager/tabs.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/modals/resume_compact.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/screens/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/_copy_spans.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/_inline_prompt.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/_links.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/_paste_textarea.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/approval.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/auth.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/auto_mode_notice.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/chat_input.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/debug_console.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/goal_review.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/goal_status.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/history.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/loading.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/plugin_reload.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/skill_trust.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/startup_tip.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/status.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/subagent_panel.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/thread_agent_switch.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/update_available.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/welcome.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/tui/widgets/yolo_mode_notice.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/hatch_build.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/images/tui.png +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/README.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/benchmarks/test_local_context_benchmarks.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_goal_criteria_remote.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_offload_server_side.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/client/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/client/commands/test_auth.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/client/commands/test_extras.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/client/commands/test_mcp.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/client/commands/test_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/models/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/models/test_models.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_client_lifecycle.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_configuration.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_engine.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_execution.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_manager.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_presenter.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_transcript.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/hooks/test_trust.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/plugins/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/plugins/test_marketplace.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/plugins/test_plugin_hooks.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/plugins/test_plugins_p0.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/plugins/test_store.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/test_merge.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/test_skill_trust.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/skills/test_thread_inspector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/smoke_tests/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/smoke_tests/conftest.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test__tool_stream.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_ask_user_types.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_auto_mode.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_config_recursion_limit.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_cost_tracking.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_cursor_style.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_debug_buffer.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_debug_console.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_glm_5p2_profile.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_goal_criteria_client.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_goal_state_notice.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_goal_state_persistence.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_invocation.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_json_types.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_mcp_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_reasoning_effort.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_reliable_rubric.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_repository_bounds.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_rubric_cli.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_startup_blocking.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_threads_resume.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_tool_catalog.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_transcript_virtualization.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tools/test_tool_arg_schemas.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/modals/plugin_manager/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/modals/plugin_manager/test_structure.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_approval.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_ask_user.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_auth_widgets.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_auto_mode_notice.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_autocomplete.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_chat_input.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_copy_spans.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_history.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_inline_prompt.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_launch_init.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_links.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_notification_settings.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_plugin_reload.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_status.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_subagent_panel.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_thread_agent_switch.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_thread_selector.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
- {deepagents_code-0.1.53 → deepagents_code-0.1.54}/tests/unit_tests/tui/widgets/test_welcome.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.54](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.53...deepagents-code==0.1.54) (2026-08-07)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- Added Meta `muse-spark-1.2` to the model switcher ([#5389](https://github.com/langchain-ai/deepagents/issues/5389)).
|
|
10
|
+
- Improved diff readability with quieter hunks and word-level highlights ([#5106](https://github.com/langchain-ai/deepagents/issues/5106)).
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- Hid startup tips when resuming threads ([#5349](https://github.com/langchain-ai/deepagents/issues/5349)).
|
|
15
|
+
- Prevented post-tool hook replay ([#5376](https://github.com/langchain-ai/deepagents/issues/5376)).
|
|
16
|
+
- Stored update logs under the OS cache directory ([#5363](https://github.com/langchain-ai/deepagents/issues/5363)).
|
|
17
|
+
|
|
5
18
|
## [0.1.53](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.52...deepagents-code==0.1.53) (2026-08-06)
|
|
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.54
|
|
4
4
|
Summary: Terminal coding agent built on the Deep Agents SDK - works with any model, with persistent memory, customizable skills, subagents, and approval controls.
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
@@ -29,7 +29,7 @@ Requires-Python: <4.0,>=3.11
|
|
|
29
29
|
Requires-Dist: aiosqlite<1.0.0,>=0.22.1
|
|
30
30
|
Requires-Dist: anyio<5.0.0,>=4.14.2
|
|
31
31
|
Requires-Dist: deepagents-acp<1.0.0,>=0.0.9
|
|
32
|
-
Requires-Dist: deepagents==0.7.
|
|
32
|
+
Requires-Dist: deepagents==0.7.5
|
|
33
33
|
Requires-Dist: filelock<3.30,>=3.29.7
|
|
34
34
|
Requires-Dist: genai-prices<0.2.0,>=0.1.1
|
|
35
35
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
@@ -39,7 +39,7 @@ Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.3.0
|
|
|
39
39
|
Requires-Dist: langchain-openai<2.0.0,>=1.4.1
|
|
40
40
|
Requires-Dist: langchain-quickjs<0.4.0,>=0.3.4
|
|
41
41
|
Requires-Dist: langchain<2.0.0,>=1.3.14
|
|
42
|
-
Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.
|
|
42
|
+
Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.1
|
|
43
43
|
Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.31
|
|
44
44
|
Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.31.1
|
|
45
45
|
Requires-Dist: langgraph-sdk<1.0.0,>=0.4.2
|
|
@@ -59,6 +59,16 @@ Set as `MCPServerInfo.error` by `app._apply_optimistic_disabled_state` (alongsid
|
|
|
59
59
|
so the producer and the tests asserting the message share one literal.
|
|
60
60
|
"""
|
|
61
61
|
|
|
62
|
+
FILE_NOT_FOUND: Final[str] = "file_not_found"
|
|
63
|
+
"""Mirror of the SDK's `deepagents.backends.protocol.FILE_NOT_FOUND` sentinel.
|
|
64
|
+
|
|
65
|
+
Hardcoded here rather than imported because `file_ops` is on the TUI import
|
|
66
|
+
path and importing `deepagents` at module scope violates the
|
|
67
|
+
startup-performance rule (see AGENTS.md); this module is dependency-free.
|
|
68
|
+
`test_file_ops.py::test_file_not_found_matches_sdk` is the drift guard that
|
|
69
|
+
fails if the SDK renames the sentinel.
|
|
70
|
+
"""
|
|
71
|
+
|
|
62
72
|
SYSTEM_MESSAGE_PREFIX: Final[str] = "[SYSTEM]"
|
|
63
73
|
"""Prefix for synthetic human messages (e.g. interrupt cancellation notices).
|
|
64
74
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
r"""Runtime patches over Textual internals, imported for side effect.
|
|
2
2
|
|
|
3
|
-
This module hosts
|
|
3
|
+
This module hosts five independent best-effort patches over private Textual
|
|
4
4
|
APIs. Each guards its own import/assignment and degrades to stock Textual
|
|
5
5
|
behavior (logging a warning) if the targeted internals move, so they have
|
|
6
6
|
separate lifecycles — do not delete the whole file when only one lands
|
|
@@ -51,6 +51,15 @@ upstream.
|
|
|
51
51
|
crashes the app with `AttributeError: 'NoneType' object has no attribute
|
|
52
52
|
'region'`. Tracked in Textualize/textual#6643; remove when that lands.
|
|
53
53
|
|
|
54
|
+
5. Diff-gutter exclusion from selections. Textual paints the selection
|
|
55
|
+
highlight from the geometry stored in `Screen.selections`, so excluding
|
|
56
|
+
a diff row's decorative gutter (line number, `+`/`-` marker) only in
|
|
57
|
+
`Widget.get_selection` would copy the right text while still highlighting
|
|
58
|
+
the gutter. The patch rewrites each selection whenever that reactive
|
|
59
|
+
changes, shifting any endpoint inside a row's gutter past it via
|
|
60
|
+
`diff.clamp_selection`. No upstream issue tracks per-widget selection
|
|
61
|
+
masking; it stays until Textual grows one.
|
|
62
|
+
|
|
54
63
|
Imported for side effect from `app.py` before any `App()` is created.
|
|
55
64
|
"""
|
|
56
65
|
|
|
@@ -68,7 +77,7 @@ from textual.geometry import Offset
|
|
|
68
77
|
from textual.selection import Selection
|
|
69
78
|
|
|
70
79
|
if TYPE_CHECKING:
|
|
71
|
-
from collections.abc import Iterable
|
|
80
|
+
from collections.abc import Awaitable, Iterable
|
|
72
81
|
|
|
73
82
|
from textual.events import Click, Event
|
|
74
83
|
from textual.screen import Screen
|
|
@@ -472,3 +481,47 @@ else:
|
|
|
472
481
|
_textual_version,
|
|
473
482
|
exc,
|
|
474
483
|
)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
try:
|
|
487
|
+
from textual.screen import Screen as _ClampScreen
|
|
488
|
+
|
|
489
|
+
from deepagents_code.tui.widgets.diff import clamp_selection
|
|
490
|
+
|
|
491
|
+
_original_watch_selections_for_clamp = _ClampScreen._watch_selections
|
|
492
|
+
except (ImportError, AttributeError) as exc: # pragma: no cover - defensive
|
|
493
|
+
logger.warning(
|
|
494
|
+
"Textual gutter-selection patch skipped (textual %s): %s",
|
|
495
|
+
_textual_version,
|
|
496
|
+
exc,
|
|
497
|
+
)
|
|
498
|
+
else:
|
|
499
|
+
|
|
500
|
+
def _watch_selections_with_gutter_clamp(
|
|
501
|
+
self: Screen,
|
|
502
|
+
old_selections: dict[Widget, Selection],
|
|
503
|
+
selections: dict[Widget, Selection],
|
|
504
|
+
) -> Awaitable[None] | None:
|
|
505
|
+
# Textual stores the new dict before invoking this watcher. Clamp that
|
|
506
|
+
# object synchronously before returning the original watcher's awaitable;
|
|
507
|
+
# assigning `self.selections` here would schedule this watcher again.
|
|
508
|
+
for widget, selection in list(selections.items()):
|
|
509
|
+
clamped = clamp_selection(widget, selection)
|
|
510
|
+
if clamped is None:
|
|
511
|
+
del selections[widget]
|
|
512
|
+
elif clamped != selection:
|
|
513
|
+
selections[widget] = clamped
|
|
514
|
+
|
|
515
|
+
result = _original_watch_selections_for_clamp(self, old_selections, selections)
|
|
516
|
+
# `_watch_selections` is async in the pinned Textual; the isawaitable
|
|
517
|
+
# guard tolerates a future synchronous implementation.
|
|
518
|
+
return result if isawaitable(result) else None
|
|
519
|
+
|
|
520
|
+
try:
|
|
521
|
+
_ClampScreen._watch_selections = _watch_selections_with_gutter_clamp # ty: ignore[invalid-assignment]
|
|
522
|
+
except (AttributeError, TypeError) as exc: # pragma: no cover - defensive
|
|
523
|
+
logger.warning(
|
|
524
|
+
"Textual gutter-selection patch assignment rejected (textual %s): %s",
|
|
525
|
+
_textual_version,
|
|
526
|
+
exc,
|
|
527
|
+
)
|
|
@@ -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.54" # 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."""
|
|
@@ -220,13 +220,20 @@ deadlock detector when two threads cold-import overlapping modules.
|
|
|
220
220
|
"""
|
|
221
221
|
|
|
222
222
|
_TOOL_GROUP_EXCLUSIONS = frozenset({"ask_user", "edit_file", "write_todos"})
|
|
223
|
-
"""Tools
|
|
224
|
-
|
|
225
|
-
Each surfaces user-facing content worth keeping visible on its own —
|
|
226
|
-
interactive prompt (`ask_user`)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
223
|
+
"""Tools kept out of the collapsing step summaries.
|
|
224
|
+
|
|
225
|
+
Each named tool surfaces user-facing content worth keeping visible on its own —
|
|
226
|
+
an interactive prompt (`ask_user`) or a todo list (`write_todos`) — so it renders
|
|
227
|
+
standalone and acts as a boundary between adjacent tool groups. Add a tool here
|
|
228
|
+
only when its collapsed one-line summary would hide something the user needs to
|
|
229
|
+
see.
|
|
230
|
+
|
|
231
|
+
`edit_file` is here because its successful row hides itself in favour of the
|
|
232
|
+
`DiffMessage` that replaces it. The group-reveal paths do consult
|
|
233
|
+
`has_own_hide_reason`, so a groupable superseded row would stay hidden — but the
|
|
234
|
+
group summary would still count and phrase a row the user cannot see, and one
|
|
235
|
+
`display` flag with two independent owners is a standing hazard even when both
|
|
236
|
+
currently agree.
|
|
230
237
|
"""
|
|
231
238
|
|
|
232
239
|
_MESSAGE_TIMESTAMP_FOOTER_CLASS = "message-timestamp-footer"
|
|
@@ -3172,6 +3179,15 @@ class DeepAgentsApp(App):
|
|
|
3172
3179
|
during background startup.
|
|
3173
3180
|
"""
|
|
3174
3181
|
self._initial_resume_requested = resume_thread is not None
|
|
3182
|
+
"""Whether `-r` resume is still in play.
|
|
3183
|
+
|
|
3184
|
+
Gates the startup tip out of `compose`. Every fallback branch of
|
|
3185
|
+
`_resolve_resume_thread` clears this, which is the signal
|
|
3186
|
+
`_restore_startup_tip_after_resume_fallback` uses to mount the tip.
|
|
3187
|
+
"""
|
|
3188
|
+
|
|
3189
|
+
self._startup_tip_dismissed = False
|
|
3190
|
+
"""Whether the startup tip has been dismissed and must not be remounted."""
|
|
3175
3191
|
|
|
3176
3192
|
self._resume_thread_resolved_event = asyncio.Event()
|
|
3177
3193
|
"""Set once `-r` resume resolution has completed or is unnecessary."""
|
|
@@ -4191,7 +4207,7 @@ class DeepAgentsApp(App):
|
|
|
4191
4207
|
# until the first spawn event; sits at the top of the bottom
|
|
4192
4208
|
# container, above the startup tip and input.
|
|
4193
4209
|
yield SubagentPanel(id="subagent-panel")
|
|
4194
|
-
if show_startup_tip():
|
|
4210
|
+
if not self._initial_resume_requested and show_startup_tip():
|
|
4195
4211
|
yield StartupTip(id="startup-tip")
|
|
4196
4212
|
yield GoalStatusPanel(id="goal-status-panel")
|
|
4197
4213
|
yield ChatInput(
|
|
@@ -5317,7 +5333,15 @@ class DeepAgentsApp(App):
|
|
|
5317
5333
|
# it constructs the state.
|
|
5318
5334
|
if self._session_state:
|
|
5319
5335
|
self._session_state.thread_id = self._lc_thread_id
|
|
5336
|
+
# Signal before restoring the tip: resolution is complete at this
|
|
5337
|
+
# point, and the tip is cosmetic follow-up work. Awaiting it first
|
|
5338
|
+
# would let a mount failure skip `set()` and strand every waiter
|
|
5339
|
+
# (`_write_launch_name_memory`), hanging onboarding.
|
|
5320
5340
|
self._resume_thread_resolved_event.set()
|
|
5341
|
+
try:
|
|
5342
|
+
await self._restore_startup_tip_after_resume_fallback()
|
|
5343
|
+
except Exception:
|
|
5344
|
+
logger.exception("Failed to restore startup tip after resume fallback")
|
|
5321
5345
|
|
|
5322
5346
|
async def _start_server_background(self) -> None:
|
|
5323
5347
|
"""Background worker: resolve resume-thread intent, start server + MCP preload.
|
|
@@ -7990,6 +8014,7 @@ class DeepAgentsApp(App):
|
|
|
7990
8014
|
footer = self._build_message_timestamp_footer(
|
|
7991
8015
|
msg_data, visible=self._message_timestamps_visible
|
|
7992
8016
|
)
|
|
8017
|
+
self._link_message_timestamp_footer(widget, footer)
|
|
7993
8018
|
nodes: list[Widget] = [widget]
|
|
7994
8019
|
if footer is not None:
|
|
7995
8020
|
nodes.append(footer)
|
|
@@ -8060,6 +8085,7 @@ class DeepAgentsApp(App):
|
|
|
8060
8085
|
footer = self._build_message_timestamp_footer(
|
|
8061
8086
|
msg_data, visible=self._message_timestamps_visible
|
|
8062
8087
|
)
|
|
8088
|
+
self._link_message_timestamp_footer(widget, footer)
|
|
8063
8089
|
nodes = [widget]
|
|
8064
8090
|
if footer is not None:
|
|
8065
8091
|
nodes.append(footer)
|
|
@@ -10336,16 +10362,61 @@ class DeepAgentsApp(App):
|
|
|
10336
10362
|
|
|
10337
10363
|
await self._submit_input(value, mode)
|
|
10338
10364
|
|
|
10365
|
+
async def _restore_startup_tip_after_resume_fallback(self) -> None:
|
|
10366
|
+
"""Mount a startup tip when resume resolution starts a fresh session.
|
|
10367
|
+
|
|
10368
|
+
`compose` skips the tip whenever `-r` was passed, so a resume that falls
|
|
10369
|
+
back to a fresh thread has to mount it after the fact. Every fallback
|
|
10370
|
+
branch of `_resolve_resume_thread` clears `_initial_resume_requested`
|
|
10371
|
+
before the `finally` block calls this, so a flag that is still set means
|
|
10372
|
+
the resume succeeded and no tip is wanted.
|
|
10373
|
+
|
|
10374
|
+
An initial submission owns the fresh session's startup flow and
|
|
10375
|
+
dismisses the tip before it is sent, so do not remount the tip while
|
|
10376
|
+
that submission is pending.
|
|
10377
|
+
"""
|
|
10378
|
+
if (
|
|
10379
|
+
self._initial_resume_requested
|
|
10380
|
+
or self._startup_tip_dismissed
|
|
10381
|
+
or self._has_initial_submission()
|
|
10382
|
+
or not show_startup_tip()
|
|
10383
|
+
or self.query(StartupTip)
|
|
10384
|
+
):
|
|
10385
|
+
return
|
|
10386
|
+
|
|
10387
|
+
# Only the lookups can raise `NoMatches`, and both widgets are composed
|
|
10388
|
+
# unconditionally — a miss means the bottom chrome was restructured, not
|
|
10389
|
+
# an expected transient state, so log it rather than vanishing silently.
|
|
10390
|
+
try:
|
|
10391
|
+
bottom = self.query_one("#bottom-app-container", _BottomChrome)
|
|
10392
|
+
goal = self.query_one("#goal-status-panel", GoalStatusPanel)
|
|
10393
|
+
except NoMatches:
|
|
10394
|
+
logger.warning(
|
|
10395
|
+
"Bottom chrome or goal panel missing; skipping startup tip restore"
|
|
10396
|
+
)
|
|
10397
|
+
return
|
|
10398
|
+
|
|
10399
|
+
# `mount` registers the widget synchronously before it suspends, so a
|
|
10400
|
+
# dismissal landing during this await finds the tip and removes it
|
|
10401
|
+
# itself — no post-mount re-check is needed.
|
|
10402
|
+
await bottom.mount(StartupTip(id="startup-tip"), before=goal)
|
|
10403
|
+
|
|
10339
10404
|
async def _dismiss_startup_tip(self) -> None:
|
|
10340
|
-
"""
|
|
10405
|
+
"""End the startup tip's lifetime: remove it, and block any remount.
|
|
10341
10406
|
|
|
10342
10407
|
Called from both submission entry points: `_submit_input` (the shared
|
|
10343
10408
|
interactive/external path) and `_submit_initial_submission` (the
|
|
10344
10409
|
`-m`/`--skill`/`--goal` startup path, which submits without going
|
|
10345
|
-
through `_submit_input`)
|
|
10346
|
-
the
|
|
10347
|
-
|
|
10410
|
+
through `_submit_input`), plus `_show_initial_prompt_as_queued` when it
|
|
10411
|
+
mounts the `-m` placeholder ahead of the real submission.
|
|
10412
|
+
|
|
10413
|
+
Latching `_startup_tip_dismissed` matters even when no tip is mounted:
|
|
10414
|
+
under `-r` the tip is skipped in `compose`, and the flag is what stops
|
|
10415
|
+
`_restore_startup_tip_after_resume_fallback` from mounting one after a
|
|
10416
|
+
fallback. Repeat calls are idempotent — the flag is already set and
|
|
10417
|
+
`query_one` raises `NoMatches` for the missing widget.
|
|
10348
10418
|
"""
|
|
10419
|
+
self._startup_tip_dismissed = True
|
|
10349
10420
|
with suppress(NoMatches):
|
|
10350
10421
|
await self.query_one("#startup-tip", StartupTip).remove()
|
|
10351
10422
|
|
|
@@ -16907,6 +16978,7 @@ class DeepAgentsApp(App):
|
|
|
16907
16978
|
msg_data, visible=self._message_timestamps_visible
|
|
16908
16979
|
)
|
|
16909
16980
|
if footer is not None:
|
|
16981
|
+
self._link_message_timestamp_footer(widget, footer)
|
|
16910
16982
|
nodes.append(footer)
|
|
16911
16983
|
if nodes:
|
|
16912
16984
|
await self._mount_transcript_nodes(messages_container, nodes)
|
|
@@ -16995,6 +17067,16 @@ class DeepAgentsApp(App):
|
|
|
16995
17067
|
classes=classes,
|
|
16996
17068
|
)
|
|
16997
17069
|
|
|
17070
|
+
@staticmethod
|
|
17071
|
+
def _link_message_timestamp_footer(widget: Widget, footer: Static | None) -> None:
|
|
17072
|
+
"""Make a tool footer follow its owning row's visibility.
|
|
17073
|
+
|
|
17074
|
+
A no-op when there is no footer or the row is not a `ToolCallMessage`,
|
|
17075
|
+
which is why most call sites can invoke it unconditionally.
|
|
17076
|
+
"""
|
|
17077
|
+
if footer is not None and isinstance(widget, ToolCallMessage):
|
|
17078
|
+
widget._register_visibility_accessories(footer)
|
|
17079
|
+
|
|
16998
17080
|
def _sync_message_timestamps_display(self) -> None:
|
|
16999
17081
|
"""Apply the current visibility to every mounted timestamp footer.
|
|
17000
17082
|
|
|
@@ -17094,7 +17176,7 @@ class DeepAgentsApp(App):
|
|
|
17094
17176
|
async def _mount_message(
|
|
17095
17177
|
self,
|
|
17096
17178
|
widget: Static | AssistantMessage | ToolCallMessage | SkillMessage,
|
|
17097
|
-
) ->
|
|
17179
|
+
) -> bool:
|
|
17098
17180
|
"""Mount a message widget to the messages area.
|
|
17099
17181
|
|
|
17100
17182
|
This method also stores the message data and handles pruning
|
|
@@ -17106,17 +17188,23 @@ class DeepAgentsApp(App):
|
|
|
17106
17188
|
|
|
17107
17189
|
Args:
|
|
17108
17190
|
widget: The message widget to mount
|
|
17191
|
+
|
|
17192
|
+
Returns:
|
|
17193
|
+
Whether the widget reached the screen. Callers that treat a mounted
|
|
17194
|
+
widget as having delivered something the user must see — a display
|
|
17195
|
+
caveat, in particular — have to distinguish this from the silent
|
|
17196
|
+
teardown skips, or they credit a surface that never rendered.
|
|
17109
17197
|
"""
|
|
17110
17198
|
try:
|
|
17111
17199
|
messages = self.query_one("#messages", Container)
|
|
17112
17200
|
except NoMatches:
|
|
17113
|
-
return
|
|
17201
|
+
return False
|
|
17114
17202
|
|
|
17115
17203
|
# During shutdown (e.g. Ctrl+D mid-stream) the container may still
|
|
17116
17204
|
# be in the DOM tree but already detached, so mount() would raise
|
|
17117
17205
|
# MountError. Bail out silently — the app is exiting anyway.
|
|
17118
17206
|
if not messages.is_attached:
|
|
17119
|
-
return
|
|
17207
|
+
return False
|
|
17120
17208
|
|
|
17121
17209
|
if isinstance(widget, QueuedUserMessage):
|
|
17122
17210
|
# Queued placeholders mount at the bottom and stay out of the
|
|
@@ -17127,7 +17215,7 @@ class DeepAgentsApp(App):
|
|
|
17127
17215
|
input_container.scroll_visible()
|
|
17128
17216
|
except NoMatches:
|
|
17129
17217
|
pass
|
|
17130
|
-
return
|
|
17218
|
+
return True
|
|
17131
17219
|
|
|
17132
17220
|
await self._ensure_transcript_spacers(messages)
|
|
17133
17221
|
await self._hydrate_all_messages_below()
|
|
@@ -17155,6 +17243,7 @@ class DeepAgentsApp(App):
|
|
|
17155
17243
|
footer = self._build_message_timestamp_footer(
|
|
17156
17244
|
message_data, visible=self._message_timestamps_visible
|
|
17157
17245
|
)
|
|
17246
|
+
self._link_message_timestamp_footer(widget, footer)
|
|
17158
17247
|
|
|
17159
17248
|
# Coalesce the whole mount-and-fold sequence into a single repaint.
|
|
17160
17249
|
# Otherwise mounting a groupable tool paints it at full height, then
|
|
@@ -17204,6 +17293,8 @@ class DeepAgentsApp(App):
|
|
|
17204
17293
|
except NoMatches:
|
|
17205
17294
|
pass
|
|
17206
17295
|
|
|
17296
|
+
return True
|
|
17297
|
+
|
|
17207
17298
|
async def _hydrate_all_messages_below(self) -> None:
|
|
17208
17299
|
"""Mount any hidden tail before appending fresh transcript output."""
|
|
17209
17300
|
while self._message_store.has_messages_below:
|
|
@@ -17389,6 +17480,13 @@ class DeepAgentsApp(App):
|
|
|
17389
17480
|
groupable = (
|
|
17390
17481
|
child.tool_name not in _TOOL_GROUP_EXCLUSIONS
|
|
17391
17482
|
and child.is_success
|
|
17483
|
+
# A caveat is carried in the row's own output and the
|
|
17484
|
+
# summary line is built from tool names, so folding one
|
|
17485
|
+
# would summarize away the only statement that the
|
|
17486
|
+
# change could not be shown. The live path evicts these
|
|
17487
|
+
# (`_evict_unfoldable`); a rehydrated transcript has to
|
|
17488
|
+
# not fold them in the first place.
|
|
17489
|
+
and not child.has_display_caveat
|
|
17392
17490
|
and not child.has_class("-grouped")
|
|
17393
17491
|
)
|
|
17394
17492
|
if not groupable:
|
|
@@ -17509,6 +17607,14 @@ class DeepAgentsApp(App):
|
|
|
17509
17607
|
tool_duration=data.tool_duration,
|
|
17510
17608
|
tool_expanded=data.tool_expanded,
|
|
17511
17609
|
tool_reject_reason=data.tool_reject_reason,
|
|
17610
|
+
# Set after the row is first stored, when its diff mounts. Without
|
|
17611
|
+
# it the store keeps the mount-time `False` and rehydration
|
|
17612
|
+
# resurrects the row next to the diff that replaced it.
|
|
17613
|
+
tool_diff_superseded=data.tool_diff_superseded,
|
|
17614
|
+
# The display caveat can arrive after the initial mount when a
|
|
17615
|
+
# file change cannot be rendered. Keep it through virtualization
|
|
17616
|
+
# so hydration does not fold away the warning.
|
|
17617
|
+
tool_display_caveat=data.tool_display_caveat,
|
|
17512
17618
|
)
|
|
17513
17619
|
if data.tool_status in {ToolStatus.PENDING, ToolStatus.RUNNING}:
|
|
17514
17620
|
self._message_store.protect_message(widget.id)
|
|
@@ -41,7 +41,8 @@ Screen {
|
|
|
41
41
|
|
|
42
42
|
/*
|
|
43
43
|
* Hide a footer whose owning row is hidden — folded into a collapsed tool
|
|
44
|
-
* group,
|
|
44
|
+
* group, replaced by an approval prompt, or superseded by the diff that took
|
|
45
|
+
* the row's place.
|
|
45
46
|
*
|
|
46
47
|
* Must stay *below* the `-visible` rule above: both selectors are two classes,
|
|
47
48
|
* so Textual breaks the specificity tie by source order and the later rule
|
|
@@ -49,11 +50,13 @@ Screen {
|
|
|
49
50
|
*
|
|
50
51
|
* These hide via a class rather than by assigning `display` so the footer keeps
|
|
51
52
|
* its own `-visible` class and returns to the `/timestamps` preference once the
|
|
52
|
-
* row comes back.
|
|
53
|
-
* at once, and releasing one must not reveal it
|
|
53
|
+
* row comes back. One class per reason, never a shared one: a footer can be
|
|
54
|
+
* hidden for more than one reason at once, and releasing one must not reveal it
|
|
55
|
+
* while another still applies.
|
|
54
56
|
*/
|
|
55
57
|
.message-timestamp-footer.-tool-group-collapsed-accessory,
|
|
56
|
-
.message-timestamp-footer.-tool-awaiting-approval-accessory
|
|
58
|
+
.message-timestamp-footer.-tool-awaiting-approval-accessory,
|
|
59
|
+
.message-timestamp-footer.-tool-superseded-accessory {
|
|
57
60
|
display: none;
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -156,34 +159,36 @@ Screen {
|
|
|
156
159
|
color: $text-muted;
|
|
157
160
|
}
|
|
158
161
|
|
|
159
|
-
/* Diff styling — used by EditFileApprovalWidget
|
|
162
|
+
/* Diff styling — used by EditFileApprovalWidget._render_string_lines
|
|
163
|
+
(fg + bg + padding) */
|
|
160
164
|
.diff-removed {
|
|
161
165
|
height: auto;
|
|
162
166
|
color: $text-error;
|
|
163
|
-
background: $error
|
|
167
|
+
background: $error 10%;
|
|
164
168
|
padding: 0 1;
|
|
165
169
|
}
|
|
166
170
|
|
|
167
171
|
.diff-added {
|
|
168
172
|
height: auto;
|
|
169
173
|
color: $text-success;
|
|
170
|
-
background: $success
|
|
174
|
+
background: $success 10%;
|
|
171
175
|
padding: 0 1;
|
|
172
176
|
}
|
|
173
177
|
|
|
174
|
-
.
|
|
175
|
-
|
|
176
|
-
color: $text-muted;
|
|
177
|
-
padding: 0 1;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/* Diff line backgrounds — used by compose_diff_lines (bg only, fg via Content) */
|
|
178
|
+
/* Diff row styling — used by compose_diff_lines.
|
|
179
|
+
Row backgrounds set bg only; fg comes from Content. */
|
|
181
180
|
.diff-line-removed {
|
|
182
|
-
background: $error
|
|
181
|
+
background: $error 10%;
|
|
183
182
|
}
|
|
184
183
|
|
|
185
184
|
.diff-line-added {
|
|
186
|
-
background: $success
|
|
185
|
+
background: $success 10%;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Hunk separator: a centered glyph, not a tinted row — no background. */
|
|
189
|
+
.diff-hunk-break {
|
|
190
|
+
width: 1fr;
|
|
191
|
+
text-align: center;
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
/* Mode-specific borders for UserMessage */
|
|
@@ -70,7 +70,7 @@ from deepagents_code.config import (
|
|
|
70
70
|
is_shell_command_allowed,
|
|
71
71
|
settings,
|
|
72
72
|
)
|
|
73
|
-
from deepagents_code.file_ops import FileOpTracker
|
|
73
|
+
from deepagents_code.file_ops import FileOpTracker, record_display_caveat
|
|
74
74
|
from deepagents_code.hooks import (
|
|
75
75
|
dispatch_hook,
|
|
76
76
|
dispatch_hook_fire_and_forget,
|
|
@@ -781,7 +781,15 @@ def _process_message_chunk(
|
|
|
781
781
|
else:
|
|
782
782
|
tool_args = {}
|
|
783
783
|
record = file_op_tracker.complete_with_message(message_obj)
|
|
784
|
-
|
|
784
|
+
# Gated on the outcome, not on `record.diff`: two of the four outcomes
|
|
785
|
+
# produce no diff at all (`unreadable_after`, which returns before one is
|
|
786
|
+
# computed, and `terminators_only`, which has none by definition), and
|
|
787
|
+
# neither does a `delete` with a lost pre-image, where both sides are
|
|
788
|
+
# empty. None of those print anything without this. Headless output is
|
|
789
|
+
# what CI reads, so a change that could not be verified has to say so
|
|
790
|
+
# here too rather than only in the TUI.
|
|
791
|
+
caveat = record_display_caveat(record)
|
|
792
|
+
if record and (record.diff or caveat):
|
|
785
793
|
if state.spinner:
|
|
786
794
|
state.spinner.stop()
|
|
787
795
|
if not state.quiet:
|
|
@@ -789,6 +797,17 @@ def _process_message_chunk(
|
|
|
789
797
|
f"[dim]📝 {escape_markup(record.display_path)}[/dim]",
|
|
790
798
|
highlight=False,
|
|
791
799
|
)
|
|
800
|
+
if caveat:
|
|
801
|
+
# Printed even under `--quiet`, which suppresses *diagnostics*;
|
|
802
|
+
# a statement that an operation could not be verified is not
|
|
803
|
+
# one, and dropping it here would leave the caveat existing
|
|
804
|
+
# nowhere. Safe for the mode's contract because quiet already
|
|
805
|
+
# routes `console` to stderr, so this cannot pollute the stdout
|
|
806
|
+
# result that `-p --quiet` exists to keep clean.
|
|
807
|
+
console.print(
|
|
808
|
+
f"[yellow]{escape_markup(caveat)}[/yellow]",
|
|
809
|
+
highlight=False,
|
|
810
|
+
)
|
|
792
811
|
tool_name = getattr(message_obj, "name", "")
|
|
793
812
|
if not tool_name:
|
|
794
813
|
tool_name = correlated_tool_name
|
|
@@ -1340,12 +1340,10 @@ class Glyphs:
|
|
|
1340
1340
|
disclosure_expanded: str # ▾ vs v
|
|
1341
1341
|
|
|
1342
1342
|
# Box-drawing characters
|
|
1343
|
-
box_vertical: str # │ vs |
|
|
1344
1343
|
box_horizontal: str # ─ vs -
|
|
1345
|
-
box_double_horizontal: str # ═ vs =
|
|
1346
1344
|
|
|
1347
1345
|
# Diff-specific
|
|
1348
|
-
|
|
1346
|
+
hunk_break: str # ⋮ vs :
|
|
1349
1347
|
|
|
1350
1348
|
# Status bar
|
|
1351
1349
|
git_branch: str # "↗" vs "git:"
|
|
@@ -1373,10 +1371,10 @@ UNICODE_GLYPHS = Glyphs(
|
|
|
1373
1371
|
disclosure_collapsed="▸",
|
|
1374
1372
|
disclosure_expanded="▾",
|
|
1375
1373
|
# Box-drawing characters
|
|
1376
|
-
box_vertical="│",
|
|
1377
1374
|
box_horizontal="─",
|
|
1378
|
-
|
|
1379
|
-
|
|
1375
|
+
# Diff-specific
|
|
1376
|
+
hunk_break="⋮",
|
|
1377
|
+
# Status bar
|
|
1380
1378
|
git_branch="↗",
|
|
1381
1379
|
)
|
|
1382
1380
|
"""Glyph set for terminals with full Unicode support."""
|
|
@@ -1403,10 +1401,10 @@ ASCII_GLYPHS = Glyphs(
|
|
|
1403
1401
|
disclosure_collapsed=">",
|
|
1404
1402
|
disclosure_expanded="v",
|
|
1405
1403
|
# Box-drawing characters
|
|
1406
|
-
box_vertical="|",
|
|
1407
1404
|
box_horizontal="-",
|
|
1408
|
-
|
|
1409
|
-
|
|
1405
|
+
# Diff-specific
|
|
1406
|
+
hunk_break=":",
|
|
1407
|
+
# Status bar
|
|
1410
1408
|
git_branch="git:",
|
|
1411
1409
|
)
|
|
1412
1410
|
"""Glyph set for terminals limited to 7-bit ASCII."""
|
|
@@ -964,7 +964,13 @@ _PROVIDER_DEPENDENCIES: dict[str, tuple[str, str]] = {
|
|
|
964
964
|
"together": ("langchain_together", "together"),
|
|
965
965
|
"xai": ("langchain_xai", "xai"),
|
|
966
966
|
}
|
|
967
|
-
"""Provider integration import modules and the extras that install them.
|
|
967
|
+
"""Provider integration import modules and the extras that install them.
|
|
968
|
+
|
|
969
|
+
Every import module name here must equal its PyPI distribution name up to
|
|
970
|
+
underscore-for-hyphen substitution -- `provider_package_name` derives the
|
|
971
|
+
distribution from it to build a `pypi.org/project/...` link, and a provider
|
|
972
|
+
whose two names diverge would render a link to a nonexistent project.
|
|
973
|
+
"""
|
|
968
974
|
|
|
969
975
|
|
|
970
976
|
def provider_install_extra(provider: str) -> str | None:
|
|
@@ -982,6 +988,26 @@ def provider_install_extra(provider: str) -> str | None:
|
|
|
982
988
|
return dependency[1] if dependency else None
|
|
983
989
|
|
|
984
990
|
|
|
991
|
+
def provider_package_name(provider: str) -> str | None:
|
|
992
|
+
"""Return the PyPI distribution that provides `provider`, if known.
|
|
993
|
+
|
|
994
|
+
Derived from the provider's integration import module by replacing
|
|
995
|
+
underscores with hyphens (e.g. `langchain_google_genai` ->
|
|
996
|
+
`langchain-google-genai`), which matches the distribution name for every
|
|
997
|
+
curated entry -- see the `_PROVIDER_DEPENDENCIES` docstring. This is not
|
|
998
|
+
PEP 503 normalization, and the result is not validated against PyPI.
|
|
999
|
+
|
|
1000
|
+
Args:
|
|
1001
|
+
provider: Provider name (e.g. `"baseten"`, `"google_genai"`).
|
|
1002
|
+
|
|
1003
|
+
Returns:
|
|
1004
|
+
The distribution name, or `None` when the provider has no curated
|
|
1005
|
+
extra (custom `class_path` providers, ambient-auth providers, etc.).
|
|
1006
|
+
"""
|
|
1007
|
+
dependency = _PROVIDER_DEPENDENCIES.get(provider)
|
|
1008
|
+
return dependency[0].replace("_", "-") if dependency else None
|
|
1009
|
+
|
|
1010
|
+
|
|
985
1011
|
def is_provider_package_installed(provider: str) -> bool:
|
|
986
1012
|
"""Return whether `provider`'s integration package is importable.
|
|
987
1013
|
|