mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 09:37:33 +00:00
e8a18a03d5a22d362d1bbb54cf89fa16e2224efb
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
46be7e23ee |
feat(settings): sign Antigravity chats in from Accounts (#28705)
* feat(accounts): sign Antigravity chats in from the Accounts page
Adds an 'Antigravity chats' row to the Antigravity section of Accounts
(behind the native chat setting, this device only): Sign in starts the
host's chat sign-in, follows it with the Link poll, opens the Google page
once, offers Copy link and Cancel, and shows one status line per phase.
The saved line reflects the sign-in file only, never that it works.
* Keep Antigravity chat sign-in bound to the current view
* feat(settings): put Antigravity chat sign-in under its install row in Chat > Providers and Accounts
The chats' sign-in row now sits directly below the Antigravity install row,
in Settings > Chat > Providers and under the agy section of Accounts, with copy
that says it is separate from the agy account. Its button reads Sign in, Change
account or Retry sign-in by state, and stays visible but disabled while the host
has no runnable server; the install row above says why.
* fix(settings): both Antigravity chat sign-in rows share one sign-in per host and pick up one already running
Settings shows the sign-in row under Chat > Providers and under Accounts at once; each kept its own
flow, so starting one silently cancelled the other and a sign-in nobody watched could not be seen or
cancelled. One entry per host now holds the flow and the saved sign-in for every row, follows the
host's Link poll while a row shows it, and on mount adopts the running flow the host names. Sign in
also waits while an install or Remove runs, read from the same install status.
* fix(settings): a failed sign-in poll re-reads the host so a running sign-in stays cancellable, and only a Remove (not an Update) holds Sign in
* fix(settings): the sign-in rows follow the host's sign-in status through the same loop as install, so an idle page sees another device's sign-in
* refactor(settings): install and sign-in rows share one subscription store; Install and Remove wait for a running sign-in, and Sign in waits for the host's answer
Both stores now follow the host through one generic subscription store
(snapshot, then a frame per newer revision, resubscribe with backoff on loss),
replacing the sign-in store's long-poll of a method the host no longer has.
While a sign-in runs, Install, Update and Remove are disabled (Cancel stays).
The sign-in row keeps Sign in disabled until the host answers, says when the
status could not be read instead of showing signed out, and sends one start or
cancel at a time.
* feat(settings): paste the last sign-in page's address to finish an Antigravity chat sign-in
While a chat sign-in waits on the browser, its row shows a field for the address of the last page after signing in, for when that page doesn't load because the browser is on another computer than the host. Continue sends it to the host, which passes it on to Antigravity; the host's refusal shows under the field. With that, remote hosts offer chat sign-in on the Accounts page too, and the row reads "Finishing sign-in…" while the host completes it.
* test(settings): give each host its own fake sign-in status and stub the new subscription export
The sign-in row tests shared one fake host across every owner, so the first test's finished sign-in made the next row show "Change account" instead of "Sign in", and rows left mounted after that failure doubled the later tests' matches. Each owner now has its own fake host behind the subscription, and every test cleans up its render. The Antigravity accounts section test's client mock also lacked the sign-in exports the status store now reads at import.
* feat(settings): the Antigravity chat sign-in row follows the host's sign-in answer
The host no longer reports whether a sign-in file exists; it reports what the
server last answered (signed in, signed out, or not known yet), and a running
sign-in started by another client arrives without its id.
The row now reads that answer:
- "Signed in on {host}." or "Not signed in on {host}."; no line until the server
has answered, with Sign in still enabled. Change account shows only when the
server said signed in.
- A sign-in another client is running reads "Sign-in is in progress in another
client.", with Sign in disabled and no Cancel, copy link or paste field, since
only the client that started it can act on it.
- "Finishing sign-in..." also follows a browser sign-in while the host checks it.
- Cancel and paste send only this client's own sign-in; the host's refusals
show under the row.
* fix(chat): a signed-out Antigravity chat says to sign in under Settings, not what the agent printed
The notice read "Sign in to Antigravity. The agent asked to sign in in a
browser": the second sentence was Orca's own log text for the sign-in prompt the
agent printed, shown as if it were the agent's words, and the notice never said
where to sign in.
The connection now closes with a sign-in prompt error whose message stays in the
logs, so the chat shows only Orca's sign-in sentence. Antigravity gets its own
sentence, in the shape Claude's already has: "Antigravity isn't signed in. Sign
in under Settings → Accounts → Antigravity." Other agents' sign-in words, and
the agent's own words in a sign-in answer, are unchanged.
* fix(chat): a sign-in prompt at chat start keeps Orca's words out of the signed-out notice
A signed-out Antigravity chat still read "... The agent asked to sign in in a
browser". The connection closes with a sign-in prompt error whose message is
Orca's log text, but the request wrapper and session setup re-typed every
sign-in answer by copying its message into a new error. The copy lost the
sign-in prompt type, so its message was quoted as the agent's own words.
Re-typing now keeps a sign-in prompt close as it is, at both the request
wrapper and session setup, so the notice says only where to sign in.
* fix(settings): the Antigravity sign-in row shows the host's answer once a sign-in is cancelled or timed out
After a cancelled or timed-out sign-in the row kept reading "Sign-in
cancelled." even when the host had answered that this computer is not signed
in. A finished sign-in now only stands in until the host answers; then the row
reads "Not signed in on <host>." or "Signed in on <host>.". A running sign-in
still shows its step.
* fix(settings): a wrong pasted sign-in address shows Orca's reason, not the browser's URL bubble
The paste field is a URL input, so the browser's own "Please enter a URL."
check ran before Orca could explain what was wrong with the address. The form
now skips the browser's check and shows the host's refusal sentence.
* style(settings): the Antigravity chat sign-in row reads as a plain row like the install row
The sign-in row sat in its own bordered box, the same bright outline the install
row lost when it became a single grey status line. It now has no box: a
medium-weight "Antigravity chats" title, the description and the grey status
line under it (errors inline in the destructive colour), and its action at the
row's right end. Sign in and Retry are primary buttons, so they stand out like
Install; Change account stays outline and Cancel stays ghost. The paste-the-
address form sits under the row without a box. Copy, keys and behaviour are
unchanged.
* ci: run the PR checks against main after the retarget
* fix(settings): list every sign-in phase in the status line switch
* test(chat): name Antigravity as the chat's agent in its signed-out sentence test
* feat(settings): Antigravity provider row with a ⋯ menu and its own sign-in area
The Providers row's status line now says only the install state. Update,
Reinstall and Remove move into a ⋯ menu beside the switch, shown for a copy
on disk; Remove keeps its confirmation. Sign-in moves into a quiet inset
area under the row, shown once a copy runs, with one sentence and one
action per state. Accounts keeps its sign-in row; its install row gets the
same menu.
* fix(settings): a damaged runtime offers Reinstall as its row's button
A damaged copy's repair is the next step, so it sits where Install does instead of inside the ⋯ menu, which then offers only Remove.
|
||
|
|
ff4a51c872 |
Show sign-in guidance for all native chat agents (#26544)
* Recognize native chat sign-in failures across structured agents * Fix authentication failures and chat sign-in guidance * Preserve sign-in diagnostics and command retry context * fix(native-chat): keep visible sign-in guidance and localize startup rows * fix(native-chat): separate auth diagnostics from retry guidance * test(native-chat): align startup guidance expectations * fix(native-chat): start a new agent for the send after it reports not signed in * fix(native-chat): scope the signed-out check by fence and read without a snapshot * fix(native-chat): keep a signed-out agent while it owes work, and read only its own rows * fix(native-chat): keep a signed-out agent that may owe a wake-up turn, and skip the check during a Stop |
||
|
|
5252884a9c |
Native chat: say when Codex is signed out or the agent isn't installed, without disabling Send (#25666)
* fix(native-chat): disable Send for unavailable agents * test: update sign-in copy expectations * fix: show automatic chat availability only on Send * fix: keep signed-out evidence when a live session lists models * refactor: split Send availability presentation and tests * refactor(native-chat): keep the sign-in verdict on the catalog's failure record The probe's "signed out" / "CLI missing" verdict now lives on the account's existing model-catalog failure record instead of two extra maps, with the failure TTL as its only lifetime: - Only the probe sets or clears the verdict; a chat's own model listing (which works while signed out) never clears or renews it. An aged-out verdict makes the next read re-probe, however fresh the catalog. - A healthy fresh catalog is no longer re-probed every 30 s; it keeps the normal 10 min fresh window. A Claude start refused as signed out ages the catalog so the next read re-probes. - A waiting picker again answers from whichever catalog lands first and never waits on a probe. A read that still owes the probe's verdict says so, and the composer waits for it once with the new optional waitForAvailability param. - The open-time start-failure line and its transcript row are hidden only while Send is disabled for the same reason; otherwise they show as before. - A host verdict lifetime longer than the client's hold is clamped, not dropped. The catalog read watches only the account settings and the paired host's contact instead of every store write. * fix(native-chat): one send-gate rule, and a missing CLI as its own failure - The sign-in/CLI verdict is gated once where the session hands it to the composer: while a turn runs it neither shows nor refuses, so a follow-up queues as before; goal mode is held by the same gate. The start-failure line and row hide only while that same value is up. - A start whose CLI was never found (a direct spawn's ENOENT, or the one a provider supervisor reports) is now a `cliMissing` failure with the disabled Send's sentence, instead of a generic "couldn't start" beside it. An older client shows the host's sentence for the new kind. - Signed-out words for a slash command keep "Run /x again". - The Claude catalog reads its models only from the reply to its own list_models request, never from the initialize reply. - The Codex probe lists models while its account check runs; a signed-out verdict still wins. - The missing-executable check moves to provider-process, out of native chat. * test(native-chat): signed-out command failures name the command to run again * fix(native-chat): probe the Codex home a launch would read - Before the catalog probe's read-only app-server reads Orca's shared Codex home, it runs the same sync a launch and the usage poll run, so a `codex login` made in ~/.codex is seen at once instead of leaving "Run codex login" up until something else re-syncs (forever on a headless host). Per-account homes are left alone. - A "no account" answer counts as signed out only when the home's auth.json is absent or holds no credential; one caught mid-write by a token refresh, or holding a credential, is unknown. * test(codex-accounts): type the node:os mock with a type import * fix(native-chat): keep the sign-in verdict until a newer answer replaces it - No gap while signed out: the host serves an aged verdict while the probe that re-derives it runs, and the composer never clears its last answer before a read; only an answer without a verdict, an error, lost contact or an account change does. Send stays disabled with its reason through every re-check. - After sign-in the stale "isn't signed in" start-failure line stays hidden: a probe that found the account fine now says so (`accountVerified`), and the line shows only when the host has no answer at all. - A Claude start refused as signed out, or any start whose CLI was never found, is recorded as that home's verdict, and the chat reads it once when that start failure arrives. - The re-probe mark is read only where the catalog read starts its probe, so a Codex chat's own picker no longer re-lists for it on every read. - Choosing an account or signing in again in Accounts settings re-derives the verdict at the next read; the account key now compares settings by value. - A re-read that brings an identical catalog keeps the option state, so focus re-reads re-render nothing. * fix(native-chat): Codex's signed-out words name only the step that unblocks this chat A chat is pinned to the Codex home it started in, so choosing another account in Codex Accounts settings never unblocks it. The system-account sentence now says only to run `codex login`, in every locale. * refactor(native-chat): give an account's sign-in status its own owner The sign-in verdict lived inside the model catalog's failure records, so the store needed guards for who wrote a failure, which listing may clear it, and whether a verdict was served while re-probing. Each guard fixed one way a chat's own listing or an older probe overwrote the account's answer. The answer now lives in AgentAccountStatuses: one in-memory, capped status per account home (ready, not signed in, or CLI missing). Only the session-less probe, a refused start and an account change write it. A blocked answer older than 30 s, or one an account change marked, makes the next read start the probe whatever else is listing, and it is served until that probe answers. Older evidence never replaces newer. The catalog's failure code is main's again, and agent-model-catalog-failures.ts is gone. The wire carries one optional `availability` field in place of `unavailable` and `accountVerified`. The renderer holds its answer per host, agent and chat, re-reads only on that agent's account inputs, and re-reads on a timer only while blocked. After an account change, Send stays disabled with the previous words until the re-probe answers, then changes once. Account switches and re-sign-ins mark the status before the settings change a chat's read follows. * fix(native-chat): re-derive the sign-in answer after an account change mid-probe, and back off while blocked Round-4 review findings on the account status owner: - An account switch or re-sign-in made while a probe was running left the old answer up for up to 30 s: the next read joined that probe, whose answer was then dropped as older than the change. A read now chains exactly one fresh probe after a probe that began before the change. - Removing the selected Claude account swapped another sign-in into the shared config dir without marking the answer; it now marks it first. - Evidence was ordered by wall-clock time, so a clock that stepped back froze a blocked answer. It is now ordered by a sequence and aged on a monotonic clock; a negative age reads as due. - A chat left open while signed out started a CLI probe every 30 s. Probes that keep finding the same block now space out (30 s, 60 s, 2 min, 4 min, then every 5 min), carried to the client as recheckInMs. An account change or a different refusal starts the hold over. - The renderer dropped no settled wait from its leave set; it now does. - A failed Claude probe logged its whole stdout, which now includes the initialize reply naming the account. Control replies are dropped from the log and the failure message. - The account services take the status re-check as an injected onSignInChanged hook instead of importing the native-chat store. - Imports moved below file headers; comments no longer say "ready" means re-checked after the failure. * test(claude-accounts): say why the runtime-auth fakes are cast where the hook was added * fix(native-chat): type the held-answer handle as the account status * fix(native-chat): re-check a block when someone returns, and catch an account change during a home's first probe Round-5 review findings: - After a chat sat blocked for a few minutes, the backoff made every read wait out a hold of up to 5 minutes, so someone who ran `/login` or `codex login` and came back still saw Send disabled for minutes. The backoff now applies only to the client's own timer read, which it marks with an optional `scheduledRecheck` param. A read from someone looking (window focus, the pane becoming visible, a new chat, a start failure) re-probes once the block is older than 30 s. The param is sent only on that timer, which only a blocked `availability` answer arms, so a host that predates the param never receives it. - An account change made during a home's first probe marked nothing, because only existing statuses were marked, so the old account's answer was written as current. Each agent's last account change is now one sequence number that every status and running probe is compared against; statuses are no longer mutated in place. - Removing an account that nothing had selected no longer re-checks. * refactor(native-chat): keep the sign-in and missing-CLI words in their own module Main's retry wording pushed the failure-words table past its line budget. * refactor(native-chat): build the structured chat's view session in the view-state module Main's send-reveal work brought NativeChatStructuredSession.tsx and the session controller to their line budgets. * fix(native-chat): keep a stated start line hidden through a running turn, and re-probe an account changed mid first probe - A chat whose open-time start failed signed out had that line hidden while the host said the same. When a new signed-out answer landed during a running turn, the line came back for the whole turn: the hide read Send's gate, which a running turn suspends. The hide now reads the host's answer itself (blocked for the same reason, or ready); Send's gate still steps aside while a turn runs. Both are views of the one answer the session holds. - An account change during a home's first probe dropped that probe's answer but left nothing to re-check the new account, and the picker's reply said no probe was pending, so the chat stayed unknown until the catalog aged out. A read now chains one fresh probe whenever the running probe began before the change, and its reply says that probe is still owed so the client asks once more for its verdict. - The client's timer read no longer carries `scheduledRecheck`. The timer already fires only when the host's backed-off `recheckInMs` says, which is past the 30 s after which any read re-probes, and every answer re-arms it. One fewer strict-schema param. * build(cli): typecheck the missing-executable check the provider process now imports Main's #25753 added managed-provider-process.ts to the CLI project, which imports this PR's provider-executable-missing.ts. * fix(native-chat): disable Send with the fix when Claude or Codex is signed out or missing What you see: in a native Claude or Codex chat whose CLI is signed out, or not installed on the computer running the chat, Send is disabled and its tooltip (hover or keyboard focus) says how to fix it, in words that match the account ("Codex isn't signed in. Run `codex login`.", "This Claude account isn't signed in. Sign in again in Claude Accounts settings.", "Claude isn't installed on the computer running this chat."). A message refused after sending gets the same words. On desktop the open-time "Chat could not be started" line, its Retry and its transcript row no longer repeat these two reasons, unless a message of yours is still waiting on that start. An unknown answer never disables Send, and while a turn runs Send stays Stop and Enter queues. How: the host's existing session-less model-catalog probe also says why no chat can start. Claude's probe child sends initialize before list_models and applies the rule chat start already uses (token source none with no API key); Codex's probe asks account/read beside model/list; a spawn that finds no executable is "CLI missing". The probe's failure record in the catalog store carries that reason, and every catalog reply carries it as an optional `unavailable` field. Only a probe writes or clears it: a live chat's own listing (which a signed-out Codex still answers) never does. It lasts the store's 30 s failure lifetime; after that the next read starts or joins the probe, serving the held reason meanwhile, and only a read that already asks to wait gets the probe's answer. A change to the managed-account settings expires it. Before probing the shared Codex mirror home, the probe runs the same sync a launch does. The renderer keeps the latest answer until the next one replaces it, and only while blocked re-reads on window focus and when the chat gains focus. No status store, timers or new request params. * fix(native-chat): no picker loading while Send re-checks a sign-in, and plain keyboard focus on the disabled Send A chat whose account is signed out and has no model list no longer shows the model picker as loading each time it re-checks the sign-in after 30 s: the re-check is for Send, so a reply that already carries the verdict ends the picker's wait. The disabled Send's wrapper takes keyboard focus (so its tooltip opens) without becoming a second button; the inner button keeps its label. Trims tests that repeated rules other tests already prove. * fix(native-chat): lift the Send gate whenever Stop shows, including while a queued card is about to send The composer shows Stop while the host's queue is about to send its next card, but the sign-in gate stayed on in that window, so Enter was refused with no message. * fix(native-chat): never disable Send for a sign-in or missing-CLI verdict; show a dismissible notice instead The host's pre-send check can be wrong while the chat would work (saved Arguments it never sees, project settings it can't read, gateways that accept a signed-out Codex), and a disabled Send left no way past it. - Delete the Send gate: the composer, Enter and goal mode no longer read the verdict, and the Send tooltip reason and focusable wrapper go back to main. - Show Codex not-signed-in and Claude/Codex not-installed as one entry in the chat's existing notice card. Dismissed per verdict; shows again when the verdict changes or clears and returns; steps aside when the failed start (launch line or latest failed-start row) says the same. - Claude: drop the probe's signed-out verdict (initialize-on-probe stdin, request-id filtering, control-reply log scrubbing). The chat start's refusal, with its account kind, is the only Claude sign-in signal. Missing-CLI from the probe stays. - Restore the failed-start line and transcript row for these causes (no more hiding on desktop) and drop the chat-root focus re-check; a window-focus re-read stays while a notice is showing. * fix(native-chat): re-check the notice's reason after a chat starts, keep a signed-out Codex's model list Review round 1 of the notice rework. - A chat that proves its start (at acquire, or on its later "started" event) marks the catalog's held reason for that account due, so the next read re-probes instead of trusting it until the TTL; the chat re-reads when a turn starts or ends while a notice shows. - The Codex probe keeps a model list it got beside a signed-out reason, so a gateway user with a wrong verdict keeps the picker list. - Failure records move to their own module; an expired failure with no reason is dropped, and expiry drops reason-less failures. - Notice: any verdict change resets the dismissal; signed-out is Codex-only; the say-once rule ignores a failed start a turn has run past. - Missing-CLI copy: "{{agent}} wasn't found on the computer running this chat. Install it, or check its Command in Settings → Agents." (6 locales). * fix(native-chat): only an acquiring start re-checks the catalog reason; drop the unreachable Claude filter Review round 2 of the notice rework. - A re-attach to a live child proved nothing new, so only an attach that acquired a child which proved its start marks the reason due. - Reword: a start proves the program exists; for a Codex sign-in it only prompts an earlier re-check. - Drop the notice's Claude signed-out filter: no host sends that verdict. - Tests: a re-attach does not notify; a turn ending re-reads once more. * fix(native-chat): never newly show a catalog reason the host is still re-checking After signing in to Codex, a new chat flashed the old "isn't signed in" notice for about half a second: past its 30 s lifetime the host answers a plain read with the held reason while its probe re-checks. A chat now adopts such a reason only when it already shows it; otherwise the joined read's answer decides. * test(native-chat): follow main's harness and the clearer Claude sign-in words after the merge * test(native-chat): run the start-proof catalog test in the Node runtime project with the other SQLite host tests |