Portal
A workspace where your team, or your client's team, talks to the agents you built. Declare the sections, channels, views, and workflows it holds; Swirls hosts the shell.
What it is. A dedicated workspace over your deployment: a sidebar of rooms and reports, a shared timeline where people talk to your agents, and launchers for the workflows they can run. You declare what it holds. Swirls builds and hosts the shell.
Use it when the people who need your system are not the people who wrote it. A support team needs the triage agent and the open-tickets report, not a builder console. An MSP hands a client team a branded workspace instead of a login to the internals.
Works with agents (through channel blocks), views, and workflows. A portal block references channels, views, and workflows declared anywhere in your project; nothing is defined inside the portal itself.
A deployment already describes a complete system: agents that reason, workflows that run, views over the data they produce. A portal block turns that description into a place people actually work: a fixed, high-quality shell your team opens every day, with your rooms, your reports, and your requests in it. Add a view block to your files, reference it from a section, and the portal grows a report. The workspace stays in sync with the system because it reads straight from what you deployed.
Declaring a portal
channel support {
platform: portal
agent: triage
}
channel finance {
platform: portal
agent: finance_guy
}
portal client_portal {
label: "Acme Operations"
brand {
accent: "#B33A2B"
logo: "https://acme.com/logo.svg"
theme: "github-light"
}
section "Talk to the team" {
channel: support
channel: finance
}
section "Reports" {
view: open_tickets { label: "Open tickets" }
view: weekly_summary { label: "Weekly summary" }
}
section "Requests" {
workflow: refund_request { label: "Request a refund" }
}
}| Field | Required | Description |
|---|---|---|
label | Yes | Quoted string. The workspace name your team sees. |
brand | No | Block with presentation hints: accent, logo, and theme. |
section | Yes, at least one | section "<Title>" { }. An ordered group in the sidebar holding channel, view, and workflow references. |
Rooms: channel blocks with platform: portal
A portal never defines agents itself. It references channel blocks, and a channel with platform: portal is a room: a shared conversation where every member of your team can post and the agent behind it is a member too.
agent triage {
label: "Triage"
provider: openrouter
model: "openai/gpt-4o-mini"
}
channel support {
label: "Support"
platform: portal
agent: triage
mode: mention
}| Field | Required | Description |
|---|---|---|
platform | Yes | Set to portal for a room. |
agent | Yes | The agent that answers in this room. |
mode | No | mention (default) or all. Controls when the agent joins the conversation. |
mode: mention keeps the agent quiet until someone tags it in the composer. mode: all has the agent respond to every top-level message in the room; a reply inside a thread still needs a tag, so a side conversation under one message does not pull the agent into every line.
Every agent behind a portal room also gets a private one-on-one conversation with each teammate, automatically. You never declare a DM: it comes with the room. In a DM, every message reaches the agent.
Reference the room from a section by name:
section "Talk to the team" {
channel: support
}Reports: view references
A section can reference any view in your project. Your team sees it rendered as a live table, with the label you give it (or the view's own label, or a prettified version of its name if you set neither):
section "Reports" {
view: open_tickets { label: "Open tickets" }
}Requests: workflow references
A section can reference any workflow. Your team sees a launcher with an input form derived from the workflow's trigger, plus a timeline of recent runs:
section "Requests" {
workflow: refund_request { label: "Request a refund" }
}Brand
brand carries presentation hints:
| Field | Description |
|---|---|
accent | Accent color, as a CSS color string. |
logo | URL of a logo image. |
theme | One of a curated set of syntax-derived themes, including a Swirls default light/dark pair. Sets the whole workspace's color palette, not just a syntax highlighter. |
Without a brand block, the portal renders in the Swirls default theme.
What your team sees
Open the portal and you get a sidebar with the sections you declared, in the order you declared them. Rooms show a shared timeline: everyone's messages, the agent's replies, and who said what. Reports show a live table over your view's rows. Requests show a form built from the workflow's inputs, with a history of past runs underneath.
Nothing you did not reference is visible. A portal only shows the channels, views, and workflows its sections name; everything else in your project stays invisible to the people using it.
Reserved fields
domain and audience parse inside a portal block but are rejected by the validator: they are reserved for portals with external, non-member audiences at their own domain, a capability still in progress. Files that use them fail loudly with a clear diagnostic rather than deploying with a field that silently does nothing.
Deploying
A portal block ships with your deployment like every other primitive. Push with git push or deploy with swirls deploy; either path lands the same portal. No CI/CD to maintain.
Opening it
The portal is its own site, separate from the dashboard. From the dashboard, open your project and select Portal in the sidebar; it takes you to the same workspace your team uses, at its own address on portal.swirls.ai. Share that address with your team directly: members sign in with their Swirls account and land in the workspace without passing through the dashboard. If a project declares more than one portal, append ?portal=<name> to the project link to choose which one opens.
Further reading
- Channels: the full
channelblock reference, including the other platforms a channel can bind to - Views: the table-shaped data surface a portal's reports read
- Workflows: what a portal's requests launch
- Agents: the actors behind every portal room
- Syntax: the
portalblock's place among top-level declarations