Repository navigation
Let first run show what OpenBot does, and what is left to set up - #915
Draft
jerelvelarde wants to merge 27 commits into
Draft
jerelvelarde wants to merge 27 commits into
jerelvelarde wants to merge 27 commits into
Conversation
The last two places still drawing boring-avatars' gradient circles now draw the orb in the colour the Bot's id picks, so a Bot looks the same in the sidebar, the conversation header and its profile. Nothing imports boring-avatars any more, so it leaves the app's dependencies.
…ll when asked A Bot's orb is a block, so a group conversation's 12px faces no longer sit on the header's text baseline and drop half out of their circles. It resizes its canvas when the screen's pixel density changes, so dragging a window to another screen or zooming no longer leaves it soft, and it follows the reduced-motion setting live rather than only when it first draws. The changelog and the stylesheet now describe what this step draws, not what later steps will.
The skins import the orb's state type from agent-orb now that ai-core is gone, OpenBot's mark keeps its agent-orb class for them, and their tests check the orb's colour rather than boring-avatars' SVG. The Appearance test's preferences carry the new skin field.
AgentOrb read "100%" as 100px, so with no Bot yet the header drew a 100px orb in a 44 or 52px slot. With a Bot, the classes that used to rescale boring-avatars' SVG squeezed the avatar's circle to 44px below 900px wide while the orb inside stayed 52px, clipped and off centre. The frame now picks 44 or 52px from the window's width and draws the face at that size, the selectors that matched only the old SVG are gone here and from OpenDots' Bot rows, and AgentOrb takes its size only in px and refuses anything else.
Every orb on screen redrew on every animation frame, uncapped, so a sidebar of conversations kept a few dozen canvases repainting at the screen's full rate while the app sat idle: a small orb's colour still drifted, so no two frames were ever the same. A small orb's colour now holds still, an orb skips any frame that would draw what its canvas already shows in the same theme and at the same density, and a small orb draws at most about thirty frames a second. A face at rest with the pointer still now draws only to blink.
…violet A Bot's face was one of nine colours and nothing else, so a team of four had about an even chance of two identical faces. In the Bots OpenBot ships with, three were the same sky blue, and release notes wore violet, OpenBot's own mark. A Bot is now drawn from its seed: one of the eight colours that aren't violet, with its colour masses turned, its hue nudged and its eyes spaced by the same hash, so two Bots in one colour still look apart. BotOrb takes the seed rather than a colour and draws OpenBot's violet when it has none. The OpenDots avatar test checked one colour in nine, so it passed or failed on the hash; it now checks that the seed reaches the orb.
GET /api/setup says, row by row, whether Intelligence, the model, the Bot computer, more apps and Slack and Teams work here, from their own answers rather than from a variable being set. POST /api/setup/check asks them again. An admin, or somebody running OpenBot alone, is told the page or the variable that closes a gap; everybody else is told only that it works or that their admin sets it up, and their response carries no variable name.
Onboarding is the only page somebody who has not finished it may open, so a consent started on its Connect your apps step returns to that step, worked or not, for OAuth and brokered apps alike. A consent cancelled at the vendor now returns to the screen it started on too, instead of the Connections list. The returnTo name is still narrowed to a closed set before it is sealed or used.
A step-by-step onboarding frame that works on a desktop screen too. One DOM, laid out by CSS: from lg up, the steps as a list (the ones reached can be picked) with the step's heading, sentence and Continue/Back on the left, and its picture filling the right; below lg, a dash for each step, a round Back and the buttons pinned to the bottom. Focus moves to each new heading. A demo's clock runs only while it is on screen in a shown tab, and holds still with reduced motion.
Welcome types a request under OpenBot's listening orb, a computer of its own shows the Bot's desktop with its pointer on an errand, the team shows three Bots' orbs taking turns at work, and an approval card waits for Allow once before it sends. Somebody running OpenBot alone also sees it on a laptop, with the agents they have, and for their organization. Each is a picture, read by its label, with nothing inside to click.
Connect your apps lists the apps the person's default Bot uses as them and connects the ones with a sign-in page right there, coming back to the step; a brokered consent is asked of the vendor on return, so the row turns Connected only when it is. Get notified previews the notification OpenBot really sends and asks the browser, sharing its answer with a Bot's page. Check your setup draws the server's checklist with a status pill per row, and Check again.
First run is now welcome, a browser and files of its own, the team of Bots, asking before it acts, running it yourself (only for somebody trying OpenBot alone), connect apps, get notified, check your setup, and the name step. Where somebody is lives in the address and is saved on every move, so a reload, browser Back and a consent's return keep their place. The name step stays last, under the orb: Get started saves the name, completes onboarding and plays the orb's finish, and a checklist link carries its page through it, since nothing else opens until onboarding is done.
…ws now The root's drop guard named the onboarding poster's composer, which is now a drawing inside onboarding's picture frame. The changelog says the computer check also runs once at start-up.
Found running the steps against a real install. Connect apps told an admin to wait for an admin; it now offers Plugins, carried through the name step like the checklist's links. The checklist's "Required" tag ran into each title, and the notification preview cut "General Assistant needs you" off at the Bot's name.
…s written out Setting OPENAI_BASE_URL to https://api.openai.com/v1 counted as a custom endpoint, so the check was skipped and the setup checklist said the model was not checked. The provider's own host is now checked as if no address were set.
…the box The step promised that a Bot asks before it sends, buys or deletes anything. Ask before making changes starts off, so out of the box a Bot asks only where a rule says to, and paying or changing account security is handed to the person. The step now says that, and where to turn asking on.
With AGENT_COMPUTER_URL set and no computer running, the usual state and always true on a first run, the row told an admin Bots can't browse the web and to set the variables and restart, for something already set. Not checked now says it is set up and none is running to check, and opens Computers.
Intelligence, model and computer answers were asked at boot and then served for as long as the server ran. An Intelligence slower to start than OpenBot read as a red required gap until somebody pressed Check again, and a key refused days after boot still read Ready. A read now asks again, in the background and under the shared 10-second limit, when an answer failed or is five minutes old, so the next read has it. Reads are answered from the last answers that are all in, so none waits on a slow fleet.
The changelog said the intro was replaced by another product's steps, and two comments cited it, which reads as a skin being added. They now say what OpenBot does. The changelog also said a cancelled connect returns to where it started from anywhere; only Connect your apps changed, so it says that.
At 1280 by 800 the self-hosting step and the name step ran past the bottom of the window, cutting Continue and Back in half; at 700 tall, four steps did. The left pane stacked the nine-step list, the step's words and its buttons, and the page was left to scroll. On a desktop the frame is now one screen tall and the step list's row is the only one that can shrink, so the step's words and its buttons always keep their full size. When the screen is too short for all of it, the list scrolls within itself, fades at the edge it scrolls under, and keeps the step on screen in view. Its rows and the space under it are a little tighter, so every step still fits whole at 1280 by 800. Only a window too short for the words and buttons themselves scrolls the page. The picture pane now stretches to the screen instead of being set to its height: a set height spanning every row gave that height to the empty last row before the list got any. It drops the phone's margin on a desktop, which would stop it short of the bottom on the name step.
This was referenced Oct 31, 2026
This branch has not been deployed
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.
Depends on #913. Its own change is the commits after that one: compare.
The problem
First run is an introduction that changes scene every four seconds, then asks for a name. A new person watches it at a pace they don't control and leaves without connecting an app or learning whether anything works. The server stores a step for each person, and its docblock says why that does nothing: "NOTHING RESUMES FROM IT YET". A reload starts again.
An admin finishing first run can't see what the deployment still lacks. The server checks the model key once at boot because, in its own words, a key without access "fails at the first message, in front of whoever sent it", but that answer goes to a log.
The approach
Steps, not a loop. First run is Welcome, a browser and files of its own, the team of Bots, asking before it acts, Running it yourself (only for somebody trying OpenBot alone), Connect your apps, Get notified, Check your setup, and the name. Each introductory step has a picture, which is read by its label, plays only while on screen in a shown tab, and holds still with reduced motion. One DOM is laid out by CSS: on a desktop the steps are a list beside the step's pane, and a step already reached can be picked; on a phone they come one at a time with the buttons pinned below. Focus moves to each new heading. On a desktop the frame is one screen tall and only the step list's row can shrink, so a step's words and buttons keep their size; on a short screen the list scrolls within itself and keeps the current step in view. Every step's buttons stay on screen at 1280×800 and at 1280×700.
A person's place survives. The step lives in the address and is saved on every move, as a number of its own rather than a position, since the self-hosting step joins only for some people. A reload, browser Back and a consent's return keep it.
Connect your apps connects them here. It lists the apps the default Bot uses as the person, and signs in from the step. The consent comes back to that step whether it connected, failed or was cancelled at the vendor. A brokered app is asked of the vendor on return, so the row reads Connected only when it is. Get notified previews the notification OpenBot really sends and asks the browser.
Check your setup asks the server.
GET /api/setupanswers row by row for Intelligence, the model key, the Bot computer, more apps, and Slack and Teams. Ready means it works, not that a variable is set: Intelligence from its entitlement answer, the model from the provider's answer for the key in use now, the computer from each running computer taking its network policy, waking none. Who reads decides what it says. An admin, or somebody running OpenBot alone, is told the page or variable that closes a gap; everybody else hears that their admin sets it up, with no variable name in the response, because anybody opens onboarding. Check again asks again at most every 10 seconds, and a read asks again in the background once an answer has failed or is five minutes old.The name step stays last. Get started saves the name, completes onboarding and plays the orb's finish. A checklist link is carried through it, since nothing else opens until onboarding is done.
The asking step says what is true out of the box: Ask before making changes starts off. A base URL that is the provider's own is now checked, not skipped.
The cost: first run is eight or nine steps where it was two or three, and reading the checklist can start calls to Intelligence, the provider and the computers.
What is not covered
Verification
typecheck, lint, format:check and the assertion-shape guard are clean. The full app suite is 2271 pass, 0 fail, against 2190 on #913 and 2129 on upstream
main. The five server test files this branch changes are 197 pass, 0 fail on this tip.app/tests/onboarding-frame.test.tsx: two panes on a desktop, one on a phone; a picture holds still off screen and in a hidden tab; the frame's rows that keep a step's buttons on screen. Happy-dom can't measure layout, so a browser check put every step's buttons inside the window at both sizes above.app/tests/onboarding-route.test.tsx: the order of steps; reload, Back and a consent's return keep the place; the self-hosting step only for somebody alone.app/tests/onboarding-steps.test.tsx: Connect starts the real connection and comes back; a brokered app is asked of the vendor once; the browser's no, no answer and no support.app/tests/setup-checklist.test.tsx: an admin sees the variable and the page, a member neither; an unchecked key never reads Ready.server/tests/setup-checklist.test.ts: Ready means it works; a member's response names no variable; old or failed answers are asked again without a read waiting.server/tests/plugin-oauth-callback.test.tsand three more, extended: the consent's return, and the provider's own address.Merge notes
This and #917 both add to
server/src/app.tsandserver/src/index.ts, and the two conflict. #918 carries both, combined.