AkurAI Build
Menu

popagent

public

Latest change 7f6c1d0ed24ffc264e50e9966eaf45024245ba71 - feat: add per-task agent communication by AkurAI Build

# Native channels

## Architecture

Popagent owns a shared channel implementation; it does not run IRC or treat a
Mastra Web adapter as a room. PostgreSQL is the durable source for channel
configuration, rooms, user messages, and task correlation. This release supports
only the seeded `general` room, displayed as `#general`; room CRUD is deliberately
deferred.

A channel post always names an existing repository workspace. Depending on the
persisted dispatch mode, every message or only `@popagent`/`@orchestrator`
mentions create a queued `popagent_agent_tasks` row in the same transaction as
the message. The existing task runtime and Mastra supervisor perform the work;
channels do not duplicate agent execution. Specialists remain internal to that
task. The `#general` history receives one concise Orchistrator-authored start
announcement for every task. User-dispatched tasks additionally project
iteration/tool updates and a terminal outcome as conversation messages. System
self-update and Build-maintenance workflow detail remains in the correlated task
card instead of being duplicated into durable chat messages; its live task
projection carries phase state, activity, final output, errors, retries, and
timestamps.

Successful task-agent sends and replies are also first-class durable `#general`
messages; they never create another task or enter the user dispatch path. Each
row retains the communication task, sender agent, recipient agent, current
display names, and optional reply message ID. The store accepts them only while
the named task is running, in that task's repository workspace, for the fixed
Popagent resource, and between persisted governed agent identities. Broadcast
persists one addressed row per successful recipient leg.

`ChannelEventBus` is the process-local real-time fan-out boundary. Posting,
settings changes, cancellation, task announcements, and task lifecycle
transitions publish typed channel events. Authenticated SSE clients subscribe at
`GET /api/channels/:id/events`, then refresh durable history when notified.
History remains authoritative after reconnect or process restart. Clients use
bounded polling when streaming is disabled and while active task progress is
changing. The SSE stream sends lightweight refresh notifications and 15-second
heartbeats; clients reconnect and resume from durable cursor-based history rather
than treating process-local events as a message store.
Agent communication persistence publishes the same typed `message` refresh
event after commit, so the existing SSE client reloads authoritative history
and its ID merge prevents duplicate rendering.

## API

- `GET /api/channels` lists configured rooms.
- `GET /api/channels/:id/messages?limit=&before=` returns chronological bounded
  history with a stable message cursor.
- `POST /api/channels/:id/messages` stores a user message and optionally creates
  and enqueues its durable task.
- `GET /api/channels/:id/events` streams typed message, task, and settings events.
- `POST /api/channels/:id/tasks/:taskId/cancel` cancels only a task correlated
  with that channel.
- `GET/PATCH /api/settings/channels` reads and updates enablement, room name,
  dispatch mode, context depth, streaming preference, and activity display.

Bodies, names, context depth, cursors, and history pages are bounded by route and
store schemas. Browser callers always use the fixed local author identity; future
adapters must supply identity only from authenticated adapter configuration, never
from an untrusted message body.

The versioned `channel-settings.sql` migrations seed configuration and
`#general` exactly once and add nullable task-agent communication metadata
without changing existing user-message or task-card rows. A deleted singleton
or room is not recreated after its migration marker exists. Channel messages
have no automatic retention or silent cleanup. Workspace deletion is blocked
while channel history references it; transcript/task correlation must not
disappear as a side effect of repository removal.

## UI

`/channels/general` is a reloadable shared workspace with history pagination,
repository selection, composer, connection state, task activity, cancellation,
outputs, errors, empty/disabled/failure states, and accessible live status.
Task-agent entries render both governed role identities, their assigned Company
people and avatars, the addressed recipient, and any reply relation in a
wrapping mobile-safe header. Existing user messages and correlated task cards
retain their prior rendering. Channels are available from primary navigation.
`/settings/channels` owns all persisted channel controls. Desktop uses the
normal workspace layout; mobile uses the existing navigation drawer and
safe-area composer treatment.

## Adapter boundary

Future Slack, Discord, or other Mastra Chat SDK adapters map an external
installation/channel/thread tuple to a Popagent channel ID and map the external
sender to `authorId`/`authorName`. Incoming text enters the same bounded post
contract with an explicitly mapped repository workspace. Task output is read
from the same correlated channel message and sent back to the external thread.
Adapters may translate external event delivery, but cannot bypass API auth,
workspace containment, persistence, dispatch policy, task cancellation, or the
supervisor runtime. Slack, Discord, and other adapters remain explicitly deferred
until a concrete installation exists.

## Contract ownership

- `src/channels.test.ts` — settings, atomic dispatch, pagination, bounds, and workspace-history references.
- `src/channels-api.test.ts` — route validation, dispatch policy, history, and cancellation.
- `src/channel-events.test.ts` — typed fan-out, SSE framing, heartbeat, and disconnect cleanup.
- `src/ui/channel-stream.test.ts` — client parsing, abort, reconnect, and polling fallback helpers.
- `src/task-agent-communication.test.ts` and
  `src/tools/agent-communication.test.ts` — task-scoped delivery, mailbox,
  broadcast, abort, terminal, identity-binding, and consume-once contracts.
- `src/ui/ChannelPage.test.tsx` — accessible agent/person/recipient/reply
  rendering.
- `src/ui/routes.test.ts` — durable channel and settings URLs.

Channel UI changes require desktop and mobile browser verification, including
connection, event delivery, cancellation, route-away cleanup, reconnect, and
polling fallback under `AGENTS_RULES.md`.