Skip to content

Fix: stop repeating the cloud subscription notice on model switches - #75

Merged
DevMando merged 1 commit into
mainfrom
fix/repeated-cloud-model-notice
Sep 11, 2026
Merged

DevMando merged 1 commit into
mainfrom
fix/repeated-cloud-model-notice

Conversation

@DevMando

Copy link
Copy Markdown
Owner

Summary

Picking a cloud model announced that cloud models need an ollama.com subscription, and kept
announcing it. The notice is removed — the model chip already says cloud, and the only message
that was ever actionable already appears when a cloud request actually fails.

What was happening

The notice was supposed to appear once. Two separate defects meant it appeared far more often than
that for some people, and never at all for others.

The guard was per-agent, not app-wide. The "already said this" flag was an instance field on
ChatController, and there is one controller per agent tab. The fact being stated is app-wide —
cloud needs a subscription — but the memory of having stated it lived in a single tab. Four agents
open meant four announcements.

The flag was burned without showing anything. It was set before the check that suppresses
announcements during restore, so a tab restored onto a cloud model marked the notice as shown while
displaying nothing — and then suppressed it for the rest of that session. So the behaviour was not
merely chatty, it was inconsistent in both directions.

What changed

  • The notice is removed, not repaired. It fired on selection, pre-emptively, in case a 403
    arrived later. But the model chip already marks a cloud model, and ResponseStreamer already
    reports the useful version if a request actually fails — that the account is signed in but has no
    active subscription. The removed notice told the user something they could not act on, before
    anything had gone wrong.
  • Replay still recognises it, and now covers the older wording too. Nothing emits it any more,
    which means journal replay is now the only thing keeping it off screen for anyone whose journal
    already holds one. The 0.14.x wording contains an apostrophe and is journaled HTML-encoded, so the
    filter now decodes before matching — comparing encoded text against a raw literal fails silently,
    which is precisely how it would have reappeared on restore.
  • The setup wizard is untouched. It explains cloud versus local while you are choosing a starter
    model, and mentions the subscription only when a sign-in check has actually failed, immediately
    before offering to sign you in. Both are conditional and actionable, unlike the removed one.

Scope and risk

Low. One notice deleted, one field deleted, and the replay filter widened. No behaviour changes
beyond what is displayed.

The judgement worth reviewing is whether losing the pre-emptive warning matters. The argument for
removing it: a user who picks a cloud model without a subscription now learns at their first
message instead of at selection — one step later, but with a message that names the actual problem
and is tied to a real failure rather than a hypothetical one. If you would rather keep a warning at
selection time, the alternative was a once-ever flag persisted to ui-settings.json; happy to build
that instead.

Verification

  • dotnet build src/MandoCode.Desktopsucceeded, 0 warnings, 0 errors.
  • dotnet test src/MandoCode.Desktop.Tests490 passed, 0 failed.
  • New coverage: both retired wordings are stripped from a replayed journal, including the
    HTML-encoded 0.14.x one — that test fails without the decode, so it pins the actual bug rather
    than restating the code.
  • Also pinned: the wizard's own cloud explainer is a dim notice mentioning the same subscription and
    must survive replay, since it is part of a walkthrough the user went through. The filter
    matches the exact retired notices rather than anything containing the word "cloud".

Not covered: no runtime check that a real cloud switch is now silent, or that a real 403 still
produces the actionable message — the 403 path is unchanged by this PR but is the thing a user now
depends on. Worth switching to a cloud model in a build of this branch and confirming you get the
chip and nothing else.

Selecting a cloud model announced that cloud models need an ollama.com
subscription. It was guarded to fire once, but the guard was an instance field
on ChatController and there is one controller per agent tab — so the fact being
stated was app-wide while the memory of having stated it was per-tab, and every
agent the user switched announced it again.

A second defect ran the other way: the flag was set before the
DeferModelAnnouncement check, so a tab restored onto a cloud model marked the
notice as shown while displaying nothing, then suppressed it for the rest of
that session.

Removed rather than repaired. The notice was pre-emptive — fired on selection in
case a 403 arrived later — but the model chip already carries "cloud", and
ResponseStreamer already reports the actionable version when a request actually
fails. It told the user something they could not act on, before anything had
gone wrong.

ModelNoticeReplay keeps recognising it, and now covers the 0.14.x wording too.
Nothing emits it any more, so replay is the only thing keeping it off screen for
anyone whose journal already holds one. That older wording contains an
apostrophe and is journaled HTML-encoded, so the filter now decodes before
matching — comparing the encoded text against a raw literal fails silently,
which is exactly how it would have come back on restore.

The setup wizard's cloud messaging is untouched: it explains cloud versus local
while the user is choosing, and only mentions the subscription when a sign-in
check has actually failed. Both are conditional and actionable.
@DevMando
DevMando merged commit 980a758 into main Sep 11, 2026
1 check passed
@DevMando
DevMando deleted the fix/repeated-cloud-model-notice branch September 11, 2026 04:51
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.

1 participant