docs: condense ws-team-events to base+delta format

This commit is contained in:
viettranx
2026-04-19 15:31:58 +07:00
parent adc2a1fafe
commit d6ae866321
+177 -505
View File
@@ -1,625 +1,287 @@
# WebSocket Team & Delegation Events
Complete reference for all WS events related to team agent operations, delegation lifecycle, and admin CRUD.
Complete reference for all WS events related to team operations, delegation lifecycle, and admin CRUD.
All events are delivered as JSON frames via the WebSocket protocol:
---
## 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:
```json
{"type": "event", "event": "<event_name>", "payload": { ... }}
```
Events are emitted via `msgBus.Broadcast(bus.Event{})` and forwarded to all connected WS clients (filtered by gateway subscriber at `server.go`).
---
## 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) |
---
## Event Catalog
## 3. Payload Base Types
### Delegation Lifecycle Events
Defined in `pkg/protocol/team_events.go`. Each event in §4 lists which base it uses plus any delta fields.
#### `delegation.started`
Emitted when a lead agent initiates a delegation to a member agent.
### 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`.
```json
{
"delegation_id": "a1b2c3d4",
"source_agent_id": "019c839b-...",
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"source_display_name": "Default Agent",
"target_agent_id": "019ca748-...",
"target_agent_key": "tieu-la",
"target_display_name": "Tieu La",
"user_id": "user123",
"target_agent_id": "<target-agent-id>",
"target_agent_key": "content-writer",
"target_display_name": "Content Writer",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "-100123456",
"chat_id": "<chat-id>",
"mode": "async",
"task": "Create Instagram image for new product",
"team_id": "019c9503-...",
"team_task_id": "019ca84f-...",
"task": "Create Instagram image",
"team_id": "<team-id>",
"team_task_id": "<team-task-id>",
"status": "running",
"created_at": "2026-03-05T10:00:00Z"
}
```
#### `delegation.completed`
Emitted when a delegation finishes successfully.
### 3.2 DelegationProgressPayload
Same payload as `delegation.started` with:
- `status`: `"completed"`
- `elapsed_ms`: total duration in milliseconds
Used by: `delegation.progress`.
#### `delegation.failed`
Emitted when a delegation fails (agent error).
Same payload as `delegation.started` with:
- `status`: `"failed"`
- `error`: error message string
- `elapsed_ms`: total duration
#### `delegation.cancelled`
Emitted when a delegation is cancelled (via `/stopall`, team task cancel, or direct cancel).
Same payload as `delegation.started` with:
- `status`: `"cancelled"`
- `elapsed_ms`: total duration
#### `delegation.progress`
Emitted periodically (~30s) for active async delegations. Groups all active delegations from the same source agent.
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?`.
```json
{
"source_agent_id": "019c839b-...",
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"user_id": "user123",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "-100123456",
"team_id": "019c9503-...",
"chat_id": "<chat-id>",
"team_id": "<team-id>",
"active_delegations": [
{
"delegation_id": "a1b2c3d4",
"target_agent_key": "tieu-la",
"target_display_name": "Tieu La",
"elapsed_ms": 45000,
"team_task_id": "019ca84f-..."
},
{
"delegation_id": "e5f6g7h8",
"target_agent_key": "tieu-ngon",
"target_display_name": "Tieu Ngon",
"elapsed_ms": 30000,
"team_task_id": "019ca850-..."
}
{"delegation_id": "a1b2c3d4", "target_agent_key": "content-writer", "elapsed_ms": 45000, "activity": "tool_exec", "tool": "create_image"}
]
}
```
#### `delegation.accumulated`
Emitted when an async delegation completes but sibling delegations are still running. The result is accumulated and will be announced when all siblings finish.
### 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?`.
```json
{
"delegation_id": "a1b2c3d4",
"source_agent_id": "019c839b-...",
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"target_agent_key": "tieu-la",
"target_display_name": "Tieu La",
"user_id": "user123",
"target_agent_key": "content-writer",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "-100123456",
"team_id": "019c9503-...",
"team_task_id": "019ca84f-...",
"chat_id": "<chat-id>",
"team_id": "<team-id>",
"team_task_id": "<team-task-id>",
"siblings_remaining": 1,
"elapsed_ms": 45300
}
```
#### `delegation.announce`
Emitted when the last sibling delegation completes and all accumulated results are sent back to the lead agent.
### 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`.
```json
{
"source_agent_id": "019c839b-...",
"source_agent_id": "<source-agent-id>",
"source_agent_key": "default",
"source_display_name": "Default Agent",
"user_id": "user123",
"user_id": "<user-id>",
"channel": "telegram",
"chat_id": "-100123456",
"team_id": "019c9503-...",
"chat_id": "<chat-id>",
"team_id": "<team-id>",
"results": [
{
"agent_key": "tieu-la",
"display_name": "Tieu La",
"has_media": true,
"content_preview": "Created Instagram post image..."
},
{
"agent_key": "tieu-ngon",
"display_name": "Tieu Ngon",
"has_media": false,
"content_preview": "Wrote caption for you..."
}
{"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": ["019ca84f-...", "019ca850-..."],
"completed_task_ids": ["<task-id-1>", "<task-id-2>"],
"total_elapsed_ms": 52000,
"has_media": true
}
```
---
### 3.5 TeamTaskEventPayload
### Team Task Events
Used by: all `team.task.*` events.
#### `team.task.created`
Emitted when a new team task is created (manual or auto-created by delegation).
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?`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"team_id": "<team-id>",
"task_id": "<task-id>",
"task_number": 5,
"subject": "Create Instagram image",
"status": "pending",
"owner_agent_key": "",
"user_id": "user123",
"user_id": "<user-id>",
"channel": "dashboard",
"chat_id": "-100123456",
"chat_id": "<chat-id>",
"timestamp": "2026-03-05T10:00:00Z",
"actor_type": "human",
"actor_id": "user123"
"actor_id": "<user-id>"
}
```
#### `team.task.claimed`
Emitted when an agent claims a task (reserved for future use; not currently emitted).
### 3.6 Team CRUD / Misc Payloads
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "in_progress",
"owner_agent_key": "tieu-la",
"owner_display_name": "Tieu La",
"user_id": "user123",
"channel": "system",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:00:01Z"
}
```
**TeamCreatedPayload** (`team.created`): `team_id`, `team_name`, `lead_agent_key`, `lead_display_name?`, `member_count`.
#### `team.task.assigned`
Emitted when a task is assigned to an agent (either auto-assigned at creation or manually via `teams.tasks.assign` RPC).
**TeamUpdatedPayload** (`team.updated`): `team_id`, `team_name`, `changes[]`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "in_progress",
"owner_agent_key": "tieu-la",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:00:01Z",
"actor_type": "human",
"actor_id": "user123"
}
```
**TeamDeletedPayload** (`team.deleted`): `team_id`, `team_name`.
#### `team.task.completed`
Emitted when a task is completed (auto-completed by delegation or marked complete by agent).
**TeamMemberAddedPayload** (`team.member.added`): `team_id`, `team_name`, `agent_id`, `agent_key`, `display_name?`, `role`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "completed",
"owner_agent_key": "tieu-la",
"owner_display_name": "Tieu La",
"user_id": "user123",
"channel": "system",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:00:45Z"
}
```
**TeamMemberRemovedPayload** (`team.member.removed`): `team_id`, `team_name`, `agent_id`, `agent_key`, `display_name?`.
#### `team.task.cancelled`
Emitted when a task is cancelled. Separated from `team.task.completed` for correct semantics.
**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`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "cancelled",
"reason": "Task no longer needed",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:01:00Z"
}
```
**AgentLinkCreatedPayload** (`agent_link.created`): `link_id`, `source_agent_id`, `source_agent_key`, `target_agent_id`, `target_agent_key`, `direction`, `team_id?`, `status`.
#### `team.task.approved`
Emitted when a human approves a task via the dashboard (status becomes completed).
**AgentLinkUpdatedPayload** (`agent_link.updated`): `link_id`, `source_agent_key`, `target_agent_key`, `direction?`, `status?`, `changes[]`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "completed",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:02:00Z",
"actor_type": "human",
"actor_id": "user123"
}
```
#### `team.task.rejected`
Emitted when a human rejects a task via the dashboard (status becomes cancelled with reason).
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "cancelled",
"reason": "Image aspect ratio should be 4:5",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:02:30Z",
"actor_type": "human",
"actor_id": "user123"
}
```
#### `team.task.commented`
Emitted when a human or agent adds a comment to a task. For agent blocker comments, also triggers task failure and leader escalation (see below).
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:02:45Z",
"actor_type": "human",
"actor_id": "user123"
}
```
**Agent blocker comments** (type='blocker') trigger special handling:
- Comment is saved with `comment_type='blocker'`
- Task is auto-failed (transitions to failed status)
- `EventTeamTaskFailed` is emitted (see below)
- Lead agent receives escalation message via `system:escalation`
- Member's session is cancelled
#### `team.task.deleted`
Emitted when a terminal-status task is hard-deleted via the dashboard.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "completed",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:03:00Z",
"actor_type": "human",
"actor_id": "user123"
}
```
#### `team.task.failed`
Emitted when a task is auto-failed due to blocker escalation or system errors.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"task_number": 5,
"subject": "Create Instagram image",
"status": "failed",
"reason": "Blocked: Cannot find API documentation",
"owner_agent_key": "tieu-la",
"owner_display_name": "Tieu La",
"user_id": "user123",
"channel": "telegram",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:02:15Z",
"actor_type": "system",
"actor_id": "blocker-escalation"
}
```
#### `team.task.reviewed`
Emitted when a member submits a task for review via `team_tasks(action="review", task_id="...")`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "in_review",
"owner_agent_key": "tieu-la",
"owner_display_name": "Tieu La",
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:02:30Z",
"actor_type": "agent",
"actor_id": "tieu-la"
}
```
#### `team.task.progress`
Emitted when a member updates task progress via `team_tasks(action="progress", task_id="...", progress_percent=..., progress_step="...")`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"progress_percent": 50,
"progress_step": "Waiting for API response",
"user_id": "user123",
"channel": "system",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:02:00Z",
"actor_type": "agent",
"actor_id": "tieu-la"
}
```
#### `team.task.updated`
Emitted when task metadata (priority, description, etc.) is updated via `team_tasks(action="update", task_id="...", ...)`.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"changes": ["priority", "description"],
"user_id": "user123",
"channel": "dashboard",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:01:30Z",
"actor_type": "human",
"actor_id": "user123"
}
```
#### `team.task.stale`
Emitted when a task hasn't been updated within a timeout threshold and is marked as stale by the system.
```json
{
"team_id": "019c9503-...",
"task_id": "019ca84f-...",
"status": "stale",
"reason": "No activity for 7 days",
"user_id": "user123",
"channel": "system",
"chat_id": "-100123456",
"timestamp": "2026-03-05T10:00:00Z",
"actor_type": "system",
"actor_id": "stale-detector"
}
```
**AgentLinkDeletedPayload** (`agent_link.deleted`): `link_id`, `source_agent_key`, `target_agent_key`.
---
### Workspace Events
## 4. Event Catalog
#### `workspace.file.changed`
Emitted when a file in a team's workspace directory is created, modified, or deleted. This event is reserved for future implementation; not currently broadcasted.
### 4.1 Delegation Events
```json
{
"team_id": "019c9503-...",
"chat_id": "-100123456",
"file_name": "project/notes.md",
"change_type": "created",
"timestamp": "2026-03-05T10:00:00Z"
}
```
| 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 |
**Potential field values:**
- `change_type`: `"created"`, `"modified"`, `"deleted"`
### 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")` |
### Team Message Events
### 4.3 Team Leader Events
#### `team.message.sent`
Emitted when an agent sends a message to another agent or broadcasts to the team.
| 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` |
```json
{
"team_id": "019c9503-...",
"from_agent_key": "default",
"from_display_name": "Default Agent",
"to_agent_key": "tieu-la",
"to_display_name": "Tieu La",
"message_type": "chat",
"preview": "Please create an Instagram image...",
"task_id": "",
"user_id": "user123",
"channel": "telegram",
"chat_id": "-100123456"
}
```
### 4.4 Team CRUD Events (Admin)
For broadcast messages: `to_agent_key = "broadcast"`, `to_display_name = ""`.
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` |
### Team CRUD Events (Admin)
### 4.5 Agent Link Events (Admin)
These events are emitted from RPC handlers when teams are managed via the Web UI. No routing context (user_id/channel/chat_id) since these are admin operations.
| Event | Base |
|-------|------|
| `agent_link.created` | `AgentLinkCreatedPayload` |
| `agent_link.updated` | `AgentLinkUpdatedPayload` |
| `agent_link.deleted` | `AgentLinkDeletedPayload` |
#### `team.created`
```json
{
"team_id": "019c9503-...",
"team_name": "Content Team",
"lead_agent_key": "default",
"lead_display_name": "Default Agent",
"member_count": 3
}
```
### 4.6 Workspace Events
#### `team.updated`
```json
{
"team_id": "019c9503-...",
"team_name": "Content Team",
"changes": ["settings"]
}
```
| Event | Payload | Notes |
|-------|---------|-------|
| `workspace.file.changed` | `{team_id, chat_id, file_name, change_type, timestamp}` | Reserved — not currently emitted. `change_type`: `created`/`modified`/`deleted` |
#### `team.deleted`
```json
{
"team_id": "019c9503-...",
"team_name": "Content Team"
}
```
### 4.7 Team Message Events
#### `team.member.added`
```json
{
"team_id": "019c9503-...",
"team_name": "Content Team",
"agent_id": "019ca748-...",
"agent_key": "tieu-la",
"display_name": "Tieu La",
"role": "member"
}
```
| Event | Base | Notes |
|-------|------|-------|
| `team.message.sent` | `TeamMessageEventPayload` | `to_agent_key="broadcast"` for team-wide messages |
#### `team.member.removed`
```json
{
"team_id": "019c9503-...",
"team_name": "Content Team",
"agent_id": "019ca748-...",
"agent_key": "tieu-la",
"display_name": "Tieu La"
}
```
### 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.
### Agent Events (Delegation Context)
`AgentEvent` payloads (broadcast as `"event": "agent"`) now include optional delegation and routing context:
**`tool.call` example** (member agent inside delegation):
```json
{
"type": "tool.call",
"agentId": "tieu-la",
"runId": "delegate-a1b2c3d4",
"delegationId": "a1b2c3d4",
"teamId": "019c9503-...",
"teamTaskId": "019ca84f-...",
"parentAgentId": "default",
"userId": "user123",
"channel": "telegram",
"chatId": "-100123456",
"payload": {"name": "create_image", "id": "call_xxx"}
}
```
**`tool.result` example:**
```json
{
"type": "tool.result",
"agentId": "tieu-la",
"runId": "delegate-a1b2c3d4",
"delegationId": "a1b2c3d4",
"teamId": "019c9503-...",
"teamTaskId": "019ca84f-...",
"parentAgentId": "default",
"userId": "user123",
"channel": "telegram",
"chatId": "-100123456",
"payload": {"name": "create_image", "id": "call_xxx", "is_error": false}
}
```
> **Note:** Tool arguments and result content are intentionally omitted from payloads to avoid leaking sensitive data over WS. Only tool name, call ID, and error status are included.
**Agent event subtypes** (the `type` field inside the payload):
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 successfully |
| `AgentEventRunCompleted` | `run.completed` | Agent run finished |
| `AgentEventRunFailed` | `run.failed` | Agent run failed |
| `AgentEventRunRetrying` | `run.retrying` | Agent run retrying after error |
| `AgentEventToolCall` | `tool.call` | Agent calling a tool |
| `AgentEventToolResult` | `tool.result` | Tool execution completed |
| *(chat events)* | `chunk` | Streaming text chunk |
| *(chat events)* | `thinking` | Extended thinking content |
| `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) |
**Note:** When `Stream: true`, `chunk` and `thinking` are emitted incrementally (one event per streamed fragment). When `Stream: false` (e.g. delegate runs), they are emitted as a single event containing the full content after the LLM response is received. Both paths carry full delegation context.
Fields present only when the agent is running inside a delegation:
- `delegationId` — correlation ID for this delegation
- `teamId` — team scope (if team-based)
- `teamTaskId` — associated team task
- `parentAgentId` — lead agent key that initiated the delegation
Fields always present when available:
- `userId` — scoped user ID (group chats: `"group:{channel}:{chatID}"`)
- `channel` — origin channel (telegram, discord, web, etc.)
- `chatId` — origin chat/conversation ID
Client can distinguish lead vs member agent events:
- `parentAgentId` absent → lead agent event
- `parentAgentId` present → member agent event (delegation)
> When `Stream: true`, `chunk`/`thinking` emit incrementally. When `Stream: false` (delegate runs), emit once with full content.
---
## Event Flow Timeline
## 5. Correlation Rules
```
User sends "Create Instagram post" to Default Agent (lead)
|
v
[agent] run.started agentId=default
[agent] chunk agentId=default, content="Let me assign..."
[agent] tool.call agentId=default, tool=delegate
|
|-- [delegation.started] target=tieu-la, task="Create image", mode=async
|-- [delegation.started] target=tieu-ngon, task="Write caption", mode=async
|
| (member agents run in parallel)
|
|-- [agent] run.started agentId=tieu-la, delegationId=xxx, parentAgentId=default
|-- [agent] run.started agentId=tieu-ngon, delegationId=yyy, parentAgentId=default
|
|-- [agent] tool.call agentId=tieu-la, tool=create_image, delegationId=xxx
|-- [agent] tool.result agentId=tieu-la, delegationId=xxx
|
|-- [delegation.progress] active=[{tieu-la, 30s}, {tieu-ngon, 30s}]
|
|-- [agent] run.completed agentId=tieu-la, delegationId=xxx
|-- [delegation.completed] target=tieu-la, elapsed_ms=35000
|-- [delegation.accumulated] target=tieu-la, siblings_remaining=1
|
|-- [agent] run.completed agentId=tieu-ngon, delegationId=yyy
|-- [delegation.completed] target=tieu-ngon, elapsed_ms=42000
|-- [delegation.announce] results=[{tieu-la, has_media}, {tieu-ngon}]
|
| (lead receives announce, processes results)
|
|-- [agent] run.started agentId=default
|-- [agent] chunk agentId=default, content="Here are the results..."
+-- [agent] run.completed agentId=default
```
| 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 |
---
## Constants Reference
## 6. Constants Reference
All event name constants are defined in `pkg/protocol/events.go`:
@@ -640,6 +302,7 @@ All event name constants are defined in `pkg/protocol/events.go`:
| `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 |
@@ -651,6 +314,8 @@ All event name constants are defined in `pkg/protocol/events.go`:
| `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 |
@@ -661,6 +326,13 @@ All event name constants are defined in `pkg/protocol/events.go`:
| `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 |
|----------|-----------|--------|
@@ -671,4 +343,4 @@ All event name constants are defined in `pkg/protocol/events.go`:
|----------|-----------|
| `EventTeamMessageSent` | `team.message.sent` |
**Payload structs:** Typed payloads are defined in `pkg/protocol/team_events.go` (e.g., `TeamTaskEventPayload`, `DelegationEventPayload`, etc.).
**Payload structs** in `pkg/protocol/team_events.go`: `DelegationEventPayload`, `DelegationProgressPayload`, `DelegationAccumulatedPayload`, `DelegationAnnouncePayload`, `TeamTaskEventPayload`, `TeamMessageEventPayload`, `TeamCreatedPayload`, `TeamUpdatedPayload`, `TeamDeletedPayload`, `TeamMemberAddedPayload`, `TeamMemberRemovedPayload`, `AgentLinkCreatedPayload`, `AgentLinkUpdatedPayload`, `AgentLinkDeletedPayload`.