fix(exec): hash aggregated output instead of content text

content.text can diverge from details.aggregated in two ways:
- node-host path: content.text uses short-circuit OR (stdout || stderr ||
  errorText), dropping stderr/error when stdout is non-empty
- gateway path: content.text prepends warnings and uses "(no output)" fallback

Use details.aggregated which always contains the full combined output,
falling back to content text when aggregated is unavailable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Keren 2026-03-10 00:28:47 +01:00
parent 48d177d102
commit 39af696552

View File

@ -230,8 +230,10 @@ function hashToolOutcome(
//
// For "running" results the content text itself embeds volatile metadata
// (session id, pid) so we omit it and hash only the status + tail output.
// For "completed" results the content text mirrors `aggregated` which is
// stable, so we include it.
// For "completed" results we use details.aggregated rather than content text
// because content.text may drop stderr/error (node-host uses short-circuit
// OR) or prepend warnings (gateway path), while aggregated always contains
// the full combined stdout+stderr+error output.
if (toolName === "exec") {
if (details.status === "running") {
return digestStable({
@ -242,7 +244,7 @@ function hashToolOutcome(
return digestStable({
status: details.status,
exitCode: details.exitCode ?? null,
text,
aggregated: details.aggregated ?? text,
});
}