deepagents-code 0.1.35__tar.gz → 0.1.37__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.35 → deepagents_code-0.1.37}/AGENTS.md +2 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/CHANGELOG.md +51 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/COMMANDS.md +4 -2
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/DEVELOPMENT.md +6 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/PKG-INFO +21 -18
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/__init__.py +3 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_constants.py +18 -0
- deepagents_code-0.1.37/deepagents_code/_debug.py +148 -0
- deepagents_code-0.1.37/deepagents_code/_debug_buffer.py +204 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_env_vars.py +13 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/agent.py +12 -2
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/app.py +743 -32
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/commands/tools.py +10 -4
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/launch/server.py +223 -22
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/launch/server_manager.py +25 -10
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/command_registry.py +9 -2
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/config.py +81 -9
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/config_manifest.py +79 -11
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/configurable_model.py +108 -9
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/extras_info.py +1 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/file_ops.py +72 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/main.py +156 -19
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_auth.py +54 -70
- deepagents_code-0.1.37/deepagents_code/mcp_config.py +176 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_tools.py +440 -153
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/model_config.py +7 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/reasoning_effort.py +77 -11
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/server_graph.py +3 -16
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/sessions.py +30 -5
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tool_catalog.py +177 -22
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/textual_adapter.py +38 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/ask_user.py +22 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/auth.py +2 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/chat_input.py +21 -5
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/cwd_switch.py +70 -27
- deepagents_code-0.1.37/deepagents_code/tui/widgets/debug_console.py +868 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/mcp_viewer.py +45 -29
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/messages.py +10 -2
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/model_selector.py +72 -13
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/startup_tip.py +5 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/status.py +7 -4
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/tool_widgets.py +29 -17
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/welcome.py +41 -10
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/ui.py +8 -8
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/update_check.py +133 -8
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/pyproject.toml +14 -13
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/client/commands/test_tools.py +22 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_agent_friendly.py +1 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_app.py +1192 -36
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_args.py +6 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_clipboard.py +6 -6
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_command_registry.py +16 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_config.py +165 -3
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_config_manifest.py +119 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_configurable_model.py +324 -2
- deepagents_code-0.1.37/tests/unit_tests/test_cursor_style.py +56 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_debug.py +77 -0
- deepagents_code-0.1.37/tests/unit_tests/test_debug_buffer.py +269 -0
- deepagents_code-0.1.37/tests/unit_tests/test_debug_console.py +862 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_exception_handling.py +7 -7
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_file_ops.py +68 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_main.py +169 -2
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_main_args.py +173 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_mcp_auth.py +89 -33
- deepagents_code-0.1.37/tests/unit_tests/test_mcp_config.py +214 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_mcp_tools.py +805 -4
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_model_config.py +14 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_model_switch.py +41 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_reasoning_effort.py +76 -1
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_server.py +738 -2
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_server_graph.py +23 -43
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_server_manager.py +106 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_sessions.py +17 -0
- deepagents_code-0.1.37/tests/unit_tests/test_threads_resume.py +350 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_tool_catalog.py +206 -3
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_update_check.py +216 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/test_textual_adapter.py +253 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_ask_user.py +258 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_auth_widgets.py +1 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_chat_input.py +25 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_cwd_switch.py +81 -6
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +125 -51
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_messages.py +37 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_model_selector.py +236 -3
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_status.py +58 -7
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_thread_selector.py +20 -2
- deepagents_code-0.1.37/tests/unit_tests/tui/widgets/test_tool_renderers.py +216 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_welcome.py +201 -14
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/uv.lock +121 -57
- deepagents_code-0.1.35/deepagents_code/_debug.py +0 -96
- deepagents_code-0.1.35/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -102
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/.gitignore +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/Makefile +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/README.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_fake_models.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/_tool_stream.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/commands/auth.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/commands/config.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/commands/mcp.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/launch/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/non_interactive.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/client/remote_client.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/paste_collapse.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/skills/trust.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/_links.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/approval.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/diff.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/goal_review.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/history.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/install_confirm.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/loading.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/message_store.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/skill_trust.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/subagent_panel.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/update_available.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/tui/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/hatch_build.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/images/tui.png +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/scripts/install.sh +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/README.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/test_auto_approve_remote.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/client/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/client/commands/test_auth.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/client/commands/test_mcp.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/skills/test_skill_trust.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/smoke_tests/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/smoke_tests/conftest.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test__tool_stream.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_install_script.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_rubric_cli.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_approval.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_autocomplete.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_diff.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_history.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_launch_init.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_links.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_message_store.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_subagent_panel.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
- {deepagents_code-0.1.35 → deepagents_code-0.1.37}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
|
@@ -91,7 +91,8 @@ Debug logging is configured **once**, on the `deepagents_code` package logger, b
|
|
|
91
91
|
|
|
92
92
|
- Do **not** add per-module `configure_debug_logging(logger)` calls. They are redundant now that the package logger is configured at import, and they reintroduce the duplicate-handler problem the single-config approach solves.
|
|
93
93
|
- Every module should create its logger with `logging.getLogger(__name__)` so it stays inside the `deepagents_code.*` hierarchy and inherits the package handler. Don't set `logger.propagate = False` or attach your own handlers.
|
|
94
|
-
- The handler only attaches when `DEEPAGENTS_CODE_DEBUG` is truthy;
|
|
94
|
+
- The **file** handler only attaches when `DEEPAGENTS_CODE_DEBUG` is truthy; that path is a single env-var read, so it's safe on the startup hot path. See `DEVELOPMENT.md` for the `DEEPAGENTS_CODE_DEBUG` / `DEEPAGENTS_CODE_DEBUG_FILE` / `DEEPAGENTS_CODE_LOG_LEVEL` env vars.
|
|
95
|
+
- Separately, an **always-on in-memory ring buffer** (`_debug_buffer.install_log_buffer`, called from `__init__.py` right before `configure_debug_logging`) attaches unconditionally at import so the in-app Debug Console (`Ctrl+\`) can tail recent `deepagents_code.*` records without file logging. It captures `INFO` and above by default (or `DEEPAGENTS_CODE_LOG_LEVEL`), and may lower the package logger to `INFO` for the process lifetime. It never spills to the terminal (a handler is always found, so `lastResort` is skipped) and is bounded (a `deque` of 1000 records), so it's cheap enough to keep on. Because it installs *before* `configure_debug_logging`, warnings that helper emits at startup are captured and visible in the console.
|
|
95
96
|
|
|
96
97
|
## CLI help screen
|
|
97
98
|
|
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.37](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.36...deepagents-code==0.1.37) (2026-07-13)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Add Meta model provider ([#4650](https://github.com/langchain-ai/deepagents/issues/4650)) ([70829c5](https://github.com/langchain-ai/deepagents/commit/70829c5846b6bdde1cee51f0f4929e819ba1026b))
|
|
10
|
+
* Set `prompt_cache_key` for OpenAI models ([#4632](https://github.com/langchain-ai/deepagents/issues/4632)) ([8cf57ac](https://github.com/langchain-ai/deepagents/commit/8cf57aca9f41c3c4ca6d9796dc2cb80d4b22fb6d))
|
|
11
|
+
* Support Fireworks `/routers` model ids ([#4591](https://github.com/langchain-ai/deepagents/issues/4591)) ([1c08d27](https://github.com/langchain-ai/deepagents/commit/1c08d2705f73f6870610849e00910b94458accf1))
|
|
12
|
+
* `/model` Ctrl+N toggle for names vs raw specs ([#4592](https://github.com/langchain-ai/deepagents/issues/4592)) ([518c322](https://github.com/langchain-ai/deepagents/commit/518c322e7dda840b5a740541afc895516a74925f))
|
|
13
|
+
* `/tools` slash command ([#4649](https://github.com/langchain-ai/deepagents/issues/4649)) ([b1600a8](https://github.com/langchain-ai/deepagents/commit/b1600a8da784899d9db5bdf93be07b4c7f53a46c))
|
|
14
|
+
* Add `-s` alias for `--skill` ([#4620](https://github.com/langchain-ai/deepagents/issues/4620)) ([c9b7ac2](https://github.com/langchain-ai/deepagents/commit/c9b7ac20752e4270d286b4af3fcf710e7e5bee87))
|
|
15
|
+
* Configurable chat cursor style ([#4687](https://github.com/langchain-ai/deepagents/issues/4687)) ([a22484b](https://github.com/langchain-ai/deepagents/commit/a22484ba2e001fd62fbff0fe916f1b3b93889fc3))
|
|
16
|
+
* Expand environment variables in MCP config ([#4681](https://github.com/langchain-ai/deepagents/issues/4681)) ([4f5d7be](https://github.com/langchain-ai/deepagents/commit/4f5d7be1b4073dee346e5a974841721646fa4860))
|
|
17
|
+
* Hide diff widget for credential files ([#4593](https://github.com/langchain-ai/deepagents/issues/4593)) ([4c49a24](https://github.com/langchain-ai/deepagents/commit/4c49a24c4c488f45859b45628cfa57719e52f596))
|
|
18
|
+
* In-app Debug Console ([#4564](https://github.com/langchain-ai/deepagents/issues/4564)) ([4f94a30](https://github.com/langchain-ai/deepagents/commit/4f94a30c11efb1819b08647d15b50b9b1e7bf043))
|
|
19
|
+
* Offer abort in `/threads` cwd-switch prompt ([#4583](https://github.com/langchain-ai/deepagents/issues/4583)) ([aaeac99](https://github.com/langchain-ai/deepagents/commit/aaeac99d9f17b6a55d663c21a4d063444b6a1870))
|
|
20
|
+
* Resume threads in-TUI with `/threads -r [ID]` ([#4609](https://github.com/langchain-ai/deepagents/issues/4609)) ([d442673](https://github.com/langchain-ai/deepagents/commit/d44267358e272553c8ece33d367514430be7c0da))
|
|
21
|
+
* Show `(debug enabled)` on splash when `DEEPAGENTS_CODE_DEBUG` is set ([#4584](https://github.com/langchain-ai/deepagents/issues/4584)) ([f10b877](https://github.com/langchain-ai/deepagents/commit/f10b877e5e48c3a1e15bd72d2ce06dfb16203231))
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* Avoid repeated startup auto-update stalls ([#4648](https://github.com/langchain-ai/deepagents/issues/4648)) ([12a9c9d](https://github.com/langchain-ai/deepagents/commit/12a9c9d6813a83e5eeff9feed0c4068d1fcc69c4))
|
|
26
|
+
* Infer Fireworks provider from qualified model IDs ([#4594](https://github.com/langchain-ai/deepagents/issues/4594)) ([4d2aa8a](https://github.com/langchain-ai/deepagents/commit/4d2aa8a9684609eee45cd93b0af5149d8dd09eea))
|
|
27
|
+
* Capture input typed before TUI startup ([#4684](https://github.com/langchain-ai/deepagents/issues/4684)) ([ef9a4a8](https://github.com/langchain-ai/deepagents/commit/ef9a4a8770f4daec70e640d6d2f23dd798d4ede2))
|
|
28
|
+
* Detach owned `langgraph dev` server from terminal ([#4642](https://github.com/langchain-ai/deepagents/issues/4642)) ([d1f3afe](https://github.com/langchain-ai/deepagents/commit/d1f3afecdc015b5d1c9fb098d6347c7d7180e417))
|
|
29
|
+
* Infer additional model providers ([#4675](https://github.com/langchain-ai/deepagents/issues/4675)) ([4ceed24](https://github.com/langchain-ai/deepagents/commit/4ceed24d3758801ed9df1024602e90488004cef1))
|
|
30
|
+
* Preserve `Ctrl+D` deletion in non-empty input ([#4626](https://github.com/langchain-ai/deepagents/issues/4626)) ([306bd89](https://github.com/langchain-ai/deepagents/commit/306bd893f214237b6b4eede7c2ce0eaff66f5527))
|
|
31
|
+
* Quit with `Ctrl+D` at end of prompt ([#4678](https://github.com/langchain-ai/deepagents/issues/4678)) ([2f8c111](https://github.com/langchain-ai/deepagents/commit/2f8c11176f5cc9350c3337b2dfcf9f19886d5d02))
|
|
32
|
+
* Reap langgraph dev server when startup is cancelled ([#4629](https://github.com/langchain-ai/deepagents/issues/4629)) ([904ff05](https://github.com/langchain-ai/deepagents/commit/904ff05620a576100e05fd65810d38405c4942d4))
|
|
33
|
+
* Reject `--auto-approve` in headless mode ([#4617](https://github.com/langchain-ai/deepagents/issues/4617)) ([997be16](https://github.com/langchain-ai/deepagents/commit/997be1643aff6d6900b8b8c95832cdf93be8c0d7))
|
|
34
|
+
* Route explicit `--stdin` + `--skill` to headless path ([#4611](https://github.com/langchain-ai/deepagents/issues/4611)) ([724e24a](https://github.com/langchain-ai/deepagents/commit/724e24a31546e1f31feca3bb2344717550682595))
|
|
35
|
+
* Skip Esc prompt-restore once output generation begins ([#4582](https://github.com/langchain-ai/deepagents/issues/4582)) ([14f384f](https://github.com/langchain-ai/deepagents/commit/14f384fc0083c07a7f44f97543b40b74cf93c13f))
|
|
36
|
+
* Remove misleading agent names from help ([#4671](https://github.com/langchain-ai/deepagents/issues/4671)) ([ac15732](https://github.com/langchain-ai/deepagents/commit/ac1573281530c1564fe07f8a21608e4d4dec2c3b))
|
|
37
|
+
* Support plain `exit` quit command ([#4543](https://github.com/langchain-ai/deepagents/issues/4543)) ([e6f10a1](https://github.com/langchain-ai/deepagents/commit/e6f10a149051128677c9f6f37663922054a7ac26))
|
|
38
|
+
* Sync `ask_user` active-question highlight with focus ([#4599](https://github.com/langchain-ai/deepagents/issues/4599)) ([e4c29b5](https://github.com/langchain-ai/deepagents/commit/e4c29b5264413d23d8dc70cabae72feb5f3f3dcb))
|
|
39
|
+
* Wrap MCP viewer navigation ([#4677](https://github.com/langchain-ai/deepagents/issues/4677)) ([cffc732](https://github.com/langchain-ai/deepagents/commit/cffc73213bfdcec26cb82c413fa7e27db4afc0ca))
|
|
40
|
+
|
|
41
|
+
### Performance Improvements
|
|
42
|
+
|
|
43
|
+
* Load MCP servers concurrently during graph build ([#4659](https://github.com/langchain-ai/deepagents/issues/4659)) ([c5345cc](https://github.com/langchain-ai/deepagents/commit/c5345cc04cd810c6238e42dfbfa14497ae1b9020))
|
|
44
|
+
|
|
45
|
+
## [0.1.36](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.35...deepagents-code==0.1.36) (2026-07-09)
|
|
46
|
+
|
|
47
|
+
### Features
|
|
48
|
+
|
|
49
|
+
* Add `GPT-5.6` model family ([#4600](https://github.com/langchain-ai/deepagents/issues/4600)) ([4a806bc](https://github.com/langchain-ai/deepagents/commit/4a806bc703b69334cccd05bcd27d411602e82318))
|
|
50
|
+
* Add Grok 4.5 model ([#4596](https://github.com/langchain-ai/deepagents/issues/4596)) ([b0a209d](https://github.com/langchain-ai/deepagents/commit/b0a209da3a8c9f80e2e3d5e199340736c854c567))
|
|
51
|
+
|
|
52
|
+
### Bug Fixes
|
|
53
|
+
|
|
54
|
+
* Strip input before Ctrl+C copy-input fallback ([#4590](https://github.com/langchain-ai/deepagents/issues/4590)) ([505d55a](https://github.com/langchain-ai/deepagents/commit/505d55ad83e8569213175911ee6c8c39fbbf340c))
|
|
55
|
+
|
|
5
56
|
## [0.1.35](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.34...deepagents-code==0.1.35) (2026-07-09)
|
|
6
57
|
|
|
7
58
|
### Features
|
|
@@ -8,7 +8,7 @@ Regenerate this file with `make commands-catalog` after changing command names,
|
|
|
8
8
|
aliases, descriptions, visibility, or hidden-command metadata.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
## Public (
|
|
11
|
+
## Public (33)
|
|
12
12
|
|
|
13
13
|
| Command | Aliases | Description |
|
|
14
14
|
| --- | --- | --- |
|
|
@@ -41,12 +41,14 @@ aliases, descriptions, visibility, or hidden-command metadata.
|
|
|
41
41
|
| `/threads` | | Browse and resume past threads |
|
|
42
42
|
| `/timestamps` | | Show or hide message timestamps |
|
|
43
43
|
| `/tokens` | | Show token usage |
|
|
44
|
+
| `/tools` | | List the tools available to the agent |
|
|
44
45
|
| `/trace` | | Open this thread in LangSmith |
|
|
45
46
|
| `/update` | | Check for and install updates |
|
|
46
47
|
| `/version` | `/about` | Show version information |
|
|
47
48
|
|
|
48
|
-
## Hidden (
|
|
49
|
+
## Hidden (2)
|
|
49
50
|
|
|
50
51
|
These commands are intentionally omitted from autocomplete and help. See the `HIDDEN_COMMANDS` docstring in the registry for context.
|
|
51
52
|
|
|
53
|
+
- `/debug`
|
|
52
54
|
- `/debug-error`
|
|
@@ -117,6 +117,12 @@ tail -f /tmp/deepagents_debug.log
|
|
|
117
117
|
|
|
118
118
|
To send it elsewhere, also `export DEEPAGENTS_CODE_DEBUG_FILE=<path>`. The handler appends across runs, so a single file accumulates every session.
|
|
119
119
|
|
|
120
|
+
### In-app Debug Console (`Ctrl+\`)
|
|
121
|
+
|
|
122
|
+
Press `Ctrl+\` (or run the hidden `/debug` command) inside a session to toggle a read-only Debug Console overlay. It shows a point-in-time session/runtime snapshot (version, model, thread, cwd, auto-approve, sandbox, MCP servers, token usage, debug-log path) plus a live tail of recent `deepagents_code.*` log records.
|
|
123
|
+
|
|
124
|
+
The tail is fed by an always-on in-memory ring buffer (`_debug_buffer.install_log_buffer`, installed on the package logger in `__init__.py`), so it works **without** `DEEPAGENTS_CODE_DEBUG` — though enabling that switch raises the captured level to `DEBUG` and adds the file handler above. In the console, `Ctrl+L` clears the on-screen view (the buffer keeps accruing) and `c` copies the visible lines.
|
|
125
|
+
|
|
120
126
|
## Local dev installs
|
|
121
127
|
|
|
122
128
|
A *local dev install* gives you a persistent `dcode-dev` command that launches your checkout directly. It lives in a dedicated editable venv under `~/.local/share/dcode-dev`, symlinked into `~/.local/bin/dcode-dev`. It can sit alongside a released `dcode` without interfering:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary: Terminal
|
|
3
|
+
Version: 0.1.37
|
|
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/
|
|
7
7
|
Project-URL: Repository, https://github.com/langchain-ai/deepagents
|
|
@@ -30,15 +30,15 @@ Requires-Dist: deepagents-acp<1.0.0,>=0.0.8
|
|
|
30
30
|
Requires-Dist: deepagents==0.7.0a6
|
|
31
31
|
Requires-Dist: filelock<4.0.0,>=3.12
|
|
32
32
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
33
|
-
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.
|
|
33
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.8
|
|
34
34
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7
|
|
35
35
|
Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.3.0
|
|
36
|
-
Requires-Dist: langchain-openai<2.0.0,>=1.3.
|
|
36
|
+
Requires-Dist: langchain-openai<2.0.0,>=1.3.5
|
|
37
37
|
Requires-Dist: langchain-quickjs<0.4.0,>=0.3.2
|
|
38
|
-
Requires-Dist: langchain<2.0.0,>=1.3.
|
|
38
|
+
Requires-Dist: langchain<2.0.0,>=1.3.13
|
|
39
39
|
Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.0
|
|
40
40
|
Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.30
|
|
41
|
-
Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.
|
|
41
|
+
Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.31.0
|
|
42
42
|
Requires-Dist: langgraph-sdk<1.0.0,>=0.4.2
|
|
43
43
|
Requires-Dist: langsmith[sandbox]>=0.9.3
|
|
44
44
|
Requires-Dist: markdownify<2.0.0,>=1.2.2
|
|
@@ -62,23 +62,24 @@ Provides-Extra: agentcore
|
|
|
62
62
|
Requires-Dist: langchain-agentcore-codeinterpreter<1.0.0,>=0.0.5; extra == 'agentcore'
|
|
63
63
|
Provides-Extra: all-providers
|
|
64
64
|
Requires-Dist: aiohttp<3.15.0,>=3.14.1; extra == 'all-providers'
|
|
65
|
-
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.
|
|
66
|
-
Requires-Dist: langchain-aws<2.0.0,>=1.6.
|
|
65
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.8; extra == 'all-providers'
|
|
66
|
+
Requires-Dist: langchain-aws<2.0.0,>=1.6.2; extra == 'all-providers'
|
|
67
67
|
Requires-Dist: langchain-baseten<1.0.0,>=0.2.1; extra == 'all-providers'
|
|
68
68
|
Requires-Dist: langchain-cohere<1.0.0,>=0.6.0; extra == 'all-providers'
|
|
69
69
|
Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
70
|
-
Requires-Dist: langchain-fireworks<2.0.0,>=1.4.
|
|
70
|
+
Requires-Dist: langchain-fireworks<2.0.0,>=1.4.4; extra == 'all-providers'
|
|
71
71
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7; extra == 'all-providers'
|
|
72
72
|
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.4; extra == 'all-providers'
|
|
73
73
|
Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'all-providers'
|
|
74
74
|
Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
75
75
|
Requires-Dist: langchain-ibm<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
76
76
|
Requires-Dist: langchain-litellm<2.0.0,>=0.7.0; extra == 'all-providers'
|
|
77
|
-
Requires-Dist: langchain-
|
|
77
|
+
Requires-Dist: langchain-meta<2.0.0,>=0.5.0; extra == 'all-providers'
|
|
78
|
+
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.6; extra == 'all-providers'
|
|
78
79
|
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.4.3; extra == 'all-providers'
|
|
79
80
|
Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
80
|
-
Requires-Dist: langchain-openai<2.0.0,>=1.3.
|
|
81
|
-
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.
|
|
81
|
+
Requires-Dist: langchain-openai<2.0.0,>=1.3.5; extra == 'all-providers'
|
|
82
|
+
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.6; extra == 'all-providers'
|
|
82
83
|
Requires-Dist: langchain-perplexity<2.0.0,>=1.4.0; extra == 'all-providers'
|
|
83
84
|
Requires-Dist: langchain-together<2.0.0,>=0.4.0; extra == 'all-providers'
|
|
84
85
|
Requires-Dist: langchain-xai<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
@@ -89,11 +90,11 @@ Requires-Dist: langchain-modal>=0.0.5; extra == 'all-sandboxes'
|
|
|
89
90
|
Requires-Dist: langchain-runloop>=0.0.6; extra == 'all-sandboxes'
|
|
90
91
|
Requires-Dist: langchain-vercel-sandbox>=0.0.1; extra == 'all-sandboxes'
|
|
91
92
|
Provides-Extra: anthropic
|
|
92
|
-
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.
|
|
93
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.8; extra == 'anthropic'
|
|
93
94
|
Provides-Extra: baseten
|
|
94
95
|
Requires-Dist: langchain-baseten<1.0.0,>=0.2.1; extra == 'baseten'
|
|
95
96
|
Provides-Extra: bedrock
|
|
96
|
-
Requires-Dist: langchain-aws<2.0.0,>=1.6.
|
|
97
|
+
Requires-Dist: langchain-aws<2.0.0,>=1.6.2; extra == 'bedrock'
|
|
97
98
|
Provides-Extra: cohere
|
|
98
99
|
Requires-Dist: langchain-cohere<1.0.0,>=0.6.0; extra == 'cohere'
|
|
99
100
|
Provides-Extra: daytona
|
|
@@ -101,7 +102,7 @@ Requires-Dist: langchain-daytona>=0.0.7; extra == 'daytona'
|
|
|
101
102
|
Provides-Extra: deepseek
|
|
102
103
|
Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'deepseek'
|
|
103
104
|
Provides-Extra: fireworks
|
|
104
|
-
Requires-Dist: langchain-fireworks<2.0.0,>=1.4.
|
|
105
|
+
Requires-Dist: langchain-fireworks<2.0.0,>=1.4.4; extra == 'fireworks'
|
|
105
106
|
Provides-Extra: google-genai
|
|
106
107
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7; extra == 'google-genai'
|
|
107
108
|
Provides-Extra: groq
|
|
@@ -115,8 +116,10 @@ Requires-Dist: langchain-litellm<2.0.0,>=0.7.0; extra == 'litellm'
|
|
|
115
116
|
Provides-Extra: media
|
|
116
117
|
Requires-Dist: av<18.0.0,>=17.0.0; extra == 'media'
|
|
117
118
|
Requires-Dist: pillow<13.0.0,>=12.2.0; extra == 'media'
|
|
119
|
+
Provides-Extra: meta
|
|
120
|
+
Requires-Dist: langchain-meta<2.0.0,>=0.5.0; extra == 'meta'
|
|
118
121
|
Provides-Extra: mistralai
|
|
119
|
-
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.
|
|
122
|
+
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.6; extra == 'mistralai'
|
|
120
123
|
Provides-Extra: modal
|
|
121
124
|
Requires-Dist: langchain-modal>=0.0.5; extra == 'modal'
|
|
122
125
|
Provides-Extra: nvidia
|
|
@@ -125,9 +128,9 @@ Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.4.3; extra == 'nvidia'
|
|
|
125
128
|
Provides-Extra: ollama
|
|
126
129
|
Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'ollama'
|
|
127
130
|
Provides-Extra: openai
|
|
128
|
-
Requires-Dist: langchain-openai<2.0.0,>=1.3.
|
|
131
|
+
Requires-Dist: langchain-openai<2.0.0,>=1.3.5; extra == 'openai'
|
|
129
132
|
Provides-Extra: openrouter
|
|
130
|
-
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.
|
|
133
|
+
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.6; extra == 'openrouter'
|
|
131
134
|
Provides-Extra: perplexity
|
|
132
135
|
Requires-Dist: langchain-perplexity<2.0.0,>=1.4.0; extra == 'perplexity'
|
|
133
136
|
Provides-Extra: quickjs
|
|
@@ -6,12 +6,14 @@ import logging
|
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
8
|
from deepagents_code._debug import configure_debug_logging
|
|
9
|
+
from deepagents_code._debug_buffer import install_log_buffer
|
|
9
10
|
from deepagents_code._version import __version__
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
12
13
|
from collections.abc import Callable
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
install_log_buffer(logging.getLogger(__name__)) # noqa: RUF067 # attach the always-on tail first so warnings from configure_debug_logging are captured
|
|
16
|
+
configure_debug_logging(logging.getLogger(__name__)) # noqa: RUF067 # package logger must be configured before child modules emit logs; sets the final level over the buffer's INFO floor
|
|
15
17
|
|
|
16
18
|
__all__ = [
|
|
17
19
|
"__version__",
|
|
@@ -13,6 +13,24 @@ from typing import Final
|
|
|
13
13
|
DEFAULT_AGENT_NAME: Final[str] = "agent"
|
|
14
14
|
"""Default agent / assistant identifier when no `-a` flag is given."""
|
|
15
15
|
|
|
16
|
+
FIREWORKS_PROVIDER_ID_PREFIX: Final[str] = "accounts/fireworks/"
|
|
17
|
+
"""Prefix used to infer Fireworks from fully-qualified IDs."""
|
|
18
|
+
|
|
19
|
+
FIREWORKS_MODEL_ID_PREFIXES: Final[tuple[str, ...]] = (
|
|
20
|
+
"accounts/fireworks/models/",
|
|
21
|
+
"accounts/fireworks/routers/",
|
|
22
|
+
)
|
|
23
|
+
"""Model and router ID prefixes used for stripping and classification."""
|
|
24
|
+
|
|
25
|
+
MCP_REENABLED_PENDING_ERROR: Final[str] = "Re-enabled — press Ctrl+R to load."
|
|
26
|
+
"""User-facing reconnect guidance shown for an MCP server that was optimistically
|
|
27
|
+
re-enabled but whose agent has not yet reconnected.
|
|
28
|
+
|
|
29
|
+
Set as `MCPServerInfo.error` by `app._apply_optimistic_disabled_state` (alongside
|
|
30
|
+
`pending_reconnect=True`, which is what `/tools` actually keys off). Named here
|
|
31
|
+
so the producer and the tests asserting the message share one literal.
|
|
32
|
+
"""
|
|
33
|
+
|
|
16
34
|
SYSTEM_MESSAGE_PREFIX: Final[str] = "[SYSTEM]"
|
|
17
35
|
"""Prefix for synthetic human messages (e.g. interrupt cancellation notices).
|
|
18
36
|
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Shared debug-logging configuration for runtime and file-based tracing.
|
|
2
|
+
|
|
3
|
+
When the `DEEPAGENTS_CODE_DEBUG` environment variable is set, modules that handle
|
|
4
|
+
streaming or remote communication can enable detailed file-based logging. This
|
|
5
|
+
helper centralizes the setup so the env-var names, file path, log level, and
|
|
6
|
+
format are defined in one place.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
from deepagents_code._env_vars import (
|
|
17
|
+
DEBUG,
|
|
18
|
+
DEBUG_FILE,
|
|
19
|
+
DEFAULT_DEBUG_FILE,
|
|
20
|
+
LOG_LEVEL,
|
|
21
|
+
is_env_truthy,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
_DEBUG_HANDLER_ATTR = "_deepagents_code_debug_handler"
|
|
27
|
+
LOG_LEVELS = {
|
|
28
|
+
"DEBUG": logging.DEBUG,
|
|
29
|
+
"INFO": logging.INFO,
|
|
30
|
+
"WARNING": logging.WARNING,
|
|
31
|
+
"ERROR": logging.ERROR,
|
|
32
|
+
"CRITICAL": logging.CRITICAL,
|
|
33
|
+
}
|
|
34
|
+
"""Canonical level-name to `logging` level mapping.
|
|
35
|
+
|
|
36
|
+
The single source of truth for level names and their numeric values, shared with
|
|
37
|
+
the Debug Console's level filter so severity ordering is never re-derived from
|
|
38
|
+
hardcoded integers.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def resolve_log_level(*, debug_enabled: bool | None = None) -> int:
|
|
43
|
+
"""Resolve the configured runtime logging level.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
debug_enabled: Whether `DEEPAGENTS_CODE_DEBUG` is truthy. When omitted,
|
|
47
|
+
the current environment is checked.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
A standard `logging` level integer. Defaults to `DEBUG` when debug file
|
|
51
|
+
logging is enabled and `INFO` otherwise.
|
|
52
|
+
"""
|
|
53
|
+
if debug_enabled is None:
|
|
54
|
+
debug_enabled = is_env_truthy(DEBUG)
|
|
55
|
+
fallback = logging.DEBUG if debug_enabled else logging.INFO
|
|
56
|
+
raw = os.environ.get(LOG_LEVEL)
|
|
57
|
+
if raw is None or not raw.strip():
|
|
58
|
+
return fallback
|
|
59
|
+
level = LOG_LEVELS.get(raw.strip().upper())
|
|
60
|
+
if level is not None:
|
|
61
|
+
return level
|
|
62
|
+
valid = ", ".join(LOG_LEVELS)
|
|
63
|
+
message = f"ignoring invalid {LOG_LEVEL}={raw!r}; expected one of {valid}"
|
|
64
|
+
# stderr for headless / pre-TUI visibility; the logger so it also lands in
|
|
65
|
+
# the always-on in-memory buffer and surfaces in the Debug Console (the
|
|
66
|
+
# buffer is installed before this runs; see __init__.py).
|
|
67
|
+
print(f"Warning: {message}", file=sys.stderr) # noqa: T201
|
|
68
|
+
logger.warning("%s", message)
|
|
69
|
+
return fallback
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def configure_debug_logging(target: logging.Logger) -> None:
|
|
73
|
+
"""Configure runtime log level and optional file logging for *target*.
|
|
74
|
+
|
|
75
|
+
Intended to be called once on the `deepagents_code` package logger; child
|
|
76
|
+
module loggers reach the same handlers via propagation, so individual modules
|
|
77
|
+
do not configure logging themselves.
|
|
78
|
+
|
|
79
|
+
`DEEPAGENTS_CODE_LOG_LEVEL` controls the package logger level independently of
|
|
80
|
+
file logging. If it is unset, `DEEPAGENTS_CODE_DEBUG=1` defaults to `DEBUG`;
|
|
81
|
+
otherwise the runtime level defaults to `INFO`.
|
|
82
|
+
|
|
83
|
+
When `DEEPAGENTS_CODE_DEBUG` is truthy, a file handler is attached. The log
|
|
84
|
+
file defaults to `DEFAULT_DEBUG_FILE` but can be overridden with
|
|
85
|
+
`DEEPAGENTS_CODE_DEBUG_FILE`. The handler appends (`mode='a'`) so logs are
|
|
86
|
+
preserved across separate process runs. Calling this again with the same
|
|
87
|
+
resolved path does not stack duplicate handlers: the existing tagged handler
|
|
88
|
+
is reused and its level re-applied. If the resolved path changes, the stale
|
|
89
|
+
handler is closed and replaced.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
target: Logger to configure.
|
|
93
|
+
"""
|
|
94
|
+
debug_enabled = is_env_truthy(DEBUG)
|
|
95
|
+
level = resolve_log_level(debug_enabled=debug_enabled)
|
|
96
|
+
target.setLevel(level)
|
|
97
|
+
|
|
98
|
+
if not debug_enabled:
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
debug_path = Path(os.environ.get(DEBUG_FILE, DEFAULT_DEBUG_FILE))
|
|
102
|
+
for existing in list(target.handlers):
|
|
103
|
+
if not (
|
|
104
|
+
isinstance(existing, logging.FileHandler)
|
|
105
|
+
and getattr(existing, _DEBUG_HANDLER_ATTR, False)
|
|
106
|
+
):
|
|
107
|
+
continue
|
|
108
|
+
if Path(existing.baseFilename) == debug_path:
|
|
109
|
+
existing.setLevel(level)
|
|
110
|
+
return
|
|
111
|
+
# The debug path changed; drop the stale handler before re-attaching so
|
|
112
|
+
# we don't leak its file descriptor or fan logs out to two files.
|
|
113
|
+
target.removeHandler(existing)
|
|
114
|
+
existing.close()
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
handler = logging.FileHandler(str(debug_path), mode="a")
|
|
118
|
+
except OSError as exc:
|
|
119
|
+
message = f"could not open debug log file {debug_path}: {exc}"
|
|
120
|
+
# stderr for headless / pre-TUI visibility; the logger so it also lands
|
|
121
|
+
# in the always-on in-memory buffer and surfaces in the Debug Console.
|
|
122
|
+
print(f"Warning: {message}", file=sys.stderr) # noqa: T201
|
|
123
|
+
logger.warning("%s", message)
|
|
124
|
+
return
|
|
125
|
+
setattr(handler, _DEBUG_HANDLER_ATTR, True)
|
|
126
|
+
handler.setLevel(level)
|
|
127
|
+
handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(message)s"))
|
|
128
|
+
target.addHandler(handler)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def installed_debug_log_path() -> Path | None:
|
|
132
|
+
"""Return the path of the active debug log file, or `None` if not logging.
|
|
133
|
+
|
|
134
|
+
Reflects the file handler actually attached by `configure_debug_logging`,
|
|
135
|
+
not the current `DEEPAGENTS_CODE_DEBUG` env value. The two diverge when the
|
|
136
|
+
variable is set after import — e.g. via a project/global `.env` loaded during
|
|
137
|
+
settings bootstrap — in which case the variable reads truthy but no handler
|
|
138
|
+
was installed and no log file exists. Callers that surface "full error in
|
|
139
|
+
<path>" hints must use this rather than the env var to avoid pointing users
|
|
140
|
+
at a file that was never created.
|
|
141
|
+
"""
|
|
142
|
+
package_logger = logging.getLogger(__package__ or "deepagents_code")
|
|
143
|
+
for handler in package_logger.handlers:
|
|
144
|
+
if isinstance(handler, logging.FileHandler) and getattr(
|
|
145
|
+
handler, _DEBUG_HANDLER_ATTR, False
|
|
146
|
+
):
|
|
147
|
+
return Path(handler.baseFilename)
|
|
148
|
+
return None
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
r"""In-memory ring buffer of recent log records for the in-app Debug Console.
|
|
2
|
+
|
|
3
|
+
A lightweight `logging.Handler` keeps the most recent structured log records in a
|
|
4
|
+
bounded `deque` so the Debug Console (`Ctrl+\`) can show a live tail without
|
|
5
|
+
requiring the opt-in file logging from `_debug.configure_debug_logging`. The
|
|
6
|
+
handler is installed once on the `deepagents_code` package logger (see
|
|
7
|
+
`__init__.py`); child module loggers reach it via propagation.
|
|
8
|
+
|
|
9
|
+
Installation is negligible, and each emitted record only appends a structured
|
|
10
|
+
record to a bounded `deque`, so the buffer is cheap enough to keep always on.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import itertools
|
|
16
|
+
import logging
|
|
17
|
+
import os
|
|
18
|
+
from collections import deque
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
|
|
21
|
+
from deepagents_code._env_vars import LOG_LEVEL
|
|
22
|
+
|
|
23
|
+
DEFAULT_CAPACITY = 1000
|
|
24
|
+
"""Maximum number of records retained in the ring buffer."""
|
|
25
|
+
|
|
26
|
+
_DATE_FORMAT = "%H:%M:%S"
|
|
27
|
+
_FORMATTER = logging.Formatter(datefmt=_DATE_FORMAT)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True, slots=True)
|
|
31
|
+
class InMemoryLogRecord:
|
|
32
|
+
"""Structured log record retained by the in-memory debug buffer."""
|
|
33
|
+
|
|
34
|
+
timestamp: str
|
|
35
|
+
level: str
|
|
36
|
+
levelno: int
|
|
37
|
+
logger: str
|
|
38
|
+
message: str
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def plain_line(self) -> str:
|
|
42
|
+
"""The record in the legacy plain-text debug-console format."""
|
|
43
|
+
return f"{self.timestamp} {self.level} {self.logger} {self.message}"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class InMemoryLogBuffer(logging.Handler):
|
|
47
|
+
"""Logging handler retaining the most recent structured records in memory."""
|
|
48
|
+
|
|
49
|
+
def __init__(self, capacity: int = DEFAULT_CAPACITY) -> None:
|
|
50
|
+
"""Create the handler with a bounded backing `deque`.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
capacity: Maximum records to retain; oldest are dropped first.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: If *capacity* is less than 1. A zero-capacity buffer
|
|
57
|
+
would silently discard every record while `total_emitted` kept
|
|
58
|
+
climbing, so it is rejected at the boundary.
|
|
59
|
+
"""
|
|
60
|
+
if capacity < 1:
|
|
61
|
+
msg = f"capacity must be >= 1, got {capacity}"
|
|
62
|
+
raise ValueError(msg)
|
|
63
|
+
super().__init__()
|
|
64
|
+
self._records: deque[InMemoryLogRecord] = deque(maxlen=capacity)
|
|
65
|
+
self._total = 0
|
|
66
|
+
|
|
67
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
68
|
+
"""Append the structured *record* to the ring buffer."""
|
|
69
|
+
self.acquire()
|
|
70
|
+
try:
|
|
71
|
+
self._records.append(self._make_record(record))
|
|
72
|
+
self._total += 1
|
|
73
|
+
except Exception: # noqa: BLE001 # never let logging crash the app
|
|
74
|
+
self.handleError(record)
|
|
75
|
+
finally:
|
|
76
|
+
self.release()
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def total_emitted(self) -> int:
|
|
80
|
+
"""Total records ever emitted (monotonic; survives buffer eviction)."""
|
|
81
|
+
self.acquire()
|
|
82
|
+
try:
|
|
83
|
+
return self._total
|
|
84
|
+
finally:
|
|
85
|
+
self.release()
|
|
86
|
+
|
|
87
|
+
def snapshot_records_since(self, index: int) -> tuple[list[InMemoryLogRecord], int]:
|
|
88
|
+
"""Return retained structured records and the next absolute index.
|
|
89
|
+
|
|
90
|
+
Absolute indices are stable even as old records are evicted, so callers
|
|
91
|
+
can poll incrementally without re-reading records they already consumed.
|
|
92
|
+
Returning the records and the resume index together under the handler
|
|
93
|
+
lock prevents a concurrent append from being skipped between separate
|
|
94
|
+
reads.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
index: Absolute emission index to start from.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
A tuple of the structured records from *index* onward that are still
|
|
101
|
+
retained, and the current total emitted count to resume from.
|
|
102
|
+
"""
|
|
103
|
+
self.acquire()
|
|
104
|
+
try:
|
|
105
|
+
return self._records_since_unlocked(index), self._total
|
|
106
|
+
finally:
|
|
107
|
+
self.release()
|
|
108
|
+
|
|
109
|
+
def _records_since_unlocked(self, index: int) -> list[InMemoryLogRecord]:
|
|
110
|
+
"""Return retained records from *index* while the handler lock is held."""
|
|
111
|
+
start_abs = self._total - len(self._records)
|
|
112
|
+
offset = index - start_abs
|
|
113
|
+
if offset <= 0:
|
|
114
|
+
return list(self._records)
|
|
115
|
+
if offset >= len(self._records):
|
|
116
|
+
return []
|
|
117
|
+
# islice avoids materializing the full deque just to slice off the tail.
|
|
118
|
+
return list(itertools.islice(self._records, offset, None))
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def _make_record(record: logging.LogRecord) -> InMemoryLogRecord:
|
|
122
|
+
"""Convert a standard logging record into a structured debug record.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Structured record for display and filtering.
|
|
126
|
+
"""
|
|
127
|
+
message = record.getMessage()
|
|
128
|
+
if record.exc_info:
|
|
129
|
+
if not record.exc_text:
|
|
130
|
+
record.exc_text = _FORMATTER.formatException(record.exc_info)
|
|
131
|
+
if record.exc_text:
|
|
132
|
+
message = f"{message}\n{record.exc_text}"
|
|
133
|
+
if record.stack_info:
|
|
134
|
+
message = f"{message}\n{_FORMATTER.formatStack(record.stack_info)}"
|
|
135
|
+
return InMemoryLogRecord(
|
|
136
|
+
timestamp=_FORMATTER.formatTime(record, _DATE_FORMAT),
|
|
137
|
+
level=record.levelname,
|
|
138
|
+
levelno=record.levelno,
|
|
139
|
+
logger=record.name,
|
|
140
|
+
message=message,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
_buffer: InMemoryLogBuffer | None = None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def install_log_buffer(
|
|
148
|
+
target: logging.Logger, capacity: int = DEFAULT_CAPACITY
|
|
149
|
+
) -> InMemoryLogBuffer:
|
|
150
|
+
"""Attach the in-memory buffer handler to *target* (idempotent).
|
|
151
|
+
|
|
152
|
+
Lowers *target*'s level to at most `INFO` so the console shows a useful tail
|
|
153
|
+
even when `DEEPAGENTS_CODE_DEBUG` is off; never raises the level. In
|
|
154
|
+
`__init__.py` this runs *before* `configure_debug_logging`, which then sets
|
|
155
|
+
the final level (honoring `DEEPAGENTS_CODE_DEBUG` and
|
|
156
|
+
`DEEPAGENTS_CODE_LOG_LEVEL`) over this `INFO` floor — so any startup warnings
|
|
157
|
+
`configure_debug_logging` emits are captured by the already-installed buffer.
|
|
158
|
+
On a fresh `NOTSET` logger the `NOTSET` branch forces `INFO` without
|
|
159
|
+
consulting `DEEPAGENTS_CODE_LOG_LEVEL`; the `> INFO and no env` branch only
|
|
160
|
+
matters on reconfiguration (e.g. an `importlib.reload`), where it preserves
|
|
161
|
+
an explicit `DEEPAGENTS_CODE_LOG_LEVEL` rather than clobbering it with `INFO`.
|
|
162
|
+
|
|
163
|
+
Lowering the level does not spill log output onto the terminal: because this
|
|
164
|
+
handler is present in the propagation chain, `Logger.callHandlers` finds a
|
|
165
|
+
handler (`found > 0`) and Python's `lastResort` stderr handler is never
|
|
166
|
+
consulted. The exception is an embedding process that attaches its own
|
|
167
|
+
`INFO`-or-lower handler to the root logger, which would then see the
|
|
168
|
+
propagated records.
|
|
169
|
+
|
|
170
|
+
Note: this runs as an import-time side effect (see `__init__.py`), so every
|
|
171
|
+
`import deepagents_code` attaches the handler and may lower the package
|
|
172
|
+
logger's level to `INFO` for the lifetime of the process.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
target: Logger to attach the buffer to (the package logger).
|
|
176
|
+
capacity: Maximum records to retain.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
The installed (or already-installed) buffer handler.
|
|
180
|
+
"""
|
|
181
|
+
global _buffer # noqa: PLW0603 # module-level singleton accessor
|
|
182
|
+
for existing in target.handlers:
|
|
183
|
+
if isinstance(existing, InMemoryLogBuffer):
|
|
184
|
+
_buffer = existing
|
|
185
|
+
return existing
|
|
186
|
+
|
|
187
|
+
handler = InMemoryLogBuffer(capacity)
|
|
188
|
+
handler.setLevel(logging.DEBUG)
|
|
189
|
+
target.addHandler(handler)
|
|
190
|
+
if target.level == logging.NOTSET or (
|
|
191
|
+
target.level > logging.INFO and not os.environ.get(LOG_LEVEL)
|
|
192
|
+
):
|
|
193
|
+
target.setLevel(logging.INFO)
|
|
194
|
+
_buffer = handler
|
|
195
|
+
return handler
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def get_log_buffer() -> InMemoryLogBuffer | None:
|
|
199
|
+
"""Return the installed buffer handler.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
The installed buffer handler, or `None` if not yet installed.
|
|
203
|
+
"""
|
|
204
|
+
return _buffer
|
|
@@ -44,6 +44,13 @@ rather than forcing the default). Also settable via `[ui].collapse_pastes` in
|
|
|
44
44
|
config.toml.
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
+
CURSOR_STYLE = "DEEPAGENTS_CODE_CURSOR_STYLE"
|
|
48
|
+
"""Chat input cursor style (`block` or `underline`).
|
|
49
|
+
|
|
50
|
+
Takes precedence over `[ui].cursor_style` in config.toml. Invalid values fall
|
|
51
|
+
through to the config file and then the default block cursor.
|
|
52
|
+
"""
|
|
53
|
+
|
|
47
54
|
DEBUG = "DEEPAGENTS_CODE_DEBUG"
|
|
48
55
|
"""Enable verbose debug logging and preserve the server subprocess log.
|
|
49
56
|
|
|
@@ -183,6 +190,12 @@ The value is comma-separated for forward-compatibility, not because multiple
|
|
|
183
190
|
destinations are written today.
|
|
184
191
|
"""
|
|
185
192
|
|
|
193
|
+
LOG_LEVEL = "DEEPAGENTS_CODE_LOG_LEVEL"
|
|
194
|
+
"""Minimum level for `deepagents_code` runtime logging.
|
|
195
|
+
|
|
196
|
+
Accepted values are DEBUG, INFO, WARNING, ERROR, and CRITICAL.
|
|
197
|
+
"""
|
|
198
|
+
|
|
186
199
|
NO_TERMINAL_ESCAPE = "DEEPAGENTS_CODE_NO_TERMINAL_ESCAPE"
|
|
187
200
|
"""Disable all terminal escape/control sequence output when enabled."""
|
|
188
201
|
|