deepagents-code 0.1.70__tar.gz → 0.1.71__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.70 → deepagents_code-0.1.71}/AGENTS.md +1 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/ARCHITECTURE.md +0 -2
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/CHANGELOG.md +15 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/DEVELOPMENT.md +1 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/PKG-INFO +5 -5
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/app.py +32 -5
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/config.py +1 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_auth.py +73 -82
- deepagents_code-0.1.71/deepagents_code/mcp_middleware.py +146 -0
- deepagents_code-0.1.71/deepagents_code/mcp_proxy.py +161 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_tools.py +609 -1110
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/model_config.py +25 -7
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/skills/load.py +1 -1
- deepagents_code-0.1.71/deepagents_code/tui/widgets/_condense_path.py +94 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/chat_input.py +15 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/debug_console.py +6 -6
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/prompt_search.py +2 -1
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/status.py +79 -21
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/pyproject.toml +4 -4
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_app.py +21 -3
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_debug_console.py +17 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_mcp_auth.py +226 -62
- deepagents_code-0.1.71/tests/unit_tests/test_mcp_lifecycle.py +419 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_mcp_oauth_ui.py +26 -17
- deepagents_code-0.1.71/tests/unit_tests/test_mcp_proxy.py +103 -0
- deepagents_code-0.1.71/tests/unit_tests/test_mcp_schema.py +75 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_mcp_tools.py +880 -1813
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_server_graph.py +13 -17
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_chat_input.py +73 -1
- deepagents_code-0.1.71/tests/unit_tests/tui/widgets/test_condense_path.py +123 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +17 -9
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_status.py +66 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/uv.lock +333 -40
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/.gitignore +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/COMMANDS.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/EXTENSIONS.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/HOOKS.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/LICENSE +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/Makefile +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/PRICING.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/README.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_content_blocks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_debug_buffer.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_dep_floor_check.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_env_vars.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_fake_models.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_glm_5p2_profile.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_home_error.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_invocation.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_markdown.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_repository_bounds.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_reserved_names.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_terminal_stderr.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_tool_stream.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/_tracing.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/acp.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/agent.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/auto_mode.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/deepagents-thread-inspector/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/deepagents-thread-inspector/scripts/inspect_sessions.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/bundled_prices.README.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/bundled_prices.json +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/commands/auth.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/commands/config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/commands/extras.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/commands/mcp.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/commands/tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/launch/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/launch/server.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/launch/server_manager.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/non_interactive.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/client/remote_client.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/cold_cache.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/config_manifest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/interpreter.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/paths.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/provider.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/providers.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/resolver.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/service.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/theme_resolution.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/types.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/configuration/writer.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/context_doctor.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/cost_tracking.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/diff_utils.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/api.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/discovery.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/hosting.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/loader.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/registry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/runtime.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/settings.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extensions/trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/goal_state_limits.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/goal_state_notice.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/capabilities.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/client.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/client_lifecycle.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/context.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/engine.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/env.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/envelope.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/interrupt.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/legacy.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/loading.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/manager.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/migration.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/models/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/models/adapters.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/models/config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/models/domain.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/models/transport.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/models/wire.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/permissions.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/presenter.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/projection.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/reducer.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/runner.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/runtime.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/server_middleware.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/snapshot.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/transcript.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/hooks/validate_terminal_sequence.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/json_types.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/main.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/model_retry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/offload_api.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/offload_middleware.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/paste_collapse.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/_json.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/adapters/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/adapters/hooks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/adapters/mcp.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/adapters/skills.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/adapters/skills_middleware.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/commands_cli.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/discovery.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/manifest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/marketplace.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/models.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/store.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/plugins/substitution.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/reasoning_effort.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/reliable_rubric.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/skills/merge.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/skills/trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tool_catalog.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/key_hints.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/cold_cache.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/model_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/plugin_manager/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/plugin_manager/content.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/plugin_manager/models.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/plugin_manager/plugin_manager.tcss +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/plugin_manager/state.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/plugin_manager/tabs.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/prompt_clipboard.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/prompt_clipboard.tcss +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/resume_blocked.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/modals/resume_compact.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/screens/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/textual_adapter.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/_copy_spans.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/_inline_prompt.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/_links.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/_paste_textarea.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/approval.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/auth.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/auto_mode_notice.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/context_usage.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/diff.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/goal_review.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/goal_status.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/history.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/install_confirm.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/loading.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/message_store.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/messages.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/model_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/skill_trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/startup_tip.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/subagent_panel.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/thread_agent_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/update_available.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/welcome.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/tui/widgets/yolo_mode_notice.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/update_check.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/deepagents_code/workspace.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/extensions/memory_store.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/hatch_build.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/images/model-stream-retry.png +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/images/tui.png +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/scripts/check_process_cwd.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/scripts/install.sh +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/README.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/benchmarks/test_local_context_benchmarks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_auto_approve_remote.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_offload_server_side.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_pending_work_recovery.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/client/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/client/commands/test_auth.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/client/commands/test_extras.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/client/commands/test_mcp.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/client/commands/test_tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/models/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/models/test_models.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_client_lifecycle.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_configuration.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_engine.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_execution.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_manager.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_presenter.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_server_lifecycle.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_transcript.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/hooks/test_trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/plugins/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/plugins/test_marketplace.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/plugins/test_plugin_hooks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/plugins/test_plugins_p0.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/test_merge.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/test_skill_trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/skills/test_thread_inspector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/smoke_tests/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/smoke_tests/conftest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test__tool_stream.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_acp.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_ask_user_types.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_auto_mode.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_cli_provider.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_cold_cache.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_config_manifest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_configuration.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_configuration_resolution.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_configuration_resolver.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_context_doctor.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_cost_tracking.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_cursor_style.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_debug_buffer.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_dep_floor_check.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_diff_utils.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_api.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_cli_trust.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_config_manifest.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_discovery.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_display.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_host_runtime.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_hosting.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extension_runtime.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extra_skills_dirs.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_glm_5p2_profile.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_goal_criteria_client.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_goal_state_limits.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_goal_state_notice.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_goal_state_persistence.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_install_script.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_invocation.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_json_types.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_mcp_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_model_retry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_offload_api.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_process_cwd_check.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_reasoning_effort.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_reliable_rubric.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_repository_bounds.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_resume_compaction_recovery.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_rubric_cli.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_server_tracing.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_terminal_stderr.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_threads_resume.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_tool_catalog.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_tracing.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_transcript_virtualization.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_uninstall_command.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/test_workspace.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tools/test_tool_arg_schemas.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tools/test_web_search.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/plugin_manager/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/plugin_manager/test_structure.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/test_cold_cache.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/test_model_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/test_prompt_clipboard.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/modals/test_resume_blocked.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/test_key_hints.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/test_modal_footer_layout.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/test_textual_adapter.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_approval.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_ask_user.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_auth_widgets.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_auto_mode_notice.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_autocomplete.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_copy_spans.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_diff.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_history.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_inline_prompt.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_launch_init.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_links.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_message_store.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_messages.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_model_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_notification_settings.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_prompt_search.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_subagent_panel.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_thread_agent_switch.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_thread_selector.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
- {deepagents_code-0.1.70 → deepagents_code-0.1.71}/tests/unit_tests/tui/widgets/test_welcome.py +0 -0
|
@@ -76,7 +76,7 @@ Apply these rules to new UI; do not treat them as a mandate to refactor existing
|
|
|
76
76
|
### Testing Textual apps
|
|
77
77
|
|
|
78
78
|
- Use `textual.pilot` for async UI testing - see [Testing guide](https://textual.textualize.io/guide/testing/)
|
|
79
|
-
- Snapshot testing available for visual regression
|
|
79
|
+
- Snapshot testing available for visual regression
|
|
80
80
|
- For modal flows, test the real interaction path with keypresses when possible. Unit tests that call action methods or resume handlers directly can miss focus and modal-stack bugs.
|
|
81
81
|
- A modal test that pushes the screen onto a bare `App` host cannot catch app-level key interception. The app owns a priority `shift+tab -> toggle_auto_approve` binding (`app.py`) that wins dispatch over any screen binding; `action_toggle_auto_approve` routes the key to the active screen. Cursor-style modals (highlighted rows, no focusable children) just implement `action_move_up` — the router's `_SupportsReverseNav` protocol branch picks them up automatically. The protocol matches on method *presence*, so enrollment is opt-out, not opt-in: a screen that defines `action_move_up` for its own arrow keys gets `shift+tab` reverse-nav whether or not it was written with that key in mind. Screens needing different behavior (`focus_previous`, tab bars) — or none — need an explicit branch *above* the protocol check in `action_toggle_auto_approve`. Add an app-level regression test in `test_app.py` when a screen needs behavior other than swallowing the key.
|
|
82
82
|
- Do not open another modal or refocus the base chat input directly inside a modal dismiss callback. Preserve the non-blocking `push_screen(..., callback)` flow and schedule follow-up UI work with `call_after_refresh` so the dismissing modal fully unwinds first.
|
|
@@ -85,6 +85,4 @@ The main cost is the client/server boundary. When debugging, first decide which
|
|
|
85
85
|
- For cost estimates and local pricing overrides (`prices.json`), see
|
|
86
86
|
[`PRICING.md`](./PRICING.md).
|
|
87
87
|
- For security boundaries, see [`THREAT_MODEL.md`](./THREAT_MODEL.md).
|
|
88
|
-
- For how a transient model failure is retried after output has already streamed,
|
|
89
|
-
see [`STREAMING_RETRY_DESIGN.md`](./STREAMING_RETRY_DESIGN.md).
|
|
90
88
|
- For package-specific coding conventions, see [`AGENTS.md`](./AGENTS.md).
|
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.71](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.70...deepagents-code==0.1.71) (2026-09-18)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- Moved MCP support onto FastMCP and `langchain.mcp`. ([#5922](https://github.com/langchain-ai/deepagents/pull/5922))
|
|
10
|
+
- Condensed the current working directory in the status bar from the middle, preserving the end of the path. ([#6252](https://github.com/langchain-ai/deepagents/pull/6252))
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- Replaced the composer with prompt search and prevented query feedback. ([#6346](https://github.com/langchain-ai/deepagents/pull/6346))
|
|
15
|
+
- Kept absolute paths intact in normal input mode. ([#6379](https://github.com/langchain-ai/deepagents/pull/6379))
|
|
16
|
+
- Pinned resumed history to the newest message. ([#6225](https://github.com/langchain-ai/deepagents/pull/6225))
|
|
17
|
+
- Improved handling of overflowing pasted content in the chat input so it scrolls correctly. ([#6382](https://github.com/langchain-ai/deepagents/pull/6382))
|
|
18
|
+
- Wrapped debug logs before the scrollbar. ([#6219](https://github.com/langchain-ai/deepagents/pull/6219))
|
|
19
|
+
|
|
5
20
|
## [0.1.70](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.69...deepagents-code==0.1.70) (2026-09-16)
|
|
6
21
|
|
|
7
22
|
### Bug Fixes
|
|
@@ -143,7 +143,7 @@ To send logs elsewhere, also `export DEEPAGENTS_CODE_DEBUG_DIRECTORY=<path>`. Ea
|
|
|
143
143
|
|
|
144
144
|
The directory is created or tightened to owner-only access, and each file is created or tightened to user-only access. Symlinks are refused. If either cannot be secured, no file handler is attached and a warning goes to stderr. Use the in-app Debug Console in that case.
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
Raw stdio MCP server stderr is discarded to protect the TUI and prevent unbounded disk growth, including in debug mode. Structured MCP log notifications still reach the application logger with the server name and severity.
|
|
147
147
|
|
|
148
148
|
### In-app Debug Console (`Ctrl+\`)
|
|
149
149
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.71
|
|
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://www.langchain.com/dcode
|
|
6
6
|
Project-URL: Documentation, https://docs.langchain.com/oss/deepagents/code/overview
|
|
@@ -31,12 +31,12 @@ Requires-Dist: aiosqlite<1.0.0,>=0.22.1
|
|
|
31
31
|
Requires-Dist: anyio<5.0.0,>=4.14.2
|
|
32
32
|
Requires-Dist: deepagents-acp<1.0.0,>=0.0.10
|
|
33
33
|
Requires-Dist: deepagents==0.7.15
|
|
34
|
+
Requires-Dist: fastmcp<5.0.0,>=4.0.0b4
|
|
34
35
|
Requires-Dist: filelock<3.30,>=3.29.7
|
|
35
36
|
Requires-Dist: genai-prices<0.2.0,>=0.1.7
|
|
36
37
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
37
38
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.7.2
|
|
38
39
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.4.0
|
|
39
|
-
Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.3.2
|
|
40
40
|
Requires-Dist: langchain-openai<2.0.0,>=1.6.2
|
|
41
41
|
Requires-Dist: langchain-quickjs<0.4.0,>=0.3.4
|
|
42
42
|
Requires-Dist: langchain<2.0.0,>=1.4.1
|
|
@@ -46,7 +46,7 @@ Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.34.1
|
|
|
46
46
|
Requires-Dist: langgraph-sdk<1.0.0,>=0.4.4
|
|
47
47
|
Requires-Dist: langsmith[sandbox]>=0.12.6
|
|
48
48
|
Requires-Dist: markdownify<2.0.0,>=1.2.3
|
|
49
|
-
Requires-Dist: mcp<
|
|
49
|
+
Requires-Dist: mcp<3.0.0,>=2.0.0
|
|
50
50
|
Requires-Dist: packaging>=26.2
|
|
51
51
|
Requires-Dist: pillow<13.0.0,>=12.3.0
|
|
52
52
|
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.53
|
|
@@ -77,7 +77,7 @@ Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.4; extra == 'all-providers'
|
|
|
77
77
|
Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'all-providers'
|
|
78
78
|
Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
79
79
|
Requires-Dist: langchain-ibm<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
80
|
-
Requires-Dist: langchain-litellm<2.0.0,>=0.7.
|
|
80
|
+
Requires-Dist: langchain-litellm<2.0.0,>=0.7.2; extra == 'all-providers'
|
|
81
81
|
Requires-Dist: langchain-meta<2.0.0,>=0.5.0; extra == 'all-providers'
|
|
82
82
|
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.6; extra == 'all-providers'
|
|
83
83
|
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.4.3; extra == 'all-providers'
|
|
@@ -116,7 +116,7 @@ Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'huggingface'
|
|
|
116
116
|
Provides-Extra: ibm
|
|
117
117
|
Requires-Dist: langchain-ibm<2.0.0,>=1.1.0; extra == 'ibm'
|
|
118
118
|
Provides-Extra: litellm
|
|
119
|
-
Requires-Dist: langchain-litellm<2.0.0,>=0.7.
|
|
119
|
+
Requires-Dist: langchain-litellm<2.0.0,>=0.7.2; extra == 'litellm'
|
|
120
120
|
Provides-Extra: media
|
|
121
121
|
Requires-Dist: av<19.0.0,>=18.0.0; extra == 'media'
|
|
122
122
|
Requires-Dist: pillow<13.0.0,>=12.3.0; extra == 'media'
|
|
@@ -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.71" # 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."""
|
|
@@ -2963,6 +2963,7 @@ class _ChatScroll(VerticalScroll):
|
|
|
2963
2963
|
"""
|
|
2964
2964
|
super().__init__(*args, **kwargs)
|
|
2965
2965
|
self._follow_bottom_when_scrollable = False
|
|
2966
|
+
self._bottom_follow_generation = 0
|
|
2966
2967
|
|
|
2967
2968
|
def anchor(self, anchor: bool = True) -> None:
|
|
2968
2969
|
"""Anchor only once the transcript is tall enough to scroll.
|
|
@@ -2979,6 +2980,8 @@ class _ChatScroll(VerticalScroll):
|
|
|
2979
2980
|
delegate to the base class.
|
|
2980
2981
|
"""
|
|
2981
2982
|
self._follow_bottom_when_scrollable = anchor
|
|
2983
|
+
if anchor:
|
|
2984
|
+
self._bottom_follow_generation += 1
|
|
2982
2985
|
if not anchor:
|
|
2983
2986
|
super().anchor(False)
|
|
2984
2987
|
return
|
|
@@ -4343,6 +4346,9 @@ class DeepAgentsApp(App):
|
|
|
4343
4346
|
self._history_prefetch_active = False
|
|
4344
4347
|
"""Whether resumed history is warming toward the soft window size."""
|
|
4345
4348
|
|
|
4349
|
+
self._history_prefetch_anchor_generation: int | None = None
|
|
4350
|
+
"""Bottom-follow generation owned by resumed-history prefetch."""
|
|
4351
|
+
|
|
4346
4352
|
self._transcript_prune_timer: Timer | None = None
|
|
4347
4353
|
"""Idle timer that defers opposite-edge pruning while scrolling."""
|
|
4348
4354
|
|
|
@@ -9453,7 +9459,7 @@ class DeepAgentsApp(App):
|
|
|
9453
9459
|
self._hydration_scheduled = False
|
|
9454
9460
|
|
|
9455
9461
|
if hydrated_count == 0 and direction == "above":
|
|
9456
|
-
self.
|
|
9462
|
+
self._stop_history_prefetch()
|
|
9457
9463
|
if hydrated_count or self._hydration_requests:
|
|
9458
9464
|
self.call_after_refresh(lambda: self._continue_hydration(direction))
|
|
9459
9465
|
|
|
@@ -9473,7 +9479,7 @@ class DeepAgentsApp(App):
|
|
|
9473
9479
|
):
|
|
9474
9480
|
self._request_hydration("above")
|
|
9475
9481
|
return
|
|
9476
|
-
self.
|
|
9482
|
+
self._stop_history_prefetch()
|
|
9477
9483
|
return
|
|
9478
9484
|
|
|
9479
9485
|
if direction == "above":
|
|
@@ -9487,8 +9493,26 @@ class DeepAgentsApp(App):
|
|
|
9487
9493
|
self._message_store.has_messages_above
|
|
9488
9494
|
and self._message_store.visible_count < self._message_store.WINDOW_SIZE
|
|
9489
9495
|
)
|
|
9490
|
-
if self._history_prefetch_active:
|
|
9491
|
-
|
|
9496
|
+
if not self._history_prefetch_active:
|
|
9497
|
+
return
|
|
9498
|
+
self._history_prefetch_anchor_generation = None
|
|
9499
|
+
with suppress(NoMatches):
|
|
9500
|
+
chat = self.query_one("#chat", _ChatScroll)
|
|
9501
|
+
chat.anchor()
|
|
9502
|
+
self._history_prefetch_anchor_generation = chat._bottom_follow_generation
|
|
9503
|
+
self._request_hydration("above")
|
|
9504
|
+
|
|
9505
|
+
def _stop_history_prefetch(self) -> None:
|
|
9506
|
+
"""End resumed-history warming and its temporary bottom anchor."""
|
|
9507
|
+
if not self._history_prefetch_active:
|
|
9508
|
+
return
|
|
9509
|
+
self._history_prefetch_active = False
|
|
9510
|
+
generation = self._history_prefetch_anchor_generation
|
|
9511
|
+
self._history_prefetch_anchor_generation = None
|
|
9512
|
+
with suppress(NoMatches):
|
|
9513
|
+
chat = self.query_one("#chat", _ChatScroll)
|
|
9514
|
+
if generation == chat._bottom_follow_generation:
|
|
9515
|
+
chat.anchor(False)
|
|
9492
9516
|
|
|
9493
9517
|
def _check_hydration_needed(self) -> None:
|
|
9494
9518
|
"""Prefetch older messages near the mounted-window boundary."""
|
|
@@ -20859,6 +20883,9 @@ class DeepAgentsApp(App):
|
|
|
20859
20883
|
self._pending_shell_messages.clear()
|
|
20860
20884
|
self._hydration_requests.clear()
|
|
20861
20885
|
self._history_prefetch_active = False
|
|
20886
|
+
self._history_prefetch_anchor_generation = None
|
|
20887
|
+
with suppress(NoMatches):
|
|
20888
|
+
self.query_one("#chat", _ChatScroll).anchor(False)
|
|
20862
20889
|
if self._transcript_prune_timer is not None:
|
|
20863
20890
|
self._transcript_prune_timer.stop()
|
|
20864
20891
|
self._transcript_prune_timer = None
|
|
@@ -25188,7 +25215,7 @@ class DeepAgentsApp(App):
|
|
|
25188
25215
|
started_at = self._first_invocation_at
|
|
25189
25216
|
if started_at is None:
|
|
25190
25217
|
return "not started"
|
|
25191
|
-
return format_duration(max(0.0, time.monotonic() - started_at))
|
|
25218
|
+
return format_duration(int(max(0.0, time.monotonic() - started_at)))
|
|
25192
25219
|
|
|
25193
25220
|
def _model_field() -> SnapshotField:
|
|
25194
25221
|
# Built directly (not via `_safe`) so the copyable metadata tracks
|
|
@@ -4817,7 +4817,7 @@ def configure_langsmith_secret_redaction() -> bool:
|
|
|
4817
4817
|
_fail_closed_disable_tracing()
|
|
4818
4818
|
return False
|
|
4819
4819
|
|
|
4820
|
-
logger.
|
|
4820
|
+
logger.debug("LangSmith secret redaction enabled for agent traces.")
|
|
4821
4821
|
return True
|
|
4822
4822
|
|
|
4823
4823
|
|
|
@@ -25,11 +25,12 @@ import secrets
|
|
|
25
25
|
import stat
|
|
26
26
|
import threading
|
|
27
27
|
import time
|
|
28
|
-
from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Callable
|
|
29
|
-
from typing import TYPE_CHECKING, Any, Literal,
|
|
28
|
+
from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Callable, Mapping
|
|
29
|
+
from typing import TYPE_CHECKING, Any, Literal, override
|
|
30
30
|
from urllib.parse import parse_qs, urlparse
|
|
31
31
|
|
|
32
32
|
import httpx
|
|
33
|
+
import httpx2
|
|
33
34
|
from anyio import CancelScope
|
|
34
35
|
from filelock import FileLock, Timeout
|
|
35
36
|
from mcp.client.auth import OAuthClientProvider, TokenStorage
|
|
@@ -40,8 +41,11 @@ from mcp.client.auth.utils import (
|
|
|
40
41
|
handle_auth_metadata_response,
|
|
41
42
|
handle_protected_resource_response,
|
|
42
43
|
)
|
|
43
|
-
from mcp.client.streamable_http import
|
|
44
|
+
from mcp.client.streamable_http import (
|
|
45
|
+
MCP_PROTOCOL_VERSION_HEADER as MCP_PROTOCOL_VERSION,
|
|
46
|
+
)
|
|
44
47
|
from mcp.shared.auth import (
|
|
48
|
+
AuthorizationCodeResult,
|
|
45
49
|
OAuthClientInformationFull,
|
|
46
50
|
OAuthMetadata,
|
|
47
51
|
OAuthToken,
|
|
@@ -56,6 +60,7 @@ if TYPE_CHECKING:
|
|
|
56
60
|
from _thread import LockType
|
|
57
61
|
from pathlib import Path
|
|
58
62
|
|
|
63
|
+
from fastmcp.client.transports import ClientTransport
|
|
59
64
|
from mcp.client.auth.oauth2 import OAuthContext
|
|
60
65
|
|
|
61
66
|
from deepagents_code.mcp_oauth_ui import OAuthInteraction
|
|
@@ -82,39 +87,19 @@ class _DeviceCodeResponse(BaseModel):
|
|
|
82
87
|
"""Recommended polling interval in seconds when the provider omits one."""
|
|
83
88
|
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
All keys are optional at the type level because `mcpServers` entries
|
|
89
|
-
are validated shape-first by `_validate_server_config` rather than by
|
|
90
|
-
the type system. This TypedDict documents the accepted shape for
|
|
91
|
-
readers and static checkers — validate the fields at use sites before
|
|
92
|
-
relying on them.
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
auth: Literal["oauth"]
|
|
96
|
-
"""Authentication mode for remote MCP servers that require OAuth login."""
|
|
97
|
-
|
|
98
|
-
type: Literal["stdio", "http", "sse"]
|
|
99
|
-
"""Transport type when the config uses the `type` key."""
|
|
100
|
-
|
|
101
|
-
transport: Literal["stdio", "http", "sse"]
|
|
102
|
-
"""Transport type when the config uses the `transport` key."""
|
|
103
|
-
|
|
104
|
-
url: str
|
|
105
|
-
"""Remote endpoint URL for HTTP or SSE MCP servers."""
|
|
90
|
+
type McpServerSpec = Mapping[str, Any]
|
|
91
|
+
"""A raw `mcpServers` entry, as it appears in a config file.
|
|
106
92
|
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
Deliberately a mapping rather than one of FastMCP's server models: entries
|
|
94
|
+
reach here straight from JSON and may still carry unresolved `${VAR}`
|
|
95
|
+
references, so they are not yet valid against those models.
|
|
109
96
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
env: dict[str, str]
|
|
117
|
-
"""Environment overrides for launching a stdio MCP server."""
|
|
97
|
+
The accepted fields are FastMCP's, not this app's — `fastmcp.mcp_config`'s
|
|
98
|
+
`StdioMCPServer` and `RemoteMCPServer` define and validate them, and
|
|
99
|
+
`mcp_tools._build_transport` is where an entry is finally checked against
|
|
100
|
+
them. Anything this app adds on top (`allowedTools`, `disabledTools`, and the
|
|
101
|
+
`auth: "oauth"` mode marker) is validated by `_validate_server_config`.
|
|
102
|
+
"""
|
|
118
103
|
|
|
119
104
|
|
|
120
105
|
logger = logging.getLogger(__name__)
|
|
@@ -824,7 +809,7 @@ class _FreshLoginTokenStorage(FileTokenStorage):
|
|
|
824
809
|
|
|
825
810
|
|
|
826
811
|
RedirectHandler = Callable[[str], Awaitable[None]]
|
|
827
|
-
CallbackHandler = Callable[[], Awaitable[
|
|
812
|
+
CallbackHandler = Callable[[], Awaitable[AuthorizationCodeResult]]
|
|
828
813
|
_LOOPBACK_BIND_HOST = "127.0.0.1"
|
|
829
814
|
_LOOPBACK_URI_HOST = "localhost"
|
|
830
815
|
_LOOPBACK_CALLBACK_PATH = "/callback"
|
|
@@ -871,7 +856,7 @@ class _LoopbackOAuthCallbackServer:
|
|
|
871
856
|
self.redirect_uri = (
|
|
872
857
|
f"http://{_LOOPBACK_URI_HOST}:{port}{_LOOPBACK_CALLBACK_PATH}"
|
|
873
858
|
)
|
|
874
|
-
self._future: concurrent.futures.Future[
|
|
859
|
+
self._future: concurrent.futures.Future[AuthorizationCodeResult] = (
|
|
875
860
|
concurrent.futures.Future()
|
|
876
861
|
)
|
|
877
862
|
self._server: object | None = None
|
|
@@ -918,11 +903,11 @@ class _LoopbackOAuthCallbackServer:
|
|
|
918
903
|
if isinstance(self._server, ThreadingHTTPServer):
|
|
919
904
|
self._server.serve_forever()
|
|
920
905
|
|
|
921
|
-
async def wait(self) ->
|
|
922
|
-
"""Wait for the authorization callback and return
|
|
906
|
+
async def wait(self) -> AuthorizationCodeResult:
|
|
907
|
+
"""Wait for the authorization callback and return its parsed result.
|
|
923
908
|
|
|
924
909
|
Returns:
|
|
925
|
-
The
|
|
910
|
+
The authorization code with its optional `state` and RFC 9207 `iss`.
|
|
926
911
|
|
|
927
912
|
Raises:
|
|
928
913
|
_LoopbackCallbackTimeoutError: If no callback arrives before the timeout.
|
|
@@ -1020,7 +1005,13 @@ class _LoopbackOAuthCallbackServer:
|
|
|
1020
1005
|
self._send_html(handler, 400, _oauth_error_html(msg))
|
|
1021
1006
|
return
|
|
1022
1007
|
|
|
1023
|
-
self._future.set_result(
|
|
1008
|
+
self._future.set_result(
|
|
1009
|
+
AuthorizationCodeResult(
|
|
1010
|
+
code=params["code"][0],
|
|
1011
|
+
state=(params.get("state") or [None])[0],
|
|
1012
|
+
iss=(params.get("iss") or [None])[0],
|
|
1013
|
+
)
|
|
1014
|
+
)
|
|
1024
1015
|
self._send_html(
|
|
1025
1016
|
handler,
|
|
1026
1017
|
200,
|
|
@@ -1136,7 +1127,7 @@ def _make_reauth_required_handlers(
|
|
|
1136
1127
|
async def redirect(_auth_url: str) -> None: # noqa: RUF029
|
|
1137
1128
|
raise MCPReauthRequiredError(server_name)
|
|
1138
1129
|
|
|
1139
|
-
async def callback() ->
|
|
1130
|
+
async def callback() -> AuthorizationCodeResult: # noqa: RUF029
|
|
1140
1131
|
raise MCPReauthRequiredError(server_name)
|
|
1141
1132
|
|
|
1142
1133
|
return redirect, callback
|
|
@@ -1164,21 +1155,21 @@ def _make_paste_back_handlers(
|
|
|
1164
1155
|
final_url = _append_query_params(auth_url, extras) if extras else auth_url
|
|
1165
1156
|
await interaction.show_authorize_url(final_url, opened_in_browser=False)
|
|
1166
1157
|
|
|
1167
|
-
async def callback() ->
|
|
1158
|
+
async def callback() -> AuthorizationCodeResult:
|
|
1168
1159
|
url = await interaction.request_callback_url()
|
|
1169
1160
|
return _parse_callback_url(url)
|
|
1170
1161
|
|
|
1171
1162
|
return redirect, callback
|
|
1172
1163
|
|
|
1173
1164
|
|
|
1174
|
-
def _parse_callback_url(url: str) ->
|
|
1175
|
-
"""Parse a provider callback URL into
|
|
1165
|
+
def _parse_callback_url(url: str) -> AuthorizationCodeResult:
|
|
1166
|
+
"""Parse a provider callback URL into the SDK's authorization result.
|
|
1176
1167
|
|
|
1177
1168
|
Args:
|
|
1178
1169
|
url: Raw callback URL pasted by the user.
|
|
1179
1170
|
|
|
1180
1171
|
Returns:
|
|
1181
|
-
The `code`
|
|
1172
|
+
The `code` with its optional `state` and RFC 9207 `iss` parameters.
|
|
1182
1173
|
|
|
1183
1174
|
Raises:
|
|
1184
1175
|
RuntimeError: If the URL contains `error=` or lacks `code`.
|
|
@@ -1193,7 +1184,11 @@ def _parse_callback_url(url: str) -> tuple[str, str | None]:
|
|
|
1193
1184
|
if "code" not in params or not params["code"]:
|
|
1194
1185
|
msg = "Callback URL is missing the 'code' parameter."
|
|
1195
1186
|
raise RuntimeError(msg)
|
|
1196
|
-
return
|
|
1187
|
+
return AuthorizationCodeResult(
|
|
1188
|
+
code=params["code"][0],
|
|
1189
|
+
state=(params.get("state") or [None])[0],
|
|
1190
|
+
iss=(params.get("iss") or [None])[0],
|
|
1191
|
+
)
|
|
1197
1192
|
|
|
1198
1193
|
|
|
1199
1194
|
def _default_ui() -> OAuthInteraction:
|
|
@@ -1275,7 +1270,7 @@ def _make_loopback_handlers(
|
|
|
1275
1270
|
return
|
|
1276
1271
|
await interaction.show_authorize_url(final_url, opened_in_browser=True)
|
|
1277
1272
|
|
|
1278
|
-
async def callback() ->
|
|
1273
|
+
async def callback() -> AuthorizationCodeResult:
|
|
1279
1274
|
try:
|
|
1280
1275
|
return await callback_server.wait()
|
|
1281
1276
|
except (
|
|
@@ -1597,12 +1592,12 @@ class _ExpiryAwareOAuthClientProvider(OAuthClientProvider):
|
|
|
1597
1592
|
if set_oauth_metadata is not None:
|
|
1598
1593
|
await set_oauth_metadata(self.context.oauth_metadata)
|
|
1599
1594
|
|
|
1600
|
-
async def _handle_token_response(self, response:
|
|
1595
|
+
async def _handle_token_response(self, response: httpx2.Response) -> None:
|
|
1601
1596
|
"""Persist tokens and any metadata discovered during full OAuth login."""
|
|
1602
1597
|
await super()._handle_token_response(response)
|
|
1603
1598
|
await self._persist_oauth_metadata()
|
|
1604
1599
|
|
|
1605
|
-
async def _handle_locked_refresh_response(self, response:
|
|
1600
|
+
async def _handle_locked_refresh_response(self, response: httpx2.Response) -> bool:
|
|
1606
1601
|
"""Handle a serialized refresh without bypassing SDK re-auth fallback.
|
|
1607
1602
|
|
|
1608
1603
|
Args:
|
|
@@ -1629,8 +1624,8 @@ class _ExpiryAwareOAuthClientProvider(OAuthClientProvider):
|
|
|
1629
1624
|
|
|
1630
1625
|
async def async_auth_flow(
|
|
1631
1626
|
self,
|
|
1632
|
-
request:
|
|
1633
|
-
) -> AsyncGenerator[
|
|
1627
|
+
request: httpx2.Request,
|
|
1628
|
+
) -> AsyncGenerator[httpx2.Request, httpx2.Response]:
|
|
1634
1629
|
"""Discover and cache OAuth metadata before the SDK refresh branch.
|
|
1635
1630
|
|
|
1636
1631
|
Yields:
|
|
@@ -1688,7 +1683,7 @@ class _ExpiryAwareOAuthClientProvider(OAuthClientProvider):
|
|
|
1688
1683
|
self.context.oauth_metadata = metadata
|
|
1689
1684
|
await self._persist_oauth_metadata()
|
|
1690
1685
|
break
|
|
1691
|
-
except
|
|
1686
|
+
except httpx2.HTTPError as exc:
|
|
1692
1687
|
# Log only the exception type, never its payload — discovery
|
|
1693
1688
|
# responses travel the same channel as bearer tokens.
|
|
1694
1689
|
logger.debug(
|
|
@@ -2076,7 +2071,7 @@ _RESOURCE_METADATA_RE = re.compile(
|
|
|
2076
2071
|
"""Capture the RFC 9728 `resource_metadata` URL from a Bearer challenge."""
|
|
2077
2072
|
|
|
2078
2073
|
|
|
2079
|
-
def _oauth_resource_challenge(headers: httpx.Headers) -> str | None:
|
|
2074
|
+
def _oauth_resource_challenge(headers: httpx.Headers | httpx2.Headers) -> str | None:
|
|
2080
2075
|
"""Return the RFC 9728 `resource_metadata` URL from a Bearer challenge.
|
|
2081
2076
|
|
|
2082
2077
|
A single `WWW-Authenticate` header line may carry several comma-separated
|
|
@@ -2106,7 +2101,9 @@ def find_oauth_challenge(exc: BaseException) -> str | None:
|
|
|
2106
2101
|
Per the MCP authorization spec (RFC 9728), a server requiring OAuth
|
|
2107
2102
|
answers an unauthenticated request with HTTP 401 plus a Bearer
|
|
2108
2103
|
`WWW-Authenticate` challenge pointing at its protected-resource metadata.
|
|
2109
|
-
The MCP client surfaces that as an `
|
|
2104
|
+
The MCP client surfaces that as an `httpx2.HTTPStatusError` (the MCP
|
|
2105
|
+
SDK's HTTP client); dcode's own `httpx` calls raise the `httpx` one, so
|
|
2106
|
+
both are matched. Walks
|
|
2110
2107
|
`exceptions` (for `ExceptionGroup`), then `__cause__`/`__context__`,
|
|
2111
2108
|
tracking visited nodes to terminate on cyclic chains.
|
|
2112
2109
|
|
|
@@ -2124,7 +2121,7 @@ def find_oauth_challenge(exc: BaseException) -> str | None:
|
|
|
2124
2121
|
if id(current) in visited:
|
|
2125
2122
|
continue
|
|
2126
2123
|
visited.add(id(current))
|
|
2127
|
-
if isinstance(current, httpx.HTTPStatusError):
|
|
2124
|
+
if isinstance(current, (httpx.HTTPStatusError, httpx2.HTTPStatusError)):
|
|
2128
2125
|
response = current.response
|
|
2129
2126
|
if (
|
|
2130
2127
|
response is not None and response.status_code == 401 # noqa: PLR2004 # HTTP Unauthorized
|
|
@@ -2140,13 +2137,19 @@ def find_oauth_challenge(exc: BaseException) -> str | None:
|
|
|
2140
2137
|
return None
|
|
2141
2138
|
|
|
2142
2139
|
|
|
2143
|
-
async def _drive_handshake(
|
|
2144
|
-
"""Open a one-shot MCP session
|
|
2145
|
-
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
2140
|
+
async def _drive_handshake(transport: ClientTransport) -> None:
|
|
2141
|
+
"""Open a one-shot MCP session to trigger the OAuth handshake.
|
|
2146
2142
|
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2143
|
+
Connecting is the whole point: the provider attached to `transport` runs
|
|
2144
|
+
its authorization flow during the connect, and persists tokens on success.
|
|
2145
|
+
Nothing is done with the session itself.
|
|
2146
|
+
|
|
2147
|
+
Args:
|
|
2148
|
+
transport: A remote transport carrying the OAuth provider to drive.
|
|
2149
|
+
"""
|
|
2150
|
+
from fastmcp.client import Client
|
|
2151
|
+
|
|
2152
|
+
async with Client(transport):
|
|
2150
2153
|
pass
|
|
2151
2154
|
|
|
2152
2155
|
|
|
@@ -2172,11 +2175,6 @@ async def login(
|
|
|
2172
2175
|
RuntimeError: If the device flow fails or times out, or the
|
|
2173
2176
|
OAuth handshake aborts.
|
|
2174
2177
|
""" # noqa: DOC502 - `RuntimeError` surfaces via the device flow / handshake
|
|
2175
|
-
from langchain_mcp_adapters.sessions import (
|
|
2176
|
-
SSEConnection,
|
|
2177
|
-
StreamableHttpConnection,
|
|
2178
|
-
)
|
|
2179
|
-
|
|
2180
2178
|
from deepagents_code.mcp_tools import MCPConfigError, _resolve_server_type
|
|
2181
2179
|
|
|
2182
2180
|
# OAuth login is discovery-based (RFC 9728), so it works for any remote
|
|
@@ -2229,22 +2227,15 @@ async def login(
|
|
|
2229
2227
|
extra_auth_params=result.extra_auth_params or None,
|
|
2230
2228
|
ui=ui,
|
|
2231
2229
|
)
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
else:
|
|
2240
|
-
conn = SSEConnection(
|
|
2241
|
-
transport="sse",
|
|
2242
|
-
url=resolved_config["url"],
|
|
2230
|
+
from deepagents_code.mcp_tools import _build_transport
|
|
2231
|
+
|
|
2232
|
+
await _drive_handshake(
|
|
2233
|
+
_build_transport(
|
|
2234
|
+
server_name,
|
|
2235
|
+
transport,
|
|
2236
|
+
{**resolved_config, "headers": resolved_config.get("headers") or {}},
|
|
2243
2237
|
auth=provider,
|
|
2238
|
+
keep_alive=False,
|
|
2244
2239
|
)
|
|
2245
|
-
|
|
2246
|
-
if "headers" in resolved_config:
|
|
2247
|
-
conn["headers"] = resolved_config["headers"]
|
|
2248
|
-
|
|
2249
|
-
await _drive_handshake({server_name: conn})
|
|
2240
|
+
)
|
|
2250
2241
|
await ui.show_success(success_message)
|