Run an agent turn
An async Space does not keep an agent process alive. A member posts a turn; the render opens the sealed room state, runs the agent, writes the reply, and goes cold again.
That is the core runtime loop.
The turn flow
turn with room key and message- A member sends
{ op:'turn', room, mk, message }. - The transport checks
commit(mk)against the Space record. - If the Space is gated, identity is verified against the sealed admission policy.
- The render opens the sealed ledger.
- The member entry is appended.
- The agent runs with the Space's persona and tools.
- The reply, widgets, files, or pending proposals are appended.
- The ledger is re-sealed and stored.
- The room key is dropped.
Read the deeper version in Async Spaces.
Minimal turn
const r = await client.turn(room, mk, {
from: 'Ada',
text: 'Summarize our plan and list the unresolved decisions.'
})
For an open Space, that is enough.
Signed member turns
A signed turn proves which admitted member wrote the entry. The client signs the entry core and sends the signature with the message. For an email-gated Space, the message also carries an ID token and the member signing public key.
Conceptually:
await client.turn(room, mk, {
text: 'I approve the itinerary.',
}, {
email: 'ada@example.com',
googleIdToken,
sign: { priv: memberPrivateKey, pub: memberPublicKey }
})
The render verifies the identity and stores only the verified attribution, not the raw ID token.
Tools during a turn
A Space's tools are declared in its sealed config. During a turn, the agent can call those tools. Tool outputs may become:
- plain text in the reply
- a shared widget such as a map, chart, diagram, itinerary, or flights card
- a file attached to the reply
- a pending proposal requiring human approval
High-stakes calls are not run directly. They become proposals under Delegated authority.
Reads after a turn
Clients normally watch a Space with pollSealed. When the sealed ledger changes, the client opens it locally and
renders the new entries.
const r = await client.pollSealed(room, mk, previousEtag, previousCount)
For gated Spaces, read operations also include the caller's identity so the server can refuse unauthorized reads before returning sealed content.
What plaintext exposure means
In the current production tier, the server-side render receives mk during turns. That is why the model can reason
over the Space. The key is request-scoped and dropped afterward, and storage remains ciphertext at rest.
This is not the same as "the operator can never see plaintext in use." The attested server tier is the path to making that stronger property checkable for production traffic; it is built and verifiable, but not yet serving ordinary Spaces.
Read: Status, The double blind, The attested tier
Code map
| Concern | File |
|---|---|
| HTTP turn op | agent/spaceHandler.mjs |
| Runtime service | agent/spaceService.mjs |
| Decrypt-once render | agent/asyncTurn.mjs |
| Agent tool loop | agent/brain.mjs, agent/brainTools.mjs |
| Delegated authority | agent/delegatedAuthority.mjs |
| Client turn wrapper | spaces/public/spaceClient.js |
Machine-readable source: agent-turns.md · every doc in one fetch: llms-full.txt (HTML) · ← create-space · tools-widgets →