Skip to content

[Feature]: Bots — named, persistent, always-on agent teammates on any provider (Grok Bot, mapped onto T3 Coil) #146

Description

@radroid

Before submitting

Area

apps/server, apps/web, apps/mobile, packages/contracts (deliberately avoided — see Cost)

Problem or use case

Grok Bot (xAI + Cursor, beta since 2026-08-11) reframed the agent product from chats to teammates: named bots with a role, memory, their own computer, routines, and an approval boundary, that you message from your phone and that keep working while your laptop is closed. It runs on one model you cannot pick, on a cloud computer you do not own, on a plan you pay xAI/Cursor for.

T3 Coil already has most of the machinery underneath that product — a real computer (the host), five providers, per-thread permission modes, loops that keep a thread alive, needs-input notifications, Web Push, and mobile — but exposes none of it as a bot. The request: research what Grok Bot is and how it is being built, decide which of its features map onto T3 Coil, and plan a "bring-your-own-provider" version of the parts worth having. This issue is that research and that plan, for review before anything is built.


1. What Grok Bot is (research, 2026-09-12)

Product. "AI teammates you can give real work to." Persistent, named bots with a role, a title, an avatar, memory, enabled skills and routines. Launched in beta 2026-08-11 as the first joint xAI/Cursor product after SpaceX's Cursor acquisition; it runs on Cursor's infrastructure and Cursor's identity/billing. Included with SuperGrok and all Cursor Pro/Teams plans since 2026-08-26, with its own usage pool. Enterprise launched 2026-09-03 (governance, audit). Android shipped 2026-09-06. No model picker; the underlying model is not documented.

The five primitives the team kept (from their design essay "Designing Grok Bot for a world of persistent agents", 2026-09-03): Bots, Chats, Prompts, Tools, Artifacts. "The main objects in Grok Bot are Bots, not conversations." Everything else — metadata, coordination dashboards, multiple computer views — was cut: "much of the design work involved taking things away." Supervision is three graduated levels: Status → Preview → Takeover.

The computer. One persistent cloud VM per user account (not per bot) with a browser, filesystem (/workspace) and terminal. Each bot gets its own screen on it; screens are parallelism, explicitly not a security boundary — bots share files, cookies and CLI credentials. Bots "sign into the tools you already use" and use connectors where available, computer use for everything else. Work continues when the app is closed.

Talking to it. Desktop (macOS/Windows/Linux) and mobile (iOS/Android), same thread on every surface. Group chats containing several bots; bots @-mention each other, pass ownership of a task, and one bot can manage others. Bots answer in prose or in inline cards/widgets.

Approvals. A fixed boundary list requires approval: sending messages/invitations, publishing, purchases/transfers, deleting/overwriting data, changing permissions, production changes, accepting legal terms. UI: Allow once / Deny / Always allow (mobile: Approve once / Deny). Auto-review rules (Settings → General) in natural language; Require Approval always beats Always Allow. Passwords, 2FA, CAPTCHAs and payments are never typed by the bot — it "hands you control of the computer"; secrets go through a masked request excluded from the transcript and the model. Local-machine execution is a separate switch (default Ask every time). "An approval controls the proposed action. It does not reverse work already completed."

Memory. Per-bot: "stable preferences, role context, and summaries of prior work." Conversation history stays per bot; the computer state is shared.

Skills → routines. The documented progression is one-time task → corrected task → saved skill → tested routine. Skills are invoked with /; teach-a-task records you doing a job (≤10 min) and saves it as a skill. Routines are scheduled (daily at 08:00) or event-triggered, run unattended, and are the stated direction: "over time, more work may begin without the user being present at all."

Templates & marketplace. Duplicate a bot (profile, settings, skills, routines — not history, memory or attachments); share a bot by link (configuration only, never the computer or logins); an official marketplace (x.ai/bot, ~69 public templates) and a .grok-plugin marketplace inherited from Cursor.

