Skip to content

fix(docker): full container_config parity for file_tools and code_execution_tool - #35937

Open
jsplec wants to merge 1 commit into
NousResearch:mainfrom
jsplec:fix/forward-docker-env-and-extra-args
Open

fix(docker): full container_config parity for file_tools and code_execution_tool#35937
jsplec wants to merge 1 commit into
NousResearch:mainfrom
jsplec:fix/forward-docker-env-and-extra-args

Conversation

@jsplec

@jsplec jsplec commented May 31, 2026

Copy link
Copy Markdown

Docker: full container_config parity for file_tools and code_execution_tool

terminal_tool._create_environment() is the source of truth for the docker container_config dict: modal_mode, docker_volumes, docker_mount_cwd_to_workspace, docker_forward_env, docker_env, docker_run_as_host_user, docker_extra_args, docker_network, docker_persist_across_processes, docker_orphan_reaper.

The shared per-task container is created lazily by whichever tool wins the race to touch it first (_resolve_container_task_id). file_tools._get_file_ops() and code_execution_tool._get_or_create_env() each build their own container_config dict, and both omitted several of the above keys — so a file or code-execution op winning the race silently dropped the user's configured proxy env, extra docker run flags, orphan reaping, and (for code_execution_tool specifically) cwd mounting and forwarded env too. Order-dependent and non-deterministic from the user's perspective.

Fix

Bring both file_tools.py and code_execution_tool.py to full parity with terminal_tool.py's container_config dict, not just docker_env/docker_extra_args.

Tests

  • Extended tests/tools/test_file_tools_container_config.py with docker_env/docker_extra_args coverage.
  • New tests/tools/test_code_execution_container_config.py pinning all container-config keys for code_execution_tool._get_or_create_env, mirroring the file_tools test.

Changes from the original PR, per review:

  • Dropped the cli.py / gateway/run.py TERMINAL_DOCKER_EXTRA_ARGS bridge hunks — already merged via fix(terminal): bridge docker_extra_args to TERMINAL_DOCKER_EXTRA_ARGS in CLI + gateway #50631 (de6b3ae3).
  • Widened the docker fix from 2 keys (docker_env, docker_extra_args) to full parity (7 more keys were still missing in code_execution_tool.py, 5 in file_tools.py) after @teknium1 pointed out terminal_tool.py:2202-2216 forwards a wider set than either tool carried — matches the parity work referenced in fix(tools): bring file_tools + code_execution container_config to terminal_tool parity #35660.
  • Dropped the agent circuit-breaker entirely rather than reworking it. main already ships agent/tool_guardrails.py's ToolCallGuardrailController, which is fully wired into both execute_tool_calls_sequential and execute_tool_calls_concurrent (tool_executor.py) and already halts run_conversation (conversation_loop.py:4690) via _tool_guardrail_halt_decision. It covers the same repeated-identical-failure case (exact_failure_warn_after/exact_failure_block_after) without the streak-key bug the original addition had (A,B,A double-counted A) and without the concurrent-path gap. The 44k-token memory-replace retry loop that motivated the original addition would be caught by this existing controller today if tool_loop_guardrails.hard_stop_enabled is turned on (it's opt-in, off by default) — a config change, not a code change, and outside this PR's scope.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists backend/docker Docker container execution tool/file File tools (read, write, patch, search) tool/code-exec execute_code sandbox labels May 31, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #35660 (superset — brings file_tools + code_execution container_config to full terminal_tool parity, including modal_mode, docker_persist_across_processes, docker_orphan_reaper in addition to docker_env/docker_extra_args). Also overlaps with #30097 (code_execution only subset).

@jsplec
jsplec force-pushed the fix/forward-docker-env-and-extra-args branch from 4ee8a7d to 1419cda Compare June 5, 2026 02:45
@jsplec jsplec changed the title fix(docker): forward docker_env and docker_extra_args from file and code-execution tools fix(agent,docker): halt loop on repeated tool errors + forward docker env/args Jun 10, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying the order-dependent Docker configuration path. The two docker_env / docker_extra_args omissions are still present on current main in tools/file_tools.py:1141-1151 and tools/code_execution_tool.py:680-688.

