deepagents-code 0.1.32__tar.gz → 0.1.34__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.32 → deepagents_code-0.1.34}/AGENTS.md +3 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/CHANGELOG.md +20 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/COMMANDS.md +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/PKG-INFO +5 -5
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/THREAT_MODEL.md +22 -22
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_env_vars.py +36 -0
- deepagents_code-0.1.34/deepagents_code/_fake_models.py +66 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_session_stats.py +86 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_testing_models.py +22 -34
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_tool_stream.py +42 -4
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/agent.py +16 -9
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/app.py +266 -78
- deepagents_code-0.1.34/deepagents_code/client/__init__.py +1 -0
- deepagents_code-0.1.34/deepagents_code/client/commands/__init__.py +1 -0
- deepagents_code-0.1.34/deepagents_code/client/commands/tools.py +402 -0
- deepagents_code-0.1.34/deepagents_code/client/launch/__init__.py +1 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client/launch}/server.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client/launch}/server_manager.py +40 -21
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client}/non_interactive.py +8 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/command_registry.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/config.py +55 -8
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/config_manifest.py +44 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/input.py +198 -12
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/main.py +105 -19
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_disabled.py +52 -22
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_tools.py +262 -65
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/media_utils.py +137 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/model_config.py +243 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/offload.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/commands.py +172 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/invocation.py +9 -0
- deepagents_code-0.1.34/deepagents_code/skills/trust.py +547 -0
- deepagents_code-0.1.34/deepagents_code/tool_catalog.py +354 -0
- deepagents_code-0.1.34/deepagents_code/tui/__init__.py +1 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/textual_adapter.py +2 -80
- deepagents_code-0.1.34/deepagents_code/tui/widgets/__init__.py +9 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/approval.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/auth.py +6 -6
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/chat_input.py +78 -7
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/codex_auth.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/goal_review.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/install_confirm.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/mcp_login.py +2 -2
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/message_store.py +2 -2
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/messages.py +4 -4
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/model_selector.py +8 -8
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/notification_center.py +6 -2
- deepagents_code-0.1.34/deepagents_code/tui/widgets/skill_trust.py +131 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/status.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/subagent_panel.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/thread_selector.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/tool_renderers.py +2 -2
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/update_available.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/update_progress.py +1 -1
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/welcome.py +20 -8
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/ui.py +49 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/pyproject.toml +11 -5
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_auto_approve_remote.py +5 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_compact_resume.py +2 -2
- deepagents_code-0.1.34/tests/unit_tests/client/__init__.py +1 -0
- deepagents_code-0.1.34/tests/unit_tests/client/commands/__init__.py +1 -0
- deepagents_code-0.1.32/tests/unit_tests/test_auth_commands.py → deepagents_code-0.1.34/tests/unit_tests/client/commands/test_auth.py +1 -1
- deepagents_code-0.1.32/tests/unit_tests/test_mcp_commands.py → deepagents_code-0.1.34/tests/unit_tests/client/commands/test_mcp.py +11 -11
- deepagents_code-0.1.34/tests/unit_tests/client/commands/test_tools.py +527 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/conftest.py +1 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/test_commands.py +287 -0
- deepagents_code-0.1.34/tests/unit_tests/skills/test_skill_trust.py +528 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_app.py +162 -156
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_args.py +5 -5
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_config_manifest.py +3 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_install_command.py +6 -6
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_install_script.py +1 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_main.py +224 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_main_args.py +19 -13
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_disabled.py +59 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_tools.py +462 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_media_utils.py +369 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_model_config.py +323 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_model_switch.py +3 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_non_interactive.py +294 -212
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_offload.py +5 -5
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_reasoning_effort.py +2 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_reload.py +206 -1
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_remote_client.py +5 -3
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_rubric_cli.py +2 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server.py +138 -56
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_helpers.py +2 -2
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_manager.py +99 -29
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_session_stats.py +95 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_skill_invocation.py +410 -7
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_startup_fast_paths.py +1 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_theme.py +28 -28
- deepagents_code-0.1.34/tests/unit_tests/test_tool_catalog.py +334 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_version.py +34 -34
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui}/test_subagent_stream.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui}/test_textual_adapter.py +101 -319
- deepagents_code-0.1.34/tests/unit_tests/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_agent_selector.py +9 -9
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_approval.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_ask_user.py +4 -3
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_auth_widgets.py +30 -30
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_autocomplete.py +2 -2
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_chat_input.py +203 -6
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_cwd_switch.py +4 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui}/widgets/test_diff.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_goal_review.py +4 -3
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_history.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_install_confirm.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_launch_init.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_links.py +17 -14
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_loading.py +4 -4
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_mcp_login_modal.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_mcp_reconnect.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_mcp_viewer.py +22 -22
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_message_store.py +3 -3
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_messages.py +31 -29
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_model_selector.py +39 -39
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_notification_center.py +3 -3
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_notification_detail.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_restart_prompt.py +1 -1
- deepagents_code-0.1.34/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +78 -0
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_status.py +4 -4
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_subagent_panel.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_thread_selector.py +56 -56
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_tool_renderers.py +2 -2
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_update_available.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_update_confirm.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_update_progress.py +1 -1
- {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_welcome.py +31 -8
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/uv.lock +6 -6
- deepagents_code-0.1.32/deepagents_code/tools_commands.py +0 -191
- deepagents_code-0.1.32/deepagents_code/widgets/__init__.py +0 -9
- deepagents_code-0.1.32/tests/unit_tests/test_tools_commands.py +0 -144
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/.gitignore +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/Makefile +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/README.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- /deepagents_code-0.1.32/deepagents_code/auth_commands.py → /deepagents_code-0.1.34/deepagents_code/client/commands/auth.py +0 -0
- /deepagents_code-0.1.32/deepagents_code/config_commands.py → /deepagents_code-0.1.34/deepagents_code/client/commands/config.py +0 -0
- /deepagents_code-0.1.32/deepagents_code/mcp_commands.py → /deepagents_code-0.1.34/deepagents_code/client/commands/mcp.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client}/remote_client.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_trust.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/paste_collapse.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/reasoning_effort.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/_links.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/diff.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/history.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/loading.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/update_check.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/hatch_build.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/images/tui.png +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/install.sh +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/README.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/conftest.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test__tool_stream.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_config.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_trust.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_offload_dict_messages.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.32/tests/unit_tests/widgets → deepagents_code-0.1.34/tests/unit_tests/tui}/__init__.py +0 -0
|
@@ -43,7 +43,7 @@ Textual's `App.notify(message)` parses the message string as Rich markup by defa
|
|
|
43
43
|
Charset-dependent characters and animations have **single sources of truth**. Reuse them instead of hand-rolling new ones — copies drift, and (more subtly) a hardcoded Unicode literal won't degrade to ASCII on terminals that need it.
|
|
44
44
|
|
|
45
45
|
- **Glyphs** (checkmarks, arrows, ellipsis, cursor, box-drawing, branch icon, etc.): pull from `get_glyphs()` (`config.Glyphs`). Each glyph has a Unicode and an ASCII variant; `get_glyphs()` returns the right set for the active terminal. Never inline `"✓"`, `"…"`, `"›"`, and friends.
|
|
46
|
-
- **Animated spinners**: reuse the `Spinner` class in `widgets/loading.py`, which wraps `get_glyphs().spinner_frames` (braille on Unicode, `(-) (\) (|) (/)` on ASCII) and exposes `next_frame()`/`current_frame()`. Do **not** define your own frame tuples or interval constants for a spinner — drive a `Spinner` on a `set_interval`. The status-bar reconnect indicator (`widgets/status.py`) is the reference example; it ticks at the same 0.1s cadence as `LoadingWidget`. All connection/queue progress lives in the status bar — the welcome banner deliberately stays out of it, so there are currently no bespoke spinners to carve an exception for.
|
|
46
|
+
- **Animated spinners**: reuse the `Spinner` class in `tui/widgets/loading.py`, which wraps `get_glyphs().spinner_frames` (braille on Unicode, `(-) (\) (|) (/)` on ASCII) and exposes `next_frame()`/`current_frame()`. Do **not** define your own frame tuples or interval constants for a spinner — drive a `Spinner` on a `set_interval`. The status-bar reconnect indicator (`tui/widgets/status.py`) is the reference example; it ticks at the same 0.1s cadence as `LoadingWidget`. All connection/queue progress lives in the status bar — the welcome banner deliberately stays out of it, so there are currently no bespoke spinners to carve an exception for.
|
|
47
47
|
|
|
48
48
|
### Textual patterns used in this codebase
|
|
49
49
|
|
|
@@ -99,7 +99,7 @@ The `deepagents-code --help` screen is hand-maintained in `ui.show_help()`, sepa
|
|
|
99
99
|
|
|
100
100
|
## Splash screen tips
|
|
101
101
|
|
|
102
|
-
When adding a user-facing CLI feature (new slash command, keybinding, workflow), add a corresponding tip to the `_TIPS` list in `deepagents_code/widgets/welcome.py`. Tips are shown randomly on startup to help users discover features. Keep tips short and action-oriented (e.g., `"Press ctrl+x to compose prompts in your external editor"`).
|
|
102
|
+
When adding a user-facing CLI feature (new slash command, keybinding, workflow), add a corresponding tip to the `_TIPS` list in `deepagents_code/tui/widgets/welcome.py`. Tips are shown randomly on startup to help users discover features. Keep tips short and action-oriented (e.g., `"Press ctrl+x to compose prompts in your external editor"`).
|
|
103
103
|
|
|
104
104
|
## Slash commands
|
|
105
105
|
|
|
@@ -115,7 +115,7 @@ To add a new slash command: (1) add a `SlashCommand` entry to `COMMANDS`, (2) se
|
|
|
115
115
|
2. `deepagents_code/model_config.py` — if the provider reads a *dedicated* endpoint env var, add `"provider_name": ("CANONICAL_BASE_URL", "ALTERNATE", ...)` to `PROVIDER_BASE_URL_ENV` (see guidelines below); omit the provider entirely when it has no provider-specific endpoint variable
|
|
116
116
|
3. `pyproject.toml` — add `provider = ["langchain-provider>=X.Y.Z,<N.0.0"]` to `[project.optional-dependencies]` and include it in the `all-providers` composite extra
|
|
117
117
|
4. `deepagents_code/model_config.py` — add `"provider_name"` to `RETRY_PARAM_BY_PROVIDER` if the provider's chat model accepts `max_retries`
|
|
118
|
-
5. `deepagents_code/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
|
|
118
|
+
5. `deepagents_code/tui/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
|
|
119
119
|
6. `tests/unit_tests/test_model_config.py` — add `assert PROVIDER_API_KEY_ENV["provider_name"] == "ENV_VAR_NAME"` to `TestProviderApiKeyEnv.test_contains_major_providers`, and pin any `PROVIDER_BASE_URL_ENV` entry with a matching assertion
|
|
120
120
|
|
|
121
121
|
### `PROVIDER_BASE_URL_ENV` guidelines
|
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.34](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.33...deepagents-code==0.1.34) (2026-07-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **code:** show `(local)` tag under ANSI themes ([#4534](https://github.com/langchain-ai/deepagents/issues/4534)) ([699e439](https://github.com/langchain-ai/deepagents/commit/699e439699723e477a621f95eef87a7d76aac5f5))
|
|
11
|
+
|
|
12
|
+
## [0.1.33](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.32...deepagents-code==0.1.33) (2026-07-06)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* In-the-moment trust prompt for symlinked skills ([#4200](https://github.com/langchain-ai/deepagents/issues/4200)) ([a4431e4](https://github.com/langchain-ai/deepagents/commit/a4431e4339348431e91533cb2b177259ab94b083))
|
|
17
|
+
* Selective per-server project MCP trust ([#4507](https://github.com/langchain-ai/deepagents/issues/4507)) ([aaa22a9](https://github.com/langchain-ai/deepagents/commit/aaa22a9340cb3d2c8e9ce1a921957d0a9121da20))
|
|
18
|
+
* Add `dcode tools list` command ([#4461](https://github.com/langchain-ai/deepagents/issues/4461)) ([1402d0e](https://github.com/langchain-ai/deepagents/commit/1402d0e735a1580503f240457c77db76fcd779d7))
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* Strip media placeholders from model-facing message text ([#4462](https://github.com/langchain-ai/deepagents/issues/4462)) ([aa0ae36](https://github.com/langchain-ai/deepagents/commit/aa0ae36b00df6411a9200610a9075ef2dc28b1af))
|
|
23
|
+
* Re-apply theme preference on `/reload` ([#4514](https://github.com/langchain-ai/deepagents/issues/4514)) ([5d1c392](https://github.com/langchain-ai/deepagents/commit/5d1c3928f7ca0ea97f28fd4d34ae1a4ee885e888))
|
|
24
|
+
|
|
5
25
|
## [0.1.32](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.31...deepagents-code==0.1.32) (2026-07-06)
|
|
6
26
|
|
|
7
27
|
### Features
|
|
@@ -29,7 +29,7 @@ aliases, descriptions, visibility, or hidden-command metadata.
|
|
|
29
29
|
| `/mcp` | | Manage MCP servers and authentication |
|
|
30
30
|
| `/model` | | Switch models or edit model settings |
|
|
31
31
|
| `/notifications` | | Configure startup warnings |
|
|
32
|
-
| `/offload` | `/compact` |
|
|
32
|
+
| `/offload` | `/compact` | Summarize and offload older messages to free context |
|
|
33
33
|
| `/quit` | `/q` | Exit app |
|
|
34
34
|
| `/reload` | | Reload environment and config |
|
|
35
35
|
| `/remember` | | Save useful context to memory or skills |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.34
|
|
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/
|
|
@@ -27,10 +27,10 @@ Classifier: Topic :: Terminals
|
|
|
27
27
|
Requires-Python: <4.0,>=3.11
|
|
28
28
|
Requires-Dist: aiosqlite<1.0.0,>=0.22.1
|
|
29
29
|
Requires-Dist: deepagents-acp<1.0.0,>=0.0.8
|
|
30
|
-
Requires-Dist: deepagents==0.7.
|
|
30
|
+
Requires-Dist: deepagents==0.7.0a6
|
|
31
31
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
32
32
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.4.7
|
|
33
|
-
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.
|
|
33
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7
|
|
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
36
|
Requires-Dist: langchain-quickjs<0.4.0,>=0.3.2
|
|
@@ -67,7 +67,7 @@ Requires-Dist: langchain-baseten<1.0.0,>=0.2.1; extra == 'all-providers'
|
|
|
67
67
|
Requires-Dist: langchain-cohere<1.0.0,>=0.6.0; extra == 'all-providers'
|
|
68
68
|
Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'all-providers'
|
|
69
69
|
Requires-Dist: langchain-fireworks<2.0.0,>=1.4.3; extra == 'all-providers'
|
|
70
|
-
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.
|
|
70
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7; extra == 'all-providers'
|
|
71
71
|
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.4; extra == 'all-providers'
|
|
72
72
|
Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'all-providers'
|
|
73
73
|
Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
|
|
@@ -102,7 +102,7 @@ Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'deepseek'
|
|
|
102
102
|
Provides-Extra: fireworks
|
|
103
103
|
Requires-Dist: langchain-fireworks<2.0.0,>=1.4.3; extra == 'fireworks'
|
|
104
104
|
Provides-Extra: google-genai
|
|
105
|
-
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.
|
|
105
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7; extra == 'google-genai'
|
|
106
106
|
Provides-Extra: groq
|
|
107
107
|
Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'groq'
|
|
108
108
|
Provides-Extra: huggingface
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
- `deepagents_code/` — all Python source modules shipped as the `deepagents-code` package
|
|
14
14
|
- CLI entry point (`main.py`, `__init__.py`)
|
|
15
|
-
- Interactive TUI (`app.py`, `textual_adapter.py`, `widgets/`)
|
|
16
|
-
- Non-interactive pipeline runner (`non_interactive.py`)
|
|
15
|
+
- Interactive TUI (`app.py`, `tui/textual_adapter.py`, `tui/widgets/`)
|
|
16
|
+
- Non-interactive pipeline runner (`client/non_interactive.py`)
|
|
17
17
|
- Agent creation (`agent.py`)
|
|
18
18
|
- Built-in tools (`tools.py`: `http_request`, `web_search`, `fetch_url`)
|
|
19
19
|
- MCP config loader and trust store (`mcp_tools.py`, `mcp_trust.py`)
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
- Session persistence (`sessions.py`)
|
|
23
23
|
- Configuration system (`config.py`, `model_config.py`)
|
|
24
24
|
- Unicode/URL safety helpers (`unicode_security.py`)
|
|
25
|
-
- LangGraph dev server subprocess management (`server.py`, `server_manager.py`, `server_graph.py`)
|
|
26
|
-
- Remote agent client (`remote_client.py`)
|
|
25
|
+
- LangGraph dev server subprocess management (`client/launch/server.py`, `client/launch/server_manager.py`, `server_graph.py`)
|
|
26
|
+
- Remote agent client (`client/remote_client.py`)
|
|
27
27
|
- Local context middleware (`local_context.py`)
|
|
28
28
|
- Custom subagent loader (`subagents.py`, `agent.py:load_async_subagents`)
|
|
29
29
|
- Conversation offload (`offload.py`)
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
3. `~/.deepagents/` is only writable by the authenticated local user — no multi-user shared home directories.
|
|
48
48
|
4. Sandbox backends are trusted third-party services. CLI responsibility ends at correctly constructing and dispatching requests to them.
|
|
49
49
|
5. LangSmith tracing, if enabled, is user-opted-in via environment variables.
|
|
50
|
-
6. The LangGraph dev server subprocess binds to `127.0.0.1` by default (`server.py:_DEFAULT_HOST`) and is ephemeral — started and stopped per CLI session.
|
|
50
|
+
6. The LangGraph dev server subprocess binds to `127.0.0.1` by default (`client/launch/server.py:_DEFAULT_HOST`) and is ephemeral — started and stopped per CLI session.
|
|
51
51
|
7. `DA_SERVER_*` environment variables are readable only by the CLI process and its child server subprocess (OS process isolation assumption).
|
|
52
52
|
8. Users who set `class_path` in `config.toml` accept the same trust model as `pyproject.toml` build scripts — they control their own machine.
|
|
53
53
|
|
|
@@ -68,19 +68,19 @@
|
|
|
68
68
|
│ ┌────────────────┼─────────────────────┐ │
|
|
69
69
|
│ ▼ ▼ ▼ │
|
|
70
70
|
│ C2: TUI (app.py) C2b: Non-interactive C13: Config Channel │
|
|
71
|
-
│ │
|
|
71
|
+
│ │ (client/non_interactive.py) (DA_SERVER_* vars) │
|
|
72
72
|
│ - - - - - - - - - - TB8: CLI / Server IPC - - - - - │ - - - - - - - │
|
|
73
73
|
│ │ ▼ │
|
|
74
|
-
│ │
|
|
74
|
+
│ │ C11: Server Manager (client/launch) │
|
|
75
75
|
│ │ │ spawns │
|
|
76
76
|
│ │ ▼ │
|
|
77
77
|
│ │ C11b: LangGraph Dev Server │
|
|
78
|
-
│ │
|
|
78
|
+
│ │ (client/launch/server.py:ServerProcess) │
|
|
79
79
|
│ │ LANGGRAPH_AUTH_TYPE=noop │
|
|
80
80
|
│ - - - - - - - - │ - - - - - TB10: RemoteAgent / Dev Server - - - - │
|
|
81
81
|
│ │ ▲ │
|
|
82
82
|
│ └─►C12: RemoteAgent────┘ (HTTP+SSE on 127.0.0.1) │
|
|
83
|
-
│ (remote_client.py)
|
|
83
|
+
│ (client/remote_client.py) │
|
|
84
84
|
│ │ │
|
|
85
85
|
│ C3: Agent Engine (server_graph.py) │
|
|
86
86
|
│ (create_cli_agent, deepagents SDK) │
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
| ID | Component | Description | Trust Level | Default? | Entry Points |
|
|
123
123
|
|-----|-----------------------------|---------------------------------------------------------------------------------------------------------------------|----------------------|----------|---------------------------------------------------------------------------------------------------|
|
|
124
124
|
| C1 | CLI Entry Point | Parses argv, loads config/env, bootstraps session | framework-controlled | Yes | `main.cli_main`, `main.parse_args` |
|
|
125
|
-
| C2 | TUI / Non-interactive | Textual UI for interactive chat; `non_interactive.py` for headless pipelines (both use `RemoteAgent`)
|
|
125
|
+
| C2 | TUI / Non-interactive | Textual UI for interactive chat; `client/non_interactive.py` for headless pipelines (both use `RemoteAgent`) | framework-controlled | Yes | `app.DeepAgentsApp.run`, `client.non_interactive.run_non_interactive` |
|
|
126
126
|
| C3 | Agent Engine | LangGraph agent graph running inside `langgraph dev` server, assembled by `create_cli_agent` | framework-controlled | Yes | `agent.create_cli_agent`, `agent._add_interrupt_on`, `server_graph.make_graph` |
|
|
127
127
|
| C4 | Built-in Tools | `http_request`, `web_search` (Tavily), `fetch_url` (HTML→markdown) | framework-controlled | Partial¹ | `tools.http_request`, `tools.web_search`, `tools.fetch_url` |
|
|
128
128
|
| C5 | MCP Loader & Trust | Discovers/loads `.mcp.json`, validates server configs, manages trust store | framework-controlled | No² | `mcp_tools.resolve_and_load_mcp_tools`, `mcp_trust.compute_config_fingerprint` |
|
|
@@ -131,8 +131,8 @@
|
|
|
131
131
|
| C8 | Session Persistence | SQLite checkpoint store for LangGraph thread state | framework-controlled | Yes | `sessions.get_db_path`, `sessions.generate_thread_id` |
|
|
132
132
|
| C9 | Configuration System | TOML config, env vars, `AGENTS.md` system prompts, model config | user-controlled | N/A | `config.settings`, `model_config.ModelConfig`, `~/.deepagents/config.toml` |
|
|
133
133
|
| C10 | Unicode/URL Safety | Detects hidden Unicode, checks URL domain spoofing for approval UI warnings | framework-controlled | Yes | `unicode_security.detect_dangerous_unicode`, `unicode_security.check_url_safety` |
|
|
134
|
-
| C11 | LangGraph Dev Server | Subprocess running `langgraph dev` with `LANGGRAPH_AUTH_TYPE=noop`; managed by `ServerProcess` | framework-controlled | Yes⁵ | `server.ServerProcess.start`, `server.generate_langgraph_json`, `server_manager.start_server_and_get_agent` |
|
|
135
|
-
| C12 | Remote Agent Client | HTTP+SSE client wrapping `RemoteGraph`; connects to C11 on localhost | framework-controlled | Yes⁵ | `remote_client.RemoteAgent.astream`, `remote_client.RemoteAgent.aget_state`
|
|
134
|
+
| C11 | LangGraph Dev Server | Subprocess running `langgraph dev` with `LANGGRAPH_AUTH_TYPE=noop`; managed by `ServerProcess` | framework-controlled | Yes⁵ | `client.launch.server.ServerProcess.start`, `client.launch.server.generate_langgraph_json`, `client.launch.server_manager.start_server_and_get_agent` |
|
|
135
|
+
| C12 | Remote Agent Client | HTTP+SSE client wrapping `RemoteGraph`; connects to C11 on localhost | framework-controlled | Yes⁵ | `client.remote_client.RemoteAgent.astream`, `client.remote_client.RemoteAgent.aget_state` |
|
|
136
136
|
| C13 | Server Config Channel | Passes CLI config to server subprocess via `DA_SERVER_*` environment variables | framework-controlled | Yes | `_server_config.ServerConfig.to_env`, `_server_config.ServerConfig.from_env` |
|
|
137
137
|
| C14 | Async Subagent Config | Loads remote LangGraph deployment specs from `[async_subagents]` in `config.toml` | user-controlled | No | `agent.load_async_subagents` |
|
|
138
138
|
| C15 | LocalContext Middleware | Runs a bash detection script via backend; injects git/project/env context into system prompt each turn | framework-controlled | Yes⁶ | `local_context.LocalContextMiddleware.before_agent`, `local_context.build_detect_script` |
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
#### DC1: API Keys / Credentials
|
|
165
165
|
|
|
166
166
|
- **Fields**: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `TAVILY_API_KEY`, `LANGSMITH_API_KEY`, `LANGGRAPH_API_KEY`, and any provider-specific keys in the user's environment.
|
|
167
|
-
- **Storage**: Loaded from environment at process start (`config.py`). The CLI explicitly strips `LANGGRAPH_CLOUD_LICENSE_KEY` and related auth vars from the server subprocess environment (`server.py:_build_server_env`) but passes the remaining env vars (including provider API keys) to the server subprocess via `os.environ.copy()`.
|
|
167
|
+
- **Storage**: Loaded from environment at process start (`config.py`). The CLI explicitly strips `LANGGRAPH_CLOUD_LICENSE_KEY` and related auth vars from the server subprocess environment (`client/launch/server.py:_build_server_env`) but passes the remaining env vars (including provider API keys) to the server subprocess via `os.environ.copy()`.
|
|
168
168
|
- **Access**: Available to both the CLI process and the server subprocess (which inherits the full environment minus stripped vars).
|
|
169
169
|
- **Encryption**: Not encrypted — in-memory process environment only.
|
|
170
170
|
- **Retention**: Process lifetime; cleared on CLI exit.
|
|
@@ -206,20 +206,20 @@
|
|
|
206
206
|
| TB7 | External LLM API → Agent State | LLM API responses drive tool call decisions | LLM client configuration, model selection, request params | LLM output content; provider-side safety |
|
|
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
|
-
| 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 |
|
|
209
|
+
| TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`client/launch/server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
|
|
210
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
|
|
|
214
214
|
#### TB1: User Input → Agent Engine
|
|
215
215
|
|
|
216
|
-
- **Inside**: `app.DeepAgentsApp` routes keystrokes to message queue; `non_interactive.run_non_interactive` reads from stdin/argv. Both paths now go through `RemoteAgent.astream` to the server. Session ID assigned per thread (`sessions.generate_thread_id`).
|
|
216
|
+
- **Inside**: `app.DeepAgentsApp` routes keystrokes to message queue; `client.non_interactive.run_non_interactive` reads from stdin/argv. Both paths now go through `RemoteAgent.astream` to the server. Session ID assigned per thread (`sessions.generate_thread_id`).
|
|
217
217
|
- **Outside**: Prompt content — the agent accepts any text the user types. No content filtering at this layer (HITL handles downstream tool calls, not prompt intent).
|
|
218
|
-
- **Crossing mechanism**: HTTP POST to `127.0.0.1:{port}` via `remote_client.RemoteAgent.astream`.
|
|
218
|
+
- **Crossing mechanism**: HTTP POST to `127.0.0.1:{port}` via `client.remote_client.RemoteAgent.astream`.
|
|
219
219
|
|
|
220
220
|
#### TB2: LLM Decision → Tool Execution Gate (HITL)
|
|
221
221
|
|
|
222
|
-
- **Inside**: `agent._add_interrupt_on` registers interrupt configs for `execute`, `write_file`, `edit_file`, `web_search`, `fetch_url`, `task`, `compact_conversation`, `launch_async_subagent`, `update_async_subagent`, `cancel_async_subagent`. In non-interactive mode, `non_interactive._handle_action_request` enforces the shell allow-list via `config.is_shell_command_allowed`.
|
|
222
|
+
- **Inside**: `agent._add_interrupt_on` registers interrupt configs for `execute`, `write_file`, `edit_file`, `web_search`, `fetch_url`, `task`, `compact_conversation`, `launch_async_subagent`, `update_async_subagent`, `cancel_async_subagent`. In non-interactive mode, `client.non_interactive._handle_action_request` enforces the shell allow-list via `config.is_shell_command_allowed`.
|
|
223
223
|
- **Outside**: Once the user clicks "approve" (interactive) or a command passes the allow-list check (non-interactive), the tool executes with no further framework-level gating.
|
|
224
224
|
- **Crossing mechanism**: LangGraph HITL interrupt routed through `RemoteAgent` SSE stream.
|
|
225
225
|
- **Key note**: `auto_approve` mode bypasses all HITL approval prompts while still displaying Unicode/URL warnings.
|
|
@@ -232,13 +232,13 @@
|
|
|
232
232
|
|
|
233
233
|
#### TB4: MCP Config → Process / Network
|
|
234
234
|
|
|
235
|
-
- **Inside**: `mcp_tools._validate_server_config` validates JSON structure and field types. `mcp_trust.compute_config_fingerprint` computes SHA-256 over config file contents. Project-level stdio servers require trust approval (fingerprint prompt) unless `--trust-project-mcp` is set.
|
|
235
|
+
- **Inside**: `mcp_tools._validate_server_config` validates JSON structure and field types. `mcp_trust.compute_config_fingerprint` computes SHA-256 over config file contents. Project-level stdio servers require trust approval (fingerprint prompt) unless `--trust-project-mcp` is set. A user can selectively pre-approve or reject individual project servers by name via `[mcp].enabled_project_servers` / `disabled_project_servers` (or the `DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS` / `..._DISABLED_...` env vars); reject wins over approval and over full trust. These lists are read by `model_config.load_mcp_server_trust_lists` only from user-controlled sources — the user-level `~/.deepagents/config.toml`, the global `~/.deepagents/.env`, and shell-exported env — never from `.mcp.json` or any repo-committed file, so a committed config cannot self-approve its own servers. In particular, the env forms (`DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS` / `..._DISABLED_...`) are added to `config._PROJECT_DOTENV_DENIED_ENV_KEYS`, so a committed *project* `.env` cannot inject them into `os.environ` even though it is loaded at bootstrap. Enabled resolves env-over-TOML, but disabled *unions* TOML and env so a deny can never be silently emptied by the other source. If the user's `config.toml` exists but cannot be read or parsed, the loader fails closed (project configs are treated as untrusted and the error is surfaced) rather than proceeding with an empty deny list. Only allowlisted (or fully trusted) names survive into the merged config, so a non-allowlisted remote entry is never preflighted and its interpolated headers are never resolved. Note that the allow list binds by server *name*, not by fingerprint: an allowlisted name is loaded whatever definition the repo currently gives it, bypassing the fingerprint change-detection that re-prompts on full-config trust — so users should only allowlist names in repos they would otherwise trust.
|
|
236
236
|
- **Outside**: Stdio server `command`, `args`, and `env` fields are user-controlled strings passed directly to `StdioConnection`. The `env` dict from MCP config is forwarded without filtering — users can set arbitrary environment variables (including `PATH`, `LD_PRELOAD`, `PYTHONPATH`) for the MCP subprocess.
|
|
237
237
|
- **Crossing mechanism**: `subprocess.Popen` (via `langchain_mcp_adapters`) for stdio; HTTP/SSE for remote servers.
|
|
238
238
|
|
|
239
239
|
#### TB8: CLI → Server Subprocess IPC
|
|
240
240
|
|
|
241
|
-
- **Inside**: `ServerConfig.to_env()` serializes all config (model, assistant_id, system_prompt, sandbox settings, cwd, MCP config path, shell-enable flags) to `DA_SERVER_*` env vars. `server_manager._apply_server_config` writes these to `os.environ` before `subprocess.Popen`. `server.py:_build_server_env` strips cloud auth vars (`LANGGRAPH_CLOUD_LICENSE_KEY`, `LANGSMITH_CONTROL_PLANE_API_KEY`, `LANGSMITH_TENANT_ID`, `LANGGRAPH_AUTH`).
|
|
241
|
+
- **Inside**: `ServerConfig.to_env()` serializes all config (model, assistant_id, system_prompt, sandbox settings, cwd, MCP config path, shell-enable flags) to `DA_SERVER_*` env vars. `client.launch.server_manager._apply_server_config` writes these to `os.environ` before `subprocess.Popen`. `client/launch/server.py:_build_server_env` strips cloud auth vars (`LANGGRAPH_CLOUD_LICENSE_KEY`, `LANGSMITH_CONTROL_PLANE_API_KEY`, `LANGSMITH_TENANT_ID`, `LANGGRAPH_AUTH`).
|
|
242
242
|
- **Outside**: The full parent environment including provider API keys flows to the child via `os.environ.copy()`. The system prompt string becomes `DA_SERVER_SYSTEM_PROMPT`. After process start, the env is fixed — no runtime mutation across processes.
|
|
243
243
|
- **Crossing mechanism**: `subprocess.Popen` env kwarg; subsequent `os.environ` reads in `_server_config.ServerConfig.from_env`.
|
|
244
244
|
|
|
@@ -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. 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.
|
|
253
|
+
- **Inside**: Server bound to `127.0.0.1` by default; `client/launch/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 (`client/launch/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
|
|
|
@@ -339,7 +339,7 @@
|
|
|
339
339
|
| ID | Data Flow | Classification | Threat | Boundary | Severity | Validation | Code Reference |
|
|
340
340
|
|-----|-----------|----------------|---------------------------------------------------------------------------------------------|----------|----------|------------|------------------------------------------------------------------------|
|
|
341
341
|
| T1 | DF8, DF9 | — | Prompt injection via fetched web content causes LLM to request harmful actions | TB3 | Medium | Likely | `tools.fetch_url`, `agent._add_interrupt_on` |
|
|
342
|
-
| T2 | DF7 | — | `--shell-allow-list all` removes pattern checks; LLM-injected shell commands execute without approval in non-interactive mode | TB2 | Medium | Verified | `config.is_shell_command_allowed`, `non_interactive._handle_action_request` |
|
|
342
|
+
| T2 | DF7 | — | `--shell-allow-list all` removes pattern checks; LLM-injected shell commands execute without approval in non-interactive mode | TB2 | Medium | Verified | `config.is_shell_command_allowed`, `client.non_interactive._handle_action_request` |
|
|
343
343
|
| T3 | DF7 | — | Unicode-homoglyph URL in LLM-generated tool args deceives user during approval | TB2 | Low | Disproven | `unicode_security.check_url_safety`, `agent._format_fetch_url_description` |
|
|
344
344
|
| T4 | DF5, DF9 | — | Auto-approve mode bypasses all HITL gates; any LLM-initiated tool call executes | TB2 | Low | Verified | `agent.create_cli_agent` (`auto_approve` param), `agent._add_interrupt_on` |
|
|
345
345
|
| T5 | DF13, DF14| DC2 | Local SQLite checkpoint file tampered with to inject adversarial content into future LLM context | None | Low | Unverified | `sessions.get_db_path` |
|
|
@@ -385,7 +385,7 @@
|
|
|
385
385
|
#### T6: Unauthenticated LangGraph Dev Server on Localhost
|
|
386
386
|
|
|
387
387
|
- **Flow**: DF3/DF4 (CLI ↔ LangGraph dev server)
|
|
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.
|
|
388
|
+
- **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`client/launch/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.
|
|
389
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).
|
|
390
390
|
|
|
391
391
|
#### T7: LocalContextMiddleware Injects Host File Contents into System Prompt
|
|
@@ -93,6 +93,42 @@ real PyPI release.
|
|
|
93
93
|
Any non-empty value enables the flag (including `"0"` or `"false"`).
|
|
94
94
|
"""
|
|
95
95
|
|
|
96
|
+
DISABLED_PROJECT_MCP_SERVERS = "DEEPAGENTS_CODE_DISABLED_PROJECT_MCP_SERVERS"
|
|
97
|
+
"""Comma-separated project MCP server names to always reject by name.
|
|
98
|
+
|
|
99
|
+
A user-level equivalent of `[mcp].disabled_project_servers`.
|
|
100
|
+
|
|
101
|
+
Rejection wins over approval: a name listed here is dropped even when it also
|
|
102
|
+
appears in `ENABLED_PROJECT_MCP_SERVERS` (or `[mcp].enabled_project_servers`)
|
|
103
|
+
and even when the project config is otherwise trusted. Unlike the enabled list,
|
|
104
|
+
this env var *unions* with (rather than replaces)
|
|
105
|
+
`[mcp].disabled_project_servers` — denies accumulate across sources, so neither
|
|
106
|
+
can silently empty a deny set in the other. This is process env the user
|
|
107
|
+
controls, not a repo file, so it does not weaken the user-level-only
|
|
108
|
+
trust boundary: a committed *project* `.env` is blocked from setting it
|
|
109
|
+
(see `config._PROJECT_DOTENV_DENIED_ENV_KEYS`); only the user's shell,
|
|
110
|
+
launch env, or global `~/.deepagents/.env` can.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
ENABLED_PROJECT_MCP_SERVERS = "DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS"
|
|
114
|
+
"""Comma-separated project MCP server names to pre-approve by name.
|
|
115
|
+
|
|
116
|
+
A user-level equivalent of `[mcp].enabled_project_servers`.
|
|
117
|
+
|
|
118
|
+
Servers named here load from an otherwise-untrusted project `.mcp.json` without
|
|
119
|
+
prompting (they are omitted from the interactive approval prompt), while
|
|
120
|
+
non-listed servers stay dropped. Like `DISABLED_PROJECT_MCP_SERVERS`, this is
|
|
121
|
+
user-controlled process env, not a repo file, so it does not weaken
|
|
122
|
+
the user-level-only trust boundary (a committed *project* `.env` cannot set it;
|
|
123
|
+
see `config._PROJECT_DOTENV_DENIED_ENV_KEYS`). This contract is name-based:
|
|
124
|
+
a project command or URL change under the same server name still matches.
|
|
125
|
+
|
|
126
|
+
When set, this replaces (takes precedence over) the
|
|
127
|
+
`[mcp].enabled_project_servers` TOML list.
|
|
128
|
+
(`DISABLED_PROJECT_MCP_SERVERS` instead *unions* with its TOML list, so a deny
|
|
129
|
+
is never silently emptied.)
|
|
130
|
+
"""
|
|
131
|
+
|
|
96
132
|
EXTERNAL_EVENT_SOCKET = "DEEPAGENTS_CODE_EXTERNAL_EVENT_SOCKET"
|
|
97
133
|
"""Enable the local Unix-socket external event listener.
|
|
98
134
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Fake chat model base shared by integration tests and tool enumeration.
|
|
2
|
+
|
|
3
|
+
Holds the tool-binding base that both the local integration-test fakes
|
|
4
|
+
(`_testing_models`) and the `dcode tools list` tool-enumeration path
|
|
5
|
+
(`tool_catalog._CatalogModel`) build on. It lives in a use-neutral module — not
|
|
6
|
+
under a `_testing_`-prefixed name — so a production import path never depends on
|
|
7
|
+
something that reads as test-only and might be pruned or excluded from the wheel.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING, Any
|
|
13
|
+
|
|
14
|
+
from langchain_core.language_models.fake_chat_models import GenericFakeChatModel
|
|
15
|
+
from pydantic import Field
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Callable, Sequence
|
|
19
|
+
|
|
20
|
+
from langchain_core.language_models import LanguageModelInput
|
|
21
|
+
from langchain_core.messages import AIMessage
|
|
22
|
+
from langchain_core.runnables import Runnable
|
|
23
|
+
from langchain_core.tools import BaseTool
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
_TOOL_BINDING_MODEL_PROFILE: dict[str, Any] = {
|
|
27
|
+
"tool_calling": True,
|
|
28
|
+
"max_input_tokens": 8000,
|
|
29
|
+
}
|
|
30
|
+
"""Minimal capability profile the agent runtime reads while compiling a model.
|
|
31
|
+
|
|
32
|
+
Only `tool_calling` is load-bearing — the agent negotiates tool support at
|
|
33
|
+
setup. `max_input_tokens` is part of the profile surface but inert here: these
|
|
34
|
+
models are compiled to bind tools and are never invoked, so no token budget ever
|
|
35
|
+
applies. Defined once so both the integration-test fakes and
|
|
36
|
+
`tool_catalog._CatalogModel` share a single source of truth.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _ToolBindingFakeModel(GenericFakeChatModel):
|
|
41
|
+
"""Base for fake chat models that must bind tools but are never invoked.
|
|
42
|
+
|
|
43
|
+
The agent runtime calls `model.bind_tools(schemas)` and reads `model.profile`
|
|
44
|
+
while compiling the graph, and a bare `GenericFakeChatModel` cannot be
|
|
45
|
+
compiled into an agent graph: it inherits `BaseChatModel.bind_tools`, which
|
|
46
|
+
raises `NotImplementedError`, and its `profile` is `None`, which breaks
|
|
47
|
+
capability negotiation. This base supplies a no-op `bind_tools` passthrough
|
|
48
|
+
and a minimal `profile`, leaving subclasses to add generation behavior
|
|
49
|
+
(tests) or nothing at all (tool enumeration).
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
# Required by `GenericFakeChatModel`, but subclasses never consume it.
|
|
53
|
+
messages: object = Field(default_factory=lambda: iter(()))
|
|
54
|
+
profile: dict[str, Any] | None = Field(
|
|
55
|
+
default_factory=lambda: dict(_TOOL_BINDING_MODEL_PROFILE)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def bind_tools(
|
|
59
|
+
self,
|
|
60
|
+
tools: Sequence[dict[str, Any] | type | Callable | BaseTool], # noqa: ARG002
|
|
61
|
+
*,
|
|
62
|
+
tool_choice: str | None = None, # noqa: ARG002
|
|
63
|
+
**kwargs: Any, # noqa: ARG002
|
|
64
|
+
) -> Runnable[LanguageModelInput, AIMessage]:
|
|
65
|
+
"""Return self so the agent can bind tool schemas without a real model."""
|
|
66
|
+
return self
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
"""Lightweight session statistics
|
|
1
|
+
"""Lightweight session statistics, token formatting, and usage-table rendering.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Holds `SessionStats`/`ModelStats`, the `format_token_count` formatter, and
|
|
4
|
+
`print_usage_table` (which imports `rich.table` lazily). The module is
|
|
5
|
+
intentionally kept free of heavy top-level dependencies (no pydantic, no
|
|
4
6
|
config, no widget imports) so that `app.py` can import `SessionStats` and
|
|
5
7
|
`format_token_count` at module level without pulling in the full
|
|
6
8
|
`textual_adapter` dependency tree.
|
|
@@ -9,7 +11,12 @@ config, no widget imports) so that `app.py` can import `SessionStats` and
|
|
|
9
11
|
from __future__ import annotations
|
|
10
12
|
|
|
11
13
|
from dataclasses import dataclass, field
|
|
12
|
-
from typing import Literal
|
|
14
|
+
from typing import TYPE_CHECKING, Literal
|
|
15
|
+
|
|
16
|
+
from deepagents_code.formatting import format_duration
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from rich.console import Console
|
|
13
20
|
|
|
14
21
|
SpinnerStatus = (
|
|
15
22
|
Literal[
|
|
@@ -150,3 +157,79 @@ def format_token_count(count: int) -> str:
|
|
|
150
157
|
if count >= 1000: # noqa: PLR2004
|
|
151
158
|
return f"{count / 1000:.1f}K"
|
|
152
159
|
return str(count)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def print_usage_table(
|
|
163
|
+
stats: SessionStats,
|
|
164
|
+
wall_time: float,
|
|
165
|
+
console: Console,
|
|
166
|
+
) -> None:
|
|
167
|
+
"""Print a model-usage stats table to a Rich console.
|
|
168
|
+
|
|
169
|
+
Each row shows the serving provider alongside the model name. When the
|
|
170
|
+
session spans multiple models each gets its own row with a totals row
|
|
171
|
+
appended; single-model sessions show one row.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
stats: Cumulative session stats.
|
|
175
|
+
wall_time: Total wall-clock time in seconds.
|
|
176
|
+
console: Rich console for output.
|
|
177
|
+
"""
|
|
178
|
+
from rich.table import Table
|
|
179
|
+
|
|
180
|
+
has_time = wall_time >= 0.1 # noqa: PLR2004
|
|
181
|
+
if not (stats.request_count or stats.input_tokens or has_time):
|
|
182
|
+
return
|
|
183
|
+
|
|
184
|
+
if stats.per_model:
|
|
185
|
+
multi_model = len(stats.per_model) > 1
|
|
186
|
+
|
|
187
|
+
table = Table(
|
|
188
|
+
show_header=True,
|
|
189
|
+
header_style="bold",
|
|
190
|
+
box=None,
|
|
191
|
+
padding=(0, 2, 0, 0),
|
|
192
|
+
show_edge=False,
|
|
193
|
+
)
|
|
194
|
+
table.add_column("Provider", style="dim")
|
|
195
|
+
table.add_column("Model", style="dim")
|
|
196
|
+
table.add_column("Reqs", justify="right", style="dim")
|
|
197
|
+
table.add_column("InputTok", justify="right", style="dim")
|
|
198
|
+
table.add_column("OutputTok", justify="right", style="dim")
|
|
199
|
+
|
|
200
|
+
if multi_model:
|
|
201
|
+
for ms in stats.per_model.values():
|
|
202
|
+
table.add_row(
|
|
203
|
+
ms.provider,
|
|
204
|
+
ms.model_name,
|
|
205
|
+
str(ms.request_count),
|
|
206
|
+
format_token_count(ms.input_tokens),
|
|
207
|
+
format_token_count(ms.output_tokens),
|
|
208
|
+
)
|
|
209
|
+
table.add_row(
|
|
210
|
+
"",
|
|
211
|
+
"Total",
|
|
212
|
+
str(stats.request_count),
|
|
213
|
+
format_token_count(stats.input_tokens),
|
|
214
|
+
format_token_count(stats.output_tokens),
|
|
215
|
+
)
|
|
216
|
+
else:
|
|
217
|
+
ms = next(iter(stats.per_model.values()))
|
|
218
|
+
table.add_row(
|
|
219
|
+
ms.provider,
|
|
220
|
+
ms.model_name,
|
|
221
|
+
str(stats.request_count),
|
|
222
|
+
format_token_count(stats.input_tokens),
|
|
223
|
+
format_token_count(stats.output_tokens),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
console.print()
|
|
227
|
+
console.print("[bold]Usage Stats[/bold]")
|
|
228
|
+
console.print(table)
|
|
229
|
+
if has_time:
|
|
230
|
+
console.print()
|
|
231
|
+
console.print(
|
|
232
|
+
f"Agent active {format_duration(wall_time)}",
|
|
233
|
+
style="dim",
|
|
234
|
+
highlight=False,
|
|
235
|
+
)
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
"""Internal chat models
|
|
1
|
+
"""Internal fake chat models for local integration tests.
|
|
2
|
+
|
|
3
|
+
The tool-binding base these build on (`_fake_models._ToolBindingFakeModel`) is
|
|
4
|
+
factored out into a use-neutral module so the `dcode tools list` enumeration
|
|
5
|
+
path can reuse it without importing this test-named module.
|
|
6
|
+
"""
|
|
2
7
|
|
|
3
8
|
from __future__ import annotations
|
|
4
9
|
|
|
5
10
|
from typing import TYPE_CHECKING, Any
|
|
6
11
|
|
|
7
|
-
from langchain_core.language_models.fake_chat_models import GenericFakeChatModel
|
|
8
12
|
from langchain_core.messages import AIMessage, BaseMessage
|
|
9
13
|
from langchain_core.outputs import ChatGeneration, ChatResult
|
|
10
|
-
|
|
14
|
+
|
|
15
|
+
from deepagents_code._fake_models import _ToolBindingFakeModel
|
|
11
16
|
|
|
12
17
|
if TYPE_CHECKING:
|
|
13
|
-
from collections.abc import Callable
|
|
18
|
+
from collections.abc import Callable
|
|
14
19
|
|
|
15
20
|
from langchain_core.callbacks import CallbackManagerForLLMRun
|
|
16
|
-
from langchain_core.language_models import LanguageModelInput
|
|
17
|
-
from langchain_core.runnables import Runnable
|
|
18
|
-
from langchain_core.tools import BaseTool
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
# Prompt markers that drive `ToolCallingIntegrationChatModel`. Each marker is the
|
|
@@ -33,13 +35,13 @@ TOP_LEVEL_WRITE_CONTENT = "auto-approved"
|
|
|
33
35
|
SUBAGENT_WRITE_CONTENT = "auto-approved-subagent"
|
|
34
36
|
|
|
35
37
|
|
|
36
|
-
class DeterministicIntegrationChatModel(
|
|
38
|
+
class DeterministicIntegrationChatModel(_ToolBindingFakeModel):
|
|
37
39
|
"""Deterministic chat model for integration tests.
|
|
38
40
|
|
|
39
|
-
This subclasses
|
|
40
|
-
stays aligned with the core fake-chat-model test surface,
|
|
41
|
-
generation to remain prompt-driven and restart-safe for real
|
|
42
|
-
integration tests.
|
|
41
|
+
This subclasses `_ToolBindingFakeModel` (itself a `GenericFakeChatModel`) so
|
|
42
|
+
the implementation stays aligned with the core fake-chat-model test surface,
|
|
43
|
+
while overriding generation to remain prompt-driven and restart-safe for real
|
|
44
|
+
CLI server integration tests.
|
|
43
45
|
|
|
44
46
|
Why the existing `langchain_core` fakes cannot be reused here:
|
|
45
47
|
|
|
@@ -53,13 +55,15 @@ class DeterministicIntegrationChatModel(GenericFakeChatModel):
|
|
|
53
55
|
identical output regardless of process lifecycle.
|
|
54
56
|
|
|
55
57
|
2. The agent runtime calls `model.bind_tools(schemas)` during
|
|
56
|
-
initialization.
|
|
57
|
-
|
|
58
|
+
initialization. A bare `GenericFakeChatModel` inherits
|
|
59
|
+
`BaseChatModel.bind_tools`, which raises `NotImplementedError` in any
|
|
60
|
+
agent-loop context. The inherited `_ToolBindingFakeModel` supplies a
|
|
58
61
|
no-op passthrough.
|
|
59
62
|
|
|
60
63
|
3. The app server reads `model.profile` for capability negotiation (e.g.
|
|
61
|
-
`tool_calling`, `max_input_tokens`).
|
|
62
|
-
causing
|
|
64
|
+
`tool_calling`, `max_input_tokens`). A bare fake's `profile` is `None`,
|
|
65
|
+
causing silent misconfiguration at runtime. The inherited
|
|
66
|
+
`_ToolBindingFakeModel` supplies a minimal profile.
|
|
63
67
|
|
|
64
68
|
Additionally, the compact middleware issues summarization prompts mid-
|
|
65
69
|
conversation. A list-based model cannot distinguish these from normal user
|
|
@@ -68,24 +72,8 @@ class DeterministicIntegrationChatModel(GenericFakeChatModel):
|
|
|
68
72
|
"""
|
|
69
73
|
|
|
70
74
|
model: str = "fake"
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
profile: dict[str, Any] | None = Field(
|
|
74
|
-
default_factory=lambda: {
|
|
75
|
-
"tool_calling": True,
|
|
76
|
-
"max_input_tokens": 8000,
|
|
77
|
-
}
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
def bind_tools(
|
|
81
|
-
self,
|
|
82
|
-
tools: Sequence[dict[str, Any] | type | Callable | BaseTool], # noqa: ARG002
|
|
83
|
-
*,
|
|
84
|
-
tool_choice: str | None = None, # noqa: ARG002
|
|
85
|
-
**kwargs: Any, # noqa: ARG002
|
|
86
|
-
) -> Runnable[LanguageModelInput, AIMessage]:
|
|
87
|
-
"""Return self so the agent can bind tool schemas during tests."""
|
|
88
|
-
return self
|
|
75
|
+
# `messages`, `profile`, and the `bind_tools` passthrough are inherited from
|
|
76
|
+
# `_ToolBindingFakeModel`; this model adds only prompt-driven generation.
|
|
89
77
|
|
|
90
78
|
def _generate(
|
|
91
79
|
self,
|