mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
The shell executor rendered every returned ExecResult and returned Ok(output), so nonzero exits, timeouts, and cancellations reached execute_one_tool() as successes. That false ToolResult propagated consistently: agent.tool.completed recorded is_error: false, the success post-tool hook ran, Anthropic saw is_error: false, OpenAI Responses saw a completed function-call output, and CLI/web rendered a successful tool call. ExecResult::is_success() is now the authoritative predicate. The executor runs through exec_command_streaming() with a sink callback, so it keeps the production providers' stream provenance and partial-output capture, and drops the exec 2>&1 prefix that merged stderr into stdout before Fabro could report it. Model-facing text labels termination, exit code, duration, and either separate stdout/stderr sections or one combined section when the provider cannot separate streams. Session-bound dispatch also emits a typed agent.tool.process.completed event carrying the process metadata, streams_separated, and bounded redacted output tails. It is subordinate diagnostic data: the following agent.tool.completed remains the one tool-protocol completion and the authoritative owner of is_error, so consumers need no new row. Nonzero, timed-out, and cancelled commands intentionally change from successful to failed tool results, and PostToolUseFailure replaces PostToolUse for them. On Docker the agent shell tool now uses the streaming path's bash -lc supervisor, which terminates the process group on timeout instead of leaving container-side processes running. The public shell schema is unchanged and pinned by an exact assertion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5 lines
96 B
Rust
5 lines
96 B
Rust
mod compaction;
|
|
#[cfg(feature = "docker")]
|
|
mod docker_shell;
|
|
mod guardrails;
|
|
mod parity_matrix;
|