grok-bot: this guide as a working app
npm start.
The grok-bot example: two Bots hand a question to each other in the team chat.
Walkthrough: start a team of Bots, hand work from one to another, run a routine, and watch the shared computer.
One computer, many Bots
In Grok Bot, every Bot on your account uses the same computer: the same files, browser, terminal, and signed-in apps. Only the conversations, the job, and the Bot’s own context differ. That maps onto Agent37 directly:POST /v1/responses has no system-prompt field. Different Bots are different sessions, so they work at the same time. Like in Grok Bot, Bots are not a security boundary: they share one disk and one set of connected apps, so separate people need separate instances.
Create the shared computer
403 tier_limit; leave resources out for 2 vCPU / 4 GB). Three fields matter: a budget so the managed LLM answers from the first message, auto_sleep so a computer nobody is using bills disk alone, and a random token in env that the agent later presents when it messages the user.credit_micros: 2000000 is $2 of managed-spend headroom shared by all the user’s Bots (see Budgets). env is write-only and fixed at create, so keep only the token’s hash on your side. The 30-minute idle window keeps the computer awake through a long routine; see long requests for why it should outlast your slowest turn.The call returns 201 with status: "running" once the computer is up. Poll GET /v1/health on the instance URL until it answers "healthy": true before the first message (see Health & version).Tell the computer it serves a team
~/.hermes/SOUL.md is the persona every turn loads. On a fresh computer it holds Hermes’ stock voice, so write your own with the Files API. A PUT replaces the whole file with the request body.Add a Bot
handle derived from the name that never changes. On create, give it a notes file on the computer, its own memory that survives across conversations. overwrite=false leaves an existing file alone and answers 409 file_exists.GET /v1/sessions/{id}. The agent’s own memory (~/.hermes/memories/) is shared by every Bot on the computer; the notes file is what keeps each Bot’s context its own.Chat with Bots in parallel
stream: true.409 session_busy with the running reply’s id in error.response_id. Follow that reply with GET /v1/responses/{id}/stream, which replays it from the start and then stays live; the same call reattaches a reply that was running when the page reloaded, found through active_response_id on GET /v1/sessions/{id}.GET /v1/sessions lists at most the 100 most recent Hermes sessions, and every routine run opens a new one, so keep your own record of which session belongs to which Bot rather than rebuilding it from that list.Give each Bot routines
name, which is how your app files each cron under its Bot, and the Bot’s brief at the top of prompt, so the run stays in character.agent: "hermes" names the harness that runs each firing, and every triggered run records the session_id it opened. Bots also schedule themselves: ask Chief to “remind me every weekday at 8:30 to review open pull requests” and it runs agent37 cron add --name "chief: ..." inside the computer, following the brief. That cron lands in the same list, under Chief, and its runs record their sessions too. An instance holds at most 50 crons, shared by all its Bots.Let Bots message you first
GROKBOT_NOTIFY_TOKEN is the token you planted at create, and AGENT37_INSTANCE_ID is set by the platform in every container. Your endpoint finds the user by instance id and compares hashes before it trusts anything:Add a team chat with @mentions
Show memory and connect apps
~/.hermes/memories/USER.md (about the user) and ~/.hermes/memories/MEMORY.md (everything else), each a list of entries separated by a line holding §. Read them with GET /v1/files/content, and write the whole list back with PUT after the user edits or deletes an entry; new conversations see the change. Each Bot’s ~/bots/<handle>/notes.md gets a plain editor of its own.Connected apps belong to the computer, so every Bot can use them. List the catalog, start a connection, and send the user to the returned link:callbackUrl at a plain “you’re connected” page that needs no sign-in, so the return works whichever address the user opened your app on (in local dev, localhost and the tunnel are different sites with different cookies). The tab that opened the link polls the connections list until the account reads ACTIVE. See App integrations for listing and disconnecting accounts.Watch and take over its computer
In Grok Bot you can watch a Bot work on its computer, and take control when a site needs you: a password, a 2FA code, a CAPTCHA. On Agent37 that is a desktop image with a screen you can stream, plus a short-lived signed URL for it. The example turns it on whenDESKTOP_TEMPLATE is set in its .env, and runs exactly as above without it.
Build the desktop template
6901. Build it into a workspace template once. The build runs in the cloud, so you don’t need Docker:"template": "hermes-vnc-desktop". Everything else on this page works unchanged, because the image is the stock one plus the screen. Add a line to SOUL.md so the Bots use it: the user can watch this computer’s screen and take it over, so when a site needs a login, a 2FA code, or a CAPTCHA, leave the page open, ask the user to take over, and carry on when they are done.Mint a token for each connection
6901 and hands the browser only a WebSocket URL built from it. The token rides in that URL’s query string, so the connection needs no cookie and works from your own origin: the browser connects straight to the instance from your page, with no proxy.- It grants full control. Watching versus controlling is a setting in your page, not a permission: anyone holding the token can connect a VNC client that clicks and types. Mint it only for the computer’s owner.
- It cannot be revoked, so keep it short.
60seconds, the minimum, is enough: the token only has to be valid while the socket opens, an open view keeps working after it expires, and every reconnect mints a fresh one.
Show the screen, then take over
session_id only once the turn finishes. Name it, "agent": "hermes", and the run links its session from the moment it fires, so you can open a routine while it is still working. The calls in Give each Bot routines already set it, but agent37 cron add has no flag for it, so PATCH the crons a Bot schedules for itself with { "agent": "hermes" }. The example does that when it lists routines.
Don’t put the signed URL itself in an iframe on your site: its auth rides a SameSite=Lax cookie, which a cross-site frame does not send. Connecting noVNC to the WebSocket, as above, avoids the cookie altogether.
Worth knowing
- Bots share everything on the computer. Files, the browser, the terminal, connected apps, and Hermes’ own memory are common to all of a user’s Bots, exactly as in Grok Bot. The per-Bot parts are the sessions, the brief, and the notes file.
- Cost follows use. With
auto_sleep, a computer nobody is using bills its disk alone, and chats and crons wake it. Awake, the 2 vCPU / 4 GB shape is $4.76 per month and 4 vCPU / 8 GB is $9.34 per month, metered per minute (see Billing). - Purchases go back to the user. The persona tells every Bot to stop and hand over anything that needs a payment.
- Routines count per computer. The 50-cron limit is shared by every Bot on the instance.
- Texting a Bot is its own guide: Text your agent on iMessage.
- Left out of this guide: approvals before an action, masked secret requests, teach-by-demonstration, voice, Slack event triggers and Team Bots, and sharing Bots.
- Chat, streaming, and sessions are the standard chat app wiring, and the token-checked callback is the same pattern as the website builder’s publish endpoint.