bots-garden/sidekickspublic Fork
⑂ feature/m2-chat
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/sidekicks.git
git clone ssh://git@rickub.com/bots-garden/sidekicks.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 6713ff0 · on feature/m2-chat · k33g · 3d ago
agents-and-events.md · 106 lines · 6.2 KBmarkdown
Blame HistoryOpen raw

Reference: agent states and events

Agent states

State Shown as Meaning
stopped stopped No process. The initial state of every agent.
starting starting… The process is launched and the ACP handshake (initialize) is in progress.
ready ready Running and idle.
busy busy Running and used by at least one conversation.
error error The start failed, or the process exited on its own (crash). The status carries the reason, followed by the agent's last stderr lines for a failed start.

outdated (shown as "restart to apply changes") is set on a running agent whose definition changed in the configuration; a restart applies it.

Transitions

From Event To
stopped, error start requested (▶ in the Agents panel, or first use) starting
starting handshake succeeds ready
starting handshake fails, protocol other than ACP v1, timeout (30 s) error
ready used busy
busy last user done ready
ready, busy stop requested (■), application quits, agent removed from the configuration stopped
ready unused for limits.stopIdleAgentsAfter (checked every 30 s) stopped
ready another agent must start and this one is the least recently used idle agent stopped
ready, busy the process exits on its own error (never restarted automatically)
starting stop requested stopped once the start ends

When limits.maxRunningAgents agents are running and all are busy, a start is refused with the message too many agents running: N agent(s) busy (…), the limit is N.

Stopping an agent closes its stdin, waits 5 seconds, then kills its process group (the agent and what it started, such as mm under scripts/agents.sh).

Events from Go to the interface

Event Payload Sent when
config:changed {path, valid, problems[]} The configuration file was saved and reloaded (valid or not).
agent:state {agent, state, error?} An agent changes state or its definition changes.
agent:log {agent, line} An agent writes a line on its standard error.

The Go names and types are in internal/events; the TypeScript constants and types are generated in frontend/bindings/events and frontend/bindings/…/internal/events.

Services called by the interface

Service Method Effect
AgentService List() Every agent with name, title, icon, description, state, error, outdated, in configuration order.
Start(name), Stop(name), Restart(name) As in the transitions above; an error is returned to the interface.
Logs(name) The last 200 stderr lines of the agent.
ConfigService Current() path, source, created, valid, problems[], warnings[], theme, language, channels[].

Conversations (milestone M2)

One conversation per agent, kept in memory until the application quits or another configuration is opened.

Messages

