From 5abae593d861bcfa276a8dfcbaff228a0eb9c532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Sun, 12 Jul 2026 22:09:25 +0200 Subject: [PATCH] fix(agent): keep streaming off for suppressed turns Streaming wrote assistant deltas straight to stdout regardless of `suppress_answer`, so `--save`/capture turns (which set it to hide the answer) leaked model text past the `runTurn` guard. Pass a null stream hook when the turn's answer is suppressed. --- src/agent/Agent.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/agent/Agent.zig b/src/agent/Agent.zig index c3a321811..36401ed43 100644 --- a/src/agent/Agent.zig +++ b/src/agent/Agent.zig @@ -1703,7 +1703,9 @@ fn processUserMessage(self: *Agent, input: TurnInput) !?[]const u8 { // non-thinking models. .effort = self.effort, .cancel = .{ .context = @ptrCast(self), .checkFn = checkCancel }, - .stream = self.streamHook(), + // Suppressed turns (e.g. `--save` capture) must keep stdout clean; + // streaming would bypass the `suppress_answer` guard in `runTurn`. + .stream = if (input.suppress_answer) null else self.streamHook(), }, ) catch |err| { self.endStreamedText(); @@ -1790,7 +1792,7 @@ fn processUserMessage(self: *Agent, input: TurnInput) !?[]const u8 { // `.none` stays off to opt out on models that reject it. .effort = if (self.effort == .none) .none else .low, .cancel = .{ .context = @ptrCast(self), .checkFn = checkCancel }, - .stream = self.streamHook(), + .stream = if (input.suppress_answer) null else self.streamHook(), }, ) catch |err| { self.endStreamedText();