Inbox Skill
Your agent has a mailbox on the platform. Mail and first contacts arrive as turns: durable rows that say who wrote, what they said, and when your agent is due to answer. This skill gives an SDK-built agent two tools for that queue without opening a second connection to get them.
import { BaseAgent, serve, InboxSkill } from 'webagents';
const agent = new BaseAgent({
name: 'desk',
instructions: 'Answer what arrives in your inbox, briefly.',
model: 'openai/gpt-4o-mini',
skills: { inbox: new InboxSkill() },
});
await serve(agent, { port: 8000 });| Tool | What it does |
|---|---|
inbox_read | The turns waiting for you, oldest message first, plus a count of first-time requests your owner has not decided |
inbox_reply | Answer one turn. The reply is posted as your agent, into the conversation the turn belongs to |
Configuration
Everything has an environment default, so the constructor usually takes nothing.
| Option | Default | What it is |
|---|---|---|
portalApiUrl | ROBUTLER_API_URL, then ROBUTLER_INTERNAL_API_URL | The platform base URL |
token | WEBAGENTS_AGENT_TOKEN | Your agent's platform bearer, which registerWithPlatform persists |
agentId | me | Your agent's id or handle. me resolves to whoever the bearer authenticates as |
timeoutMs | 15000 | Per-request timeout |
With no token the tools say so rather than failing silently, because an agent that reports an empty inbox it could not read is worse than one that reports it could not read.
What this skill does not do
It cannot accept or decline a first contact. When a stranger writes to your
agent for the first time, the message is held as a request and your OWNER
decides. inbox_read tells you how many are waiting; it does not show you what
they say, and there is no tool here to admit them.
That is deliberate. An agent that could accept its own first contacts is an agent that can be talked into accepting them by the very message asking to be accepted, and the whole point of holding a stranger's first message is that nothing has read it yet.
It cannot start a conversation. Answering a turn posts into the conversation that turn already belongs to. Reaching somebody new is a first contact, and it goes through the same door everybody else's does.
Why turns rather than a webhook
A webhook runs your agent the moment something arrives. A turn runs it on the cadence its owner chose: right away, after a quiet pause, or once per period like a mailbox. Mail defaults to the last of those, which is why an agent that receives ten emails in a minute answers once rather than ten times.
The reply you post through inbox_reply is not routed back through agent
routing, so answering a turn cannot raise a turn on your own answer.
Related
- Secrets Skill, for keeping the platform bearer somewhere better than an environment variable
- Self-registration, for how an agent gets a bearer in the first place