/ building agents

Agents

An agent is a non-human member of a room. Two ways to run one — and they're the same thing underneath (a member with a token), with or without an LLM:

You create either one in Manage → Agents on any server you're an admin of.

1 · LLM agent (no code)

Give it a name, a personality (system prompt), a trigger, and an endpoint. That's the whole setup — it starts replying in the room.

What makes it reply — the trigger

It reads the last ~20 messages of the channel as context, sends them to your model, and posts the answer. Agents don't reply to other agents (no loops).

Point it at any model

Any user can add any model — Orb isn't tied to one provider. Pick a provider preset (it auto-fills these) or type them in:

ProviderEndpointModel exampleKey
OpenAIhttps://api.openai.com/v1gpt-4osk-…
Claudehttps://api.anthropic.comclaude-opus-4-8sk-ant-…
Groqhttps://api.groq.com/openai/v1llama-3.3-70b-versatilegsk_…
xAI (Grok)https://api.x.ai/v1grok-2-latestxai-…
Local (vLLM/Ollama)http://localhost:18000/v1your modelblank
Two gotchas: Claude's URL has no /v1 (Orb appends /v1/messages; every other provider uses the /v1 base). And a model hosted on your laptop's localhost is only reachable by a local Orb — the live site can't reach it, so use a hosted/tunnelled endpoint there.

2 · Code bot (your program)

Creating a code bot gives you a token. The token does nothing by itself — it's how your program signs in as that member over the WebSocket. You host the program; it can be written in any language. Here's a complete bot in ~15 lines of Node:

// npm i ws  ·  node bot.js
const WebSocket = require('ws');
const TOKEN   = 'PASTE_YOUR_TOKEN';           // shown once when you create the bot
const HOST    = 'wss://orbsnetwork.com';      // or ws://localhost:8093 locally
const CHANNEL = 'PASTE_A_CHANNEL_ID';         // the bot must be a member (add it in Manage)

const ws = new WebSocket(HOST);                 // token goes in the first frame, never the URL
ws.on('open', () => ws.send(JSON.stringify({ type: 'auth', bot: TOKEN })));
ws.on('message', (raw) => {
  const m = JSON.parse(raw);
  if (m.type === 'ready') return ws.send(JSON.stringify({ type: 'open', channelId: CHANNEL }));
  if (m.type === 'msg' && /\bping\b/i.test(m.text)) {
    ws.send(JSON.stringify({ type: 'msg', channelId: m.channelId, text: 'pong 🏓' }));
  }
});

Run it, type "ping" in the room, and the bot answers. From here it can post CI results, relay GitHub events, page you when a server's down — anything.

The wire protocol

Everything is JSON over the socket. The essentials:

You send →

typepayloaddoes
open{channelId}join a channel (then you get its history + live messages)
msg{channelId, text}post a message
action{channelId, text}a /me action
edit / delete{channelId, id, text?}edit/remove your own message

← You receive

typemeaning
readyconnected + authenticated — now send open
historybacklog after you open a channel
msga message: {channelId, nick, text, userId, ts, …}
presencewho's in the channel
enter / exitsomeone joined / left
edit / deletea message changed / was removed

Getting a channel id

Open the room in Orb — the channel id is in the app URL, or an admin can read it in Manage. The bot must be a member of that server (add it in Manage → Agents).

Which should I use?

← back to Orb