Add bot mode functionality - #81
Merged
Merged
Conversation
A bot is a named, long-lived agent you keep messaging, listed the way a messages app lists conversations. Each bot owns its own keke process, its own workspace, persona, provider/model and trust level; the sidebar list is deliberately cold, so a process only starts when you open a bot, and stays up so coming back to one costs nothing. Settings read the live agent where they can — provider and model come from the running session's own lists once a bot has been opened, and are typed in by hand before that. keke's absence is handled where the user is looking: the composer is replaced by an inline prompt with an Install button that runs `npm install -g @milisp/keke` and re-resolves the presets, instead of a toast. That needs a def to distinguish "installed" from "runnable": every preset has an `npx -y <package>@latest` fallback, so with Node on PATH every npm-published agent reports `available`. Defs now also carry `local` — the agent's own binary resolved — and the Bot tab keys off that, while the ACP chat pane keeps using `available`, where running through npx is a deliberate offer rather than an accident. Two smaller things the Bot tab needs to behave: - `useAcpAgents` returns null until the list has resolved, so a first render cannot mistake "still loading" for "nothing installed". - The composer reads liveness off this bot's own connection and session rather than the global ACP store, which can hold the chat pane's connection to a different agent — a stale one there neither hides the install prompt nor receives a bot's message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PF1yKf8CW1SEePDThwVQrr
Jumping straight to the chat left a fresh bot on default name/model/ persona with no prompt to configure it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018bv61EeuSvQgLWBj8BcG4t
The bot settings dialog had grown a second, hand-rolled provider/model picker, and only offered it while that bot's own connection happened to be the live one. Reuse the composer's menu instead: - extract the presentation of AcpModelMenu into AcpChoiceMenu, leaving the live wiring (optimistic apply, revert on rejection, sign-in) behind; the choice helpers move to modelChoices.ts so the .tsx only exports a component - cache what keke advertises in useBotOptionsStore, so a bot that has never run — a brand new one included — still gets a list - split the dialog into BotIdentityFields / BotModelFields / BotTrustFields and useBotSettingsForm A bot picks a provider, it does not sign in: the account row reads "Provider", and both rows offer "keke's default" so a bot can go back to inheriting ~/.keke/config.toml instead of overriding it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PF1yKf8CW1SEePDThwVQrr
The Bot tab renders from the single ACP store, which holds one conversation at a time. Four ways that leaked: - Opening is async, so a bot switched away from mid-load replayed its transcript into the pane of the bot now on screen. Every store write after an await now checks the bot is still selected. - A bot gets a fresh session on each app restart, so the newest stored session is regularly an empty one. Replay now shows the newest session that has updates, followed by the current session's own, sealed at the seam so the two turns do not merge into one bubble. - Creating a bot never starts it, and nothing cleared the pane, so a new bot opened showing the previous bot's messages. `openBlank` clears it. - `running` was global, so a turn in one bot showed another as typing, and finishing it cleared the wrong bot's state. It is now per bot. Also show a shell tool call's command even once output arrives — `rawInput` was only rendered when there was no content, which is never the case by the time the command has run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PF1yKf8CW1SEePDThwVQrr
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PF1yKf8CW1SEePDThwVQrr
Dropping a folder (or file) onto the header sets the bot's cwd via the Tauri drag-drop event, and the header shows the sidebar trigger when the sidebar is collapsed while reserving space for macOS traffic lights, matching AgentViewHeader. The drag region is applied explicitly across the name/title area so the whole strip stays draggable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PF1yKf8CW1SEePDThwVQrr
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.
This PR adds bot mode functionality to the Codexia desktop application, including:
The implementation consists of 7 commits that extend the codebase to support bot‑oriented interactions, improving usability and organization of chat sessions.