Skip to content

feat(tui): add thinking effort, mcp status, and tab agent hints - #39

Open
yan-ad wants to merge 7 commits into
Blankeos:mainfrom
yan-ad:feat/home-status-parity
Open

feat(tui): add thinking effort, mcp status, and tab agent hints#39
yan-ad wants to merge 7 commits into
Blankeos:mainfrom
yan-ad:feat/home-status-parity

Conversation

@yan-ad

@yan-ad yan-ad commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • show the model's default reasoning effort and preserve per-model overrides
  • add the tab agents home hint
  • add the thinking effort per model
  • show enabled and connected MCP server counts with status coloring
  • display model metadata names with model IDs as fallback

Validation

  • cargo fmt --all
  • cargo check
  • focused reasoning and MCP status tests
  • git diff --check

Notes

  • the full test suite still hits an existing session persistence isolation failure when run in parallel
  • strict Clippy remains blocked by pre-existing warnings outside this change
Before After
image image
image image |

@yan-ad yan-ad changed the title feat(tui): improve home status parity feat(tui): add thinking effort, mcp status, and tab agent hints Aug 31, 2026
@Blankeos

Copy link
Copy Markdown
Owner

Before and after screenshots look super gud btw, helps a lot with the review. Did you automate it or just manual. If automate, did u use something like before-and-after + cua-driver?

PR Review — #39

Branch: feat/home-status-paritymain
PR: #39
Author: yan-ad · State: OPEN · Merge: clean (no conflicts vs current origin/main)

Merge confidence: 3/5

Solid, scoped TUI parity work with helper tests and a clean merge. Confidence is capped because the default-reasoning change also feeds live LLM requests, GitHub CI does not run tests, and /status MCP state can miss servers if McpManager was not captured at hydrate.


GitHub comment

Home parity looks good: default reasoning effort, per-model overrides, display names, MCP counts, and the tab agents hint.

One thing to confirm before merge: resolved_reasoning_effort_for_model now returns the model default when there is no override. That path is also used by active_primary_agent_reasoning_effort(), so requests that previously omitted reasoning_effort will now send the catalog default (usually medium). If that is intended, great — please add a test. If it was meant to be display-only, split the label from the request resolver.

/status is MCP-only despite the “system status” copy, and it depends on mcp_manager being set at startup. /mcp already has live views via McpManager::ensure; /status and the home badge should use the same source so empty-at-hydrate configs still show.

No migrations. I ran cargo fmt --check, git diff --check, merge-tree, and the focused unit tests — all green.


What changed

+711 / −29 across 7 files. No persistence, config schema, or aisdk changes.

Area Change
Home tab agents hint; MCP connected/enabled badge; model/provider names instead of ids
Reasoning No-override now resolves to the model default instead of hiding as unset/off
/variants Dialog to pick Default or an effort; persists via existing prefs
/status Read-only MCP server list with status coloring
Discovery get_model_name / get_provider_name; custom-provider reasoning without catalog cache

Regressions

No obvious display regressions. Tab already cycles agents (toggle_agent_mode), so the hint is accurate. Model ids used for API calls are unchanged; only home labels switch to metadata names.

Possible behavior change (not just UI):

// before
let requested = self.reasoning_effort_override_for_model(...)?;
let resolved = capability.resolve(Some(requested))?;

// after
let requested = self.reasoning_effort_override_for_model(...);
let resolved = capability.resolve(requested)?;

active_reasoning_effort() feeds active_primary_agent_reasoning_effort() → main session + subagent requests. Previously “no override” meant None (omit param). Now it sends capability.default_effort() (typically medium). Aligning the label with the request is probably correct, but it is untested in app.rs.

MCP status edge cases (not a main-path regression if MCP is present at startup):

  • mcp_manager is only stored when hydrate config is non-empty. Later /mcp uses the process pool; home//status can still show 0/N or “No MCP servers configured”.
  • /status has no mouse dismiss (Esc/Enter only). Clicks are swallowed, not passed through.
  • /status hidden_tokens: ["mcp"] is a no-op because /mcp already exists as its own command.

