Skip to content

Give completed Agent thoughts descriptive labels#650

Merged
AnthonyRonning merged 4 commits into
masterfrom
codex/issue-646-thought-labels
Jul 21, 2026
Merged

Give completed Agent thoughts descriptive labels#650
AnthonyRonning merged 4 commits into
masterfrom
codex/issue-646-thought-labels

Conversation

@marksftw

@marksftw marksftw commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Closes #646

What changed

  • Track newly completed Agent reasoning phases without changing timeline order or content.
  • Generate one bounded, phase-specific present-tense label with auto:quick.
  • Keep Thinking visible while the label is pending, fall back to Thought after five seconds or on failure, and fade between label changes.
  • Validate and locally persist only single-line labels, reuse cached labels, and clear them with the related task, turn, or Agent history.
  • Coalesce duplicate in-flight requests and invalidate pending work safely when history is replaced or deleted.

Why

Completed reasoning rows previously used the hard-coded Thought label, which gave no indication of what a phase had done. The generated-label prompt now treats the user request as background and prioritizes the current phase's latest concrete action, producing more useful labels without adding conversation history, tool data, or an immediate-action field.

Impact

Label generation is non-blocking and does not delay Agent activity, approvals, final responses, or run completion. Invalid or failed responses remain a silent Thought fallback, and loading old history does not trigger new requests.

Validation

  • bun run test — 170 passing
  • bun run typecheck
  • bun run lint — 0 errors (12 existing warnings)
  • bun run format:check

The desktop binary was not built.

Summary by CodeRabbit

  • New Features
    • Added generated, per–agent thinking phase labels with deterministic phase tracking and timeline-aware rendering.
    • Introduced automatic provisional-to-final label generation and commit flow across active runs.
    • Added reduced-motion-aware “thinking/thought” label UI with animated dots and accessible live updates.
  • Bug Fixes
    • Improved consistency across completed, failed, cancelled, and restored sessions; obsolete labels are now invalidated after timeline/run changes.
  • Tests
    • Added/expanded Bun coverage for label generation, timeline phase tracking, markdown label rendering, and run-finish lifecycle behavior.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a1ebf754-4de4-420a-89f6-877d3b316557

📥 Commits

Reviewing files that changed from the base of the PR and between c0739f8 and 574f16e.

📒 Files selected for processing (1)
  • frontend/src/services/agentThoughtLabels.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/services/agentThoughtLabels.test.ts

📝 Walkthrough

Walkthrough

Agent Mode now tracks reasoning phases, requests bounded generated labels during streaming and completion, handles run and session lifecycle invalidation, and renders labels through an animated, accessible ThinkingBlock.

Changes

Agent thought labels

Layer / File(s) Summary
Thought phase tracking
frontend/src/services/agentTimeline.ts, frontend/src/services/agentTimeline.test.ts
Adds stable thought-phase identities, live phase tracking, latest-turn reconstruction, lifecycle reset operations, and renderability filtering.
Label generation and scheduling
frontend/src/services/agentThoughtLabels.ts, frontend/src/services/agentThoughtLabels.test.ts
Adds bounded OpenAI label generation, validation, provisional milestones, final-request coordination, cancellation, fallback behavior, and comprehensive tests.
Agent Mode lifecycle integration
frontend/src/components/AgentMode.tsx, frontend/src/components/agent/agentModeThoughtRun.ts, frontend/src/services/agentThoughtRunLifecycle.ts, tests
Connects phase tracking and label requests to runtime events, run settlement, timeline replacement, history changes, session removal, and cleanup.
Thinking label rendering
frontend/src/components/markdown.tsx, frontend/src/components/markdown.test.ts, frontend/src/components/AgentMode.tsx
Adds optional thinking labels, fading transitions, reduced-motion handling, animated dots, accessibility attributes, and timeline prop wiring.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds label generation, but it removes the required localStorage persistence and cross-restart/task reuse for completed thoughts. Restore localStorage-backed label storage with stable account/task/phase keys, reload saved labels after task switches or restarts, and delete them with the related history.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: generated descriptive labels for completed Agent thoughts.
Out of Scope Changes check ✅ Passed The changes stay focused on Agent thought labeling, lifecycle handling, and tests, with no clear unrelated feature additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-646-thought-labels

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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

@AnthonyRonning

Copy link
Copy Markdown
Contributor
Screenshot 2026-07-19 at 9 49 28 PM

Just tested it, had a few thoughts on the approach.

When it comes to the thinking thoughts, I know there's a couple approaches. One is a continual summarizer that runs on whatever tokens have already streamed in. Updating after a few seconds with the latest amount. This gives an appearance like it is actively thinking.

Another is sort of combining the thoughts + content + tool calls + repeat into the collapsed form and doing something similar with the continuous summarizer. Though I kinda like that they stream in first, and then collapse down.

