Skip to content

Access tiers

Every message that starts a turn comes from a speaker, and every speaker has a tier. There are three tiers, from most to least trusted: owner, admin, and member. A person who holds none of them is nobody: the bot does not answer and starts no turn.

With no speakers setting, only the owner can talk to the agents. The owner is the person whose Discord user id is owner.id, and there is exactly one. Bots are ignored, and so is every channel the agent server does not own: only the agents’ and groups’ channels get answers.

List people under speakers in roundtable.config.ts. Each tier takes user ids, role ids, or everyone:

export default {
// ...
owner: { id: env("OWNER_ID"), name: "Ada" },
speakers: {
admins: { users: ["<user id>"] },
members: { roles: ["<role id>"] },
},
} satisfies RoundtableConfig;
Field Type Meaning
users list of strings Discord user ids.
roles list of strings Discord role ids. Anyone who holds one of these roles in the server qualifies.
everyone boolean When true, every person qualifies.

A person gets the highest tier they qualify for: the owner first, then admins, then members. The code accepts everyone under both admins and members. Under admins it would make every person who writes in an agent channel an admin, so use it under members at most.

A tool is offered to a speaker only when the speaker’s tier is at least the tool’s minimum tier. The table shows the tiers that the core and the built-in addons declare. The agent tools reference lists every tool with its tier.

Tier Can use
member Talk to the agents and answer their own questions. Read attachments. List and read agents (agent_list, agent_get), read channels (channel_read), and message agents (message_agent). Use memory (memory_add, memory_search, memory_remove) and list schedules (schedule_list).
admin Everything a member can, plus create and edit agents and groups, archive them, arrange channels, change skills and agent skills, create and change schedules, and delegate tasks.
owner Everything else: the shell and file tools, notify_owner, the discord_* administration tools, every plugin tool that does not declare a lower tier, and the /roundtable slash command.

A few points follow from this:

  • Each speaker has a memory of their own, shared by all agents. A member’s memory_add never writes to the owner’s memory.
  • The stop button on a long turn answers only the owner.
  • A held action, such as a destructive shell command, waits for approval on a card. By default only the owner can answer it. If you lower the tool’s tier with toolTiers, speakers at that tier or above can approve it as well, and the card says Who can approve: <tier> and above.
  • A question an agent asks with ask_user can be answered by the speaker whose turn asks it, and by the owner.

toolTiers sets the lowest tier that may use a tool, by tool name:

export default {
// ...
toolTiers: {
delegate_task: "member",
memory_remove: "admin",
},
} satisfies RoundtableConfig;

The setting wins over everything else. Without it, a tool needs the tier its plugin declared; failing that, the core’s default; and a tool nobody named needs the owner. Each value must be "owner", "admin", or "member".

Every speaker other than the owner, whether an admin or a member, gets the guest prompt instead of the shared prompt. The agent also receives a section that names the speaker, their Discord user id, and their tier, and tells it to address them, to take their answers and approvals, and that tools above their tier are not available this turn. Their messages reach the agent prefixed with (Message from <name>, at the <tier> tier.).

Set the guest prompt with a file path, next to the shared prompt:

export default {
// ...
prompts: {
shared: "./persona/shared.md",
guest: "./persona/guest.md",
},
} satisfies RoundtableConfig;

Both files are read once, at start. An unreadable or empty file stops the start and names the key, for example config prompts.guest: <path> is empty. Write the prompt in it.

Without prompts.guest, a guest prompt bundled with the package is used. It tells the agent that the person is a guest of the server, that it does not speak for the owner, that the owner’s private facts stay the owner’s, and that what it stores in memory is the guest’s alone.