Skip to content

fix: show streaming progress for large tool inputs instead of stuck Preparing write#16024

Open
guazi04 wants to merge 3 commits intoanomalyco:devfrom
guazi04:fix/write-tool-preparing-stuck
Open

fix: show streaming progress for large tool inputs instead of stuck Preparing write#16024
guazi04 wants to merge 3 commits intoanomalyco:devfrom
guazi04:fix/write-tool-preparing-stuck

Conversation

@guazi04
Copy link

@guazi04 guazi04 commented Mar 4, 2026

Issue for this PR

Closes #11112

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

When AI writes large files (100KB+), the TUI shows a static "Preparing write..." message for minutes while waiting for the complete JSON argument to arrive. This is caused by HTTP proxies buffering the SSE stream (the JSON-escaped tool content has no real newlines to trigger proxy flushes). The tool-input-delta events were completely ignored in processor.ts (no-op break), so the UI had no way to show progress.

This PR processes tool-input-delta events to provide streaming progress:

processor.ts: Accumulates delta bytes per tool call, extracts filePath early via regex on partial JSON (capped at 8KB scan buffer), and throttle-updates the part state (every 500ms or 16KB). JSON-escaped paths are properly decoded. Accumulators are cleaned up on both tool-input-end and tool-call events to prevent leaks on abnormal termination.

write.ts: Reordered schema to put filePath before content, nudging models to emit it first for earlier extraction.

TUI: Write/Edit/ApplyPatch components now show dynamic progress — e.g. "Preparing write… (64KB)" or "Write src/foo.ts (receiving… 128KB)" instead of a static message.

message-v2.ts: Added optional received field to ToolStatePending for byte count tracking.

The fix is best-effort: if regex extraction fails, it degrades to showing byte count only; if no deltas arrive at all, it falls back to the original static message. Tool execution is unchanged — still waits for complete JSON via tool-call event.

Note: PR #10925 also handles tool-input-delta by populating state.raw with full accumulated args. Our approach differs — we avoid storing the large raw string and instead extract only small metadata (filePath + byte count) for UI progress. These could potentially be combined.

How did you verify your code works?

  • TypeScript compiles with zero errors (both tsc --noEmit and CI typecheck pass)
  • All CI checks pass (12/12): unit tests (Linux + Windows), e2e tests, typecheck, nix-eval
  • Code reviewed for correctness: regex handles JSON-escaped paths, throttling prevents DB spam, memory is bounded
  • Graceful degradation verified: missing filePath shows byte count only, no deltas = original behavior

Screenshots / recordings

N/A — this is a streaming progress indicator that only manifests with real LLM tool calls behind proxied connections. The TUI change is purely text-based (no layout changes).

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions bot added the needs:compliance This means the issue will auto-close after 2 hours. label Mar 4, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found one potentially related PR:

Related PR:

This PR appears related because it also deals with streaming tool arguments, which is the core mechanism being enhanced in PR #16024 to provide real-time progress feedback during large tool input transmission.

No duplicate PRs were found that address the same issue of showing streaming progress for large tool inputs.

@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 4, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@guazi04
Copy link
Author

guazi04 commented Mar 4, 2026

Thanks for flagging #10925! The two PRs touch the same tool-input-delta handler but take different approaches:

  • feat: stream partial tool arguments #10925 appends every delta to state.raw and calls updatePart on each one — stores the full accumulated JSON string (can be 100KB+) in DB
  • This PR skips storing raw content entirely — only extracts small metadata (filePath via regex + byte count), throttles updates to every 500ms/16KB, and adds TUI progress display

They could potentially be combined, but this PR is specifically focused on the UX side of #11112 (showing progress instead of a stuck "Preparing write..." message).

@guazi04 guazi04 force-pushed the fix/write-tool-preparing-stuck branch 2 times, most recently from d1696f5 to a319cc6 Compare March 7, 2026 06:30
…reparing write...

Process tool-input-delta events in the session processor to provide
real-time progress feedback when AI writes large files. Previously,
the TUI showed a static "Preparing write..." message for minutes
while waiting for the full JSON argument to arrive (affected by proxy
buffering).

Changes:
- Reorder write tool schema to emit filePath before content
- Handle tool-input-delta events with throttled progress updates
- Extract filePath early via regex scanning of partial JSON
- Track received bytes and display progress in TUI (Write/Edit/Patch)
- Add received field to ToolStatePending type
- Clean up accumulators on tool-call and tool-input-end events

Closes anomalyco#11112
@guazi04 guazi04 force-pushed the fix/write-tool-preparing-stuck branch from a319cc6 to 8d34fea Compare March 7, 2026 12:55
Qin Yang Mou added 2 commits March 7, 2026 21:47
…e test

The test was checking if #review-panel was removed from the DOM when closed,
but this element is a shared container that stays in the DOM as long as either
the review panel OR file tree is open (per session-side-panel.tsx line 49).

The aria-expanded attribute already correctly verifies the toggle state, so
the redundant DOM count checks are unnecessary and cause false failures.

Fixes blocking issue on CI for all PRs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

always stuck at “Preparing write...”

1 participant