Skip to content

fix(chat): keep pre-tool answers visible - #1780

Merged
devswha merged 1 commit into
devswha:mainfrom
odfalik:fix/chat-pretool-answer
Oct 25, 2026
Merged

devswha merged 1 commit into
devswha:mainfrom
odfalik:fix/chat-pretool-answer

Conversation

@odfalik

@odfalik odfalik commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Context

Gemini 4 Argon (gemini-4-argon) frequently writes its full multi-paragraph answer in a message with stopReason: "toolUse" and a trailing tool call. It may answer the user's question in full while starting a background status check, then emit only a one-sentence follow-up with stopReason: "stop" after the tool finishes.

Codex and Claude usually emit brief status commentary before tool calls and save the full answer for after the final tool call. splitTurn assumed that ordering, so Argon's substantive pre-tool answer moved into the collapsed Worked for … block once the short follow-up arrived.

Change

Classify only explicit commentary as work text. All other assistant text now stays in the main chat, including answer segments before and after tool calls. Reasoning and tool rows remain collapsible.

No external code was adapted.

Validation

  • bun test src/lib/workBlocks.test.ts server/claude-turn-boundaries.test.ts: 26 passed
  • bun run typecheck
  • bun run build

Fixes #1779

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: devswha/ovis
  • Branch: main
  • File: .coderabbit.yaml
  • Commit: c165e04
  • Layers: Repository YAML
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 55248380-c022-429a-8ad7-8a461cd9a879

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review.

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: devswha/ovis
  • Branch: main
  • File: .coderabbit.yaml
  • Commit: df9daae
  • Layers: Repository YAML
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 60bc7d8f-3a0e-4d30-b895-1e7511e82fb2
📥 Commits

Reviewing files that changed from the base of the PR and between df9daae and f6d576a.

📒 Files selected for processing: 4
  • changelog.d/chat-answer-before-tool.md
  • server/claude-turn-boundaries.test.ts
  • src/lib/workBlocks.test.ts
  • src/lib/workBlocks.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Assistant responses that appear before a tool action or another answer remain visible in the answer instead of being hidden in the collapsed work summary.
    • Tool activity remains grouped in the work summary, while ordinary answer text stays with the response.
    • Completed turns with an answer before a tool action now remain folded by default.

Turn splitting now keeps non-commentary assistant text in the main answer, including when tool calls follow it. Commentary and non-text parts remain in work. Tests and a changelog entry cover this behavior.

Changes: Turn splitting

Layer / File(s) Summary
Classify and verify turn content
src/lib/workBlocks.ts, src/lib/workBlocks.test.ts, server/claude-turn-boundaries.test.ts, changelog.d/chat-answer-before-tool.md
splitTurn now places non-commentary text in the answer and commentary text and non-text parts in work. Tests cover answer grouping, work-block open state, and transcript output. The changelog describes the visibility fix.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • devswha/herdr-web-ui#1053: The issue tracks keeping narration between tool runs visible, which aligns with keeping non-commentary text in the main chat.

Suggested reviewers: devswha, demrom

Merge Risk: Minimal · up to f6d57

Answers before tool calls should remain visible when work is collapsed. No issue identified here prevents merging after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title "fix(chat): keep pre-tool answers visible" matches the main change. The changeset stops treating unphased assistant text before tool calls as collapsible work, so those answers stay visible …
Linked Issues check Passed Issue #1779 requires every non-commentary assistant text segment to remain in the answer, including text before a tool call. splitTurn now places every non-empty text part except `phase === "comment…
Out of Scope Changes check Passed The changes stay within issue #1779. The implementation changes turn classification, the tests verify the required behavior, and the changelog documents the fix. No unrelated behavior or files are int…
Description check Passed The description includes the problem context, resulting behavior, change details, linked issue, and validation commands. The required Change and Validation sections are present. Validation results are…
Full details: Title check

Explanation

The title "fix(chat): keep pre-tool answers visible" matches the main change. The changeset stops treating unphased assistant text before tool calls as collapsible work, so those answers stay visible in the main chat. The title is concise, specific, and follows a conventional commit style.

Full details: Linked Issues check

Explanation