Existing /mcp toggle/auth dialog is unchanged.


Migrations

No. Nothing in src/persistence/, SQLite, auth.json, or models.dev cache schema. Reasoning overrides reuse prefs APIs already on main.


Merge checklist

  • Confirm default reasoning effort is meant to be sent on requests, not display-only
  • Add an app test: no override → resolved_reasoning_effort_for_model returns capability default
  • Smoke home: display name, default effort, MCP badge colors ( all-up / partial / error)
  • /variants: Default vs explicit effort, restart persistence
  • /status with 0 / connecting / mixed / failed servers
  • Confirm /mcp still opens the interactive dialog independently
  • Narrow width: MCP counts + tab agents / ctrl+p do not collide
  • cargo fmt --all -- --check
  • git diff --check
  • merge-tree vs origin/main (no conflicts)
  • Focused tests (see below)
  • Full cargo test — skipped; author notes a pre-existing parallel session-persistence isolation failure
  • Clippy — skipped; author notes pre-existing warnings outside this PR
  • GitHub Actions: only Release plan ran; this repo has no PR test workflow

Confidence bumps

If you do this New score
Current 3/5
Add the no-override → default-effort app test, and confirm that default is intended on the request path 4/5
Plus: home//status read MCP views the same way as /mcp (live_mcp_views / McpManager::ensure), so hydrate-empty configs work 4.5/5
Plus: Esc-click dismiss on /status, and either drop the dead mcp hidden token or make /status a real system-status panel 5/5

The reasoning-request confirmation is the highest-leverage item. Everything else is polish / edge-case coverage.


Checks I ran (non-mutating)

Worktree at /tmp/crabcode-pr-39-review @ 622832e.

Check Result
git diff --check origin/main...refs/tmp/pr39 pass
git merge-tree vs origin/main no conflicts
cargo fmt --all -- --check pass
views::home::tests::mcp_status_* (2) pass
views::variants_dialog::tests::variants_include_default_and_select_override pass
command::handlers::tests::test_handle_variants pass
command::handlers::tests::test_handle_status pass
model::discovery::tests::custom_model_reasoning_capability_is_available_without_catalog_cache pass
model::discovery::tests::custom_provider_ids_and_names_match_model_filters pass
app::tests::reasoning_effort_overrides_* (2) pass

Not run: full suite, clippy, interactive TUI smoke.

@yan-ad

yan-ad commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review! The before/after screenshots were captured and arranged manually — I did not use before-and-after or cua-driver, but those look useful for making this reproducible in future UI PRs.

The default reasoning behavior is intentional: when there is no explicit override, the model catalog/config default should be used by both the UI and the actual request path. This keeps the displayed variant consistent with what we send to the provider. Good call on the missing coverage; I’ll add an app-level regression test for no override → capability default.

The MCP findings are also valid. I’ll follow up before merge to:

  • make the home badge and /status use the same live McpManager::ensure source as /mcp, including configs that were empty during hydrate;
  • add click-outside dismissal for /status;
  • remove the ineffective mcp hidden token;
  • adjust the /status description/copy so it does not imply formatter/plugin status while the panel is MCP-only.

Thanks as well for running the focused checks and documenting the remaining confidence gaps so clearly.

@yan-ad

yan-ad commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks again for the detailed review. I pushed 87620bc to address the actionable findings:

  • Added a regression test proving that a reasoning-capable model with no saved override resolves to the catalog default (medium) through the active-agent request path.
  • The app now always keeps the workspace McpManager singleton returned by McpManager::ensure(...), including when the hydrated config starts empty. Home and /status snapshots now derive their enabled count from the manager's live server views rather than the initial config map.
  • Added click-outside dismissal for the /status modal, matching the other overlays.
  • Changed the command copy to Show MCP status and removed the hidden mcp search token so it is not presented as broader system/formatter/plugin status.
  • Updated the command registry regression test for /variants and /status.

