deepagents-code 0.1.23__tar.gz → 0.1.25__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.23 → deepagents_code-0.1.25}/CHANGELOG.md +30 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/Makefile +1 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/PKG-INFO +8 -2
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/README.md +6 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/THREAT_MODEL.md +21 -10
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_cli_context.py +11 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_env_vars.py +19 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_server_config.py +75 -3
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/agent.py +59 -3
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/app.py +248 -38
- deepagents_code-0.1.25/deepagents_code/approval_mode.py +131 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/auth_store.py +5 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/config.py +47 -6
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/config_commands.py +189 -31
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/config_manifest.py +30 -3
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/configurable_model.py +3 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/extras_info.py +115 -17
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/file_ops.py +42 -11
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/main.py +146 -33
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/managed_tools.py +77 -6
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/memory_guard.py +83 -15
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/non_interactive.py +2 -2
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/remote_client.py +52 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/server.py +102 -10
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/server_graph.py +132 -67
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/server_manager.py +15 -9
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/sessions.py +2 -2
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/textual_adapter.py +109 -6
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/tool_display.py +1 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/tools.py +89 -2
- deepagents_code-0.1.25/deepagents_code/tools_commands.py +191 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/ui.py +61 -3
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/update_check.py +242 -19
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/_links.py +21 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/approval.py +7 -4
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/chat_input.py +83 -26
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/messages.py +20 -1
- deepagents_code-0.1.25/deepagents_code/widgets/subagent_panel.py +969 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/tool_renderers.py +42 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/welcome.py +2 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/pyproject.toml +8 -5
- deepagents_code-0.1.25/scripts/check_imports.py +44 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/scripts/install.sh +37 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/conftest.py +32 -13
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_agent.py +185 -6
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_agent_friendly.py +8 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_app.py +520 -21
- deepagents_code-0.1.25/tests/unit_tests/test_approval_mode.py +129 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_store.py +8 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_chat_input.py +280 -12
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_config.py +4 -4
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_config_manifest.py +392 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_configurable_model.py +34 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_extras_info.py +223 -11
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_file_ops.py +90 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_install_command.py +3 -9
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_install_script.py +92 -2
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_launch_init.py +1 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_links.py +29 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_local_context.py +39 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_main.py +48 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_main_args.py +342 -10
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_managed_tools.py +150 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_memory_guard.py +112 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_messages.py +79 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_non_interactive.py +1 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_reload.py +64 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_remote_client.py +75 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server.py +185 -4
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server_config.py +151 -0
- deepagents_code-0.1.25/tests/unit_tests/test_server_graph.py +425 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server_helpers.py +13 -10
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server_manager.py +48 -3
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sessions.py +24 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_startup_fast_paths.py +2 -0
- deepagents_code-0.1.25/tests/unit_tests/test_subagent_panel.py +549 -0
- deepagents_code-0.1.25/tests/unit_tests/test_subagent_stream.py +41 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_textual_adapter.py +227 -2
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_tool_display.py +9 -3
- deepagents_code-0.1.25/tests/unit_tests/test_tool_renderers.py +43 -0
- deepagents_code-0.1.25/tests/unit_tests/test_tools_commands.py +144 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_check.py +290 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_version.py +65 -4
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_welcome.py +5 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/tools/test_fetch_url.py +132 -1
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/uv.lock +11 -14
- deepagents_code-0.1.23/scripts/check_imports.py +0 -32
- deepagents_code-0.1.23/tests/unit_tests/test_server_graph.py +0 -199
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/.gitignore +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/AGENTS.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/COMMANDS.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/auth_commands.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_commands.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/model_config.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/auth.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/diff.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/history.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/install_confirm.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/loading.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/message_store.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/model_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/status.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/update_available.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/hatch_build.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/images/tui.png +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/README.md +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_commands.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_widgets.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_history.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_install_confirm.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_commands.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_status.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_confirm.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_progress.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/widgets/__init__.py +0 -0
- {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/widgets/test_diff.py +0 -0
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.25](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.24...deepagents-code==0.1.25) (2026-06-26)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* Bind ephemeral port instead of squatting `langgraph dev`'s 2024 ([#4264](https://github.com/langchain-ai/deepagents/issues/4264)) ([11e5359](https://github.com/langchain-ai/deepagents/commit/11e5359851f0291783661b4311ad5e4436a36fb7))
|
|
10
|
+
* Block dotenv shell startup hooks ([#4288](https://github.com/langchain-ai/deepagents/issues/4288)) ([686d6f3](https://github.com/langchain-ai/deepagents/commit/686d6f3a1da8b6393efb4c0cf87b3eb35e0cca50))
|
|
11
|
+
* Defer server graph construction ([#4300](https://github.com/langchain-ai/deepagents/issues/4300)) ([220dfc0](https://github.com/langchain-ai/deepagents/commit/220dfc0e6b03f9ccb499c6b850c586b9d57cc077))
|
|
12
|
+
* Avoid blocking MCP imports during graph readiness ([#4302](https://github.com/langchain-ai/deepagents/issues/4302)) ([7533ca8](https://github.com/langchain-ai/deepagents/commit/7533ca89f3afc9863ba5e1ecee2d4c5974dea320))
|
|
13
|
+
* Gate `delete` file operations ([#4299](https://github.com/langchain-ai/deepagents/issues/4299)) ([92a8681](https://github.com/langchain-ai/deepagents/commit/92a86819adfefbc6ccfd01a861191ba292eca754))
|
|
14
|
+
* Handle recursive `fetch_url` conversion ([#4257](https://github.com/langchain-ai/deepagents/issues/4257)) ([f240a40](https://github.com/langchain-ai/deepagents/commit/f240a40dc05d812c38e9926c1d81ba38deb86e3f))
|
|
15
|
+
* Report editable SDK runtime version ([#4304](https://github.com/langchain-ai/deepagents/issues/4304)) ([4439e91](https://github.com/langchain-ai/deepagents/commit/4439e912da4bfa6f1e38e14b5a03d2bfe9367d3b))
|
|
16
|
+
* Show months instead of "0y ago" for 360-364 day old timestamps ([#4267](https://github.com/langchain-ai/deepagents/issues/4267)) ([820b331](https://github.com/langchain-ai/deepagents/commit/820b331552cb7ce4695ddca3c9b8343a3144392b))
|
|
17
|
+
* Surface `/auth`-stored credentials in `config show`/`get` ([#4258](https://github.com/langchain-ai/deepagents/issues/4258)) ([c7c8788](https://github.com/langchain-ai/deepagents/commit/c7c8788ecf0068914298a6055a5f3fd31c36bd44))
|
|
18
|
+
* Switch input mode without flashing the mode trigger ([#4243](https://github.com/langchain-ai/deepagents/issues/4243)) ([fc5d9cb](https://github.com/langchain-ai/deepagents/commit/fc5d9cb8fb978ec95f98407692d4809ea1e86577))
|
|
19
|
+
|
|
20
|
+
## [0.1.24](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.23...deepagents-code==0.1.24) (2026-06-25)
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* Enable `js_eval` by default ([#4245](https://github.com/langchain-ai/deepagents/issues/4245)) ([2e04ff3](https://github.com/langchain-ai/deepagents/commit/2e04ff397e60389c9a19c4a9b528e15602ad8338))
|
|
25
|
+
* Dynamic subagents UI ([#4221](https://github.com/langchain-ai/deepagents/issues/4221)) ([10bcba2](https://github.com/langchain-ai/deepagents/commit/10bcba25600e51aba135f170b34aa6315c0f53d6))
|
|
26
|
+
* Gate onboarding integrations modal behind opt-in flag ([#4227](https://github.com/langchain-ai/deepagents/issues/4227)) ([6c930c5](https://github.com/langchain-ai/deepagents/commit/6c930c5e4502f572be554acc896c5fb6d061e0e5))
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* Eager managed ripgrep install via `dcode tools install` ([#4199](https://github.com/langchain-ai/deepagents/issues/4199)) ([cf536f3](https://github.com/langchain-ai/deepagents/commit/cf536f339958d6726fa41f896c4a3e42df644c9f))
|
|
31
|
+
* Interrupt remote runs on chat cancellation ([#4234](https://github.com/langchain-ai/deepagents/issues/4234)) ([37c5fa2](https://github.com/langchain-ai/deepagents/commit/37c5fa23e621616836694bc59c1b0c38def81604))
|
|
32
|
+
* Sync approval toggles during active runs ([#4239](https://github.com/langchain-ai/deepagents/issues/4239)) ([4600365](https://github.com/langchain-ai/deepagents/commit/4600365ea0b60c3e9113ecf59b5336be37d03428))
|
|
33
|
+
* Clear stale live approval mode keys ([#4242](https://github.com/langchain-ai/deepagents/issues/4242)) ([f11a769](https://github.com/langchain-ai/deepagents/commit/f11a76962c9d536a38e27ac05b32feca364b2424))
|
|
34
|
+
|
|
5
35
|
## [0.1.23](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.22...deepagents-code==0.1.23) (2026-06-25)
|
|
6
36
|
|
|
7
37
|
### Features
|
|
@@ -105,7 +105,7 @@ check: lint check_imports test
|
|
|
105
105
|
@echo "🔍 Verifying pyproject.toml and _version.py agree..."
|
|
106
106
|
uv run --all-groups python "$(REPO_ROOT)/.github/scripts/check_version_equality.py"
|
|
107
107
|
@echo "🔒 Verifying uv.lock is up-to-date..."
|
|
108
|
-
uv lock --check
|
|
108
|
+
UV_FROZEN=false uv lock --check
|
|
109
109
|
@echo "🔗 Checking SDK pin against workspace SDK (advisory)..."
|
|
110
110
|
@uv run --all-groups python "$(REPO_ROOT)/.github/scripts/check_sdk_pin.py" || \
|
|
111
111
|
{ rc=$$?; [ $$rc -eq 1 ] && echo "⚠️ Stale SDK pin (advisory, non-fatal)." || exit $$rc; }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.25
|
|
4
4
|
Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
@@ -33,6 +33,7 @@ Requires-Dist: langchain-anthropic<2.0.0,>=1.4.7
|
|
|
33
33
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.5
|
|
34
34
|
Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.3.0
|
|
35
35
|
Requires-Dist: langchain-openai<2.0.0,>=1.3.3
|
|
36
|
+
Requires-Dist: langchain-quickjs<0.4.0,>=0.3.2
|
|
36
37
|
Requires-Dist: langchain<2.0.0,>=1.3.11
|
|
37
38
|
Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.0
|
|
38
39
|
Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.30
|
|
@@ -123,7 +124,6 @@ Requires-Dist: langchain-openrouter<2.0.0,>=0.2.4; extra == 'openrouter'
|
|
|
123
124
|
Provides-Extra: perplexity
|
|
124
125
|
Requires-Dist: langchain-perplexity<2.0.0,>=1.4.0; extra == 'perplexity'
|
|
125
126
|
Provides-Extra: quickjs
|
|
126
|
-
Requires-Dist: langchain-quickjs<0.4.0,>=0.3.1; extra == 'quickjs'
|
|
127
127
|
Provides-Extra: runloop
|
|
128
128
|
Requires-Dist: langchain-runloop>=0.0.6; extra == 'runloop'
|
|
129
129
|
Provides-Extra: together
|
|
@@ -180,6 +180,12 @@ The fastest way to start using Deep Agents. `deepagents-code` is a pre-built cod
|
|
|
180
180
|
- **Headless mode** — run non-interactively for scripting and CI
|
|
181
181
|
- **Human-in-the-loop** — approve or reject tool calls before execution
|
|
182
182
|
|
|
183
|
+
## 🔒 Security model
|
|
184
|
+
|
|
185
|
+
By default, `dcode` trusts the directory you run it in. Human-in-the-loop approval gates model-requested tool calls, but project artifacts are read before any approval prompt.
|
|
186
|
+
|
|
187
|
+
Do not run `dcode` in a directory you do not trust without a sandbox backend. For untrusted repositories, use a [remote sandbox](https://docs.langchain.com/oss/python/deepagents/code/remote-sandboxes) so execution is isolated from your machine. Running `dcode` in a directory lets that directory's files shape execution. See [`THREAT_MODEL.md`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/THREAT_MODEL.md) for details.
|
|
188
|
+
|
|
183
189
|
## 📖 Resources
|
|
184
190
|
|
|
185
191
|
- **[Documentation](https://docs.langchain.com/deepagents-code)**
|
|
@@ -42,6 +42,12 @@ The fastest way to start using Deep Agents. `deepagents-code` is a pre-built cod
|
|
|
42
42
|
- **Headless mode** — run non-interactively for scripting and CI
|
|
43
43
|
- **Human-in-the-loop** — approve or reject tool calls before execution
|
|
44
44
|
|
|
45
|
+
## 🔒 Security model
|
|
46
|
+
|
|
47
|
+
By default, `dcode` trusts the directory you run it in. Human-in-the-loop approval gates model-requested tool calls, but project artifacts are read before any approval prompt.
|
|
48
|
+
|
|
49
|
+
Do not run `dcode` in a directory you do not trust without a sandbox backend. For untrusted repositories, use a [remote sandbox](https://docs.langchain.com/oss/python/deepagents/code/remote-sandboxes) so execution is isolated from your machine. Running `dcode` in a directory lets that directory's files shape execution. See [`THREAT_MODEL.md`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/THREAT_MODEL.md) for details.
|
|
50
|
+
|
|
45
51
|
## 📖 Resources
|
|
46
52
|
|
|
47
53
|
- **[Documentation](https://docs.langchain.com/deepagents-code)**
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
| TB8 | CLI → Server Subprocess IPC | Config passed from CLI to `langgraph dev` subprocess via `DA_SERVER_*` env vars | `ServerConfig.to_env()` serialization; env var scoping to parent+child process | Subprocess environment post-fork; /proc visibility to same-uid processes |
|
|
208
208
|
| TB9 | LocalContextMiddleware → Host Env | Bash detect script output (git info, project files, Makefile) injected into system prompt | Script is framework-generated static code; 30s timeout; exit-code check | Content of Makefile, pyproject.toml, git branch names, directory listing |
|
|
209
209
|
| TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
|
|
210
|
-
| TB11 | Config File → Code Execution | `class_path` in `config.toml` triggers `importlib.import_module()`
|
|
210
|
+
| TB11 | Config File → Code Execution | `class_path` in `config.toml` triggers `importlib.import_module()`; project/global `.env` values are loaded into the process environment and can reach Bash startup hooks | Format validation (`module:ClassName`); `issubclass(BaseChatModel)` check; dotenv loading denies shell startup / environment-hijack keys (`BASH_ENV`, `ENV`) | Module-level side effects execute during import; user controls config file; project files in the working directory influence execution |
|
|
211
211
|
|
|
212
212
|
### Boundary Details
|
|
213
213
|
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
|
|
251
251
|
#### TB10: RemoteAgent → LangGraph Dev Server
|
|
252
252
|
|
|
253
|
-
- **Inside**: Server bound to `127.0.0.1` by default; `server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end.
|
|
253
|
+
- **Inside**: Server bound to `127.0.0.1` by default; `server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Binds a free ephemeral port by default (`server.py:_EPHEMERAL_PORT`); an explicit port is honored but still falls back to a free port if occupied.
|
|
254
254
|
- **Outside**: `LANGGRAPH_AUTH_TYPE=noop` disables all LangGraph server authentication. Any process on localhost that discovers the port can submit requests, read thread state, or inject messages.
|
|
255
255
|
- **Crossing mechanism**: HTTP POST/GET to `http://127.0.0.1:{port}` using `langgraph.pregel.remote.RemoteGraph`.
|
|
256
256
|
|
|
@@ -259,6 +259,8 @@
|
|
|
259
259
|
- **Inside**: `config._create_model_from_class` validates `class_path` format (`module:ClassName`), imports the module via `importlib.import_module()`, and checks `issubclass(cls, BaseChatModel)` before instantiation.
|
|
260
260
|
- **Outside**: Module-level code in the imported module executes unconditionally during `import_module()`. The `issubclass` check only runs after import. Any side effects (file I/O, network calls, subprocess spawning) in the module's top-level scope execute before the type check.
|
|
261
261
|
- **Crossing mechanism**: `importlib.import_module(module_path)` in `config._create_model_from_class`.
|
|
262
|
+
- **Inside (dotenv)**: `config._load_dotenv` loads project and global `.env` values with `override=False` and drops shell startup / environment-hijack keys (`BASH_ENV`, `ENV`, and related) so a project `.env` cannot register a script that Bash would source at startup. The preview path (`_preview_dotenv_environ`) applies the same denylist so a dry-run config change cannot report a value a real reload would reject.
|
|
263
|
+
- **Outside (dotenv)**: All other `.env` keys are applied to the process environment, and any project file in the working directory (`.env`, `Makefile`, build scripts) can still influence execution. See T12.
|
|
262
264
|
|
|
263
265
|
---
|
|
264
266
|
|
|
@@ -346,6 +348,7 @@
|
|
|
346
348
|
| T8 | DF21 | DC3 | Custom subagent AGENTS.md body used verbatim as system_prompt without content validation | None | Low | Verified | `subagents._parse_subagent_file`, `agent.create_cli_agent` |
|
|
347
349
|
| T9 | DF23 | — | `class_path` in config.toml triggers arbitrary Python code execution via `importlib.import_module()` | TB11 | Low | Verified | `config._create_model_from_class`, `model_config.ProviderConfig` |
|
|
348
350
|
| T10 | DF24 | DC1 | MCP stdio subprocess env dict accepts arbitrary keys including `PATH`, `LD_PRELOAD`, `PYTHONPATH` without filtering | TB4 | Low | Verified | `mcp_tools._validate_server_config`, `mcp_tools._load_tools_from_config` |
|
|
351
|
+
| T12 | DF10 | — | Project `.env` sets shell startup-hook variables (`BASH_ENV`, `ENV`) that run attacker-controlled scripts when `dcode` spawns Bash, before any HITL approval | TB11 | High | Verified | `config._load_dotenv`, `local_context.build_detect_script` |
|
|
349
352
|
|
|
350
353
|
### Threat Details
|
|
351
354
|
|
|
@@ -382,7 +385,7 @@
|
|
|
382
385
|
#### T6: Unauthenticated LangGraph Dev Server on Localhost
|
|
383
386
|
|
|
384
387
|
- **Flow**: DF3/DF4 (CLI ↔ LangGraph dev server)
|
|
385
|
-
- **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (
|
|
388
|
+
- **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (a free ephemeral port by default, so it no longer squats the well-known `langgraph dev` port 2024). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
|
|
386
389
|
- **Preconditions**: (1) Attacker has a local process running as the same user (or as root); (2) Attacker discovers the server port (port scan on localhost, or reads process arguments).
|
|
387
390
|
|
|
388
391
|
#### T7: LocalContextMiddleware Injects Host File Contents into System Prompt
|
|
@@ -411,10 +414,16 @@
|
|
|
411
414
|
|
|
412
415
|
#### T11: Auto-Installed ripgrep Binary from Upstream Release
|
|
413
416
|
|
|
414
|
-
- **Flow**:
|
|
415
|
-
- **Description**:
|
|
416
|
-
- **Mitigations**: (1) SHA-256 verified against the pinned hash table before move — a mismatch aborts the install and leaves `BIN_DIR` clean. (2) Network egress is limited to `github.com`. (3) Opt-out via `DEEPAGENTS_CODE_OFFLINE` for air-gapped environments. (4) Pinned version + checksums are bumped in-tree, so a compromised upstream release is detected on the next Deep Agents Code release rather than silently propagating. (5) Atomic move-into-place avoids partial installs when concurrent CLI invocations race.
|
|
417
|
-
- **Preconditions**: User has not installed `rg` via their package manager, `DEEPAGENTS_CODE_OFFLINE` is unset, and the host can reach `github.com`. The pinned SHA-256 in `RIPGREP_ASSETS` would need to be incorrect (a supply-chain compromise of the deepagents-code release) for a tampered binary to be installed.
|
|
417
|
+
- **Flow**: Download performed by `managed_tools.ensure_ripgrep` when `rg` is not on `PATH` — either on first run, or eagerly at install time via `dcode tools install` (invoked by `scripts/install.sh`).
|
|
418
|
+
- **Description**: Without a system `rg`, Deep Agents Code fetches the pinned ripgrep release tarball from `github.com/BurntSushi/ripgrep/releases/...`, verifies it against an in-tree SHA-256 (`RIPGREP_ASSETS`), extracts it under a `TemporaryDirectory`, and atomically moves the binary into `~/.deepagents/bin/rg`. The binary then runs unsandboxed, inheriting the same trust as a user-installed `rg` (the SDK invokes it via `subprocess.run(["rg", ...])`). The same verified path backs the `dcode tools install` verb, so the install script reuses it rather than re-encoding the version + checksum table in bash.
|
|
419
|
+
- **Mitigations**: (1) SHA-256 verified against the pinned hash table before move — a mismatch aborts the install and leaves `BIN_DIR` clean. (2) Network egress is limited to `github.com`. (3) Opt-out via `DEEPAGENTS_CODE_OFFLINE` for air-gapped environments, or `DEEPAGENTS_CODE_RIPGREP_INSTALLER=system` to defer to the OS package manager instead of the managed binary. (4) Pinned version + checksums are bumped in-tree, so a compromised upstream release is detected on the next Deep Agents Code release rather than silently propagating. (5) Atomic move-into-place avoids partial installs when concurrent CLI invocations race. (6) The eager install-script path is non-`sudo` (no system package manager is invoked in the default `managed` mode).
|
|
420
|
+
- **Preconditions**: User has not installed `rg` via their package manager, `DEEPAGENTS_CODE_OFFLINE` is unset, `DEEPAGENTS_CODE_RIPGREP_INSTALLER` is not `system`, and the host can reach `github.com`. The pinned SHA-256 in `RIPGREP_ASSETS` would need to be incorrect (a supply-chain compromise of the deepagents-code release) for a tampered binary to be installed.
|
|
421
|
+
|
|
422
|
+
#### T12: Project `.env` Injects Shell Interpreter Startup Hooks
|
|
423
|
+
|
|
424
|
+
- **Flow**: DF10 (project `.env` → process environment) → bash subprocess startup (DF19)
|
|
425
|
+
- **Description**: `config._load_dotenv` discovers the nearest project `.env` by walking up from the working directory and applies its values to the process environment (`override=False`, so shell-exported values still win). Bash treats several environment variables as startup hooks — `BASH_ENV` and `ENV` name a file that is sourced when a non-interactive shell starts. Because Deep Agents Code runs its own local-context detection through Bash at startup (`local_context.build_detect_script`) and spawns shells for the `execute` tool, a project `.env` that sets one of these keys could run attacker-controlled scripts inside the `dcode` process *before* any model-requested tool call or HITL approval prompt. The broader trust boundary is that running `dcode` in a project directory lets that project influence the process environment.
|
|
426
|
+
- **Preconditions**: (1) User launches `dcode` in a directory containing an attacker-controlled `.env` (for example, a freshly cloned untrusted repository); (2) the `.env` sets a shell startup-hook key that is not already exported in the user's shell (dotenv uses `override=False`).
|
|
418
427
|
|
|
419
428
|
---
|
|
420
429
|
|
|
@@ -426,7 +435,7 @@
|
|
|
426
435
|
| LLM output | DF6, DF7 | T1, T2, T3, T4| HITL gate; shell allow-list; Unicode/URL warnings on tool args | Project | LLM-generated tool args not scanned for injection beyond Unicode/URL |
|
|
427
436
|
| Tool/function results | DF9, DF11 | T1 | Unicode warning on URL args; `markdownify` HTML conversion | Shared | Tool *results* pass to context without prompt-injection scan |
|
|
428
437
|
| URL-fetched content | DF8, DF9 | T1 | `check_url_safety` on URL arg; HTML→markdown conversion | Shared | Markup-embedded instructions survive markdownify; no LLM-layer guardrail |
|
|
429
|
-
| Configuration | DF10, DF12, DF15, DF23| T9, T10
|
|
438
|
+
| Configuration | DF10, DF12, DF15, DF23| T9, T10, T12 | Dotenv shell-env precedence; TOML schema; MCP schema + fingerprint; JSON structure check; `class_path` format check | User | Project `.env` can set shell startup-hook vars; `class_path` executes module code before type check; MCP env dict unfiltered |
|
|
430
439
|
| Session restore | DF14 | T5 | OS file permissions; SQLite | Project | Unencrypted at rest |
|
|
431
440
|
| Server IPC (env vars) | DF18 | T6 | `ServerConfig` serialization; parent env passed to child | Project | Provider API keys flow to server subprocess; system prompt in env |
|
|
432
441
|
| Host environment | DF19, DF20 | T7 | Static script; exit code check; 30s timeout | Shared | Makefile content injected into system prompt without sanitization |
|
|
@@ -450,8 +459,8 @@ Threats that appear valid in isolation but fall outside project responsibility b
|
|
|
450
459
|
| Sandbox provider security vulnerabilities | Daytona, LangSmith, Modal, Runloop, and AgentCore are third-party services. Their internal security is not this project's responsibility. | Correctly initializing sandbox sessions via `integrations.sandbox_factory.create_sandbox`. |
|
|
451
460
|
| Hook commands doing harmful things | Hooks in `~/.deepagents/hooks.json` are 100% user-authored. The payload is data-only (JSON on stdin). | JSON structure validation (`hooks._load_hooks`); 5-second timeout. |
|
|
452
461
|
| Async subagent traffic interception / MitM | Async subagents connect to user-configured LangGraph deployment URLs. The project does not control those endpoints or their TLS certificates. | Accepting URL/headers from user config and passing them to the LangGraph SDK (`agent.load_async_subagents`). |
|
|
453
|
-
| LangGraph dev server port enumeration / discovery | Discovering the local dev server port requires local access. Port scanning localhost is a general OS security concern, not a framework vulnerability. | Binding to `127.0.0.1` by default (`server._DEFAULT_HOST`); ephemeral server lifetime.
|
|
454
|
-
| `.env` file from parent directory changes
|
|
462
|
+
| LangGraph dev server port enumeration / discovery | Discovering the local dev server port requires local access. Port scanning localhost is a general OS security concern, not a framework vulnerability. | Binding to `127.0.0.1` by default (`server._DEFAULT_HOST`); ephemeral server lifetime; OS-assigned ephemeral port (`server._EPHEMERAL_PORT`) is not predictable across runs. |
|
|
463
|
+
| `.env` file from parent directory changes app/API configuration | `config._find_dotenv_from_start_path` walks up the directory tree to find `.env` files. Discovering ordinary configuration values (API keys, `DEEPAGENTS_CODE_*` settings) this way is standard `python-dotenv` behavior, and the user controls their filesystem. The *code-execution* implication of a project `.env` (shell startup hooks) is tracked in-scope as T12. | Finding `.env` from the project root (`config._find_dotenv_from_start_path`); `override=False` by default (existing env vars preserved); shell startup / environment-hijack keys (`BASH_ENV`, `ENV`) denied during dotenv loading. |
|
|
455
464
|
|
|
456
465
|
### Rationale
|
|
457
466
|
|
|
@@ -483,3 +492,5 @@ Threats that appear valid in isolation but fall outside project responsibility b
|
|
|
483
492
|
| 2026-03-10 | langster-threat-model (automated) | Initial threat model |
|
|
484
493
|
| 2026-03-27 | langster-threat-model (automated) | Deep expansion: added C11-C16 (server subprocess, RemoteAgent, LocalContextMiddleware, async subagent config, custom subagent loader); added TB8-TB10 (CLI/server IPC, LocalContext/host env, RemoteAgent/dev server); added DF18-DF22; added T6 (unauthenticated dev server), T7 (Makefile injection), T8 (subagent body injection); updated T5 (upstream msgpack fix confirmed); added data classification; added Investigated and Dismissed section; updated architecture diagram to reflect server-subprocess model |
|
|
485
494
|
| 2026-03-28 | langster-threat-model (automated) | Deep validation pass: added C17 (Model Config Loader with class_path), TB11 (Config→Code Execution); added DC5 (offloaded conversation history); added DF23-DF25 (class_path flow, MCP env dict flow, offload flow); added T9 (class_path arbitrary code execution), T10 (MCP env dict unfiltered); added D3 (SSRF dismissed — HITL is intended control), D4 (offload path injection dismissed — UUID7); **removed Status column and Mitigations/Residual Risk fields from all threats** (open source visibility compliance — mitigation status must not appear in public threat models); updated T6 validation from Likely to Verified (port is deterministic at 2024 default, discoverable via /proc); updated external context (no published advisories found); updated architecture diagram |
|
|
495
|
+
| 2026-06-25 | manual update | Added T12 (project `.env` injects shell interpreter startup hooks) under TB11; extended the TB11 boundary controls and details with the dotenv shell-startup-hook denylist (`BASH_ENV`, `ENV`); clarified the `.env` out-of-scope row to separate ordinary config discovery from the in-scope code-execution implication |
|
|
496
|
+
| 2026-06-25 | manual update | Updated T6 and TB10 to reflect the dev server binding an OS-assigned ephemeral port by default (`server._EPHEMERAL_PORT`) instead of squatting the well-known `langgraph dev` port 2024; noted unpredictable-port-across-runs as added defense-in-depth in the port-discovery dismissal row |
|
|
@@ -39,6 +39,8 @@ class CLIContextSchema:
|
|
|
39
39
|
|
|
40
40
|
auto_approve: bool = False
|
|
41
41
|
|
|
42
|
+
approval_mode_key: str | None = None
|
|
43
|
+
|
|
42
44
|
|
|
43
45
|
class CLIContext(TypedDict, total=False):
|
|
44
46
|
"""Client-facing builder for the per-run graph context payload.
|
|
@@ -76,3 +78,12 @@ class CLIContext(TypedDict, total=False):
|
|
|
76
78
|
this to suppress interrupts at the source when "approve always" is on,
|
|
77
79
|
avoiding the interrupt-then-auto-resolve round-trip.
|
|
78
80
|
"""
|
|
81
|
+
|
|
82
|
+
approval_mode_key: str | None
|
|
83
|
+
"""Store key for the live approval-mode control record.
|
|
84
|
+
|
|
85
|
+
The TUI updates this record when the user toggles approval mode mid-run.
|
|
86
|
+
The server-side interrupt predicate reads it from the LangGraph Store on
|
|
87
|
+
each gated tool call so auto-to-manual changes can take effect before the
|
|
88
|
+
current stream returns.
|
|
89
|
+
"""
|
|
@@ -158,6 +158,15 @@ and `/api/show`. See `_ollama_discovery_enabled` for accepted truthy/falsy
|
|
|
158
158
|
values.
|
|
159
159
|
"""
|
|
160
160
|
|
|
161
|
+
ONBOARDING_INTEGRATIONS_SCREEN = "DEEPAGENTS_CODE_ONBOARDING_INTEGRATIONS_SCREEN"
|
|
162
|
+
"""Show the "Installed Integrations" summary screen during first-run onboarding.
|
|
163
|
+
|
|
164
|
+
Off by default: onboarding goes straight from the name prompt to the model
|
|
165
|
+
selector, which already surfaces (and installs) uninstalled model providers.
|
|
166
|
+
Set to a truthy value to bring the standalone integrations screen back into the
|
|
167
|
+
flow. Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
|
|
168
|
+
"""
|
|
169
|
+
|
|
161
170
|
RESTARTED_AFTER_UPDATE = "DEEPAGENTS_CODE_RESTARTED_AFTER_UPDATE"
|
|
162
171
|
"""Internal sentinel recording the target version immediately before the
|
|
163
172
|
startup auto-update re-execs the process.
|
|
@@ -168,6 +177,16 @@ version), skips auto-updating to break out of an otherwise endless
|
|
|
168
177
|
upgrade/restart loop. Set and read internally across `os.execv`.
|
|
169
178
|
"""
|
|
170
179
|
|
|
180
|
+
RIPGREP_INSTALLER = "DEEPAGENTS_CODE_RIPGREP_INSTALLER"
|
|
181
|
+
"""Select how ripgrep is provisioned: `managed` (default) or `system`.
|
|
182
|
+
|
|
183
|
+
`managed` downloads the pinned, SHA-256-verified upstream binary into
|
|
184
|
+
`~/.deepagents/bin` (no sudo). `system` skips that download so power users can
|
|
185
|
+
rely on their distro package / existing toolchain instead; the install script's
|
|
186
|
+
`system` mode keeps the brew/apt/cargo path. A system `rg` already on `PATH` is
|
|
187
|
+
reused under either setting. Unrecognized values fall back to `managed`. See
|
|
188
|
+
`managed_tools.ripgrep_installer`."""
|
|
189
|
+
|
|
171
190
|
SERVER_ENV_PREFIX = "DEEPAGENTS_CODE_SERVER_"
|
|
172
191
|
"""Environment variable prefix used to pass CLI config to the server subprocess."""
|
|
173
192
|
|
|
@@ -101,6 +101,67 @@ def _read_env_optional_bool(suffix: str) -> bool | None:
|
|
|
101
101
|
return raw.lower() == "true"
|
|
102
102
|
|
|
103
103
|
|
|
104
|
+
def _resolve_enable_interpreter(
|
|
105
|
+
enable_interpreter: bool | None, sandbox_type: str | None
|
|
106
|
+
) -> bool:
|
|
107
|
+
"""Resolve the interpreter's tri-state caller option to a concrete boolean.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
enable_interpreter: Explicit caller preference, or `None` to use the
|
|
111
|
+
sandbox-aware default.
|
|
112
|
+
sandbox_type: Sandbox backend identifier. Any falsy value (`None`, `""`)
|
|
113
|
+
or `"none"` is treated as local execution.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
The explicit `enable_interpreter` value when not `None`; `False` for
|
|
117
|
+
remote-sandbox defaults; otherwise the configured local default
|
|
118
|
+
(`settings.enable_interpreter`).
|
|
119
|
+
"""
|
|
120
|
+
if enable_interpreter is not None:
|
|
121
|
+
return enable_interpreter
|
|
122
|
+
if sandbox_type and sandbox_type != "none":
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
from deepagents_code.config import settings
|
|
126
|
+
|
|
127
|
+
return settings.enable_interpreter
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _interpreter_suppressed_by_sandbox(
|
|
131
|
+
*, enable_interpreter: bool | None, sandbox_type: str | None, local_default: bool
|
|
132
|
+
) -> bool:
|
|
133
|
+
"""Whether a remote sandbox suppressed the otherwise-default interpreter.
|
|
134
|
+
|
|
135
|
+
Used to decide whether to surface an advisory: returns `True` only when the
|
|
136
|
+
user made no explicit choice, a remote sandbox is active, and the local
|
|
137
|
+
default would have enabled it — i.e. the sandbox (not an explicit
|
|
138
|
+
`--no-interpreter` opt-out, nor a disabled `[interpreter]` config) is why
|
|
139
|
+
`js_eval` is unavailable.
|
|
140
|
+
|
|
141
|
+
Takes the *raw* tri-state caller intent rather than the resolved boolean: a
|
|
142
|
+
sandbox-suppressed default and an explicit `--no-interpreter` both resolve to
|
|
143
|
+
`False`, so the resolved value cannot distinguish them. Any explicit choice
|
|
144
|
+
(`not None`) is the user's own decision and is left unannounced.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
enable_interpreter: The raw tri-state caller intent (`--interpreter` →
|
|
148
|
+
`True`, `--no-interpreter` → `False`, unset → `None`).
|
|
149
|
+
sandbox_type: Sandbox backend identifier. Any falsy value (`None`, `""`)
|
|
150
|
+
or `"none"` is treated as local execution.
|
|
151
|
+
local_default: The local-mode default (`settings.enable_interpreter`);
|
|
152
|
+
gating on it keeps the advisory quiet for users who disabled the
|
|
153
|
+
interpreter in config.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
`True` when the advisory should be shown, otherwise `False`.
|
|
157
|
+
"""
|
|
158
|
+
if enable_interpreter is not None:
|
|
159
|
+
return False
|
|
160
|
+
if not (sandbox_type and sandbox_type != "none"):
|
|
161
|
+
return False
|
|
162
|
+
return local_default
|
|
163
|
+
|
|
164
|
+
|
|
104
165
|
@dataclass(frozen=True)
|
|
105
166
|
class ServerConfig:
|
|
106
167
|
"""Full configuration payload passed from the app to the server subprocess.
|
|
@@ -155,6 +216,13 @@ class ServerConfig:
|
|
|
155
216
|
enable_interpreter: bool = False
|
|
156
217
|
"""Enable `CodeInterpreterMiddleware` (`js_eval` REPL) on the main agent.
|
|
157
218
|
|
|
219
|
+
Always the resolved concrete value: `from_cli_args` collapses the tri-state
|
|
220
|
+
caller option via `_resolve_enable_interpreter` before constructing the
|
|
221
|
+
config, so the `bool | None` "defer to default" sentinel never reaches this
|
|
222
|
+
field. The `False` default here is only the bare-constructor/`from_env`
|
|
223
|
+
fallback; the user-facing default (on in local mode) lives in
|
|
224
|
+
`settings.enable_interpreter`.
|
|
225
|
+
|
|
158
226
|
Local-mode only; the server graph raises if a sandbox is configured and
|
|
159
227
|
this flag is `True`.
|
|
160
228
|
"""
|
|
@@ -341,7 +409,7 @@ class ServerConfig:
|
|
|
341
409
|
sandbox_setup: str | None,
|
|
342
410
|
enable_shell: bool,
|
|
343
411
|
enable_ask_user: bool,
|
|
344
|
-
enable_interpreter: bool =
|
|
412
|
+
enable_interpreter: bool | None = None,
|
|
345
413
|
interpreter_ptc: str | list[str] | None = None,
|
|
346
414
|
interpreter_ptc_acknowledge_unsafe: bool = False,
|
|
347
415
|
mcp_config_path: str | None,
|
|
@@ -373,7 +441,7 @@ class ServerConfig:
|
|
|
373
441
|
enable_shell: Enable shell execution tools.
|
|
374
442
|
enable_ask_user: Enable ask_user tool.
|
|
375
443
|
enable_interpreter: Enable `CodeInterpreterMiddleware` on the main
|
|
376
|
-
agent.
|
|
444
|
+
agent. `None` uses the sandbox-aware default.
|
|
377
445
|
interpreter_ptc: Override for `settings.interpreter_ptc`.
|
|
378
446
|
interpreter_ptc_acknowledge_unsafe: Mirror of
|
|
379
447
|
`settings.interpreter_ptc_acknowledge_unsafe`.
|
|
@@ -387,6 +455,10 @@ class ServerConfig:
|
|
|
387
455
|
"""
|
|
388
456
|
normalized_mcp = _normalize_path(mcp_config_path, project_context, "MCP config")
|
|
389
457
|
|
|
458
|
+
resolved_enable_interpreter = _resolve_enable_interpreter(
|
|
459
|
+
enable_interpreter, sandbox_type
|
|
460
|
+
)
|
|
461
|
+
|
|
390
462
|
return cls(
|
|
391
463
|
model=model_name,
|
|
392
464
|
model_params=model_params,
|
|
@@ -397,7 +469,7 @@ class ServerConfig:
|
|
|
397
469
|
interactive=interactive,
|
|
398
470
|
enable_shell=enable_shell,
|
|
399
471
|
enable_ask_user=enable_ask_user,
|
|
400
|
-
enable_interpreter=
|
|
472
|
+
enable_interpreter=resolved_enable_interpreter,
|
|
401
473
|
interpreter_ptc=interpreter_ptc,
|
|
402
474
|
interpreter_ptc_acknowledge_unsafe=interpreter_ptc_acknowledge_unsafe,
|
|
403
475
|
sandbox_type=sandbox_type,
|
|
@@ -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.25" # 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."""
|
|
@@ -217,7 +217,7 @@ class ShellAllowListMiddleware(AgentMiddleware):
|
|
|
217
217
|
|
|
218
218
|
|
|
219
219
|
_INTERPRETER_WRITE_TOOLS: frozenset[str] = frozenset(
|
|
220
|
-
{"execute", "write_file", "edit_file"}
|
|
220
|
+
{"execute", "write_file", "edit_file", "delete"}
|
|
221
221
|
)
|
|
222
222
|
"""Tools considered write/shell capable for PTC auditing.
|
|
223
223
|
|
|
@@ -910,6 +910,17 @@ def _format_edit_file_description(
|
|
|
910
910
|
return f"Action: Replace text ({scope})"
|
|
911
911
|
|
|
912
912
|
|
|
913
|
+
def _format_delete_description(
|
|
914
|
+
_tool_call: ToolCall, _state: AgentState[Any], _runtime: Runtime[Any]
|
|
915
|
+
) -> str:
|
|
916
|
+
"""Format delete tool call for approval prompt.
|
|
917
|
+
|
|
918
|
+
Returns:
|
|
919
|
+
Formatted description string for the delete tool call.
|
|
920
|
+
"""
|
|
921
|
+
return "Action: Delete file or directory"
|
|
922
|
+
|
|
923
|
+
|
|
913
924
|
def _format_web_search_description(
|
|
914
925
|
tool_call: ToolCall, _state: AgentState[Any], _runtime: Runtime[Any]
|
|
915
926
|
) -> str:
|
|
@@ -1030,6 +1041,38 @@ def _is_auto_approve_enabled(value: object) -> bool:
|
|
|
1030
1041
|
return isinstance(value, bool) and value
|
|
1031
1042
|
|
|
1032
1043
|
|
|
1044
|
+
def _read_live_auto_approve(store: object, key: str | None) -> bool | None:
|
|
1045
|
+
"""Return live approval mode from the LangGraph Store when configured.
|
|
1046
|
+
|
|
1047
|
+
Args:
|
|
1048
|
+
store: `request.runtime.store` from the graph server.
|
|
1049
|
+
key: Live approval-mode store key, or `None` when this run has no live
|
|
1050
|
+
control record.
|
|
1051
|
+
|
|
1052
|
+
Returns:
|
|
1053
|
+
`None` when no live key is configured for this run — the caller should
|
|
1054
|
+
fall back to the static `auto_approve` context snapshot.
|
|
1055
|
+
`True` or `False` when a live key is configured: these reflect
|
|
1056
|
+
the stored mode, and `False` is also returned when the key
|
|
1057
|
+
is configured but the store is unreadable (missing item,
|
|
1058
|
+
malformed value, read error), so an unreadable live mode fails
|
|
1059
|
+
closed and interrupts.
|
|
1060
|
+
`None` therefore means "feature not in play," the opposite of the store
|
|
1061
|
+
reader's `None` ("unreadable, be careful").
|
|
1062
|
+
"""
|
|
1063
|
+
if not key:
|
|
1064
|
+
return None
|
|
1065
|
+
from deepagents_code.approval_mode import read_approval_mode_from_store
|
|
1066
|
+
|
|
1067
|
+
value = read_approval_mode_from_store(store, key)
|
|
1068
|
+
if value is None:
|
|
1069
|
+
logger.warning(
|
|
1070
|
+
"Approval-mode store item is unavailable; interrupting for safety"
|
|
1071
|
+
)
|
|
1072
|
+
return False
|
|
1073
|
+
return value
|
|
1074
|
+
|
|
1075
|
+
|
|
1033
1076
|
def _should_interrupt_tool_call(request: ToolCallRequest) -> bool:
|
|
1034
1077
|
"""Decide whether a gated tool call should pause for human approval.
|
|
1035
1078
|
|
|
@@ -1052,9 +1095,16 @@ def _should_interrupt_tool_call(request: ToolCallRequest) -> bool:
|
|
|
1052
1095
|
"""
|
|
1053
1096
|
runtime = getattr(request, "runtime", None)
|
|
1054
1097
|
ctx = getattr(runtime, "context", None)
|
|
1098
|
+
store = getattr(runtime, "store", None)
|
|
1055
1099
|
if isinstance(ctx, CLIContextSchema):
|
|
1100
|
+
if (live := _read_live_auto_approve(store, ctx.approval_mode_key)) is not None:
|
|
1101
|
+
return not live
|
|
1056
1102
|
return not _is_auto_approve_enabled(ctx.auto_approve)
|
|
1057
1103
|
if isinstance(ctx, dict):
|
|
1104
|
+
raw_key = ctx.get("approval_mode_key")
|
|
1105
|
+
key = raw_key if isinstance(raw_key, str) else None
|
|
1106
|
+
if (live := _read_live_auto_approve(store, key)) is not None:
|
|
1107
|
+
return not live
|
|
1058
1108
|
# Type-checked (not truthiness) check: over the JSON/RemoteGraph boundary a
|
|
1059
1109
|
# malformed payload (e.g. "yes", 1) must fail closed and interrupt, not
|
|
1060
1110
|
# silently auto-approve. Only a genuine boolean `True` suppresses.
|
|
@@ -1107,6 +1157,12 @@ def _add_interrupt_on() -> dict[str, InterruptOnConfig]:
|
|
|
1107
1157
|
"when": _should_interrupt_tool_call,
|
|
1108
1158
|
}
|
|
1109
1159
|
|
|
1160
|
+
delete_interrupt_config: InterruptOnConfig = {
|
|
1161
|
+
"allowed_decisions": ["approve", "reject"],
|
|
1162
|
+
"description": _format_delete_description, # ty: ignore[invalid-argument-type] # Callable description narrower than TypedDict expects
|
|
1163
|
+
"when": _should_interrupt_tool_call,
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1110
1166
|
web_search_interrupt_config: InterruptOnConfig = {
|
|
1111
1167
|
"allowed_decisions": ["approve", "reject"],
|
|
1112
1168
|
"description": _format_web_search_description, # ty: ignore[invalid-argument-type] # Callable description narrower than TypedDict expects
|
|
@@ -1135,6 +1191,7 @@ def _add_interrupt_on() -> dict[str, InterruptOnConfig]:
|
|
|
1135
1191
|
"execute": execute_interrupt_config,
|
|
1136
1192
|
"write_file": write_file_interrupt_config,
|
|
1137
1193
|
"edit_file": edit_file_interrupt_config,
|
|
1194
|
+
"delete": delete_interrupt_config,
|
|
1138
1195
|
"web_search": web_search_interrupt_config,
|
|
1139
1196
|
"fetch_url": fetch_url_interrupt_config,
|
|
1140
1197
|
"task": task_interrupt_config,
|
|
@@ -1267,8 +1324,7 @@ def create_cli_agent(
|
|
|
1267
1324
|
list or `interpreter_ptc="all"` with
|
|
1268
1325
|
`interpreter_ptc_acknowledge_unsafe=True`.
|
|
1269
1326
|
|
|
1270
|
-
Requires the `quickjs`
|
|
1271
|
-
(`langchain-quickjs>=0.3.1,<0.4.0`).
|
|
1327
|
+
Requires the core `langchain-quickjs` dependency.
|
|
1272
1328
|
checkpointer: Optional checkpointer for session persistence.
|
|
1273
1329
|
When `None`, the graph is compiled without a checkpointer.
|
|
1274
1330
|
mcp_server_info: MCP server metadata to surface in the system prompt.
|