deepagents-code 0.1.3__tar.gz → 0.1.4__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.3 → deepagents_code-0.1.4}/CHANGELOG.md +16 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/PKG-INFO +5 -3
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_server_config.py +55 -0
- deepagents_code-0.1.4/deepagents_code/_startup_error.py +45 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/agent.py +175 -1
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/app.py +76 -5
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/config.py +325 -15
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/extras_info.py +39 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/integrations/sandbox_factory.py +28 -5
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/main.py +126 -8
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_commands.py +74 -2
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_login_service.py +4 -4
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/non_interactive.py +16 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/server_graph.py +21 -8
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/server_manager.py +30 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/sessions.py +104 -7
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/textual_adapter.py +16 -9
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/tool_display.py +8 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/ui.py +37 -6
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/chat_input.py +80 -59
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/mcp_login.py +0 -1
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/messages.py +7 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/pyproject.toml +14 -2
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/install.sh +30 -19
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_agent.py +351 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_app.py +187 -19
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_args.py +194 -11
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_chat_input.py +221 -77
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_config.py +68 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_extras_info.py +36 -8
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_commands.py +1 -1
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_login_service.py +2 -2
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_non_interactive.py +45 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_sandbox_factory.py +80 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_config.py +27 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_graph.py +58 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_manager.py +1 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_sessions.py +254 -8
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_textual_adapter.py +27 -3
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/uv.lock +79 -9
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/.gitignore +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/AGENTS.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/COMMANDS.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/DEV.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/Makefile +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/README.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_env_vars.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/model_config.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/remote_client.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/server.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/token_state.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/update_check.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/_links.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/approval.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/auth.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/diff.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/history.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/loading.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/message_store.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/model_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/status.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/update_available.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/welcome.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/images/tui.png +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/README.md +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_agent_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_approval.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_ask_user.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_auth_widgets.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_autocomplete.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_history.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_launch_init.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_links.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_loading.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_tools.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_message_store.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_messages.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_model_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_notification_center.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_notification_detail.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_status.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_thread_selector.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_token_tracker.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_update_available.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_update_progress.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_welcome.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/tools/test_fetch_url.py +0 -0
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Deep Agents Code Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.4](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.3...deepagents-code==0.1.4) (2026-05-23)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* Add `--sandbox-snapshot-name` flag ([#3538](https://github.com/langchain-ai/deepagents/issues/3538)) ([b01392e](https://github.com/langchain-ai/deepagents/commit/b01392e7549798434f27f3784fa8c4e734053787))
|
|
8
|
+
* `dcode mcp config` and unify `--mcp-config` flag ([#3541](https://github.com/langchain-ai/deepagents/issues/3541)) ([f037b14](https://github.com/langchain-ai/deepagents/commit/f037b140f90a1ba3725b3ef23ab385b3cafe223b))
|
|
9
|
+
* Interpreter middleware via `langchain-quickjs` ([#3525](https://github.com/langchain-ai/deepagents/issues/3525)) ([f0ca89c](https://github.com/langchain-ai/deepagents/commit/f0ca89c962c22058194121526638bc2d29f546bd))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* Chat input history navigation and newline scrolling ([#3560](https://github.com/langchain-ai/deepagents/issues/3560)) ([3b51cbd](https://github.com/langchain-ai/deepagents/commit/3b51cbdc8c50d9990477e18a47de6a58e9165bab))
|
|
14
|
+
* Distinguish LangSmith failure modes in `/trace` ([#3558](https://github.com/langchain-ai/deepagents/issues/3558)) ([4d158a0](https://github.com/langchain-ai/deepagents/commit/4d158a031aecad8862e02e332f127573003938ec))
|
|
15
|
+
* Recover initial session prompts from writes table ([#3535](https://github.com/langchain-ai/deepagents/issues/3535)) ([46b6f3f](https://github.com/langchain-ai/deepagents/commit/46b6f3f3e6ce880cd5ec9cf59622bb745d6ac2eb))
|
|
16
|
+
* Install script binary checks reference `dcode` ([#3546](https://github.com/langchain-ai/deepagents/issues/3546)) ([f8977a6](https://github.com/langchain-ai/deepagents/commit/f8977a63769e3f2037619f32596cb9bb7bd1020b))
|
|
17
|
+
* Show tool call previews during batched HITL approvals ([#3530](https://github.com/langchain-ai/deepagents/issues/3530)) ([84daa1a](https://github.com/langchain-ai/deepagents/commit/84daa1a2e27963a6d7694dc9278de83782b4a7b7))
|
|
18
|
+
|
|
3
19
|
## [0.1.3](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.2...deepagents-code==0.1.3) (2026-05-20)
|
|
4
20
|
|
|
5
21
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
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/
|
|
@@ -69,7 +69,7 @@ Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.3; extra == 'all-providers'
|
|
|
69
69
|
Requires-Dist: langchain-groq<2.0.0,>=1.1.2; extra == 'all-providers'
|
|
70
70
|
Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
71
71
|
Requires-Dist: langchain-ibm<2.0.0,>=1.0.7; extra == 'all-providers'
|
|
72
|
-
Requires-Dist: langchain-litellm<2.0.0,>=0.6.
|
|
72
|
+
Requires-Dist: langchain-litellm<2.0.0,>=0.6.6; extra == 'all-providers'
|
|
73
73
|
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.4; extra == 'all-providers'
|
|
74
74
|
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.2.1; extra == 'all-providers'
|
|
75
75
|
Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
@@ -106,7 +106,7 @@ Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'huggingface'
|
|
|
106
106
|
Provides-Extra: ibm
|
|
107
107
|
Requires-Dist: langchain-ibm<2.0.0,>=1.0.7; extra == 'ibm'
|
|
108
108
|
Provides-Extra: litellm
|
|
109
|
-
Requires-Dist: langchain-litellm<2.0.0,>=0.6.
|
|
109
|
+
Requires-Dist: langchain-litellm<2.0.0,>=0.6.6; extra == 'litellm'
|
|
110
110
|
Provides-Extra: mistralai
|
|
111
111
|
Requires-Dist: langchain-mistralai<2.0.0,>=1.1.4; extra == 'mistralai'
|
|
112
112
|
Provides-Extra: modal
|
|
@@ -121,6 +121,8 @@ Provides-Extra: openrouter
|
|
|
121
121
|
Requires-Dist: langchain-openrouter<2.0.0,>=0.2.3; extra == 'openrouter'
|
|
122
122
|
Provides-Extra: perplexity
|
|
123
123
|
Requires-Dist: langchain-perplexity<2.0.0,>=1.2.0; extra == 'perplexity'
|
|
124
|
+
Provides-Extra: quickjs
|
|
125
|
+
Requires-Dist: langchain-quickjs<0.2.0,>=0.1.2; extra == 'quickjs'
|
|
124
126
|
Provides-Extra: runloop
|
|
125
127
|
Requires-Dist: langchain-runloop>=0.0.4; extra == 'runloop'
|
|
126
128
|
Provides-Extra: together
|
|
@@ -152,6 +152,26 @@ class ServerConfig:
|
|
|
152
152
|
enable_skills: bool = True
|
|
153
153
|
"""Enable the skills subsystem (SKILL.md loading and skill tools)."""
|
|
154
154
|
|
|
155
|
+
enable_interpreter: bool = False
|
|
156
|
+
"""Enable `CodeInterpreterMiddleware` (`js_eval` REPL) on the main agent.
|
|
157
|
+
|
|
158
|
+
Local-mode only; the server graph raises if a sandbox is configured and
|
|
159
|
+
this flag is `True`.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
interpreter_ptc: str | list[str] | None = None
|
|
163
|
+
"""Override for `settings.interpreter_ptc`.
|
|
164
|
+
|
|
165
|
+
`None` means "fall through to whatever `settings.interpreter_ptc` resolves
|
|
166
|
+
to from `~/.deepagents/config.toml`". A string is one of `"safe"`/`"all"`;
|
|
167
|
+
a list is an explicit allowlist of tool names.
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
interpreter_ptc_acknowledge_unsafe: bool = False
|
|
171
|
+
"""Mirror of `settings.interpreter_ptc_acknowledge_unsafe` — required when
|
|
172
|
+
`interpreter_ptc="all"` is paired with non-`auto_approve` mode.
|
|
173
|
+
"""
|
|
174
|
+
|
|
155
175
|
sandbox_type: str | None = None
|
|
156
176
|
"""Sandbox backend identifier (e.g. `'daytona'`); `None` runs tools on the
|
|
157
177
|
host. `'none'` is normalized to `None` in `__post_init__`."""
|
|
@@ -159,6 +179,10 @@ class ServerConfig:
|
|
|
159
179
|
sandbox_id: str | None = None
|
|
160
180
|
"""Existing sandbox ID to attach to; `None` creates a fresh sandbox."""
|
|
161
181
|
|
|
182
|
+
sandbox_snapshot_name: str | None = None
|
|
183
|
+
"""Sandbox snapshot name to use or create. LangSmith-only; must be `None`
|
|
184
|
+
when `sandbox_id` is set."""
|
|
185
|
+
|
|
162
186
|
sandbox_setup: str | None = None
|
|
163
187
|
"""Absolute path to a setup script executed inside the sandbox on first attach."""
|
|
164
188
|
|
|
@@ -226,8 +250,18 @@ class ServerConfig:
|
|
|
226
250
|
"ENABLE_ASK_USER": str(self.enable_ask_user).lower(),
|
|
227
251
|
"ENABLE_MEMORY": str(self.enable_memory).lower(),
|
|
228
252
|
"ENABLE_SKILLS": str(self.enable_skills).lower(),
|
|
253
|
+
"ENABLE_INTERPRETER": str(self.enable_interpreter).lower(),
|
|
254
|
+
"INTERPRETER_PTC": (
|
|
255
|
+
json.dumps(self.interpreter_ptc)
|
|
256
|
+
if self.interpreter_ptc is not None
|
|
257
|
+
else None
|
|
258
|
+
),
|
|
259
|
+
"INTERPRETER_PTC_ACKNOWLEDGE_UNSAFE": str(
|
|
260
|
+
self.interpreter_ptc_acknowledge_unsafe
|
|
261
|
+
).lower(),
|
|
229
262
|
"SANDBOX_TYPE": self.sandbox_type,
|
|
230
263
|
"SANDBOX_ID": self.sandbox_id,
|
|
264
|
+
"SANDBOX_SNAPSHOT_NAME": self.sandbox_snapshot_name,
|
|
231
265
|
"SANDBOX_SETUP": self.sandbox_setup,
|
|
232
266
|
"CWD": self.cwd,
|
|
233
267
|
"PROJECT_ROOT": self.project_root,
|
|
@@ -268,8 +302,14 @@ class ServerConfig:
|
|
|
268
302
|
enable_ask_user=_read_env_bool("ENABLE_ASK_USER"),
|
|
269
303
|
enable_memory=_read_env_bool("ENABLE_MEMORY", default=True),
|
|
270
304
|
enable_skills=_read_env_bool("ENABLE_SKILLS", default=True),
|
|
305
|
+
enable_interpreter=_read_env_bool("ENABLE_INTERPRETER"),
|
|
306
|
+
interpreter_ptc=_read_env_json("INTERPRETER_PTC"),
|
|
307
|
+
interpreter_ptc_acknowledge_unsafe=_read_env_bool(
|
|
308
|
+
"INTERPRETER_PTC_ACKNOWLEDGE_UNSAFE"
|
|
309
|
+
),
|
|
271
310
|
sandbox_type=_read_env_str("SANDBOX_TYPE"),
|
|
272
311
|
sandbox_id=_read_env_str("SANDBOX_ID"),
|
|
312
|
+
sandbox_snapshot_name=_read_env_str("SANDBOX_SNAPSHOT_NAME") or None,
|
|
273
313
|
sandbox_setup=_read_env_str("SANDBOX_SETUP"),
|
|
274
314
|
cwd=_read_env_str("CWD"),
|
|
275
315
|
project_root=_read_env_str("PROJECT_ROOT"),
|
|
@@ -295,9 +335,13 @@ class ServerConfig:
|
|
|
295
335
|
shell_allow_list: list[str] | None = None,
|
|
296
336
|
sandbox_type: str = "none",
|
|
297
337
|
sandbox_id: str | None,
|
|
338
|
+
sandbox_snapshot_name: str | None,
|
|
298
339
|
sandbox_setup: str | None,
|
|
299
340
|
enable_shell: bool,
|
|
300
341
|
enable_ask_user: bool,
|
|
342
|
+
enable_interpreter: bool = False,
|
|
343
|
+
interpreter_ptc: str | list[str] | None = None,
|
|
344
|
+
interpreter_ptc_acknowledge_unsafe: bool = False,
|
|
301
345
|
mcp_config_path: str | None,
|
|
302
346
|
no_mcp: bool,
|
|
303
347
|
trust_project_mcp: bool | None,
|
|
@@ -321,9 +365,16 @@ class ServerConfig:
|
|
|
321
365
|
server subprocess for `ShellAllowListMiddleware`.
|
|
322
366
|
sandbox_type: Sandbox type.
|
|
323
367
|
sandbox_id: Existing sandbox ID to reuse.
|
|
368
|
+
sandbox_snapshot_name: Sandbox snapshot name to use or create
|
|
369
|
+
(langsmith only).
|
|
324
370
|
sandbox_setup: Path to setup script for the sandbox.
|
|
325
371
|
enable_shell: Enable shell execution tools.
|
|
326
372
|
enable_ask_user: Enable ask_user tool.
|
|
373
|
+
enable_interpreter: Enable `CodeInterpreterMiddleware` on the main
|
|
374
|
+
agent.
|
|
375
|
+
interpreter_ptc: Override for `settings.interpreter_ptc`.
|
|
376
|
+
interpreter_ptc_acknowledge_unsafe: Mirror of
|
|
377
|
+
`settings.interpreter_ptc_acknowledge_unsafe`.
|
|
327
378
|
mcp_config_path: Path to MCP config.
|
|
328
379
|
no_mcp: Disable MCP.
|
|
329
380
|
trust_project_mcp: Trust project MCP servers.
|
|
@@ -344,8 +395,12 @@ class ServerConfig:
|
|
|
344
395
|
interactive=interactive,
|
|
345
396
|
enable_shell=enable_shell,
|
|
346
397
|
enable_ask_user=enable_ask_user,
|
|
398
|
+
enable_interpreter=enable_interpreter,
|
|
399
|
+
interpreter_ptc=interpreter_ptc,
|
|
400
|
+
interpreter_ptc_acknowledge_unsafe=interpreter_ptc_acknowledge_unsafe,
|
|
347
401
|
sandbox_type=sandbox_type,
|
|
348
402
|
sandbox_id=sandbox_id,
|
|
403
|
+
sandbox_snapshot_name=sandbox_snapshot_name,
|
|
349
404
|
sandbox_setup=_normalize_path(
|
|
350
405
|
sandbox_setup, project_context, "sandbox setup"
|
|
351
406
|
),
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Stderr marker emission used by the langgraph server graph entry point.
|
|
2
|
+
|
|
3
|
+
Lives in its own module so unit tests can exercise the marker contract
|
|
4
|
+
without triggering `server_graph.make_graph()` at import time.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import sys
|
|
11
|
+
import traceback
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
STARTUP_ERROR_MARKER = "DEEPAGENTS_STARTUP_ERROR:"
|
|
16
|
+
"""Stderr marker the parent app scans for in `server._extract_startup_error_marker`
|
|
17
|
+
to upgrade an opaque "Server process exited with code N" into a one-line summary.
|
|
18
|
+
Format is `{STARTUP_ERROR_MARKER}{single-line message}`."""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def emit_startup_failure(exc: BaseException) -> None:
|
|
22
|
+
"""Report a server graph startup failure to the parent app process.
|
|
23
|
+
|
|
24
|
+
Emits two stderr outputs: the full traceback for logs/debugging, then a
|
|
25
|
+
single-line `{STARTUP_ERROR_MARKER}{type}: {summary}` line that
|
|
26
|
+
`server._extract_startup_error_marker` parses to upgrade an opaque
|
|
27
|
+
"Server process exited with code N" into an actionable summary.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
exc: The exception raised during graph initialization.
|
|
31
|
+
"""
|
|
32
|
+
logger.critical("Failed to initialize server graph", exc_info=exc)
|
|
33
|
+
print( # noqa: T201 # stderr fallback — logger may not reach parent process
|
|
34
|
+
f"Failed to initialize server graph: {exc}\n{traceback.format_exc()}",
|
|
35
|
+
file=sys.stderr,
|
|
36
|
+
)
|
|
37
|
+
# Marker contract is single-line; guard against multi-line/empty `str(exc)`
|
|
38
|
+
# and include the type so e.g. `ValueError` and `RuntimeError` are
|
|
39
|
+
# distinguishable in the parent's truncated summary.
|
|
40
|
+
exc_lines = str(exc).splitlines()
|
|
41
|
+
summary = exc_lines[0] if exc_lines else "<no message>"
|
|
42
|
+
print( # noqa: T201
|
|
43
|
+
f"{STARTUP_ERROR_MARKER}{type(exc).__name__}: {summary}",
|
|
44
|
+
file=sys.stderr,
|
|
45
|
+
)
|
|
@@ -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.4" # 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."""
|
|
@@ -9,7 +9,7 @@ import shutil
|
|
|
9
9
|
import tempfile
|
|
10
10
|
import tomllib
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from typing import TYPE_CHECKING, Any
|
|
12
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
13
13
|
|
|
14
14
|
from deepagents import create_deep_agent
|
|
15
15
|
from deepagents.backends import CompositeBackend, LocalShellBackend
|
|
@@ -198,6 +198,121 @@ class ShellAllowListMiddleware(AgentMiddleware):
|
|
|
198
198
|
return await handler(request)
|
|
199
199
|
|
|
200
200
|
|
|
201
|
+
_INTERPRETER_WRITE_TOOLS: frozenset[str] = frozenset(
|
|
202
|
+
{"execute", "write_file", "edit_file"}
|
|
203
|
+
)
|
|
204
|
+
"""Tools considered write/shell capable for PTC auditing.
|
|
205
|
+
|
|
206
|
+
When `interpreter_ptc="all"` resolves to this set, an INFO log names every
|
|
207
|
+
write tool that was included so the audit trail is searchable. The `"safe"`
|
|
208
|
+
preset already excludes them; this is the belt-and-braces check for `"all"`.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _resolve_ptc_option(
|
|
213
|
+
ptc: str | bool | list[str],
|
|
214
|
+
*,
|
|
215
|
+
tools: Sequence[BaseTool | Callable | dict[str, Any]],
|
|
216
|
+
acknowledge_unsafe: bool,
|
|
217
|
+
auto_approve: bool,
|
|
218
|
+
) -> list[str] | None:
|
|
219
|
+
"""Resolve the configured PTC allowlist to a concrete list of tool names.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
ptc: Raw `interpreter_ptc` value from settings or CLI. Accepts
|
|
223
|
+
`False`/`[]`, `"safe"`, `"all"`, or a list of names.
|
|
224
|
+
tools: Live tool list given to `create_cli_agent`. Used to validate
|
|
225
|
+
explicit names, intersect the `"safe"` preset, and enumerate
|
|
226
|
+
`"all"`.
|
|
227
|
+
acknowledge_unsafe: Mirrors `settings.interpreter_ptc_acknowledge_unsafe`;
|
|
228
|
+
required when `ptc="all"` and `auto_approve` is `False`.
|
|
229
|
+
auto_approve: Whether HITL approval is globally disabled. When `True`,
|
|
230
|
+
`"all"` does not require `acknowledge_unsafe` because every host
|
|
231
|
+
tool already runs without prompting.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
`None` when PTC should be disabled, otherwise a list of tool names
|
|
235
|
+
suitable for `CodeInterpreterMiddleware(ptc=...)`.
|
|
236
|
+
|
|
237
|
+
Raises:
|
|
238
|
+
ValueError: For unknown names in an explicit list, or for `"all"`
|
|
239
|
+
without `acknowledge_unsafe` outside of `auto_approve`.
|
|
240
|
+
"""
|
|
241
|
+
from langchain.tools import BaseTool as _BaseTool
|
|
242
|
+
|
|
243
|
+
if ptc is False or ptc is None or ptc == []:
|
|
244
|
+
return None
|
|
245
|
+
|
|
246
|
+
live_names: list[str] = []
|
|
247
|
+
for tool in tools:
|
|
248
|
+
if isinstance(tool, _BaseTool):
|
|
249
|
+
name = tool.name
|
|
250
|
+
if isinstance(name, str):
|
|
251
|
+
live_names.append(name)
|
|
252
|
+
elif isinstance(tool, dict):
|
|
253
|
+
raw_name = cast("dict[str, Any]", tool).get("name")
|
|
254
|
+
if isinstance(raw_name, str):
|
|
255
|
+
live_names.append(raw_name)
|
|
256
|
+
else:
|
|
257
|
+
attr = getattr(tool, "name", None)
|
|
258
|
+
if isinstance(attr, str):
|
|
259
|
+
live_names.append(attr)
|
|
260
|
+
live_set: set[str] = set(live_names)
|
|
261
|
+
|
|
262
|
+
if isinstance(ptc, str):
|
|
263
|
+
normalized = ptc.strip().lower()
|
|
264
|
+
if normalized == "safe":
|
|
265
|
+
from deepagents_code.config import INTERPRETER_PTC_SAFE_PRESET
|
|
266
|
+
|
|
267
|
+
selected = sorted(INTERPRETER_PTC_SAFE_PRESET & live_set)
|
|
268
|
+
dropped = sorted(INTERPRETER_PTC_SAFE_PRESET - live_set)
|
|
269
|
+
if dropped:
|
|
270
|
+
logger.debug(
|
|
271
|
+
"interpreter_ptc='safe' preset members not present in toolset: %s",
|
|
272
|
+
dropped,
|
|
273
|
+
)
|
|
274
|
+
return selected
|
|
275
|
+
if normalized == "all":
|
|
276
|
+
if not auto_approve and not acknowledge_unsafe:
|
|
277
|
+
msg = (
|
|
278
|
+
"interpreter_ptc='all' exposes every host tool to PTC "
|
|
279
|
+
"calls that bypass HITL approval. Set "
|
|
280
|
+
"interpreter_ptc_acknowledge_unsafe=True (or use "
|
|
281
|
+
"auto_approve=True) to opt in."
|
|
282
|
+
)
|
|
283
|
+
raise ValueError(msg)
|
|
284
|
+
included = sorted(live_set)
|
|
285
|
+
write_included = sorted(_INTERPRETER_WRITE_TOOLS & live_set)
|
|
286
|
+
if write_included:
|
|
287
|
+
logger.info(
|
|
288
|
+
"interpreter_ptc='all' includes write/shell tools: %s",
|
|
289
|
+
write_included,
|
|
290
|
+
)
|
|
291
|
+
return included
|
|
292
|
+
msg = (
|
|
293
|
+
f"Invalid interpreter_ptc string {ptc!r}; expected 'safe', 'all', "
|
|
294
|
+
"or a list of tool names."
|
|
295
|
+
)
|
|
296
|
+
raise ValueError(msg)
|
|
297
|
+
|
|
298
|
+
if isinstance(ptc, list):
|
|
299
|
+
unknown = [name for name in ptc if name not in live_set]
|
|
300
|
+
if unknown:
|
|
301
|
+
available = ", ".join(sorted(live_set)) or "<none>"
|
|
302
|
+
msg = (
|
|
303
|
+
"Unknown tool names in interpreter_ptc: "
|
|
304
|
+
f"{sorted(set(unknown))}. Available tools: {available}."
|
|
305
|
+
)
|
|
306
|
+
raise ValueError(msg)
|
|
307
|
+
return list(ptc)
|
|
308
|
+
|
|
309
|
+
msg = (
|
|
310
|
+
"interpreter_ptc must be False, 'safe', 'all', or a list of tool names; "
|
|
311
|
+
f"got {type(ptc).__name__}."
|
|
312
|
+
)
|
|
313
|
+
raise ValueError(msg)
|
|
314
|
+
|
|
315
|
+
|
|
201
316
|
def load_async_subagents(config_path: Path | None = None) -> list[AsyncSubAgent]:
|
|
202
317
|
"""Load async subagent definitions from `config.toml`.
|
|
203
318
|
|
|
@@ -924,6 +1039,7 @@ def create_cli_agent(
|
|
|
924
1039
|
enable_memory: bool = True,
|
|
925
1040
|
enable_skills: bool = True,
|
|
926
1041
|
enable_shell: bool = True,
|
|
1042
|
+
enable_interpreter: bool = False,
|
|
927
1043
|
checkpointer: BaseCheckpointSaver | None = None,
|
|
928
1044
|
mcp_server_info: list[MCPServerInfo] | None = None,
|
|
929
1045
|
cwd: str | Path | None = None,
|
|
@@ -980,6 +1096,27 @@ def create_cli_agent(
|
|
|
980
1096
|
enable_skills: Enable `SkillsMiddleware` for custom agent skills
|
|
981
1097
|
enable_shell: Enable shell execution via `LocalShellBackend`
|
|
982
1098
|
(only in local mode). When enabled, the `execute` tool is available.
|
|
1099
|
+
enable_interpreter: Wire `CodeInterpreterMiddleware` from
|
|
1100
|
+
`langchain-quickjs` into the main agent.
|
|
1101
|
+
|
|
1102
|
+
Local-mode only — passing a non-`None` `sandbox` while
|
|
1103
|
+
`enable_interpreter=True` raises `ValueError`. Subagents do not
|
|
1104
|
+
receive the interpreter in v1.
|
|
1105
|
+
|
|
1106
|
+
PTC (`tools.*` host bridge) calls bypass `interrupt_on`/HITL
|
|
1107
|
+
approval, so `settings.interpreter_ptc` is the only effective
|
|
1108
|
+
control over which host tools can be invoked from inside the
|
|
1109
|
+
REPL. `js_eval` itself is intentionally not gated by HITL —
|
|
1110
|
+
per-call approval would be unusably noisy and would not block
|
|
1111
|
+
PTC fan-out anyway. The `"safe"` preset is therefore restricted
|
|
1112
|
+
to tools that are already non-HITL outside the REPL (read-only
|
|
1113
|
+
file inspection); exposing HITL-gated tools — network fetch,
|
|
1114
|
+
subagent dispatch, shell, file writes — requires an explicit
|
|
1115
|
+
list or `interpreter_ptc="all"` with
|
|
1116
|
+
`interpreter_ptc_acknowledge_unsafe=True`.
|
|
1117
|
+
|
|
1118
|
+
Requires the `quickjs` optional extra
|
|
1119
|
+
(`langchain-quickjs>=0.1.2,<0.2.0`).
|
|
983
1120
|
checkpointer: Optional checkpointer for session persistence.
|
|
984
1121
|
When `None`, the graph is compiled without a checkpointer.
|
|
985
1122
|
mcp_server_info: MCP server metadata to surface in the system prompt.
|
|
@@ -998,6 +1135,12 @@ def create_cli_agent(
|
|
|
998
1135
|
- `agent_graph`: Configured LangGraph Pregel instance ready
|
|
999
1136
|
for execution
|
|
1000
1137
|
- `composite_backend`: `CompositeBackend` for file operations
|
|
1138
|
+
|
|
1139
|
+
Raises:
|
|
1140
|
+
ValueError: When `enable_interpreter=True` is paired with a
|
|
1141
|
+
non-`None` `sandbox`, when `settings.interpreter_ptc` contains
|
|
1142
|
+
unknown tool names, or when `interpreter_ptc="all"` is used
|
|
1143
|
+
without `auto_approve` or `interpreter_ptc_acknowledge_unsafe`.
|
|
1001
1144
|
"""
|
|
1002
1145
|
tools = tools or []
|
|
1003
1146
|
effective_cwd = (
|
|
@@ -1201,6 +1344,37 @@ def create_cli_agent(
|
|
|
1201
1344
|
# Note: Shell middleware not used in sandbox mode
|
|
1202
1345
|
# File operations and execute tool are provided by the sandbox backend
|
|
1203
1346
|
|
|
1347
|
+
if enable_interpreter:
|
|
1348
|
+
if sandbox is not None:
|
|
1349
|
+
msg = (
|
|
1350
|
+
"enable_interpreter=True is not supported with a remote "
|
|
1351
|
+
"sandbox in this release. Disable the sandbox or unset "
|
|
1352
|
+
"enable_interpreter."
|
|
1353
|
+
)
|
|
1354
|
+
raise ValueError(msg)
|
|
1355
|
+
# Lazy import keeps `dcode -v` fast — see AGENTS.md startup-perf rule.
|
|
1356
|
+
from langchain_quickjs import CodeInterpreterMiddleware, PTCOption
|
|
1357
|
+
|
|
1358
|
+
ptc_names = _resolve_ptc_option(
|
|
1359
|
+
settings.interpreter_ptc,
|
|
1360
|
+
tools=tools,
|
|
1361
|
+
acknowledge_unsafe=settings.interpreter_ptc_acknowledge_unsafe,
|
|
1362
|
+
auto_approve=auto_approve,
|
|
1363
|
+
)
|
|
1364
|
+
ptc_option: PTCOption | None = (
|
|
1365
|
+
cast("PTCOption", list(ptc_names)) if ptc_names is not None else None
|
|
1366
|
+
)
|
|
1367
|
+
agent_middleware.append(
|
|
1368
|
+
CodeInterpreterMiddleware(
|
|
1369
|
+
tool_name="js_eval",
|
|
1370
|
+
timeout=settings.interpreter_timeout_seconds,
|
|
1371
|
+
memory_limit=settings.interpreter_memory_limit_mb * 1024 * 1024,
|
|
1372
|
+
max_ptc_calls=settings.interpreter_max_ptc_calls,
|
|
1373
|
+
max_result_chars=settings.interpreter_max_result_chars,
|
|
1374
|
+
ptc=ptc_option,
|
|
1375
|
+
)
|
|
1376
|
+
)
|
|
1377
|
+
|
|
1204
1378
|
# Local context middleware (git info, directory tree, etc.).
|
|
1205
1379
|
if isinstance(backend, (_ExecutableBackend, _AsyncExecutableBackend)):
|
|
1206
1380
|
agent_middleware.append(
|
|
@@ -3446,7 +3446,13 @@ class DeepAgentsApp(App):
|
|
|
3446
3446
|
Custom themes use their stored registry colors; built-in Textual themes
|
|
3447
3447
|
resolve colors from the active app theme. Terminal write failures are
|
|
3448
3448
|
logged and swallowed because the OSC background sync is cosmetic.
|
|
3449
|
+
|
|
3450
|
+
ANSI themes intentionally skip this step so the terminal's native
|
|
3451
|
+
background is preserved.
|
|
3449
3452
|
"""
|
|
3453
|
+
if self.theme in {"ansi-dark", "ansi-light"}:
|
|
3454
|
+
return
|
|
3455
|
+
|
|
3450
3456
|
from deepagents_code.terminal_escape import set_terminal_background
|
|
3451
3457
|
|
|
3452
3458
|
entry = theme.get_registry().get(self.theme)
|
|
@@ -4918,7 +4924,14 @@ class DeepAgentsApp(App):
|
|
|
4918
4924
|
Args:
|
|
4919
4925
|
command: The raw command text (displayed as user message).
|
|
4920
4926
|
"""
|
|
4921
|
-
from deepagents_code.config import
|
|
4927
|
+
from deepagents_code.config import (
|
|
4928
|
+
LangSmithApiError,
|
|
4929
|
+
LangSmithImportError,
|
|
4930
|
+
LangSmithLookupTimeoutError,
|
|
4931
|
+
_assemble_langsmith_thread_url,
|
|
4932
|
+
fetch_langsmith_project_url_or_raise,
|
|
4933
|
+
get_langsmith_project_name,
|
|
4934
|
+
)
|
|
4922
4935
|
|
|
4923
4936
|
if not self._session_state:
|
|
4924
4937
|
await self._mount_message(UserMessage(command))
|
|
@@ -4926,15 +4939,18 @@ class DeepAgentsApp(App):
|
|
|
4926
4939
|
return
|
|
4927
4940
|
thread_id = self._session_state.thread_id
|
|
4928
4941
|
try:
|
|
4929
|
-
|
|
4942
|
+
project_name = await asyncio.to_thread(get_langsmith_project_name)
|
|
4930
4943
|
except Exception:
|
|
4931
|
-
logger.exception(
|
|
4944
|
+
logger.exception(
|
|
4945
|
+
"Failed to resolve LangSmith project name for thread %s",
|
|
4946
|
+
thread_id,
|
|
4947
|
+
)
|
|
4932
4948
|
await self._mount_message(UserMessage(command))
|
|
4933
4949
|
await self._mount_message(
|
|
4934
|
-
AppMessage("Failed to resolve LangSmith
|
|
4950
|
+
AppMessage("Failed to resolve LangSmith project name."),
|
|
4935
4951
|
)
|
|
4936
4952
|
return
|
|
4937
|
-
if not
|
|
4953
|
+
if not project_name:
|
|
4938
4954
|
await self._mount_message(UserMessage(command))
|
|
4939
4955
|
await self._mount_message(
|
|
4940
4956
|
AppMessage(
|
|
@@ -4943,6 +4959,61 @@ class DeepAgentsApp(App):
|
|
|
4943
4959
|
),
|
|
4944
4960
|
)
|
|
4945
4961
|
return
|
|
4962
|
+
try:
|
|
4963
|
+
project_url = await asyncio.to_thread(
|
|
4964
|
+
fetch_langsmith_project_url_or_raise, project_name
|
|
4965
|
+
)
|
|
4966
|
+
except LangSmithImportError:
|
|
4967
|
+
logger.warning(
|
|
4968
|
+
"langsmith package not installed; cannot resolve thread URL for %s",
|
|
4969
|
+
thread_id,
|
|
4970
|
+
)
|
|
4971
|
+
await self._mount_message(UserMessage(command))
|
|
4972
|
+
await self._mount_message(
|
|
4973
|
+
AppMessage(
|
|
4974
|
+
"The `langsmith` package is not installed. "
|
|
4975
|
+
"Install it with `pip install langsmith` to enable `/trace`.",
|
|
4976
|
+
),
|
|
4977
|
+
)
|
|
4978
|
+
return
|
|
4979
|
+
except LangSmithLookupTimeoutError:
|
|
4980
|
+
logger.warning(
|
|
4981
|
+
"LangSmith project URL lookup timed out for thread %s",
|
|
4982
|
+
thread_id,
|
|
4983
|
+
)
|
|
4984
|
+
await self._mount_message(UserMessage(command))
|
|
4985
|
+
await self._mount_message(
|
|
4986
|
+
AppMessage(
|
|
4987
|
+
"Could not reach LangSmith to resolve the thread URL. "
|
|
4988
|
+
"Check your network connection and try again.",
|
|
4989
|
+
),
|
|
4990
|
+
)
|
|
4991
|
+
return
|
|
4992
|
+
except LangSmithApiError as exc:
|
|
4993
|
+
logger.warning(
|
|
4994
|
+
"LangSmith API call failed while resolving thread URL for %s: %s",
|
|
4995
|
+
thread_id,
|
|
4996
|
+
exc,
|
|
4997
|
+
)
|
|
4998
|
+
await self._mount_message(UserMessage(command))
|
|
4999
|
+
await self._mount_message(
|
|
5000
|
+
AppMessage(
|
|
5001
|
+
f"LangSmith rejected the project lookup: {exc}. "
|
|
5002
|
+
"Verify LANGSMITH_API_KEY and the project name are correct.",
|
|
5003
|
+
),
|
|
5004
|
+
)
|
|
5005
|
+
return
|
|
5006
|
+
except Exception:
|
|
5007
|
+
logger.exception(
|
|
5008
|
+
"Failed to fetch LangSmith project URL for thread %s",
|
|
5009
|
+
thread_id,
|
|
5010
|
+
)
|
|
5011
|
+
await self._mount_message(UserMessage(command))
|
|
5012
|
+
await self._mount_message(
|
|
5013
|
+
AppMessage("Failed to resolve LangSmith thread URL."),
|
|
5014
|
+
)
|
|
5015
|
+
return
|
|
5016
|
+
url = _assemble_langsmith_thread_url(project_url, thread_id)
|
|
4946
5017
|
|
|
4947
5018
|
def _open_browser() -> None:
|
|
4948
5019
|
try:
|