Skip to content

Cell - Ta Channels ​

A built-in Ta package (enabled by default but can be toggled in the Web client's Settings → Packages): agents and channels. It is composed of three parts, none of which modify Ta's core:

  • Server side (pi.host, web-src/host.ts → host/index.mjs): ta serve runs it once in the same process. Teams, messages, and queues of pending answers are all managed and processed by it; forwarding happens on the server and continues even when the page is closed.
  • pi extension (pi.extensions, web-src/extension.ts → extension/index.mjs): adds team tools to Ta's sessions and obtains teams from the server via pi.events.
  • Web extension (pi.web, web-src/index.tsx → web/index.js): responsible only for display and initiating changes.

Concepts ​

  • Agent: a normal Ta session plus a name and responsibility (as appendSystemPrompt); the session name is the agent's name, and the session belongs to the @celljs/ta-channels group (folded into one row in the conversation list). Each agent has its own cartoon avatar (web-src/faces.tsx, with 16 shapes and color schemes stored in face; on creation, it tries to avoid duplicates with existing avatars; old data without face is assigned by id), blinks, and looks left and right while answering; Ta itself remains the Cell logo. The session file is recorded when first opened and reopened from the file next time. A session with an agent has no team tools.
  • Channel: members (agents, with the first being the lead) and messages. Messages are sent to members @-mentioned; agents' answers are posted back to the channel, and if they @ someone in their answer, it is passed on to them. Each agent processes one message at a time. Users can mute members in a channel (muted): they do not answer anything in this channel, even if @-mentioned; when the lead is muted, messages with no one @-mentioned go to the next unmuted member.
  • Loop prevention (ChannelsUtil.limit): relaying between agents is at most 3 hops; one message yields at most 8 answers, with at most 2 per agent. When cut off, after this round a light-colored note is appended to the channel ("reached relay limit, waiting for you to continue"), only once per round; the return from post_to_channel includes this note too.
  • Tools: each session in Ta (web pages and other clients connected to ta serve) has create_agent, create_channel, add_to_channel, post_to_channel, and list_channels. When a user specifies a goal ("assemble a team to do the landing page"), Ta creates agents and channels, posts the goal, and waits for answers from each member before replying to the user. When a role is missing from a channel, Ta uses add_to_channel to add an existing agent (added after existing members; lead unchanged). The open page marks this channel with a green dot in the sidebar, which disappears when opened. Pausing Ta just stops waiting; agents continue to answer in the channel.
  • UI: the "Agents" tab at the top of the sidebar (next to the "Conversations" tab) puts the double, channels, and agents together (the double is a built-in page from ta-web, and once enabled is listed at the top, no longer appears separately in the navigation bar); the search box and + are on the right of the tab. + → create agent opens a draft page in the main area: first assigns an unused name and avatar, clicking the name in the top bar can rename or pick from 16 avatars, the sidebar has one more line "not started"; the agent is truly created when the first message is sent from the input box (responsibility is generic, what to do is written in this message), then switches to its session and sends the message. + → create channel is a dialog: name, search and check agents (1–12, first checked is lead), create; channel row has lead first, next member in overlapping avatars, lead is labeled beside the name, second line is the most recent message or who's answering; agents are grouped by working directory, second line is "idle" or which channel they're answering in, right side is time of most recent message. Click agent to open its session (openAgent request, server opens or finds the session then pi.switchSession displays it as the current conversation). Hovering over agent row (long-press on touch) shows …, menu has: stop (abort its current answer), restart (open new session), rename, responsibility (edit the role in the system prompt, takes effect in next session), move to… (switch working directory, open new session in that directory), copy working directory, export conversation (Markdown, strip channel context blocks), add to channel, delete (leave all channels it's in, delete channels that only have it, keep the session file); when near the bottom the menu expands upward. Channel is a page in the main area (not in the right workbench), displayed as a group chat: others' messages on the left with avatar and name, user's on the right, consecutive messages are grouped, after a long pause insert a time line; top bar is channel name and member avatars, click avatar to open "Channel Members" (members, location: 'panel' view, follows the current channel) in the right workbench: lists members, lead has a marker, answering ones are marked green; each row opens that agent's session, hovering (long-press on touch) shows set as lead, mute, restart session (forget earlier conversation, open new session next time it answers, old session stays in conversation list), and remove from channel (at least one left); top has "Add Members" as a searchable agent list, check to add, bottom of list has "New Agent" to open the draft page for creating a new agent; bottom has delete channel (confirm once more, messages deleted too, ongoing answers no longer posted). Input box is the conversation input box (pi.ui.Composer), @ lists members, + allows naming members or adding members (opens the member list for adding); messages use the conversation's Markdown rendering (pi.ui.Markdown), @-mentioned members are bold.

Data and Forwarding ​

Data is stored on the server in <agentDir>/extension-data/@celljs/ta-channels.json; only the server writes to it. Each channel keeps the most recent 200 messages.

KeyContent
teamagents and channels
messages/<channel>messages in the channel
queuepending answers (job: which agent answers which message, how many hops, which round) and counts per round
workingagents currently answering
focuschannels Ta has created tools for or posted messages to; pages use this to mark them in the sidebar
requests/<id> / results/<id>requests initiated by the page (create agent, create channel, add channel member, set lead / mute / remove member, delete channel, restart agent session, modify or delete agent, post message as user, open agent session) and server's responses; pages only write requests/*

The page learns of changes via pi.storage.onChange and rereads them. Each answer is first recorded as a job in queue and removed only after the answer is posted to the channel. After ta serve restarts, it continues processing remaining jobs: jobs that already have an answer (the channel has this agent's reply to that message) are not asked again, and messages already forwarded are not forwarded again, so processed messages do not duplicate. On restart, the one message that was being answered and not yet posted is asked again.

Limitations ​

  • Only ta serve has teams: when running plain ta (CLI, without ta serve), the team tools still exist but calling them returns "ta serve required" and does not create or forward anything. When the package's server side fails to start, the tool explains the failure and asks to check ta serve's logs.
  • Messages with no @ to anyone (user or Ta) go to the lead, the first unmuted member of the channel; when an agent's answer has no @ to anyone, relay ends.
  • Changes on the page wait for server processing; when ta serve is not running or the package is disabled, operations on the page report "Ta service not responding" after 30 seconds.

Future ​

  • A task board can be another package, based on the same agents and channels.

Why Not in Core ​

pi's core only manages how one session runs; multi-session is provided by ta serve (openSession with appendSystemPrompt and group, prompt, getState, getLastAssistantText); the server part of the package runs on the host (pi.host). Agents and channels are just one product form of combining these concepts. Switching to another organization (task board, pipeline) makes another package, so it is an optional pi package like ones users build themselves. The core only provides host capabilities: loading and toggling built-in packages, the server part of packages, package server data and its change notifications.

Development ​

Source is in web-src/ with three entry points: index.tsx (page), host.ts (server), and extension.ts (pi extension); team.ts is the server-side team, channels.ts is what the page sees, and channels-util.ts is shared pure logic. bun run build first checks with tsc and outputs to lib/ (tests run lib/**/*.spec.js); then uses bun build to bundle the three entry points into separate files with no imports. React comes from the page (web-src/react.ts's bind(pi.React)), and icons use pi.ui.icons. End-to-end tests (faux models, real ta serve) are in apps/ta/test/builtin-packages.spec.ts.