How the team develops it. No public roadmap document. Updates go out through the @bot X account; cadence since launch: plans expansion (08-26), Enterprise (09-03), Android (09-06), "automatic token optimisation" promised by Musk with no date, enterprise waitlist. Rough edges reported by early users: one long conversation mixes projects, usage burns fast on browser sessions, the shared computer is a shared trust boundary, and the advanced controls (teach-a-task, routine editing) are desktop-only.

The open-source echo (all within three weeks of launch): CopilotKit OpenBot ("an open source Grok Bot that works with ANY agent harness": one container per bot, AG-UI, CEL policy gateway, audit rows); OpenMausBot (Claude/Codex/Grok, cloud Linux desktop or local VM); gawkbot (bots on your own machine, human approval gates); OpenSquad (BYO-key, each bot gets model + computer + memory + email + phone); Hermes Agent bridges to it over MCP. The common shape everyone converges on: identity + computer + channel + approvals + memory + schedule, on any harness.

Sources: Introducing Grok Bot · more plans · Designing Grok Bot · docs: overview · docs: bots · docs: approvals & security · docs: FAQ · Cursor docs · Flavio Copes deep dive · architecture deep dive · awesome-grok-bot · OpenBot · OpenMausBot · xAI release notes


2. Feature-by-feature mapping onto T3 Coil