Separately of the approach, I think whatever prompt you're using for the summarization would need some more examples of what it should output. These make it look like it is making the tool calls, but it is just thinking about the tool calls it might want to make.

We should use llama or gemma for this, not gpt-oss, It has random problems at times.

@marksftw

Copy link
Copy Markdown
Contributor Author

Thanks, this makes sense. I agree the current labels can sometimes sound like the agent is already making a tool call when it is really only considering one. I'll adjust that.

As for the concept of collapsing the reasoning and tool calling into UI phases, that is already part of the broader [Agent timeline exploration](#635). I'm trying your suggestion from last week to break UX experiments into smaller chunks instead of trying to redesign the whole timeline at once. I also like the direction of letting activity stream in first and collapsing it afterward.

For this pass, I’m going to try gemma, strengthen the prompt with examples that distinguish intent from actual execution, and test a bounded version of the continual summarizer: one provisional label during longer thoughts, followed by a final label when the thought ends. If gemma isn’t fast enough, I’ll try llama and retune the prompt for it.

@AnthonyRonning

Copy link
Copy Markdown
Contributor

Makes sense. Make sure to set reasoning off for gemma. I have an example of that with my auto approver classifier for tool calls.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 20, 2026

Copy link
Copy Markdown

Deploying maple with  Cloudflare Pages  Cloudflare Pages

Latest commit: 574f16e
Status: ✅  Deploy successful!
Preview URL: https://ead9d143.maple-ca8.pages.dev
Branch Preview URL: https://codex-issue-646-thought-labe.maple-ca8.pages.dev

View logs

@marksftw

Copy link
Copy Markdown
Contributor Author

The direction here is to make Agent activity feel more legible without turning this PR into a full timeline redesign. Instead of leaving someone staring at a generic “Thinking” or “Thought” label, the UI provides a short description of the current reasoning phase. This remains a focused step within the broader [Agent timeline exploration](#635).

The latest update:

  • Uses Gemma with model reasoning disabled, plus a stronger prompt and examples that favor concrete subjects and distinguish considering an action from actually performing it.
  • Asks for labels between 3 and 8 words. That range is controlled in the prompt and can be adjusted in code.
  • Generates bounded provisional labels during longer reasoning phases at the 1-, 5-, and 15-second milestones. Requests have a short deadline, skip unchanged reasoning, and are capped to avoid excessive background work.
  • Generates a final label when the reasoning phase completes. Any provisional label remains visible while that request settles, so the UI does not jump backward to “Thinking.”
  • Keeps the animated “Thinking…” state until a descriptive label is available. “Thought” remains the fallback when label generation fails or does not return in time.
  • Saves displayed labels in localStorage so they remain stable when returning to a task. These labels are not persisted to the server.
  • Fades between label changes and cancels stale requests when phases complete, tasks are replaced or deleted, or account history is cleared.

@marksftw
marksftw marked this pull request as ready for review July 20, 2026 22:28

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@AnthonyRonning

Copy link
Copy Markdown
Contributor

Thanks for the follow-ups. The direction is improved, and the Gemma choice, disabled reasoning, provisional labels, and expanded intent-versus-execution examples all address the feedback in code. Before I approve this, I would like the following changes.

  1. Validate and tune the prompt against the real Gemma model.

The current tests verify that prompt text and examples exist, then feed mocked labels back. They do not show that Gemma actually follows the distinction. In a live test, the reasoning said “Let me read both files…” and “I’ll read both files…”, but the generated label was “Reading agentThoughtLabels and package.json.” Read tool calls did follow, so the complete timeline was understandable, but the reasoning label still converted a prospective action into active execution.

Please spend time prompt-engineering this with the actual model rather than inferring that the prompt should work. Build a small fixed evaluation set covering planning, considering a tool, actively executing a tool, interpreting results, and producing a final response, and test the real outputs. Since reasoning text is not authoritative tool state, the safest initial rule may be to reserve verbs such as Reading, Running, Searching, and Testing for labels derived from actual tool events. Reasoning-only labels can use Planning, Evaluating, Comparing, or similar language.

  1. Make the label state machine race-safe.

An older provisional request can currently finish after newer reasoning arrives and commit a label based on the obsolete snapshot. That older label can then become the durable fallback if final generation fails. An older thought summary must never overwrite a newer one.

Please associate every request with the exact phase/snapshot generation that started it, discard any result that is no longer current, and abort the previous request whenever a newer snapshot or newer thought supersedes it. The final-label request also needs an AbortSignal. Completion, cancellation, task deletion, history replacement, unmount, and a newer thought beginning should terminate any request that is no longer useful. Please add lifecycle tests that deliberately resolve requests out of order and prove that only the newest valid result can commit.

  1. Preserve provisional labels when a run fails.

The failed-run path currently discards the provisional scheduler entry. The subsequent authoritative reload reconstructs the phase without the retained label, producing a provisional → Thinking… → final/fallback regression on an already-terminal run. Failed runs should preserve and finish the active thought in the same way as completed runs. Only an explicitly cancelled run should discard it. Please cover completed, failed, and cancelled sequencing in AgentMode-level tests.

  1. Keep thought summaries in memory only for this first version.

Please remove localStorage persistence and the positional v1 cache. We do not need to recover generated summaries after restarting the application or when opening older tasks. If a summary is not already available in current in-memory state, a completed historical reasoning block should simply show the fallback “Thought.”

This also avoids establishing thought-N plus cached labels as a persistence contract while the Goose timeline representation is still evolving. No source hash, prompt migration, or recovery scheme is needed for this version because the generated metadata should be disposable.

The normal success path and background-run recovery are moving in a good direction. The remaining work is to prove the model behavior and make concurrent request/lifecycle transitions deterministic before merging.

@marksftw

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review — this was really helpful. I pushed a follow-up that addresses each of these areas.

  • Gemma prompt validation: I built a fixed 11-case evaluation set covering planning, prospective/claimed tool use, interpreting results, comparisons, and final responses, and ran each case three times against the real Gemma model through Maple. The baseline reproduced the reported “I’ll read…” → “Reading…” problem 3/3 times. After tuning, all 33 runs produced accepted labels, with no reserved tool-execution verbs or missed concrete subjects. Gemma reasoning remains disabled, and reasoning-only labels now reject execution-leading verbs such as Reading, Running, Searching, and Testing. The live evaluation harness was development-only and is not included in the app.

  • Race-safe state: Provisional and final requests now belong to the exact phase snapshot that started them. Newer snapshots abort older work, stale results cannot commit, and final requests receive an AbortSignal. Cancellation, deletion, history replacement, unmount, and superseding thoughts all invalidate requests that are no longer useful. The tests deliberately resolve requests out of order to verify that only the newest valid result wins.

  • Failed-run behavior: Completed and failed runs now both preserve the provisional label and finish the active thought; only an explicitly cancelled run discards it. I added an AgentMode event-boundary integration test that exercises completed, failed, and cancelled runFinished events through the authoritative timeline reload. It verifies that failed runs never regress from a provisional label to Thinking/Thought, reloads do not start duplicate final requests, and cancelled work cannot commit late.

  • Memory-only labels: All thought-label localStorage persistence and recovery code has been removed. Labels live only in the current in-memory AgentMode state, and completed historical thoughts without an in-memory label simply render the Thought fallback.

The frontend suite is green with 196 tests, along with typecheck and formatting; lint has no errors.

marksftw added 3 commits July 20, 2026 23:13
Generate phase-specific present-tense labels for completed Agent reasoning, keep Thinking visible while labels load, persist labels safely, and animate label transitions.
@marksftw
marksftw force-pushed the codex/issue-646-thought-labels branch from be7e88d to c0739f8 Compare July 21, 2026 04:17
@marksftw

Copy link
Copy Markdown
Contributor Author

Rebased this branch onto the latest master so the PR includes the recent trusted-local-skills and proxy updates. The only conflict was in AgentMode.tsx; I resolved it by preserving both the upstream skills-trust guard and the thought-label lifecycle. I reran the frontend checks afterward: 205 tests, typecheck, formatting, and lint all pass.

coderabbitai[bot]

This comment was marked as resolved.

@AnthonyRonning

Copy link
Copy Markdown
Contributor

One remaining merge blocker after the rebase: the frontend suite is still red both locally and in GitHub CI (203 passed, 2 failed), at frontend/src/services/agentThoughtLabels.test.ts:328 and :397. This looks like test synchronization rather than a production behavior failure: both requests are finally-chained and the assertions only flush one microtask. Replacing those await Promise.resolve() calls with the existing await nextTask() helper should let the chained settle/commit finish. Please fix those two tests, rerun the suite, and update the green-test claim. I do not have another blocker for the proof-of-concept scope.

@marksftw

Copy link
Copy Markdown
Contributor Author

Fixed both test synchronization points in 574f16e. The assertions now use the existing nextTask() helper so the finally-to-then chain settles before results are checked; this is test-only and does not change production behavior. I reran the full frontend CI sequence with Bun 1.3.5: formatting, lint (0 errors), typecheck, and all 205 tests pass. Thanks for catching the runtime-specific timing difference.

@AnthonyRonning AnthonyRonning left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. The test synchronization fix is the correct scoped change, the full CI matrix is green, and I have no remaining blockers for this proof of concept. The branch is currently clean against master; please rebase if master advances before merge, then squash merge when ready.

@AnthonyRonning
AnthonyRonning merged commit ef5f26c into master Jul 21, 2026
18 checks passed
@AnthonyRonning
AnthonyRonning deleted the codex/issue-646-thought-labels branch July 21, 2026 17:12
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.

Give completed Agent thoughts descriptive labels

2 participants