16 KiB
WebSocket Team & Delegation Events
Complete reference for all WS events related to team operations, delegation lifecycle, and admin CRUD.
1. Overview
Events are emitted via msgBus.Broadcast(bus.Event{}) and forwarded to all connected WS clients by the gateway subscriber. The domain event bus (internal/eventbus) is internal-only and does not forward to WS clients.
Wire frame:
{"type": "event", "event": "<event_name>", "payload": { ... }}
2. Event Envelope
| Field | Type | Description |
|---|---|---|
type |
string | Always "event" |
event |
string | Event name (e.g. "delegation.started") |
payload |
object | Event-specific payload (see §3) |
3. Payload Base Types
Defined in pkg/protocol/team_events.go. Each event in §4 lists which base it uses plus any delta fields.
3.1 DelegationEventPayload
Used by: delegation.started/completed/failed/cancelled.
Fields: delegation_id, source_agent_id, source_agent_key, source_display_name?, target_agent_id, target_agent_key, target_display_name?, user_id, channel, chat_id, mode (async/sync), task?, team_id?, team_task_id?, status?, elapsed_ms?, error?, created_at.
{
"delegation_id": "a1b2c3d4",
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"source_display_name": "Default Agent",
"target_agent_id": "<target-agent-id>",
"target_agent_key": "content-writer",
"target_display_name": "Content Writer",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "<chat-id>",
"mode": "async",
"task": "Create Instagram image",
"team_id": "<team-id>",
"team_task_id": "<team-task-id>",
"status": "running",
"created_at": "2026-03-05T10:00:00Z"
}
3.2 DelegationProgressPayload
Used by: delegation.progress.
Fields: source_agent_id, source_agent_key, user_id, channel, chat_id, team_id?, active_delegations[] — each item: delegation_id, target_agent_key, target_display_name?, elapsed_ms, team_task_id?, activity? (thinking/tool_exec/compacting), tool?.
{
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "<chat-id>",
"team_id": "<team-id>",
"active_delegations": [
{"delegation_id": "a1b2c3d4", "target_agent_key": "content-writer", "elapsed_ms": 45000, "activity": "tool_exec", "tool": "create_image"}
]
}
3.3 DelegationAccumulatedPayload
Used by: delegation.accumulated.
Fields: delegation_id, source_agent_id, source_agent_key, target_agent_key, target_display_name?, user_id, channel, chat_id, team_id?, team_task_id?, siblings_remaining, elapsed_ms?.
{
"delegation_id": "a1b2c3d4",
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"target_agent_key": "content-writer",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "<chat-id>",
"team_id": "<team-id>",
"team_task_id": "<team-task-id>",
"siblings_remaining": 1,
"elapsed_ms": 45300
}
3.4 DelegationAnnouncePayload
Used by: delegation.announce.
Fields: source_agent_id, source_agent_key, source_display_name?, user_id, channel, chat_id, team_id?, results[] (agent_key, display_name?, has_media, content_preview?), completed_task_ids?[], total_elapsed_ms, has_media.
{
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"source_display_name": "Default Agent",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "<chat-id>",
"team_id": "<team-id>",
"results": [
{"agent_key": "content-writer", "display_name": "Content Writer", "has_media": true, "content_preview": "Created image..."},
{"agent_key": "copywriter", "has_media": false, "content_preview": "Wrote caption..."}
],
"completed_task_ids": ["<task-id-1>", "<task-id-2>"],
"total_elapsed_ms": 52000,
"has_media": true
}
3.5 TeamTaskEventPayload
Used by: all team.task.* events.
Fields: team_id, task_id, task_number?, subject?, status, owner_agent_key?, owner_display_name?, reason?, user_id, channel, chat_id, peer_kind? (group/direct), local_key?, timestamp, comment_text?, progress_percent?, progress_step?, actor_type? (agent/human/system), actor_id?.
{
"team_id": "<team-id>",
"task_id": "<task-id>",
"task_number": 5,
"subject": "Create Instagram image",
"status": "pending",
"owner_agent_key": "",
"user_id": "<user-id>",
"channel": "dashboard",
"chat_id": "<chat-id>",
"timestamp": "2026-03-05T10:00:00Z",
"actor_type": "human",
"actor_id": "<user-id>"
}
3.6 Team CRUD / Misc Payloads
TeamCreatedPayload (team.created): team_id, team_name, lead_agent_key, lead_display_name?, member_count.
TeamUpdatedPayload (team.updated): team_id, team_name, changes[].
TeamDeletedPayload (team.deleted): team_id, team_name.
TeamMemberAddedPayload (team.member.added): team_id, team_name, agent_id, agent_key, display_name?, role.
TeamMemberRemovedPayload (team.member.removed): team_id, team_name, agent_id, agent_key, display_name?.
TeamMessageEventPayload (team.message.sent): team_id, from_agent_key, from_display_name?, to_agent_key ("broadcast" for team broadcast), to_display_name?, message_type, preview, task_id?, user_id, channel, chat_id.
AgentLinkCreatedPayload (agent_link.created): link_id, source_agent_id, source_agent_key, target_agent_id, target_agent_key, direction, team_id?, status.
AgentLinkUpdatedPayload (agent_link.updated): link_id, source_agent_key, target_agent_key, direction?, status?, changes[].
AgentLinkDeletedPayload (agent_link.deleted): link_id, source_agent_key, target_agent_key.
4. Event Catalog
4.1 Delegation Events
| Event | Base | Delta Fields | Notes |
|---|---|---|---|
delegation.started |
DelegationEventPayload |
status="running" |
Lead initiates delegation to member |
delegation.completed |
DelegationEventPayload |
status="completed", +elapsed_ms |
Member completed successfully |
delegation.failed |
DelegationEventPayload |
status="failed", +elapsed_ms, +error |
Member failed |
delegation.cancelled |
DelegationEventPayload |
status="cancelled", +elapsed_ms |
Via /stopall, task cancel, or direct cancel |
delegation.progress |
DelegationProgressPayload |
— | Periodic (~30s) snapshot of all active async delegations |
delegation.accumulated |
DelegationAccumulatedPayload |
— | Member done but siblings still running; result held |
delegation.announce |
DelegationAnnouncePayload |
— | Last sibling done; all results returned to lead |
4.2 Team Task Events
| Event | Base | Delta Fields | Notes |
|---|---|---|---|
team.task.created |
TeamTaskEventPayload |
status="pending" |
New task (manual or via delegation) |
team.task.assigned |
TeamTaskEventPayload |
status="in_progress", +owner_agent_key |
Auto-assigned at creation or via teams.tasks.assign RPC |
team.task.dispatched |
TeamTaskEventPayload |
status="in_progress", +owner_agent_key |
Leader dispatches pending task to member |
team.task.claimed |
TeamTaskEventPayload |
status="in_progress", +owner_agent_key, +owner_display_name |
Reserved; not currently emitted |
team.task.progress |
TeamTaskEventPayload |
+progress_percent, +progress_step |
Member calls team_tasks(action="progress") |
team.task.reviewed |
TeamTaskEventPayload |
status="in_review", +owner_agent_key, +owner_display_name |
Member submits for review |
team.task.approved |
TeamTaskEventPayload |
status="completed" |
Human approves via dashboard |
team.task.rejected |
TeamTaskEventPayload |
status="cancelled", +reason |
Human rejects via dashboard |
team.task.completed |
TeamTaskEventPayload |
status="completed", +owner_agent_key, +owner_display_name |
Auto-completed by delegation or agent |
team.task.failed |
TeamTaskEventPayload |
status="failed", +reason, +owner_agent_key, +task_number, +subject |
Blocker escalation or system error |
team.task.cancelled |
TeamTaskEventPayload |
status="cancelled", +reason? |
Explicit cancel |
team.task.stale |
TeamTaskEventPayload |
status="stale", +reason |
No activity within timeout |
team.task.commented |
TeamTaskEventPayload |
+comment_text |
Blocker-type comment also auto-fails task + escalates lead |
team.task.updated |
TeamTaskEventPayload |
+changes[] |
Metadata update via team_tasks(action="update") |
team.task.deleted |
TeamTaskEventPayload |
status=<terminal> |
Hard-delete of terminal-status task |
team.task.attachment_added |
TeamTaskEventPayload |
+task_number, +subject |
File attached via team_tasks(action="attach") |
4.3 Team Leader Events
| Event | Payload | Notes |
|---|---|---|
team.leader.processing |
{agentId: string, tasks: int} |
Bridge: announce queue draining; fires before leader run.started. Emitted from cmd/gateway_subagent_announce_queue.go |
4.4 Team CRUD Events (Admin)
No routing context (user_id/channel/chat_id) — admin operations only.
| Event | Base |
|---|---|
team.created |
TeamCreatedPayload |
team.updated |
TeamUpdatedPayload |
team.deleted |
TeamDeletedPayload |
team.member.added |
TeamMemberAddedPayload |
team.member.removed |
TeamMemberRemovedPayload |
4.5 Agent Link Events (Admin)
| Event | Base |
|---|---|
agent_link.created |
AgentLinkCreatedPayload |
agent_link.updated |
AgentLinkUpdatedPayload |
agent_link.deleted |
AgentLinkDeletedPayload |
4.6 Workspace Events
| Event | Payload | Notes |
|---|---|---|
workspace.file.changed |
{team_id, chat_id, file_name, change_type, timestamp} |
Reserved — not currently emitted. change_type: created/modified/deleted |
4.7 Team Message Events
| Event | Base | Notes |
|---|---|---|
team.message.sent |
TeamMessageEventPayload |
to_agent_key="broadcast" for team-wide messages |
4.8 Agent Events (Delegation Context)
Agent events use top-level "event": "agent". The type field inside the payload is the subtype. When running inside a delegation, extra context fields are present.
Delegation-only fields: delegationId, teamId, teamTaskId, parentAgentId (lead agent key). Always-present when available: userId, channel, chatId. Distinguish lead vs member: parentAgentId absent = lead, present = member.
| Constant | Type | Description |
|---|---|---|
AgentEventRunStarted |
run.started |
Agent run begins |
AgentEventRunCompleted |
run.completed |
Agent run finished |
AgentEventRunFailed |
run.failed |
Agent run failed |
AgentEventRunCancelled |
run.cancelled |
Agent run cancelled |
AgentEventRunRetrying |
run.retrying |
Retrying after error |
AgentEventToolCall |
tool.call |
Tool invoked — name + call ID only (no args) |
AgentEventToolResult |
tool.result |
Tool done — name + call ID + is_error (no content) |
AgentEventBlockReply |
block.reply |
Block-level reply |
AgentEventActivity |
activity |
Phase: thinking, tool_exec, compacting |
| (chat) | chunk |
Streaming text fragment |
| (chat) | thinking |
Extended thinking content |
| (chat) | message |
Full message (non-streaming) |
When
Stream: true,chunk/thinkingemit incrementally. WhenStream: false(delegate runs), emit once with full content.
5. Correlation Rules
| Source Event | Correlated Event(s) | Key | Notes |
|---|---|---|---|
delegation.started |
delegation.completed/failed/cancelled |
delegation_id |
Lifecycle pair |
delegation.completed (async) |
delegation.accumulated → delegation.announce |
delegation_id, team_id |
Accumulated per member; announce once when last sibling done |
delegation.progress |
— | source_agent_id |
Groups all active delegations from same leader |
team.task.created |
team.task.assigned / team.task.dispatched |
task_id |
Assignment follows creation |
team.task.reviewed |
team.task.approved / team.task.rejected |
task_id |
Human review loop |
team.task.commented (blocker) |
team.task.failed |
task_id |
Blocker comment auto-fails task + escalates lead |
last team.task.completed (batch) |
team.leader.processing → leader run.started |
team_id, agentId |
Bridge: announce queue start → leader run |
agent run.started (member) |
agent run.completed/failed |
runId, delegationId |
Member run lifecycle |
6. Constants Reference
All event name constants are defined in pkg/protocol/events.go:
Delegation Lifecycle Events
| Constant | Event Name |
|---|---|
EventDelegationStarted |
delegation.started |
EventDelegationCompleted |
delegation.completed |
EventDelegationFailed |
delegation.failed |
EventDelegationCancelled |
delegation.cancelled |
EventDelegationProgress |
delegation.progress |
EventDelegationAccumulated |
delegation.accumulated |
EventDelegationAnnounce |
delegation.announce |
Team Task Lifecycle Events
| Constant | Event Name | Status |
|---|---|---|
EventTeamTaskCreated |
team.task.created |
Active |
EventTeamTaskClaimed |
team.task.claimed |
Reserved (not emitted) |
EventTeamTaskAssigned |
team.task.assigned |
Active |
EventTeamTaskDispatched |
team.task.dispatched |
Active |
EventTeamTaskCompleted |
team.task.completed |
Active |
EventTeamTaskCancelled |
team.task.cancelled |
Active |
EventTeamTaskApproved |
team.task.approved |
Active |
EventTeamTaskRejected |
team.task.rejected |
Active |
EventTeamTaskCommented |
team.task.commented |
Active |
EventTeamTaskDeleted |
team.task.deleted |
Active |
EventTeamTaskFailed |
team.task.failed |
Active |
EventTeamTaskReviewed |
team.task.reviewed |
Active |
EventTeamTaskProgress |
team.task.progress |
Active |
EventTeamTaskUpdated |
team.task.updated |
Active |
EventTeamTaskStale |
team.task.stale |
Active |
EventTeamTaskAttachmentAdded |
team.task.attachment_added |
Active |
EventTeamLeaderProcessing |
team.leader.processing |
Active |
Team CRUD Events
| Constant | Event Name |
|---|---|
EventTeamCreated |
team.created |
EventTeamUpdated |
team.updated |
EventTeamDeleted |
team.deleted |
EventTeamMemberAdded |
team.member.added |
EventTeamMemberRemoved |
team.member.removed |
Agent Link Events
| Constant | Event Name |
|---|---|
EventAgentLinkCreated |
agent_link.created |
EventAgentLinkUpdated |
agent_link.updated |
EventAgentLinkDeleted |
agent_link.deleted |
Workspace Events
| Constant | Event Name | Status |
|---|---|---|
EventWorkspaceFileChanged |
workspace.file.changed |
Reserved (future) |
Team Message Events
| Constant | Event Name |
|---|---|
EventTeamMessageSent |
team.message.sent |
Payload structs in pkg/protocol/team_events.go: DelegationEventPayload, DelegationProgressPayload, DelegationAccumulatedPayload, DelegationAnnouncePayload, TeamTaskEventPayload, TeamMessageEventPayload, TeamCreatedPayload, TeamUpdatedPayload, TeamDeletedPayload, TeamMemberAddedPayload, TeamMemberRemovedPayload, AgentLinkCreatedPayload, AgentLinkUpdatedPayload, AgentLinkDeletedPayload.