Verified against main @ e39f8be6d (sync #135 pending). "Rows" = seam-ledger rows in upstream-owned files.

Grok Bot T3 Coil today Gap → what it would take Verdict
Named persistent bot (name, role, avatar, memory, skills, routines) Threads and projects; no persistent identity across threads A fork-owned bot record (coil-bots.json, state-file + route pattern from autoResume/) binding name, role prompt, provider + model, project, permission mode, routines, a long-lived thread. 0 rows on the server. Build — the core
Own computer (cloud VM: browser, fs, terminal; keeps working when laptop closed) The environment is a computer — the user's real machine, real credentials, provider CLI with shell + fs; preview MCP toolkit is a browser the agent drives; upstream devices (simulators) in #135; docs/user/background-service.md + Tailscale/T3 Connect keep it reachable None to build. Trade-off is inverted: T3 works with your real logins and repos, but the host must stay on (headless Mac/Linux box or the background service). Document, don't build. Already have (better on creds, worse on "laptop closed")
Message it from phone/desktop, same thread Web, desktop, mobile on the same thread; Web Push for closed tabs None Already have
Only comes back when it needs you Loops raise_blocker + loop_status, needs-input notifications (#11), Web Push (#23) Per-bot notification routing (which bot is asking) — one field on the notification Already have
Approvals: Allow once / Deny / Always allow Per-thread permission modes (Supervised / Auto-accept edits / Auto / Full), provider-native approval prompts on web + mobile A bot carries its permission mode; "Always allow" as a persistent rule is provider-native (Claude allow-lists, Codex AI reviewer) — no T3 rules engine in v1 Mostly have
Auto-review (natural-language rules, Require-Approval wins) Codex "Auto" delegates to an AI reviewer; Claude has its own auto mode; OpenCode falls back to asking A provider-agnostic rules layer would need to sit in every adapter's approval path = 5 adapter rows. Defer — use provider-native
Boundary list (send / publish / pay / delete / prod / permissions / legal) Not encoded anywhere Ship it as text in the bot's role preamble, not as enforcement. Cheap, honest. Build (as prompt)
Hand-me-control for logins/2FA/CAPTCHA; secret requests The agent already runs on the user's machine with the user's sessions; "takeover" is the user's own terminal/browser No secret vault. Not needed for the local model; needed if bots ever run on a shared remote host. N/A in v1
Memory (preferences, facts, summaries per bot) Provider-native only (CLAUDE.md, Claude memory dir, AGENTS.md) A per-bot BOT.md in the bot's workspace: role + learned notes, injected as the preamble of every routine turn, and the bot may edit it. 0 rows. Build (v1, minimal)
Skills, / invocation Skill discovery + $ picker already shipped upstream (Claude, Grok Build loads the Anthropic skill format) — but picking a Claude skill is a no-op (#109/#113) Fix the picker (wayfinder map #108 already owns it); bots then get skills for free Already have, one bug
Teach-a-task (screen recording → skill) Nothing Computer-use recording + skill synthesis; large, provider-specific Out of scope
Routines (cron / event → unattended run) Loops (#133) keep an existing run alive within bounds; Claude self-schedules via ScheduleWakeup; coil/loop/cron already parses 5-field cron A routines reactor: cron → dispatch thread.turn.start into the bot's thread (the auto-resume dispatch primitive, "byte-for-byte the path a keystroke produces"), bounded like a loop, receipts, timeline activities, one run per bot at a time, skip while a rate-limit hold is on. 0 rows. Build — the second half of the core
Event-triggered routines (e.g. a new GitHub issue) #44's detection design (REST poll, dedupe, PR-filter) Same reactor with a trigger instead of a cron. #44 becomes a bot template ("Maintainer") rather than its own feature. Build in phase 2, as #44
Group chat, bots @-mention each other, manager bot Nothing; #43 (delegate_task) is the primitive A bot-to-bot channel is #43. Defer to #43
Inline cards/widgets instead of prose Tool-call rendering, plans, diffs, PR cards Nothing bot-specific Already have (enough)
Status / Preview / Takeover Thread timeline / preview panel + browser preview / the user's own machine Nothing to build; name the analogy in docs Already have
Templates, duplicate, share by link Nothing Export/import a bot record as JSON (no history, no secrets). v2
Plugin / connector marketplace MCP servers per provider config Out; MCP is the connector story Out of scope
Own usage pool, no model picker BYO subscription, any provider, any model — the whole premise of T3 This is the differentiator, not a gap Better
Enterprise governance, audit, private networks Pairing + scopes, T3 Connect Out Out of scope
Delete a bot — Reverse state (AGENTS.md): delete keeps the thread (archive it), removes routines, keeps BOT.md on disk Build

Net: of 20 rows, 8 already exist, 5 are the v1 build (bot record, routines reactor, BOT.md memory, boundary preamble, delete), 3 defer to issues that already exist (#43, #44, #108), 4 are out of scope.


3. Proposed v1: a Bot is a pinned thread with an identity, a preamble, and routines

The cheapest model that makes the behaviour unsurprising, and the one that costs zero contract/migration rows:

Bot = { id, name, role, providerId, modelId, projectId, threadId, permissionMode, routines[], memoryFile, createdAt, archivedAt }
stored in <stateDir>/coil-bots.json (every field withDecodingDefaultKey), one long-lived thread per bot (pinned — upstream's pin, 0 rows), role and BOT.md prepended to every dispatched turn, routines run by a reactor that dispatches into that thread.

Grok Bot's own "bot ≠ conversation" model (many chats per bot) is deliberately not copied in v1: a bot with many threads needs a bespoke sidebar section (Sidebar.tsx, churn 54 — the row #124 is already arguing about). One thread per bot gets the identity, memory and routines with the sidebar untouched; if it proves itself, "new chat with this bot" is a v2 that can reuse the same record.

Phases (each a PR)

  1. Bot record + routes — apps/server/src/coil/bots/{state,http,types}.ts + tests. GET/POST /api/coil/bots (create / update / archive / list), via CoilRoutesLive and authenticateWithOperateScope. Create = dispatch thread.create server-side (the engine already does this in serverRuntimeStartup.ts) against the project's workspace root, then pin. No worktree bootstrap in v1 (that lives in ws.ts, the [Feature]: maintainer agent — work a repo's issue queue automatically (triage → plan or draft PR → human approval) #44 finding) — a bot works in the project root. 0 rows.
  2. Routines reactor — coil/bots/Reactor.ts: cron (reuse coil/loop/cron) + a manual trigger; each firing prepends role + BOT.md and dispatches thread.turn.start; guards: thread busy → skip with a timeline note, rate-limit hold → defer to resetsAt (share autoResume's classifier), bounds per routine (max runs/day, stop-by) reusing loops' bound vocabulary; receipts from day one (the feat(coil): loops — a durable supervisor for unattended threads #133/test(coil): auto-resume reactor tests wait on scheduler turns, and flaked once in CI #134 lesson); every decision appended as a coil.bot.* timeline activity. 0 rows.
  3. Web: Settings → Bots — create/edit (name, role, provider + model picker from the existing catalog, project, permission mode), routines editor (cron presets + next-fire preview), archive. Same pattern as Settings → Loops: settingsSearch.ts +N/-0 and SettingsSidebarNav.tsx +2/-0 (both already ledger rows), routeTree.gen.ts regenerated. The thread itself gets a bot header card and a "run now" button through ThreadCoilOverlay (0 rows).
  4. Memory — BOT.md at <workspace>/.coil/bots/<id>/BOT.md: the role, a ## Boundaries block (Grok's list, as text), and a ## Notes section the bot is told it may edit. Injected as the turn preamble. Tests on the composer. 0 rows.
  5. Mobile — bots surface as pinned threads (already); a read-only bot card (name, role, next routine) inside the thread via the mobile overlay; approvals and messaging already work. Routine editing: desktop/web only (Grok Bot made the same call). Providers: all five for dispatch (turn.start is provider-agnostic); "Auto" permission semantics differ per provider exactly as permission-modes.md already documents.
  6. Docs — docs/user/bots.md; docs/coil/bots/DESIGN.md for the record/reactor; ledger update.

Deferred with reasons: group chat / bot-to-bot (#43 — needs the toolkit), event triggers (#44 — the Maintainer template, phase 2 of that issue once routines exist), templates/sharing (v2 — JSON export is trivial once the record exists), auto-review rules (provider-native for now), teach-a-task and marketplace (out).

Cost: ~0 new ledger rows in phases 1, 2, 4, 5; phase 3 spends on three rows that already exist (settingsSearch.ts, SettingsSidebarNav.tsx, routeTree.gen.ts). Estimate: phases 1–2 one agent-day each, 3 one to two, 4–6 half each.


4. Decisions to make

  1. Bot = one thread (v1) vs bot = many chats (Grok's model). Recommend one thread; it is the entire difference between 0 sidebar rows and the highest-risk row on the ledger.
  2. Routines in v1, or bots first and routines later? Recommend together — a bot that cannot run unattended is a saved prompt, and routines are what Grok's team says the product is heading toward.
  3. Fold [Feature]: maintainer agent — work a repo's issue queue automatically (triage → plan or draft PR → human approval) #44 into this as a template (Maintainer = a bot with a GitHub-issue trigger)? Recommend yes; it removes the "supervisor that creates threads" bootstrap gap from [Feature]: maintainer agent — work a repo's issue queue automatically (triage → plan or draft PR → human approval) #44's critical path because the bot's thread already exists.
  4. Settings page vs a dedicated /bots route. Recommend Settings (pattern paid for by Loops); a dedicated page can come with many-chats-per-bot.
  5. Memory as a file the bot edits vs T3-owned structured memory. Recommend the file — it is provider-agnostic, inspectable, and Grok's docs themselves warn memory "is not a substitute for an authoritative source."
  6. Name. "Bots" collides with nothing in T3 today; "Teammates" or "Crew" are the alternatives.
  7. Sequencing: phases 1–2 can start now (fork-owned); phase 3 waits for sync [coil-sync] daily sync needs attention (conflict) #135 (Settings files are in its conflict set).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions