Skip to content

feat: add TUI session controls#66

Merged
gnanam1990 merged 2 commits into
mainfrom
feat/m2-tui-session-controls
Jun 5, 2026
Merged

feat: add TUI session controls#66
gnanam1990 merged 2 commits into
mainfrom
feat/m2-tui-session-controls

Conversation

@Vasanthdev2004

@Vasanthdev2004 Vasanthdev2004 commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add Go TUI shell controls for /compact, /effort, and /style
  • show effort, style, compaction, and usage/cost state in /context and the footer
  • record provider usage after agent runs while preserving existing OnUsage callbacks
  • use token-only cost-unavailable display for custom/unpriced model usage instead of transcript errors
  • split render helpers out of model.go to keep the main TUI model smaller

Tests

  • go test ./internal/tui
  • go test ./...
  • bun run typecheck
  • bun test ./tests --timeout 15000
  • bun run build

Summary by CodeRabbit

  • New Features

    • Added /effort, /style, and /compact session commands for runtime configuration
    • Integrated usage tracking to show token/request metrics and a usage summary in the UI
    • Model switching now clears unsupported reasoning-effort preferences and reflects effort status in responses
  • Tests

    • Added comprehensive tests covering session commands, usage-event handling, model switches, and edge cases

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Typecheck: bun run typecheck
  • [pass] Tests: bun run test
  • [pass] Build: bun run build
  • [pass] Smoke build: bun run smoke:build

Scope

Head: eec0cc2bd7a4
Changed files (8): internal/tui/command_center.go, internal/tui/commands.go, internal/tui/model.go, internal/tui/model_test.go, internal/tui/options.go, internal/tui/rendering.go, internal/tui/session_controls.go, internal/tui/session_controls_test.go

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 66cafd5c-c07c-4cf9-bc8d-ae46cc8d9588

📥 Commits

Reviewing files that changed from the base of the PR and between 398b982 and eec0cc2.

📒 Files selected for processing (4)
  • internal/tui/model_test.go
  • internal/tui/rendering.go
  • internal/tui/session_controls.go
  • internal/tui/session_controls_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/tui/rendering.go
  • internal/tui/session_controls_test.go
  • internal/tui/session_controls.go

Walkthrough

Adds three TUI commands (/effort, /style, /compact), records agent usage events into the UI, and extends model/options/rendering to surface session preferences, compaction status, and usage summaries.

Changes

TUI Session Controls for Effort, Style, Compaction & Usage Tracking

Layer / File(s) Summary
Configuration and command definitions
internal/tui/options.go, internal/tui/commands.go
tui.Options gains UsageTracker, AgentOptions, PermissionMode, ReasoningEffort, and ResponseStyle. Adds commandKind entries and commandDefinitions for /compact, /effort, and /style.
Model state and message types
internal/tui/model.go
Internal model extended with reasoning effort, response style, usage tracker, compaction/unpriced counters; agentResponseMsg carries usageEvents and usageModelID; constructors initialize these fields.
Agent execution and usage event wiring
internal/tui/model.go
runAgent initializes usage event list, wires OnUsage to collect events, and includes usageEvents/usageModelID on both success and error responses; update loop processes usage events into transcript rows.
Command routing, context, and model switching
internal/tui/model.go, internal/tui/command_center.go
handleSubmit routes new command kinds to handlers and appends system transcript entries; contextText() now includes effort/style/usage/compaction lines; switching models clears unsupported reasoning-effort and reports the reset.
Footer and transcript rendering
internal/tui/rendering.go
Adds helpers (displayValue, runState, footerText) and formatCommandFooterText to select featured commands and append key hints; renderRow formats transcript rows by kind.
Session control handlers & usage recording
internal/tui/session_controls.go
Implements /effort (list/set/auto/validate via modelregistry), /style (list/set/normalize), /compact (request/status), recordUsageEvent with normalization and unpriced-error handling, and usageSummaryText/formatUnpricedUsage.
Command parsing and session control tests
internal/tui/model_test.go, internal/tui/session_controls_test.go
Adds tests for parsing /compact, /effort, /style; effort/style/compact behaviors; usage-event footer/context updates; forwarding to AgentOptions.OnUsage; custom-model cost fallback; invalid/stale usage handling; model-switch effort reset; OpenAI profile helper.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Gitlawb/zero#63: TUI model-switching changes that overlap with effort reset behavior.
  • Gitlawb/zero#56: Model-registry reasoning-effort catalog and validation APIs used by /effort.
  • Gitlawb/zero#57: Prior command/footer rendering and slash-command parsing changes this PR extends.

Suggested reviewers

  • gnanam1990
  • anandh8x
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'feat: add TUI session controls' directly and accurately describes the main change: introducing new TUI shell commands (/compact, /effort, /style) and session control functionality.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/m2-tui-session-controls

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/tui/rendering.go (1)

55-64: 💤 Low value

Decide whether session control commands should appear in the footer