Issue #1779 requires every non-commentary assistant text segment to remain in the answer, including text before a tool call. splitTurn now places every non-empty text part except phase === "commentary" in answer, and keeps commentary and non-text parts in work. Tests cover unphased text before tools, multi-step answers, closing text, and Claude turn boundaries.

Full details: Out of Scope Changes check

Explanation

The changes stay within issue #1779. The implementation changes turn classification, the tests verify the required behavior, and the changelog documents the fix. No unrelated behavior or files are introduced.

Full details: Description check

Explanation

The description includes the problem context, resulting behavior, change details, linked issue, and validation commands. The required Change and Validation sections are present. Validation results are explicit for the targeted tests, while typecheck and build are listed without detailed output.

Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devswha

devswha commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Checked this PR against main da04bda17 for #1779.

Reproduction. On main's code with this PR's two test files, 7 tests fail, including splitTurn > keeps an unphased response visible when a tool follows it. With this PR's src/lib/workBlocks.ts they pass, 26/26.

On a merge with main da04bda17 (clean, though the branch is 23 commits behind):

  • unit tests: 573 pass across 29 files, including every test that exercises splitTurn / workStartsOpen;
  • typecheck and build pass;
  • the server/claude-turn-boundaries.test.ts changes move the text assertions into the answer, keeping roles, timestamps and tool output;
  • the changelog fragment validates.

One CI browser check fails on the merge. scripts/chat-fallback-browser-qa.ts:164 (run by scripts/ci-browser.sh:86) waits for the unphased narration Checking the Claude catalog. inside .work-block. With this PR that text is outside the work block, so the wait times out after 10 s. The script passes on main. The script needs to expect the narration outside the folded work block, with the tool still inside it (line 165); its answer, timestamp and turn assertions can stay as they are.

Behaviour note. Every unphased assistant text now stays in the main chat and in copied answers, as #1779 asks. Claude leaves its pre-tool status text unphased (only thinking shown as updates is explicit commentary, server/claude-transcript.ts:363-368), so Claude's short status lines before tools now show in the chat. Codex keeps its native commentary phase, so its pre-tool commentary stays in the work block. Pi, OmO, omp, GJC, OpenCode and Grok mark final text but not commentary; Hermes, Devin and Agy leave ordinary text unphased.

@odfalik
odfalik force-pushed the fix/chat-pretool-answer branch from f6d576a to 8e43c4b Compare October 24, 2026 07:11
@odfalik
odfalik force-pushed the fix/chat-pretool-answer branch from 8e43c4b to cfc8552 Compare October 24, 2026 07:15
@devswha

devswha commented Oct 25, 2026

Copy link
Copy Markdown
Owner

Reviewed against main a1e4f8b83.

  • Reproduced Assistant text before a tool call is hidden in collapsed work #1779 on unchanged main 63af5d5e3 using this PR's regression tests: 7 fail, including pre-tool answer/narration classification.
  • Current head cfc8552f6 already includes the browser correction requested in the earlier maintainer comment. scripts/chat-fallback-browser-qa.ts checks that unphased narration remains visible outside folded work, appears once, and leaves the tool inside work.
  • Focused work-block, Claude turn, Codex, skill-activity, and translation tests: 162 pass, 0 fail across five files.
  • Unphased Claude narration now stays with the answer; explicit Codex commentary stays in work, as the issue requests.

Only CodeRabbit is currently listed in the PR checks; fork CI still needs maintainer approval.

  • dori heavy ext-pr-review -- bun run check fast: exit 0, 6,719 pass, 0 fail, 13 skip. Workflow, generated-file, typecheck, build, and unit-test steps pass; the report verifies unchanged source. Local Node is 24 rather than CI's 22.
  • dori heavy ext-pr-review -- bun run check run --build bun scripts/chat-fallback-browser-qa.ts: exit 0. Both the folded-work assertions and the adjacent fallback/background-continuation checks pass.
  • Inspected the fixture at 1280×800 and 390×844: the narration and closing answer remain readable while the work block is folded, without clipped or overlapping content.
  • No follow-up change or push was needed: the requested correction is already in the contributor's current commit. The local rebase and merge-tree check are clean, and the remote head is still cfc8552f6.

Review prepared with a code-review agent and checked against the code. The merge decision stays with the maintainer's merge pass.

@devswha

devswha commented Oct 25, 2026