Problems

  • The PR's cli.py, gateway/run.py, and bridge-test changes are already implemented by merged PR #50631 (de6b3ae37).
  • The Docker configs still would not be fully identical: tools/terminal_tool.py:2202-2216 forwards additional settings that the PR's code_execution_tool.py config does not carry. This matches the linked #35660 superset discussion.
  • The new unconditional agent halt bypasses main's explicit warning-first, opt-in hard-stop policy in agent/tool_guardrails.py:64-79 (0704589). Its per-error map also does not reset on a different failure, so it does not enforce a consecutive streak, and it is not wired into the concurrent executor.

Suggested changes

  • Salvage the two remaining Docker keys with focused file-tools and execute-code coverage; drop the already-merged bridge hunks.
  • Rework any loop-stop proposal through ToolCallGuardrailController and cover sequential/concurrent behavior.

Automated hermes-sweeper review.

Comment thread agent/tool_executor.py Outdated
if _is_error_result:
_err_key = (function_name, _err_text[:120])
streak = agent._consecutive_tool_error_streak
streak[_err_key] = streak.get(_err_key, 0) + 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This counter is keyed by error text but only cleared after a success. A failure sequence A, B, A increments A twice even though the failures were not consecutive. Reset the prior fingerprint whenever a different result is observed, or use the existing guardrail controller.

Comment thread agent/conversation_loop.py Outdated
@@ -3987,6 +3989,20 @@ def _perform_api_call(next_api_kwargs):
pass
break

if agent._tool_error_loop_halt is not None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new halt flag is only updated in the sequential executor. Current concurrent execution has its own path in agent/tool_executor.py, so this loop check cannot halt repeated failures produced there. Route any policy through the shared guardrail mechanism instead.

Comment thread cli.py
@@ -602,6 +602,7 @@ def load_cli_config() -> Dict[str, Any]:
"container_persistent": "TERMINAL_CONTAINER_PERSISTENT",
"docker_volumes": "TERMINAL_DOCKER_VOLUMES",
"docker_env": "TERMINAL_DOCKER_ENV",
"docker_extra_args": "TERMINAL_DOCKER_EXTRA_ARGS",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bridge is already on current main via merged PR #50631 (de6b3ae37). Please drop this duplicate hunk when salvaging the remaining container-config propagation fix.

@@ -649,6 +649,8 @@ def _get_or_create_env(task_id: str):
"container_persistent": config.get("container_persistent", True),
"docker_volumes": config.get("docker_volumes", []),
"docker_run_as_host_user": config.get("docker_run_as_host_user", False),
"docker_env": config.get("docker_env", {}),
"docker_extra_args": config.get("docker_extra_args", []),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two keys fix part of the divergence, but the resulting config still differs from terminal_tool's container config: it omits settings such as docker_forward_env and docker_mount_cwd_to_workspace. Either narrow the PR claim or align with the linked parity work (#35660).

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit labels Jul 13, 2026
…er_config parity with terminal_tool

terminal_tool._create_environment() is the source of truth for docker
container_config: modal_mode, docker_volumes, docker_mount_cwd_to_workspace,
docker_forward_env, docker_env, docker_run_as_host_user, docker_extra_args,
docker_network, docker_persist_across_processes, docker_orphan_reaper.

The container is created lazily by whichever tool wins the race to touch it
first (file ops, code execution, or terminal), via _resolve_container_task_id.
file_tools._get_file_ops() and code_execution_tool._get_or_create_env() built
their own container_config dicts that omitted several of these keys, so a
file or code-execution op winning the race silently dropped the user's
configured proxy env, docker run flags, orphan reaping, and (for
code_execution_tool specifically) cwd mounting and forwarded env too. The
result was order-dependent and non-deterministic from the user's perspective.

Bring both to full parity with terminal_tool's container_config dict, and pin
each key with focused tests (test_file_tools_container_config.py,
new test_code_execution_container_config.py) so a future divergence is
caught the same way test_terminal_config_env_sync.py already catches
CLI/gateway bridge drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsplec
jsplec force-pushed the fix/forward-docker-env-and-extra-args branch from 1419cda to e83c496 Compare July 14, 2026 14:06
@jsplec jsplec changed the title fix(agent,docker): halt loop on repeated tool errors + forward docker env/args fix(docker): full container_config parity for file_tools and code_execution_tool Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/docker Docker container execution P2 Medium — degraded but workaround exists sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state tool/code-exec execute_code sandbox tool/file File tools (read, write, patch, search) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants