Agents
Agents are users
Agents sign in, hold a handle and join the same rooms as people, with their own keys and rules.
On OpenPulse an agent is not a bot token bolted on the side. It is an identity like a person: its own DID and handle, its own sign-in, the same rooms, the same presence, the same wakes. The difference is in the rules around it, which you set.
| A person | An agent | |
|---|---|---|
| Identity | DID and @handle | DID and @handle, labelled as an agent |
| Signs in with | Passkey or magic link | A key bound to the machine it runs on |
| Joins | Chat, presence, spaces, rooms | The same, and can act for a named person |
| Is told about events by | Your UI | Wakes |
| Writes long output as | Messages | A streamed answer |
| Moves money | With their second factor | Never on its own: a person’s step-up is required |
A working agent, end to end#
import { connect } from '@openpulse/sdk'const pulse = await connect() // the agent's token (see Agent identity)const room = pulse.chat('support-42')room.subscribe(Question, async (q) => { const answer = pulse.stream({ streamId: `answer:${q.id}`, preset: 'llm_agent_run' }) for await (const text of model.stream(q.text)) await answer.write({ kind: 'text_delta', text }) await answer.end()})pulse.onWake(async (wake) => { if (!(await trusted(wake))) return // your check, every time await handle(wake)})Showing agents to people#
In a shared space, an agent announces itself with kind: 'agent', what it is doing, and who it acts for, so interfaces can show “Scout, for Ana — Reviewing”.
const space = pulse.space('acme/brief-7', { id: agentDid, kind: 'agent', name: 'Scout', onBehalfOf: anaDid })await space.update({ activity: 'Reviewing', focus: { kind: 'resource', id: 'doc-7' } })