Field Meaning
id, agent, createdAt identity
role user, agent or system
parts text (Markdown), thought (reasoning), tool (a tool call), plan (plan entries)
done false while an agent message streams
queued a user message waiting for the current answer
stopReason how an agent message ended: end_turn, cancelled, max_tokens, max_turn_requests, refusal
error why an agent message ended without a stop reason (the agent's own explanation), or cancelled for a queued message dropped by Stop
code system messages: agent-restarted (new session, the agent forgot the beginning), agent-unavailable (could not start or reach it; error says why)

A tool call has id, title, kind (read, edit, delete, move, search, execute, think, fetch, other), status (pending, in_progress, completed, failed), input (compact JSON), output, locations, diffs (path, oldText, newText, newFile).

Events

Event Payload Sent when
message:updated {agent, message} a message is added, or finished
message:delta {agent, messageId, index, kind, text?, part?} text is appended to the part at index (text, thought), or part replaces it (tool, plan)
turn:changed {agent, busy, queued} the agent starts or stops answering; queued messages wait
permission:requested {id, agent, messageId, toolCall, options[], rejections} the agent asks to run a tool; rejections counts the refusals already given in this turn
permission:resolved {id, agent} the request was answered, or cancelled by Stop
usage:changed {agent, usage: {used, size}} the agent reported its context window use (size is 0 when unknown)

ChatService

Method Effect
Send(agent, text) Adds a user message and returns its id; starts the agent if needed; queues the message if the agent is answering. Empty text and unknown agents are errors.
Cancel(agent) Stops the current answer (session/cancel), answers pending permission requests "cancelled", drops the queued messages.
AnswerPermission(id, optionId) Answers a pending request with one of its options.
Conversation(agent) The whole conversation: messages, busy, queued, usage, commands, permissions.

Settings methods of ConfigService

Method Effect
Content() The text of the configuration file.
Validate(text) The problems and warnings of text, with line, column, message, warning, without saving.
Save(text) Writes text if it is valid; otherwise returns its problems and writes nothing.
Schema() The configuration JSON Schema.
Open(path) Stops every agent, forgets the conversations, loads and watches path, remembers it.
Choose() Shows the native file dialog and opens the chosen file; returns "" when cancelled.
Recent() The configuration files opened from the application, most recent first (8 at most).

Stopping an agent

The agent's stdin is closed; after 5 s the agent and its children get SIGTERM (time for scripts/agents.sh to unload the model); after 3 more seconds, SIGKILL.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
# Reference: agent states and events

## Agent states

| State | Shown as | Meaning |
| --- | --- | --- |
| `stopped` | stopped | No process. The initial state of every agent. |
| `starting` | starting… | The process is launched and the ACP handshake (`initialize`) is in progress. |
| `ready` | ready | Running and idle. |
| `busy` | busy | Running and used by at least one conversation. |
| `error` | error | The start failed, or the process exited on its own (crash). The status carries the reason, followed by the agent's last stderr lines for a failed start. |

`outdated` (shown as "restart to apply changes") is set on a running agent whose definition changed in the configuration; a restart applies it.

## Transitions

| From | Event | To |
| --- | --- | --- |
| `stopped`, `error` | start requested (▶ in the Agents panel, or first use) | `starting` |
| `starting` | handshake succeeds | `ready` |
| `starting` | handshake fails, protocol other than ACP v1, timeout (30 s) | `error` |
| `ready` | used | `busy` |
| `busy` | last user done | `ready` |
| `ready`, `busy` | stop requested (■), application quits, agent removed from the configuration | `stopped` |
| `ready` | unused for `limits.stopIdleAgentsAfter` (checked every 30 s) | `stopped` |
| `ready` | another agent must start and this one is the least recently used idle agent | `stopped` |
| `ready`, `busy` | the process exits on its own | `error` (never restarted automatically) |
| `starting` | stop requested | `stopped` once the start ends |

When `limits.maxRunningAgents` agents are running and all are `busy`, a start is refused with the message `too many agents running: N agent(s) busy (…), the limit is N`.

Stopping an agent closes its stdin, waits 5 seconds, then kills its process group (the agent and what it started, such as `mm` under `scripts/agents.sh`).

## Events from Go to the interface

| Event | Payload | Sent when |
| --- | --- | --- |
| `config:changed` | `{path, valid, problems[]}` | The configuration file was saved and reloaded (valid or not). |
| `agent:state` | `{agent, state, error?}` | An agent changes state or its definition changes. |
| `agent:log` | `{agent, line}` | An agent writes a line on its standard error. |

The Go names and types are in `internal/events`; the TypeScript constants and types are generated in `frontend/bindings/events` and `frontend/bindings/…/internal/events`.

## Services called by the interface

| Service | Method | Effect |
| --- | --- | --- |
| `AgentService` | `List()` | Every agent with `name, title, icon, description, state, error, outdated`, in configuration order. |
| | `Start(name)`, `Stop(name)`, `Restart(name)` | As in the transitions above; an error is returned to the interface. |
| | `Logs(name)` | The last 200 stderr lines of the agent. |
| `ConfigService` | `Current()` | `path, source, created, valid, problems[], warnings[], theme, language, channels[]`. |

## Conversations (milestone M2)

One conversation per agent, kept in memory until the application quits or another configuration is opened.

### Messages

| Field | Meaning |
| --- | --- |
| `id`, `agent`, `createdAt` | identity |
| `role` | `user`, `agent` or `system` |
| `parts` | `text` (Markdown), `thought` (reasoning), `tool` (a tool call), `plan` (plan entries) |
| `done` | false while an agent message streams |
| `queued` | a user message waiting for the current answer |
| `stopReason` | how an agent message ended: `end_turn`, `cancelled`, `max_tokens`, `max_turn_requests`, `refusal` |
| `error` | why an agent message ended without a stop reason (the agent's own explanation), or `cancelled` for a queued message dropped by Stop |
| `code` | system messages: `agent-restarted` (new session, the agent forgot the beginning), `agent-unavailable` (could not start or reach it; `error` says why) |

A tool call has `id, title, kind` (`read, edit, delete, move, search, execute, think, fetch, other`), `status` (`pending, in_progress, completed, failed`), `input` (compact JSON), `output`, `locations`, `diffs` (`path, oldText, newText, newFile`).

### Events

| Event | Payload | Sent when |
| --- | --- | --- |
| `message:updated` | `{agent, message}` | a message is added, or finished |
| `message:delta` | `{agent, messageId, index, kind, text?, part?}` | `text` is appended to the part at `index` (text, thought), or `part` replaces it (tool, plan) |
| `turn:changed` | `{agent, busy, queued}` | the agent starts or stops answering; `queued` messages wait |
| `permission:requested` | `{id, agent, messageId, toolCall, options[], rejections}` | the agent asks to run a tool; `rejections` counts the refusals already given in this turn |
| `permission:resolved` | `{id, agent}` | the request was answered, or cancelled by Stop |
| `usage:changed` | `{agent, usage: {used, size}}` | the agent reported its context window use (`size` is 0 when unknown) |

### `ChatService`

| Method | Effect |
| --- | --- |
| `Send(agent, text)` | Adds a user message and returns its id; starts the agent if needed; queues the message if the agent is answering. Empty text and unknown agents are errors. |
| `Cancel(agent)` | Stops the current answer (`session/cancel`), answers pending permission requests "cancelled", drops the queued messages. |
| `AnswerPermission(id, optionId)` | Answers a pending request with one of its options. |
| `Conversation(agent)` | The whole conversation: `messages, busy, queued, usage, commands, permissions`. |

### Settings methods of `ConfigService`

| Method | Effect |
| --- | --- |
| `Content()` | The text of the configuration file. |
| `Validate(text)` | The problems and warnings of `text`, with `line, column, message, warning`, without saving. |
| `Save(text)` | Writes `text` if it is valid; otherwise returns its problems and writes nothing. |
| `Schema()` | The configuration JSON Schema. |
| `Open(path)` | Stops every agent, forgets the conversations, loads and watches `path`, remembers it. |
| `Choose()` | Shows the native file dialog and opens the chosen file; returns `""` when cancelled. |
| `Recent()` | The configuration files opened from the application, most recent first (8 at most). |

### Stopping an agent

The agent's stdin is closed; after 5 s the agent and its children get SIGTERM (time for `scripts/agents.sh` to unload the model); after 3 more seconds, SIGKILL.