Files
oh-my-pi/docs/tools/irc.md
T
can1357 384a206737 refactor(task): replaced numeric-prefix ids with name-first agent output ids
- Changed `AgentOutputManager` to use requested names verbatim, adding `-2`/`-3` suffixes only on repeats (e.g. `Anna`, `Anna-2`).
- Renamed main agent id from `0-Main` to `Main`; nested ids now use dot notation without numeric prefix (e.g. `Parent.Child`).
- Updated task widget to render dotted hierarchy as `Parent>Child` breadcrumb without leading index.
- Resume scan now tracks seen names instead of a counter to avoid clobbering prior outputs.
2026-06-02 06:50:03 +02:00

120 lines
8.8 KiB
Markdown

# irc
> Send short prose messages to other live agents in the current process.
## Source
- Entry: `packages/coding-agent/src/tools/irc.ts`
- Model-facing prompt: `packages/coding-agent/src/prompts/tools/irc.md`
- Key collaborators:
- `packages/coding-agent/src/registry/agent-registry.ts` — process-global live agent directory.
- `packages/coding-agent/src/session/agent-session.ts` — side-channel reply generation and history injection.
- `packages/coding-agent/src/prompts/system/irc-incoming.md` — no-tools auto-reply prompt.
- `packages/coding-agent/src/tools/index.ts` — tool availability gating.
- `packages/coding-agent/src/config/settings-schema.ts` — `irc.enabled` default.
- `packages/coding-agent/src/modes/controllers/event-controller.ts` — renders IRC events into chat UI.
- `packages/coding-agent/src/modes/utils/ui-helpers.ts` — formats `[IRC]` transcript lines.
- `packages/coding-agent/src/task/executor.ts` — carries `irc.enabled` into subagents.
## Inputs
### `op: "list"`
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | `"list"` | Yes | Lists peers visible to the caller. |
### `op: "send"`
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | `"send"` | Yes | Sends one message to one peer or to `"all"`. |
| `to` | `string` | Yes | Peer id such as `Main`, or `"all"` for broadcast. Whitespace is trimmed. |
| `message` | `string` | Yes | Message body. Whitespace is trimmed; empty-after-trim is rejected. |
| `awaitReply` | `boolean` | No | Wait for prose replies. Defaults to `true` for direct messages and `false` for `to: "all"`. |
## Outputs
- Single-shot `AgentToolResult`; no streaming updates.
- `content` is one text block.
- `list` returns either `No other live agents.` or a bullet list headed by `<n> peer(s):`.
- `send` returns delivery summary text, then optional `## Replies`, `## Failed`, and `Unknown / unavailable peers:` sections.
- `details` is structured metadata:
- `list`: `{ op, from, peers, channels }`
- `send`: `{ op, from, to, delivered, replies?, failed?, notFound? }`
- The tool does not return raw IRC frames, message ids, or a transcript object.
## Flow
1. `IrcTool.createIf` only constructs the tool when `irc.enabled` is on and the session has both an `AgentRegistry` and `getAgentId` (`packages/coding-agent/src/tools/irc.ts`).
2. Tool discovery adds another gate in `packages/coding-agent/src/tools/index.ts`: if the caller is `Main` and `async.enabled` is off, `irc` is hidden because the main agent cannot talk to concurrent peers in sync mode.
3. `execute` resolves the process-global registry and sender id. Missing either returns a text error result instead of throwing.
4. `op: "list"` calls `registry.listVisibleTo(senderId)`, which exposes every other agent in flat namespace whose status is `running` or `idle` (`packages/coding-agent/src/registry/agent-registry.ts`).
5. `list` formats human-readable lines and returns `channels` as `['all', ...peerIds]`. These are logical targets only; there is no channel join state.
6. `op: "send"` trims `to` and `message`; missing values produce text errors.
7. `send` resolves targets:
- `to === "all"`: all visible peers.
- otherwise: one exact registry id, excluding self and excluding peers not in `running`/`idle`.
8. `send` chooses `awaitReply = params.awaitReply ?? !isBroadcast`.
9. Each target is dispatched in parallel via `target.session.respondAsBackground(...)`. One slow or failing peer does not block dispatch to the others.
10. `respondAsBackground` emits an `irc_message` session event, forwards a display-only relay to the main session UI, and either:
- queues just the incoming message for later history injection when `awaitReply === false`, or
- renders `packages/coding-agent/src/prompts/system/irc-incoming.md`, runs `runEphemeralTurn` with `toolChoice: "none"`, emits an auto-reply event, then queues both incoming and reply messages for history injection.
11. Deferred injection waits until the recipient is no longer streaming; `#flushPendingBackgroundExchanges` appends the custom messages through normal `message_start`/`message_end` external events so persistence and listeners see them.
12. Dispatch waits are bounded by `irc.timeoutMs` (default `120_000` ms). A value of `0` disables the local timeout; parent aborts still abort the dispatch.
13. `send` aggregates `delivered`, `replies`, `failed`, and `notFound`, then returns one text summary plus matching `details`.
## Modes / Variants
- `list`: enumerate visible peers and logical channels.
- `send` direct message: one exact peer id, default synchronous auto-reply.
- `send` broadcast: `to: "all"`, default fire-and-forget (`awaitReply: false`) to every visible peer.
- `send` with `awaitReply: false`: recipient records the incoming message but does not generate a reply.
- `send` with `awaitReply: true`: recipient performs a no-tools ephemeral LLM turn and returns prose.
## Side Effects
- Session state
- Reads from the process-global `AgentRegistry`.
- Emits `irc_message` session events on recipient sessions.
- Queues IRC custom messages into recipient persisted history after the current stream finishes.
- For non-main recipients, forwards display-only relay observations into the main session UI; these relays are not persisted to the main agent history.
- Subagents inherit `irc.enabled` from task executor settings.
- User-visible prompts / interactive UI
- IRC events render as `[IRC]` transcript lines in the TUI.
- Auto-replies are generated from `packages/coding-agent/src/prompts/system/irc-incoming.md` and explicitly forbid tool use.
- Background work / cancellation
- `send` starts one background `respondAsBackground` call per target.
- The caller's `AbortSignal` is forwarded into each background reply turn. `irc.timeoutMs` creates a per-recipient `AbortController` and reports timeout failures per target.
- Network
- No IRC server connection.
- When `awaitReply: true`, the recipient may make model-provider API calls through `runEphemeralTurn`.
- Filesystem
- No direct filesystem writes in the tool itself.
## Limits & Caps
- Availability gates:
- `irc.enabled` defaults to `true` in `packages/coding-agent/src/config/settings-schema.ts`.
- Main agent tool discovery suppresses `irc` when `async.enabled` is off (`packages/coding-agent/src/tools/index.ts`).
- Visibility scope: only peers in status `running` or `idle` are addressable via `listVisibleTo`.
- Reply execution:
- No tools are available in auto-reply turns (`toolChoice: "none"` in `runEphemeralTurn`).
- `irc.timeoutMs` defaults to `120_000`; `0` disables the timeout, non-finite values fall back to the default, and positive values are truncated and clamped to at least `1` ms.
- No retry, backoff, rate limit, or reply length cap is defined in `irc.ts`; behavior otherwise relies on the underlying model stream and any upstream API limits.
- Flush scheduling: deferred history injection polls every `50` ms while the recipient is still streaming (`#scheduleBackgroundExchangeFlush` in `packages/coding-agent/src/session/agent-session.ts`).
## Errors
- The tool returns text errors, not thrown exceptions, for:
- missing registry: `IRC is unavailable in this session.`
- missing sender id: `IRC is unavailable: caller has no agent id.`
- missing `to`: `` `to` is required for op="send". ``
- missing `message`: `` `message` is required for op="send". ``
- unknown op: `Unknown irc op.`
- Unknown, self-addressed, non-running, and non-idle direct targets are reported under `details.notFound` and in the text footer `Unknown / unavailable peers:`.
- If a target has no attached session, it is treated as not found.
- Exceptions thrown by `respondAsBackground`, `runEphemeralTurn`, abort handling, or timeout handling are caught per-target and surfaced under `details.failed` as `{ id, error }`; other recipients still complete.
- If no target succeeds, `send` still returns normally with `No recipients received the message.` and optional `failed`/`notFound` metadata.
## Notes
- This is IRC-like naming only. There are no servers, sockets, nick registration, auth handshakes, channels beyond `all`, or commands such as join/part/topic.
- Addressing is by exact agent id from the registry; there is no fuzzy lookup or aliasing.
- `channels` in `list` is synthetic output: `all` plus visible peer ids. Nothing is persisted across calls as channel membership.
- Persistence is per recipient history, not per sender history. The sender gets the tool result; the recipient later sees injected custom messages on its next turn.
- The main UI may show IRC relays for conversations it was not part of, but those relay records are explicitly display-only.
- Because reply generation snapshots in-flight assistant text, a recipient can answer based on partially streamed context.
- Direct self-messaging is rejected by resolving the target as unavailable.