internal/tui/rendering.go shows a hard-coded featured list (and defaultCommandFooterText) containing only /help /model /provider /context /tools /permissions /clear /exit (plus Esc clear/Esc cancel and Ctrl+C quit), intentionally omitting /compact, /effort, and /style even though they’re registered in internal/tui/commands.go. If discoverability in the footer is desired, add commandCompact, commandEffort, and commandStyle to the featured slice; otherwise the current behavior is consistent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/tui/rendering.go` around lines 55 - 64, The footer's featured
command list currently omits session control commands; update the featured
[]commandKind slice in internal/tui/rendering.go to include commandCompact,
commandEffort, and commandStyle (in addition to commandHelp, commandModel, etc.)
so those registered commands from internal/tui/commands.go appear in the footer;
ensure the defaultCommandFooterText remains consistent with the footer
presentation after adding these symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/tui/session_controls.go`:
- Around line 183-190: The current error handling around m.usageTracker.Record
in recordUsageEvent always treats any Record(...) error as a pricing-unavailable
case and increments m.unpricedRequests/m.unpricedTokens; change this so only
known "unpriced" Record errors increment those counters. Implement an
isUnpricedUsageError(err) predicate (or use the usageTracker's typed error) and,
after calling usageTracker.Record, if err != nil then: if
isUnpricedUsageError(err) increment m.unpricedRequests and m.unpricedTokens and
return as before; otherwise convert the error into a rowError transcript (like
other normalization errors) and append it rather than marking the request as
unpriced. Ensure you reference usageTracker.Record, recordUsageEvent,
m.unpricedRequests, m.unpricedTokens, and the new isUnpricedUsageError helper
when making the change.

---

Nitpick comments:
In `@internal/tui/rendering.go`:
- Around line 55-64: The footer's featured command list currently omits session
control commands; update the featured []commandKind slice in
internal/tui/rendering.go to include commandCompact, commandEffort, and
commandStyle (in addition to commandHelp, commandModel, etc.) so those
registered commands from internal/tui/commands.go appear in the footer; ensure
the defaultCommandFooterText remains consistent with the footer presentation
after adding these symbols.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f0a5f0e-3954-4b8b-ba1b-b55132153e29

📥 Commits

Reviewing files that changed from the base of the PR and between 2a5b89c and 398b982.

📒 Files selected for processing (8)
  • internal/tui/command_center.go
  • internal/tui/commands.go
  • internal/tui/model.go
  • internal/tui/model_test.go
  • internal/tui/options.go
  • internal/tui/rendering.go
  • internal/tui/session_controls.go
  • internal/tui/session_controls_test.go

Comment thread internal/tui/session_controls.go Outdated

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] Do not collapse all usage record failures into unpriced usage

currently treats every error as a pricing-unavailable case by incrementing and . I verified can fail from () as well as pricing paths such as missing rates or tier selection. The TUI should only use the token-only/cost-unavailable fallback for known pricing/unpriced failures; non-pricing tracker errors should be surfaced as a transcript, like the existing normalization error path. Otherwise future tracker failures can be silently hidden in the footer as if they were expected custom-model pricing gaps.

Validation run on PR head :

  • ok github.com/Gitlawb/zero/internal/tui 0.230s
    ok github.com/Gitlawb/zero/internal/usage 0.606s
    ok github.com/Gitlawb/zero/internal/modelregistry 0.776s

CI is green, but this behavior issue should be fixed before merge.

@gnanam1990

Copy link
Copy Markdown
Collaborator

Correction to my review body above, the shell stripped the Markdown code spans. The intended blocker is:

[P1] Do not collapse all usage record failures into unpriced usage

internal/tui/session_controls.go:187 currently treats every m.usageTracker.Record(...) error as a pricing-unavailable case by incrementing m.unpricedRequests and m.unpricedTokens. I verified Tracker.Record can fail from registry.Require (unknown Zero model) as well as pricing paths such as missing rates or tier selection. The TUI should only use the token-only/cost-unavailable fallback for known pricing/unpriced failures; non-pricing tracker errors should be surfaced as a rowError transcript, like the existing normalization error path. Otherwise future tracker failures can be silently hidden in the footer as if they were expected custom-model pricing gaps.

Validation run on PR head 398b98216bcf6d12e7b790dc9dd25f1d3506a871:

  • go test -count=1 ./internal/tui ./internal/usage ./internal/modelregistry
  • git diff --check origin/main...HEAD

CI is green, but this behavior issue should be fixed before merge.

@Vasanthdev2004
Vasanthdev2004 requested a review from gnanam1990 June 5, 2026 09:30

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good on the updated head eec0cc2bd7a4f11e9b225e538777f79d0314365f.

The previous blocker is resolved enough for this slice: invalid usage normalization now appends a transcript error instead of being counted as unpriced, and the remaining unknown/custom-model path is intentionally treated as token-only cost-unavailable usage for custom TUI models.

Validation:

  • go test -count=1 ./internal/tui ./internal/usage ./internal/modelregistry
  • git diff --check origin/main...HEAD

GitHub checks are green: Ubuntu/macOS/Windows Smoke, Performance Smoke, Zero Review, and CodeRabbit.

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.

2 participants