Skip to content

feat(tui): offer the other backend once the first one works - #226

Open
plombeer31 wants to merge 2 commits into
valeryb/onboarding-local-modelsfrom
valeryb/onboarding-propose-second
Open

feat(tui): offer the other backend once the first one works#226
plombeer31 wants to merge 2 commits into
valeryb/onboarding-local-modelsfrom
valeryb/onboarding-propose-second

Conversation

@plombeer31

Copy link
Copy Markdown
Collaborator

Stacked on #225#224#223#222#220.

Why

atomic-agent runs local and cloud side by side and switches between them mid-session. The first run never said so, so an operator who configured one left believing that was the choice they had made — and the second backend is a switch away, not a reinstall.

The screen

  ✓  Cloud model ready

  atomic-agent runs both side by side — local for private or offline work,
  cloud for the heavy turns, switchable mid-session. You have one of the two.

  ›  Set up local models too
     one download, then it runs offline and costs nothing per token

     Skip — take me to the agent
     you can add it later from the menu (ctrl+p)

Mirrored when local came first ("Set up a cloud model too — an API key and a model, about a minute, for the heavy turns").

When it is not shown

decideSecondBackendOffer is a pure function with the whole rule set, and a test per rule:

situation offer
finished with cloud, no local local
finished with local, no cloud cloud
both already configured none
finished with a custom endpoint none — that operator has answered the question by running the server
skipped setup none — they asked to be left alone
already offered once none

The stamp is written when the offer is shown, not when it is answered: the offer was made either way, and a declined one must not come back on the next launch.

Flow

Accepting re-enters the other branch — the model picker, or the providers wizard — and the flow finishes for real when that lands (by then alreadyProposed is set, so it closes rather than looping). Declining hands over to the agent.

The decision lives in the host effect rather than the reducer, because it reads config; the reducer stays pure.

Tests

propose-second-backend.test.ts — one case per rule above. onboarding-propose-step.test.tsx — both directions of the offer and the cursor.

Full suite: 5196 passed. fs-glob-real and send-message-concurrency fail on main; bootstrap.test.ts flaked under parallel load and passes in isolation (26/26).

atomic-agent holds local and cloud at the same time and switches between
them mid-session. Nothing in the first run ever said so, so an operator
who configured one of them left believing that was the choice they had
made.

After the first backend verifies, the flow offers the other one — once.
The rules, all pinned by `decideSecondBackendOffer`:

- a custom endpoint never sees it: someone pointing the agent at a
  server they already run has answered the question by running it;
- both configured, no offer — there is nothing left to add;
- a skip is not followed by a pitch;
- shown once, recorded in `tui.onboarding.proposedSecondBackendAt` at
  the moment it is *shown*, so a declined offer never comes back.

Accepting re-enters the other branch — the model picker, or the
providers wizard — and the flow finishes for real when that lands.
Declining hands over to the agent and points at ctrl+p.
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