feat(tools): compose deferred tools in execute_code - #82243
Conversation
9c786fd to
42d5ccb
Compare
|
@teknium1 I think this would be a useful addition to Hermes. |
Interlock —
|
a9b95c9 to
af24e14
Compare
|
Thanks for the detailed interlock. I addressed all three findings and kept the overlapping transport work separate.
The follow-up verification also exposed lifecycle cases around concurrent profiles and live terminal changes. The final head carries profile and backend identity through environment reuse, stable creation locks, file-operation caches, prompt probes, task overrides, working-directory records, aliases, expiry, and teardown. Stale detection, slow cleanup, replacement creation, and file-wrapper publication now share one lock boundary. Shared file wrappers retain their raw session owner, so stale recovery cannot overwrite another session's workspace. Remote RPC loss cancels the active standard or managed command and stops its script worker before the degraded result returns. Terminal, file, and code-execution creation also use the same complete container and SSH policy. The PR body carries the current exact-head verification and regression summary so this reviewer disposition does not become a per-head status log. |
f3d5573 to
19c5964
Compare
_rpc_server_loop and _rpc_poll_loop dispatched nested tool calls (e.g. read_file invoked by execute_code) via handle_function_call without passing session_id. Plugin hooks on_pre_tool_call / on_post_tool_call therefore saw an empty session_id and could not correlate nested calls with the originating turn (NousResearch#51931). The fix reads HERMES_SESSION_ID from the session context on the parent thread (before spawning the RPC thread) and passes it explicitly through to handle_function_call in both the local (UDS) and remote (file-based) RPC paths. Fixes NousResearch#51931 (cherry picked from commit 1749a2b3b65c70af9f24b9a3516de01e2ddcbda5)
JSON-encode every RPC result so plain and multiline plugin outputs remain valid frames across local and file transports. Keep execute_code's established direct-helper umbrella visible in its dynamic schema while continuing to gate deferred Tool Search bridges on the final session surface. Rebuild cached gateway agents when the canonical or effective terminal backend changes so local-only bridge schemas cannot survive a switch to a remote backend.
Co-Authored-By: Dominic Griego <hello@mysticmages.xyz>
Co-Authored-By: Dominic Griego <hello@mysticmages.xyz>
Resolve all terminal settings from the active profile snapshot and namespace cached environments, locks, task overrides, working directories, and aliases by profile and effective backend configuration. This keeps schema selection and runtime dispatch aligned without changing single-profile behavior. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Keep the profile-scoped degraded-mode value when terminal configuration has loaded, and use a safe snapshot fallback when configuration resolution itself raises. This preserves structured redaction on connection failures. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Carry profile and terminal configuration identity through environment reuse, cleanup, prompt probes, and gateway agent caches. Preserve parent sandbox overrides for delegated children, sanitize remote working directories, and evict dead remote environments through structured degraded-mode handling. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Resolve the active profile backend before consulting the process cache, skip local toolchain probes for remote profiles, and propagate profile context into the probe worker. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Retry CI after the ripgrep installation step exited before tests began. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Revalidate cached environments after creation-lock waits, keep file wrappers inside the same publication boundary, apply task CWD policy to lazy creation, fail closed on a live remote RPC poller, and make prompt probes ephemeral. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Keep multiplex task keys internal, honor managed backend policy, retain stable creation locks, evict dead shared environments, abort failed remote RPC waits promptly, and clean every agent-owned terminal task identity. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Keep stale retirement, backend cleanup, replacement creation, and file wrapper publication under stable per-task locks. Propagate remote RPC cancellation through standard and managed execution backends, preserve complete container policy, and clear task-scoped state during teardown. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
Tag shared file wrappers with their raw session owner so stale wrapper recovery cannot overwrite another session's workspace. Replace source-shape network coverage with behavioral checks through the shared container policy. Co-Authored-By: Dominic Grieco <hello@mysticmages.xyz>
d711266 to
9f15ff4
Compare
Ensure sandbox cleanup still runs when profile scope setup fails, and add the requested registry-level explicit-empty execute_code coverage.
9f15ff4 to
a03e251
Compare
Summary
execute_codeprograms search, inspect, and invoke deferred MCP and plugin tools through Hermes' existing Tool Search bridgeexecute_codeschema from the final per-session tool surface while preserving its established direct terminal, file, and web helper umbrellaCloses #82287.
Problem
Hermes already had two complementary paths:
execute_codelets one Python program compose several Hermes tool calls.Those paths did not compose. Once an MCP or plugin tool was deferred,
execute_codecould not search for it, inspect its schema, or invoke it.Changes
tool_search,tool_describe, andtool_callexecute_code's existing direct helper umbrella at runtime and document it in the dynamic schemasession_id,enabled_toolsets, anddisabled_toolsetsthrough nested dispatchexecute_codepromptly when its RPC transport fails while the generated client is waitingSafety
tool_callstill routes the underlying tool through normal schema validation, middleware, hooks, approvals, and dispatchReview fixes
The follow-up commits address the reported integration and lifecycle cases:
finallyblock.mpx:cannot bypass the active profile and backend namespace.default.finallypath even after the active environment has already been evicted.session_id, toolset scope, and deferred-bridge authorization to execution.Behavioral tests cover code-execution-only sessions, final Tool Search surfaces, remote withholding, generated-client round trips, cache hits, terminal configuration transitions, concurrent profiles, same-task environment isolation, all-namespace teardown, profile-scoped cleanup, per-environment expiry, task overrides, working directories, child aliases, child cleanup, multimodal results, errors, and concurrent calls.
Local verification
Verified against base and merge-base
45af7a71fcd420b4422d2c074b1ce58b9ce0d048at exact headd711266f3e4118a5c214e5d7069b121e10242ab7.The changed-surface matrix completed with:
It covers the changed agent, gateway, tool-definition, code-execution, terminal, file, managed-backend, environment-probe, image-source, approval-routing, and profile-home paths. It includes the stale cleanup and held-lock interleavings, complete managed container policy, local and managed cancellation, blocked remote RPC cancellation, canonical teardown cleanup, raw-session file-wrapper ownership, and current-main approval-routing regressions.
Additional exact-head checks passed:
A full local
scripts/run_tests.shrun was also attempted. The current macOS development environment lacks several optional packages and external binaries, so that broad run had unrelated collection and runtime failures. The twotests/tools/test_file_tools.pyfailures are the known macOS/tmpversus/private/tmppath mismatch. The scoped suite above is clean, and GitHub CI is authoritative for the full Linux matrix.GitHub CI at this exact head passed all required checks, including all 12 Python test slices, E2E tests, macOS and Windows tests, Ruff and type checks, contributor attribution, supply chain scans, and both Docker builds. A fresh independent exact-head blocking review returned PASS with no findings and ended
READY FOR MAINTAINER REVIEW: yes.Related work
This PR includes the functional session-ID forwarding commit from #52000 with Christopher Schulze's original authorship preserved. That change also fixes #51931.