Copy link
Copy Markdown
Owner

Merge pass review-work report. Overall: PASSED. This is an outside-contributor PR, and the maintainer approved merging it in this pass. The ext-pr-review lane verified it; see its comment above.

Lane Verdict
Codex (gpt-6.1-sol, xhigh) APPROVE
Code review (omo-native-code-reviewer) PASS

An answer or explanation written before a tool call no longer hides inside the collapsed work block. This is what issue #1779 asks for.

  • With main's workBlocks.ts, 7 of its tests fail; with the fix, all 26 pass.
  • On the tree merged with main, 2,473 unit tests pass, and chat-fallback-browser-qa.ts passes.

MEDIUM note: for Claude and other agents that don't mark narration as commentary, short status lines between tools now also show below the folded block, and they are included in a copied answer. The maintainer accepted this in an earlier review comment.

CodeRabbit did not review this PR (rate-limited or skipped). The reviews above stand in for it.

@devswha
devswha merged commit 6e729da into devswha:main Oct 25, 2026
17 checks passed
devswha added a commit that referenced this pull request Oct 27, 2026
## Change

Chat could show a turn's tool calls above words the agent wrote before
them, unlike the terminal.
In the reported OmO turn, one assistant message held `thinking | text |
toolCall` and two more
calls followed. The terminal shows the text first, but Chat showed
"Working… · 2 commands" with
both commands above that text.

Cause: `splitTurn` (`src/lib/workBlocks.ts`) splits a turn into all of
its work and all of its
answer text, and `Turn` (`src/components/ChatView.tsx`) drew one work
block above every answer.
Since #1780, unphased text before a tool call stays visible as answer
text (not folded into work),
so it was drawn below every tool of the turn. The bug is not tied to one
harness: Claude, pi/OmO,
omp and gjc all write unphased text before tools. Codex's `commentary`
text stays inside work, so
Codex turns mostly looked right. It showed up only "sometimes" because
only turns whose text
comes before a tool are affected.

Now a turn is drawn as ordered runs (`turnSegments`): each run of work
between two answers gets
its own work block, so text and tools keep the agent's order, live and
after reload. The order
follows the Claude app, which interleaves prose with its tool groups.
The work-line grouping is
unchanged:

- A turn with only tools and then an answer still has one `Worked for 7s
· N commands` block
  above the answer.
- When a turn has several runs, its last run that draws a row is the
head. It reads
`Working…`/`Needs you` while the turn runs and carries the turn's
duration once settled. The
  runs before it read `Worked`, so there is still one Working at a time.
- Folding is unchanged: blocks are open while live and folded once
settled. The final run stays
  open when commentary comes after the last answer.
- Row open state is keyed by the part's index in the turn, so rows in
different blocks never
  share state.

No external code was adapted.

## Validation

- `server/turn-order.test.ts` parses an OmO/pi transcript with the
reported record shape and a
Claude turn that talks between tools, then checks the drawn order.
`src/lib/workBlocks.test.ts`
  covers `turnSegments`. On `main` both fail.
- `scripts/chat-fallback-browser-qa.ts` (Integration and browser lane)
renders the real ChatView.
On this branch it shows `["I read this as: …", "work Worked · 3
commands", "The test server …"]`,
the Claude turn in five ordered rows, and, with the agent working, only
the last run reading
  `Working…`. On `main` the same script fails with
`["work Worked · 3 commands", "I read this as: …", …]`, which is the
reported bug.
- `bun test src/lib/workBlocks.test.ts server/turn-order.test.ts
server/claude-turn-boundaries.test.ts server/skill-activity.test.ts
server/codex.test.ts`
- `bun run check fast` on 5c9d18d: all steps ok, report verification
`verified` (unit: 7665 pass, 0 fail)

## Review fixes (e1f6b47)

A running turn with no work yet keeps its Working head. Blocks and rows
are named by their parts' indices in the turn, so a run that splits
keeps every fold. Todo groups are found once per turn. While the turn
runs only the head opens. `src/components/ChatTurn.test.ts` renders
`Turn` for these cases; the browser QA adds a run-split check. Details
are in the review-resolution comment.

---------

Co-authored-by: mp <mp@local>
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.

Assistant text before a tool call is hidden in collapsed work

2 participants