Validation completed:

  • cargo test reasoning_capable_model_uses_catalog_default_without_override
  • cargo test rendered_dialog_tracks_bounds_for_outside_click_dismissal
  • cargo test test_handle_status
  • cargo test test_registry_has_all_commands
  • cargo test --no-run
  • cargo check
  • cargo fmt --all

Would appreciate a re-review when you have time.

@Blankeos

Blankeos commented Sep 1, 2026

Copy link
Copy Markdown
Owner

PR Review — #39 (re-review)

Branch: feat/home-status-paritymain
HEAD: 87620bc fix(tui): address home status review
Merge: clean (no conflicts vs origin/main)

Merge confidence: 5/5 (was 4/5 → 3/5 originally)

87620bc closed the remaining merge gaps: app-level default-effort test, live MCP source for home//status, click-outside dismiss, and /status copy/token. Ready to merge from review findings.

Follow-up addresses the review. Thanks.

  • Default-on-no-override is now covered by reasoning_capable_model_uses_catalog_default_without_override through active_primary_agent_reasoning_effort().
  • Home//status always hold the workspace McpManager::ensure singleton, including empty hydrate, and enabled counts come from live views.
  • /status dismisses on outside click; copy is Show MCP status; dead mcp hidden token is gone.
  • Registry test now includes /variants and /status.

I re-ran fmt, diff-check, merge-tree, and the focused tests (including the new ones) — all green. No migrations. LGTM.

What landed since last review

+70 / −12 in 3 files on top of the original TUI work.

Finding Fix
No app test for default effort reasoning_capable_model_uses_catalog_default_without_override
/status/home could miss MCP if hydrate was empty Always McpManager::ensure; enabled count from live views
No click-outside dismiss Left-click outside tracked dialog bounds closes it
“system status” + dead mcp token Show MCP status; hidden_tokens cleared
Registry count stale 20 → 22, asserts variants + status

Regressions

None from the follow-up. Original display/request change remains intentional.

Nits only (not blockers):

  • Outside-click handles left-down only. Scroll/move can still fall through to widgets under the modal (same as before for non-click). Fine.
  • refresh_mcp_summary still try_locks and skips a frame if the manager is busy connecting — badge can lag one paint. Existing MCP pattern.

Migrations

No. Still prefs-only; no SQLite / auth / cache schema.

Merge checklist

  • Confirm default reasoning is sent on requests, not display-only
  • App test: no override → catalog default via request path
  • Home//status use live McpManager::ensure (including empty hydrate)
  • /status click-outside dismiss
  • /status copy is MCP-only; dead mcp token removed
  • Registry includes /variants + /status
  • Optional smoke: home names/effort/MCP colors; /variants persist; /mcp still interactive
  • cargo fmt --all -- --check
  • git diff --check
  • merge-tree vs origin/main (no conflicts)
  • Focused tests (see below)
  • Full cargo test — skipped; author notes pre-existing parallel session-persistence flake
  • GitHub Actions: still no PR test workflow

Checks I ran (non-mutating)

@ 87620bc

Check Result
git diff --check origin/main...yan-ad/feat/home-status-parity pass
git merge-tree vs origin/main no conflicts
cargo fmt --all -- --check pass
app::tests::reasoning_capable_model_uses_catalog_default_without_override pass
views::status_dialog::tests::rendered_dialog_tracks_bounds_for_outside_click_dismissal pass
command::handlers::tests::test_handle_status pass
command::handlers::tests::test_handle_variants pass
command::handlers::tests::test_registry_has_all_commands pass
views::home::tests::mcp_status_* (2) pass
views::variants_dialog::tests::variants_include_default_and_select_override pass
model::discovery::tests::custom_model_reasoning_capability_is_available_without_catalog_cache pass

Not run: full suite, interactive TUI smoke.

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