From d878cf026c558cc5b381249d225cc29f6c1f25b7 Mon Sep 17 00:00:00 2001 From: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com> Date: Wed, 22 Apr 2026 21:33:10 -0400 Subject: [PATCH] fix(pi-embedded-runner): address greptile review on incomplete-turn gate - Drop redundant !lastToolError check from the messaging-tool clean-stop early return; the earlier lastToolError early return already handles that case, so the extra condition was dead and misleading. - Update the CHANGELOG entry to reference only stopReason=stop; the pi-ai StopReason type does not include end_turn, so the earlier mention was a documentation-only discrepancy. --- CHANGELOG.md | 2 +- .../pi-embedded-runner/run/incomplete-turn.ts | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b07777bdbdf..e00b46d2490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,7 @@ Docs: https://docs.openclaw.ai - Providers/SDK retry: cap long `Retry-After` sleeps in Stainless-based Anthropic/OpenAI model SDKs so 60s+ retry windows surface immediately for OpenClaw failover instead of blocking the run. (#68474) Thanks @jetd1. - Agents/TTS: preserve spoken text in TTS tool results while defusing reply directives in transcript content, so future turns remember voice replies without treating spoken `MEDIA:` or voice tags as delivery metadata. (#68869) Thanks @zqchris. - Providers/OpenAI: harden Voice Call realtime transcription against OpenAI Realtime session-update drift, forward language and prompt hints, and add live coverage for realtime STT. -- Agents/Pi embedded runs: suppress the "⚠️ Agent couldn't generate a response" warning when the assistant already delivered user-visible content through a messaging tool and the turn ended cleanly (`stopReason=stop`/`end_turn`). Real failure modes (tool errors, provider `stopReason=error`, interrupted tool use) still surface the existing "verify before retrying" warning. Fixes #70396. +- Agents/Pi embedded runs: suppress the "⚠️ Agent couldn't generate a response" warning when the assistant already delivered user-visible content through a messaging tool and the turn ended cleanly (`stopReason=stop`). Real failure modes (tool errors, provider `stopReason=error`, interrupted tool use) still surface the existing "verify before retrying" warning. Fixes #70396. (#70425) Thanks @neeravmakwana. - Providers/Moonshot: stop strict-sanitizing Kimi's native tool_call IDs (shaped like `functions.:`) on the OpenAI-compatible transport, so multi-turn agentic flows through Kimi K2.6 no longer break after 2-3 tool-calling rounds when the serving layer fails to match mangled IDs against the original tool definitions. Adds a `sanitizeToolCallIds` opt-out to the shared `openai-compatible` replay family helper and wires Moonshot to it. Fixes #62319. (#70030) Thanks @LeoDu0314. - Dependencies/security: override transitive `uuid` to `14.0.0`, clearing the runtime advisory across dependencies. - Codex harness: ignore dynamic tool descriptions when deciding whether to reuse a native app-server thread while still fingerprinting tool schemas, so channel-specific copy changes no longer reset otherwise compatible Codex conversations. (#69976) Thanks @chen-zhang-cs-code. diff --git a/src/agents/pi-embedded-runner/run/incomplete-turn.ts b/src/agents/pi-embedded-runner/run/incomplete-turn.ts index 02e1ad863a4..961b5b8fddd 100644 --- a/src/agents/pi-embedded-runner/run/incomplete-turn.ts +++ b/src/agents/pi-embedded-runner/run/incomplete-turn.ts @@ -183,14 +183,11 @@ export function resolveIncompleteTurnPayloadText(params: { // If the assistant already delivered user-visible content via a messaging // tool during this turn and ended cleanly (stopReason=stop), do not surface // an incomplete-turn warning. The user has received the reply; a follow-up - // "couldn't generate a response" bubble is a false positive. Real failure - // modes (tool errors, provider stopReason=error, tool-use interruption) - // still fall through to the normal incomplete-turn paths below. - if ( - params.attempt.didSendViaMessagingTool && - !params.attempt.lastToolError && - stopReason === "stop" - ) { + // "couldn't generate a response" bubble is a false positive. Provider-side + // failures (stopReason=error, toolUse interruption) still fall through to + // the normal incomplete-turn paths below; tool-error cases are already + // handled by the lastToolError early return above. + if (params.attempt.didSendViaMessagingTool && stopReason === "stop") { return null; } const incompleteTerminalAssistant = isIncompleteTerminalAssistantTurn({