Fix SSH transfer integrity and malformed provider completion - #673
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9e2029b. Configure here.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e58595246f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Large SSH-backed file edits could report success while saving truncated content. The namespace bridge now drains stdin explicitly, preserves pending output when the command exits, and uses a status-only wait while forwarding output. Public
NamespaceProcess.wait()drains unread stdout and stderr before returning, so callers which only wait cannot deadlock on SSH backpressure. Pipe capture belongs toProcessOutput; namespace and workspace commands share one SSH forwarding function. Regression coverage includes large stdin/stdout, terminal backpressure, early process exit, and connection reuse after a command timeout. File-write confirmations count UTF-8 bytes.Gemini's adapter classifies
MALFORMED_FUNCTION_CALLas an error with normalized stop reasonmalformed_tool_call. The generic agent loop records and stops on provider errors without invoking auto-response or dispatching tools. The raw provider finish reason remains available on the step.Atomic file replacement and checksum verification are separate follow-up work and are not included in this PR. Existing file-operation semantics remain unchanged.
Validation
810bd41c: 5 before moving back to the main checkout and the remaining 12 afterward. Each run built the SDK wheel from the tested checkout; platform reporting was disabled.git diff --checkpassed.The transport fix must reach the SDK embedded in environment images; the provider handling must reach the agent SDK. No production rollout or model inference was performed.
Note
Medium Risk
Changes core namespace/SSH I/O relay semantics where truncated writes were observed in production; agent loop behavior on provider errors also shifts, but auth and file atomicity are untouched.
Overview
Fixes SSH-backed command and file I/O where large stdin/stdout could truncate or deadlock. Namespace spawning now relays stdin explicitly, forwards stdout/stderr through shared
ProcessOutput/forward_output(with backpressure and post-exit pipe draining), and coordinates exit with stream tasks.NamespaceProcess.wait()drains unread output before returning;wait_status()is for callers that read streams concurrently. Workspace sessions use the same capture/forward path. SSHfile_writesuccess messages report UTF-8 byte length, not Python string length.On the agent side, Gemini maps
MALFORMED_FUNCTION_CALLto a step error and normalizedstop_reason: malformed_tool_call.AgentStepgainsstop_reason; the tool agent loop records and exits on provider step errors without auto-response or tool dispatch, with trace statuserror.Regression tests cover large streams, terminal backpressure, early exit with huge stdin, post-timeout connection reuse, and provider-error stopping.
Reviewed by Cursor Bugbot for commit 52513f5. Bugbot is set up for automated code reviews on this repo. Configure here.