Repository navigation
Conversation
Shows the notice the nightly desktop's ProviderStatusBanner gives for the provider instance the composer would send with, above the thread error banner. Alt+N dismisses it and Alt+O opens the whole message. The two banners share one card for drawing, keys and clicks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Covers the stacked banners, same-driver instances, unsent choices, one dismissal across threads, an instance with no models or none at all, a thread moved by another client, no provider work for a streamed answer or a frame, one banner open at a time, every screen size, and a late model list read or a reconnect. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #24 at
d1d7e87. The code, tests and docs are written. I ran no tests, Clippy, build, fixture or terminal check, so nothing here is verified yet. Sol runs every check and the visual verification, and only the user merges.This PR adds the provider half of the "Error and provider status banners" row in group 1 of
docs/parity.md. When the provider instance the composer would send the next message with isn't ready, or runs a version T3 marks broken or unsupported, a banner over the conversation says so, as the nightly desktop'sProviderStatusBannerdoes. It sits above #21's thread error banner, and each one shows and dismisses on its own.What changes
src/tui/provider.rs(new) reads the selected provider from T3's config as the desktop decodes it. It works out the notice's title, message, severity and dismissal key asProviderStatusBanner.tsxdoes.picker::viewwith the open thread's draft. t3term finds it byinstanceIdalone, so a provider with no models still shows its status, and no other provider stands in for one T3 no longer lists.ChatView.tsxkeeps it, until the selected provider has no notice. Alt+O opens the whole message.src/tui/banner.rsmoves its drawing, keys and clicks into a sharedCard, which both banners use.src/tui/mod.rsstacks the two and routes their keys and clicks. It works the notice out again only when the config, the open thread's selection or its draft changes.docs/sprint.mdgets row 16.No CLI command,
--jsonoutput, RPC or setting changes.Commits:
39b8ad7adds the banner,84698b4the App tests, andb9c1305the README and sprint row.Tests: 26 new, none run yet
18 in
src/tui/provider.rs:an_unsupported_version_warns_on_a_ready_provider_until_t3_relaxes_its_policya_broken_version_shows_its_advice_in_place_of_the_failure_it_causessigning_in_again_comes_before_a_version_warningantigravity_waits_for_its_auth_result_before_warninga_warning_reads_as_one_and_an_error_as_an_errorthe_messages_point_to_t3_codes_provider_setup_or_the_clia_provider_the_desktop_couldnt_read_or_cant_send_with_has_no_noticedriver_ids_read_as_wordsone_dismissal_holds_until_the_selection_has_no_noticethe_same_notice_keeps_the_banner_as_it_was_and_cleans_nothingdismissal_goes_by_the_whole_message_past_what_the_banner_printsthe_selection_is_stale_only_when_its_inputs_changea_notice_draws_its_title_over_its_message_and_names_its_keysa_long_message_shows_three_rows_and_opens_with_alt_oits_keys_are_its_own_and_only_while_it_showsit_takes_its_clicks_and_closes_with_its_xa_frame_rewraps_only_for_a_new_widthlong_unicode_and_control_text_stays_inside_the_banner_at_any_size8 App tests in
src/tui/mod.rs:the_provider_banner_stacks_over_the_error_and_each_dismisses_alonethe_banner_follows_the_instance_the_composer_would_send_withone_dismissal_holds_across_threads_until_a_selection_has_no_noticethe_banner_finds_the_threads_instance_without_models_and_after_it_leavesstreaming_frames_and_unchanged_statuses_do_no_provider_workone_banner_is_open_at_a_time_and_alt_arrows_scroll_the_open_one_firstat_any_size_the_banners_stay_apart_inside_the_transcripta_late_model_list_read_or_a_reconnect_never_brings_an_old_status_backNo existing test was renamed or removed.
Fixture for the visual check
/tmp/t3term-provider-banner-fixture.pyis review tooling and isn't committed. I wrote it and never ran or compiled it, so its first run is Sol's. It runs the real TUI in tmux against a fake T3 server on 127.0.0.1. HOME and T3CODE_HOME are inside the fixture directory,T3TERM_NO_SAVED_LOGIN=1keeps the Keychain out, and every provider, thread and credential in it is invented. It servessubscribeServerConfig, so provider statuses change live.Its docstring (
--help) walks 17 steps in order. They cover:checkedAtticksDecision log
What I noticed
docs/parity.mdmarks "Error and provider status banners" as partial. #21 added the thread error banner, and t3term had no provider banner. A provider's state showed only in the model menu, as "(status)" after the name of a provider that isn't ready. A message could go to a signed-out or broken provider with nothing about it on the conversation screen.How I confirmed it
I read the desktop sources at the nightly
docs/parity.mdpins.ProviderStatusBanner.tsxdecides when the banner shows and what its title, message and severity are.ChatView.tsxkeeps the dismissed key, andresolveComposerProviderSelectionpicks the provider. In t3term I read how the config arrives (client.watch_config, andprojection::apply_configforsnapshotandproviderStatusesitems) and how the chip picks its model (picker::view). Each desktop rule has a unit test case. The App tests drive config, thread and draft changes throughApp. None of them has run yet.Options
instanceId. I rejected porting the desktop'sresolveComposerProviderSelectionfallbacks (the running session, the project default, another available provider). t3term sends with the chip's selection, so a banner about another provider would describe one the send doesn't use.Cardinbanner.rsfor both banners. I rejected a second copy of the error banner's wrap, clip, scroll and click code.ChatView.tsxkeeps it. I rejected saving it insettings.json. The desktop doesn't, and a saved dismissal would hide the notice after a restart.What review changed
Nothing yet. Greptile and Sol haven't reviewed it.
Known limits
🤖 Generated with Claude Code