diff --git a/internal/runtime/loop/run.go b/internal/runtime/loop/run.go index fed6728..b9c36ee 100644 --- a/internal/runtime/loop/run.go +++ b/internal/runtime/loop/run.go @@ -187,11 +187,7 @@ func (l *Loop) driveTurn(ctx context.Context, sessionID string, msgs []model.Mes } msgs = batch.messages res.ToolCallsExecuted += batch.executed - // speak 的出站结论逐批回填(M57):后面批次里没有 speak 时保留 - // 前面那批的结论 —— 这条回复想用语音这件事发生在哪一批都算数。 - if batch.voice != nil { - res.Voice = batch.voice - } + applyBatchVoice(res, &batch) l.saveCheckpoint(ctx, sessionID, step, msgs, agent.StopReasonToolCalls) // 关键工具循环安全网(或终止钩子)不等真正的最终答案 diff --git a/internal/runtime/loop/voice_deps.go b/internal/runtime/loop/voice_deps.go index 8e57457..9f88044 100644 --- a/internal/runtime/loop/voice_deps.go +++ b/internal/runtime/loop/voice_deps.go @@ -86,6 +86,15 @@ func (l *Loop) withSpeakSpec(schemas []model.ToolSpec) []model.ToolSpec { return append(out, *spec) } +// applyBatchVoice 把一批工具调用的语音结论回填进本回合的 Result。 +// 后面批次里没有 speak 时保留前面那批的结论 —— 「这条回复想用语音」 +// 发生在哪一批都算数。 +func applyBatchVoice(res *Result, batch *toolRunResult) { + if batch.voice != nil { + res.Voice = batch.voice + } +} + // captureVoice 从一批调用的结局里提取本回合的出站语音结论。返回 nil // 表示「这一批没有要求语音」,Result.Voice 因此保持 nil,客户端按纯 // 文本呈现 —— 与没有 speak 之前逐字节一致。