🐛 fix: gateway client-tool pluginState + drop redundant Exit code: 0 tail#14596
Merged
Conversation
… result Gateway-mode client tool results lost the `state` field at three points: the toolResult Zod schema didn't declare it (silently stripped by safeParse), the ToolResultPayload interface didn't carry it, and projectToExecutionResult didn't return it. As a result the "技能状态" tab was always empty for tools dispatched via Agent Gateway, even though clients send `state` correctly and non-gateway paths persist it as `pluginState`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## canary #14596 +/- ##
=========================================
Coverage 65.84% 65.84%
=========================================
Files 2890 2890
Lines 250258 250262 +4
Branches 30003 24174 -5829
=========================================
+ Hits 164775 164779 +4
Misses 85333 85333
Partials 150 150
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
For successful runs, "Command completed successfully." already conveys the same signal — appending "Exit code: 0" was just noise the LLM had to skim past. Non-zero exit codes (130 SIGINT, 137 OOM, etc.) keep the line so the diagnostic information remains available. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Exit code: 0 tail
3 tasks
… header
`success` is the envelope ("the service responded") and `exitCode` is the
command's own status — they're independent. With `success: true` +
`exitCode: 137` the prior format rendered "Command completed successfully."
on top of a SIGKILL/OOM, lying to the LLM.
Now the header is derived from both: any non-zero exit folds the message
into the failure branch as "Command failed with exit code N[: error]".
The trailing "Exit code: N" line is gone — the same info now lives in the
header, so success rendering is also free of the redundant zero tail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closed
Innei
pushed a commit
to Innei/lobehub
that referenced
this pull request
May 12, 2026
…` tail (lobehub#14596) * 🐛 fix(agent-runtime): forward pluginState through gateway client tool result Gateway-mode client tool results lost the `state` field at three points: the toolResult Zod schema didn't declare it (silently stripped by safeParse), the ToolResultPayload interface didn't carry it, and projectToExecutionResult didn't return it. As a result the "技能状态" tab was always empty for tools dispatched via Agent Gateway, even though clients send `state` correctly and non-gateway paths persist it as `pluginState`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(prompts): suppress redundant `Exit code: 0` tail in command result For successful runs, "Command completed successfully." already conveys the same signal — appending "Exit code: 0" was just noise the LLM had to skim past. Non-zero exit codes (130 SIGINT, 137 OOM, etc.) keep the line so the diagnostic information remains available. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(prompts): treat non-zero exit code as command failure in result header `success` is the envelope ("the service responded") and `exitCode` is the command's own status — they're independent. With `success: true` + `exitCode: 137` the prior format rendered "Command completed successfully." on top of a SIGKILL/OOM, lying to the LLM. Now the header is derived from both: any non-zero exit folds the message into the failure branch as "Command failed with exit code N[: error]". The trailing "Exit code: N" line is gone — the same info now lives in the header, so success rendering is also free of the redundant zero tail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
arvinxx
added a commit
that referenced
this pull request
May 12, 2026
…` tail (#14596) * 🐛 fix(agent-runtime): forward pluginState through gateway client tool result Gateway-mode client tool results lost the `state` field at three points: the toolResult Zod schema didn't declare it (silently stripped by safeParse), the ToolResultPayload interface didn't carry it, and projectToExecutionResult didn't return it. As a result the "技能状态" tab was always empty for tools dispatched via Agent Gateway, even though clients send `state` correctly and non-gateway paths persist it as `pluginState`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(prompts): suppress redundant `Exit code: 0` tail in command result For successful runs, "Command completed successfully." already conveys the same signal — appending "Exit code: 0" was just noise the LLM had to skim past. Non-zero exit codes (130 SIGINT, 137 OOM, etc.) keep the line so the diagnostic information remains available. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(prompts): treat non-zero exit code as command failure in result header `success` is the envelope ("the service responded") and `exitCode` is the command's own status — they're independent. With `success: true` + `exitCode: 137` the prior format rendered "Command completed successfully." on top of a SIGKILL/OOM, lying to the LLM. Now the header is derived from both: any non-zero exit folds the message into the failure branch as "Command failed with exit code N[: error]". The trailing "Exit code: N" line is gone — the same info now lives in the header, so success rendering is also free of the redundant zero tail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 12, 2026
Closed
Merged
arvinxx
added a commit
that referenced
this pull request
May 13, 2026
# 🚀 LobeHub Release (20260513) **Hotfix Scope:** Ship the canary backlog (111 PRs) onto main as a fast-tracked patch — operator-focused, no weekly-style write-up. > Brings the accumulated canary work into main: agent/task improvements, hetero-agent fixes, desktop & onboarding polish, and several reliability caps. ## ✨ What's Included - **Agent & tasks** — Self-review proposal-to-action automation, sub-agent dispatch consolidated to `lobe-agent`, AskUserQuestion wiring for Claude Code, scheduler/hotkey/TodoList polish. (#14583, #14657, #14715, #14639, #14732, #14707, #14713) - **Home & onboarding** — Daily brief with linkable welcome + paired input hint, inline skill auth in recommended task templates, cleanup of captcha-on-signin and marketplace early-exit. (#14589, #14676, #14573, #14598) - **Bots & integrations** — Slack MPIM support, Discord DM fix, slash-command + connect-error fixes, gateway client-tool plugin state. (#14733, #14591, #14596) - **Desktop & CLI** — Windows `.cmd` shim detection for `claude` / `codex` CLIs, auth focus & pending-login reset fixes. (#14720, #14694, #14695) - **Reliability** — Cap web-crawler body size and image binary at safe limits, attach error listeners to Neon/Node pools, reject inactive OIDC access. (#14660, #14711, #14606, #14674) - **Database** — `agent_operations` table + persist agent operations from the runtime; switch user memory search to `paradedb.match(...)`. (#14416, #14736, #14590) ## ⚙️ Upgrade - **Self-hosted:** pull the latest image and restart. Drizzle migrations (including the new `agent_operations` table) run automatically on boot.
lezi-fun
pushed a commit
to lezi-fun/lobehub
that referenced
this pull request
May 13, 2026
…` tail (lobehub#14596) * 🐛 fix(agent-runtime): forward pluginState through gateway client tool result Gateway-mode client tool results lost the `state` field at three points: the toolResult Zod schema didn't declare it (silently stripped by safeParse), the ToolResultPayload interface didn't carry it, and projectToExecutionResult didn't return it. As a result the "技能状态" tab was always empty for tools dispatched via Agent Gateway, even though clients send `state` correctly and non-gateway paths persist it as `pluginState`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(prompts): suppress redundant `Exit code: 0` tail in command result For successful runs, "Command completed successfully." already conveys the same signal — appending "Exit code: 0" was just noise the LLM had to skim past. Non-zero exit codes (130 SIGINT, 137 OOM, etc.) keep the line so the diagnostic information remains available. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(prompts): treat non-zero exit code as command failure in result header `success` is the envelope ("the service responded") and `exitCode` is the command's own status — they're independent. With `success: true` + `exitCode: 137` the prior format rendered "Command completed successfully." on top of a SIGKILL/OOM, lying to the LLM. Now the header is derived from both: any non-zero exit folds the message into the failure branch as "Command failed with exit code N[: error]". The trailing "Exit code: N" line is gone — the same info now lives in the header, so success rendering is also free of the redundant zero tail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three related fixes for noisy / lossy / dishonest tool-result rendering in the agent loop:
1. Forward
pluginStatethrough gateway client tool resultGateway-mode client tool results lost the
statefield (the UI's "技能状态" /pluginState) at three points along the chain, so the tab was always empty even though the client sentstatecorrectly and non-gateway paths persist it fine:src/server/agent-hono/handlers/toolResult.ts— ZodToolResultBodySchemadidn't declarestate, sosafeParsesilently dropped it before the LPUSH.src/server/modules/AgentRuntime/ToolResultWaiter.ts—ToolResultPayloadhad nostatefield, so even if Redis carried it, the parsed type wouldn't.src/server/modules/AgentRuntime/dispatchClientTool.ts—projectToExecutionResultdidn't forwardstateinto theToolExecutionResultResponse.RuntimeExecutorswas already callingupdateToolMessage({ pluginState: executionResult.state })on the gateway path; it just always sawundefined.2. Treat non-zero exit code as command failure
formatCommandResultwas driving the header off thesuccessflag alone, butsuccessis envelope-level ("the service returned a result") whileexitCodeis the command's own status. Withsuccess: true+exitCode: 137we were renderingCommand completed successfully.on top of a SIGKILL/OOM, lying to the LLM.Now the header is derived from both — any non-zero exit folds into the failure branch as
Command failed with exit code N[: error].3. Drop the trailing
Exit code: NlineNow redundant with the new failure header (and was always redundant for success runs). Successful commands no longer carry an
Exit code: 0tail; failed ones surface the exit code in the header.Before / after
{ success: true, exitCode: 137, stdout: 'partial output' }Before:
After:
Test plan
bunx vitest run src/server/agent-hono/handlers/__tests__/toolResult.test.ts— added a case assertingstatesurvives Zod validation and lands in the LPUSHed payloadbunx vitest run src/server/modules/AgentRuntime/__tests__/dispatchClientTool.test.ts— added a case asserting BLPOP'dstateis forwarded ontoToolExecutionResultResponsebunx vitest run src/server/modules/AgentRuntime/__tests__/ToolResultWaiter.test.ts— still greencd packages/prompts && bunx vitest run src/prompts/fileSystem/formatCommandResult.test.ts— updated snapshots; added a non-zero-exit-with-success case asserting the failure headerbun run type-check🤖 Generated with Claude Code