@bastani/atomic 0.9.19-alpha.6 → 0.9.19-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/subagents/package.json +1 -1
  6. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  7. package/dist/builtin/web-access/index.bundle.mjs +22 -3
  8. package/dist/builtin/web-access/package.json +1 -1
  9. package/dist/builtin/workflows/CHANGELOG.md +19 -0
  10. package/dist/builtin/workflows/README.md +1 -1
  11. package/dist/builtin/workflows/builtin/adversarial-verification.js +2 -2
  12. package/dist/builtin/workflows/builtin/{chunk-vhmnzdj9.js → chunk-1jth021m.js} +1 -1
  13. package/dist/builtin/workflows/builtin/{chunk-p8jjwfg6.js → chunk-2377r57g.js} +4 -2
  14. package/dist/builtin/workflows/builtin/{chunk-hbnwv56f.js → chunk-31j2gs7h.js} +2 -2
  15. package/dist/builtin/workflows/builtin/{chunk-n8zysf1t.js → chunk-ngkqkzej.js} +1 -1
  16. package/dist/builtin/workflows/builtin/{chunk-1nbq96fh.js → chunk-nkrafh9s.js} +1 -1
  17. package/dist/builtin/workflows/builtin/{chunk-1kx4aggw.js → chunk-wf741bv3.js} +2 -2
  18. package/dist/builtin/workflows/builtin/{chunk-t6x2d78s.js → chunk-z29qbehr.js} +1 -1
  19. package/dist/builtin/workflows/builtin/generate-and-filter.js +2 -2
  20. package/dist/builtin/workflows/builtin/goal.js +3 -3
  21. package/dist/builtin/workflows/builtin/index.js +7 -7
  22. package/dist/builtin/workflows/builtin/ralph.js +3 -3
  23. package/dist/builtin/workflows/builtin/tournament.js +2 -2
  24. package/dist/builtin/workflows/package.json +1 -1
  25. package/dist/builtin/workflows/src/extension/index.bundle.mjs +590 -256
  26. package/dist/builtin/workflows/src/index.js +67 -19
  27. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -0
  28. package/dist/modes/interactive/components/task-live-transcript.d.ts +1 -1
  29. package/dist/modes/interactive/components/task-live-transcript.d.ts.map +1 -1
  30. package/dist/modes/interactive/components/task-live-transcript.js +19 -11
  31. package/dist/modes/interactive/components/task-live-transcript.js.map +1 -1
  32. package/docs/background-tasks.md +1 -1
  33. package/docs/build.md +51 -0
  34. package/docs/changelog.mdx +8 -8
  35. package/docs/compaction/reference.md +267 -0
  36. package/docs/compaction.md +36 -219
  37. package/docs/computer-use.md +35 -0
  38. package/docs/containerization.md +2 -0
  39. package/docs/custom-provider/api-reference.md +145 -0
  40. package/docs/custom-provider/oauth.md +131 -0
  41. package/docs/custom-provider/override.md +34 -0
  42. package/docs/custom-provider/registration.md +163 -0
  43. package/docs/custom-provider/streaming.md +214 -0
  44. package/docs/custom-provider.md +43 -607
  45. package/docs/development.md +76 -0
  46. package/docs/docs.json +199 -77
  47. package/docs/environment-variables.md +1 -1
  48. package/docs/extensions/api-reference.md +1001 -0
  49. package/docs/extensions/authoring.md +676 -0
  50. package/docs/extensions/events.md +793 -0
  51. package/docs/extensions/examples.md +94 -0
  52. package/docs/extensions/ui.md +470 -0
  53. package/docs/extensions.md +270 -2768
  54. package/docs/getting-started/authentication.md +55 -0
  55. package/docs/getting-started/first-session.md +172 -0
  56. package/docs/getting-started/installation.md +154 -0
  57. package/docs/getting-started/project-instructions.md +43 -0
  58. package/docs/guides/configuration.md +65 -0
  59. package/docs/guides/intercom.md +24 -0
  60. package/docs/guides/non-interactive.md +33 -0
  61. package/docs/guides/subagents.md +24 -0
  62. package/docs/guides/workflows.md +27 -0
  63. package/docs/guides.md +41 -0
  64. package/docs/index.md +13 -45
  65. package/docs/intercom/operations.md +178 -0
  66. package/docs/intercom/reference.md +146 -0
  67. package/docs/intercom.md +54 -259
  68. package/docs/json.md +17 -0
  69. package/docs/llama-cpp.md +5 -0
  70. package/docs/models/artificial-analysis-index.md +89 -0
  71. package/docs/models/evals.md +2 -2
  72. package/docs/models/model-selection.md +3 -3
  73. package/docs/models/pareto-efficiency.md +2 -2
  74. package/docs/models/reference.md +601 -0
  75. package/docs/models.md +45 -550
  76. package/docs/packages/authoring.md +88 -0
  77. package/docs/packages/reference.md +43 -0
  78. package/docs/packages.md +28 -107
  79. package/docs/programmatic.md +29 -0
  80. package/docs/prompt-templates.md +11 -0
  81. package/docs/providers/reference.md +23 -0
  82. package/docs/providers.md +10 -15
  83. package/docs/quickstart.md +44 -238
  84. package/docs/reference/cli.md +252 -0
  85. package/docs/reference.md +52 -0
  86. package/docs/rpc/examples.md +64 -0
  87. package/docs/rpc/extension-ui.md +198 -0
  88. package/docs/rpc/protocol.md +1341 -0
  89. package/docs/rpc.md +109 -1346
  90. package/docs/sdk/reference.md +1090 -0
  91. package/docs/sdk.md +56 -1002
  92. package/docs/session-format.md +2 -0
  93. package/docs/sessions.md +6 -10
  94. package/docs/settings.md +6 -45
  95. package/docs/skills/authoring.md +95 -0
  96. package/docs/skills/reference.md +60 -0
  97. package/docs/skills.md +20 -122
  98. package/docs/subagents/authoring.md +37 -0
  99. package/docs/subagents/reference.md +60 -0
  100. package/docs/subagents.md +39 -95
  101. package/docs/terminal-setup.md +1 -1
  102. package/docs/themes/reference.md +176 -0
  103. package/docs/themes.md +21 -135
  104. package/docs/tmux.md +5 -0
  105. package/docs/tools/edit.md +5 -0
  106. package/docs/tools.md +5 -0
  107. package/docs/tui/reference.md +343 -0
  108. package/docs/tui.md +23 -286
  109. package/docs/usage.md +26 -209
  110. package/docs/web-access.md +2 -0
  111. package/docs/windows.md +2 -1
  112. package/docs/workflows/api-reference.md +11 -4
  113. package/docs/workflows/authoring.md +4 -2
  114. package/docs/workflows/builtins.md +2 -2
  115. package/docs/workflows/operations.md +15 -10
  116. package/docs/workflows/reliable-design.md +21 -3
  117. package/docs/workflows/verification.md +8 -0
  118. package/npm-shrinkwrap.json +32 -32
  119. package/package.json +3 -3
package/docs/rpc.md CHANGED
@@ -1,9 +1,24 @@
1
+ ---
2
+ title: "RPC"
3
+ description: "Drive a long-lived Atomic process over stdin/stdout JSONL."
4
+ ---
5
+
1
6
  # RPC Mode
2
7
 
3
8
  RPC mode enables headless operation of the coding agent via a JSON protocol over stdin/stdout. This is useful for embedding the agent in other applications, IDEs, or custom UIs.
4
9
 
5
10
  **Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@bastani/atomic` instead of spawning a subprocess. See [`src/core/agent-session.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/agent-session.ts) for the API. For a subprocess-based TypeScript client, see [`src/modes/rpc/rpc-client.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/modes/rpc/rpc-client.ts).
6
11
 
12
+ ## Where to go next
13
+
14
+ This page starts RPC mode and walks one client end to end. The rest is split by job:
15
+
16
+ - [RPC protocol](/rpc/protocol) — every command, event, type, and error contract.
17
+ - [RPC extension UI protocol](/rpc/extension-ui) — drive extension-rendered UI over RPC.
18
+ - [RPC client examples](/rpc/examples) — additional client implementations.
19
+
20
+ Not sure RPC is the right integration mode? Compare it with the SDK and JSON mode on [Programmatic use](/programmatic).
21
+
7
22
  ## Starting RPC Mode
8
23
 
9
24
  ```bash
@@ -42,1529 +57,331 @@ In particular, Node `readline` is not protocol-compliant for RPC mode because it
42
57
 
43
58
  ## Commands
44
59
 
45
- ### Prompting
46
-
47
- #### prompt
48
-
49
- Send a user prompt to the agent. The command response is emitted after the prompt is accepted, queued, or handled. Events continue streaming asynchronously after acceptance.
50
-
51
- ```json
52
- {"id": "req-1", "type": "prompt", "message": "Hello, world!"}
53
- ```
60
+ Moved to [RPC protocol](/rpc/protocol#commands).
54
61
 
55
- With images:
56
- ```json
57
- {"type": "prompt", "message": "What's in this image?", "images": [{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}]}
58
- ```
59
-
60
- **During streaming**: If the agent is already streaming, you must specify `streamingBehavior` to queue the message:
61
-
62
- ```json
63
- {"type": "prompt", "message": "New instruction", "streamingBehavior": "steer"}
64
- ```
65
-
66
- - `"steer"`: Queue the message while the agent is running. It is delivered after the current assistant turn finishes executing its tool calls, before the next LLM call.
67
- - `"followUp"`: Wait until the agent finishes. Message is delivered only when agent stops.
68
-
69
- If the agent is streaming and no `streamingBehavior` is specified, the command returns an error.
70
-
71
- **Extension commands**: If the message is an extension command (e.g., `/mycommand`), it executes immediately even during streaming. Extension commands manage their own LLM interaction via `pi.sendMessage()`.
72
-
73
- **Input expansion**: Skill commands (`/skill:name`) and prompt templates (`/template`) are expanded before sending/queueing.
62
+ ### Prompting
74
63
 
75
- Response:
76
- ```json
77
- {"id": "req-1", "type": "response", "command": "prompt", "success": true}
78
- ```
64
+ Moved to [RPC protocol](/rpc/protocol#prompting).
79
65
 
80
- `success: true` means the prompt was accepted, queued, or handled immediately. `success: false` means the prompt was rejected before acceptance. Failures after acceptance are reported through the normal event and message stream, not as a second `response` for the same request id.
66
+ #### prompt
81
67
 
82
- The `images` field is optional. Each image uses `ImageContent` format: `{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}`.
68
+ Moved to [RPC protocol](/rpc/protocol#prompt).
83
69
 
84
70
  #### steer
85
71
 
86
- Queue a steering message while the agent is running. It is delivered after the current assistant turn finishes executing its tool calls, before the next LLM call. Skill commands and prompt templates are expanded. Extension commands are not allowed (use `prompt` instead).
87
-
88
- ```json
89
- {"type": "steer", "message": "Stop and do this instead"}
90
- ```
91
-
92
- With images:
93
- ```json
94
- {"type": "steer", "message": "Look at this instead", "images": [{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}]}
95
- ```
96
-
97
- The `images` field is optional. Each image uses `ImageContent` format (same as `prompt`).
98
-
99
- Response:
100
- ```json
101
- {"type": "response", "command": "steer", "success": true}
102
- ```
103
-
104
- See [set_steering_mode](#set_steering_mode) for controlling how steering messages are processed.
72
+ Moved to [RPC protocol](/rpc/protocol#steer).
105
73
 
106
74
  #### follow_up
107
75
 
108
- Queue a follow-up message to be processed after the agent finishes. Delivered only when agent has no more tool calls or steering messages. Skill commands and prompt templates are expanded. Extension commands are not allowed (use `prompt` instead).
109
-
110
- ```json
111
- {"type": "follow_up", "message": "After you're done, also do this"}
112
- ```
113
-
114
- With images:
115
- ```json
116
- {"type": "follow_up", "message": "Also check this image", "images": [{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}]}
117
- ```
118
-
119
- The `images` field is optional. Each image uses `ImageContent` format (same as `prompt`).
120
-
121
- Response:
122
- ```json
123
- {"type": "response", "command": "follow_up", "success": true}
124
- ```
125
-
126
- See [set_follow_up_mode](#set_follow_up_mode) for controlling how follow-up messages are processed.
76
+ Moved to [RPC protocol](/rpc/protocol#follow_up).
127
77
 
128
78
  #### abort
129
79
 
130
- Abort the current operation and wait for the session to become idle before responding.
131
-
132
- ```json
133
- {"type": "abort"}
134
- ```
135
-
136
- Response:
137
- ```json
138
- {"type": "response", "command": "abort", "success": true}
139
- ```
80
+ Moved to [RPC protocol](/rpc/protocol#abort).
140
81
 
141
82
  #### clear_queue
142
83
 
143
- Remove queued steering and follow-up messages and return their text.
144
-
145
- ```json
146
- {"type": "clear_queue"}
147
- ```
148
-
149
- Response:
150
- ```json
151
- {
152
- "type": "response",
153
- "command": "clear_queue",
154
- "success": true,
155
- "data": {
156
- "steering": ["Change direction"],
157
- "followUp": ["Summarize when finished"]
158
- }
159
- }
160
- ```
161
-
162
- To implement interactive Esc behavior, send `clear_queue` before `abort`, then restore the returned text in the client editor. `abort` continues queued messages when they remain in the session.
84
+ Moved to [RPC protocol](/rpc/protocol#clear_queue).
163
85
 
164
86
  #### new_session
165
87
 
166
- Start a fresh session. Can be cancelled by a `session_before_switch` extension event handler.
167
-
168
- ```json
169
- {"type": "new_session"}
170
- ```
171
-
172
- With optional parent session tracking:
173
- ```json
174
- {"type": "new_session", "parentSession": "/path/to/parent-session.jsonl"}
175
- ```
176
-
177
- Response:
178
- ```json
179
- {"type": "response", "command": "new_session", "success": true, "data": {"cancelled": false}}
180
- ```
181
-
182
- If an extension cancelled:
183
- ```json
184
- {"type": "response", "command": "new_session", "success": true, "data": {"cancelled": true}}
185
- ```
88
+ Moved to [RPC protocol](/rpc/protocol#new_session).
186
89
 
187
90
  ### State
188
91
 
189
- #### get_state
190
-
191
- Get current session state.
192
-
193
- ```json
194
- {"type": "get_state"}
195
- ```
92
+ Moved to [RPC protocol](/rpc/protocol#state).
196
93
 
197
- Response:
198
- ```json
199
- {
200
- "type": "response",
201
- "command": "get_state",
202
- "success": true,
203
- "data": {
204
- "model": {...},
205
- "thinkingLevel": "medium",
206
- "isStreaming": false,
207
- "isCompacting": false,
208
- "steeringMode": "all",
209
- "followUpMode": "one-at-a-time",
210
- "sessionFile": "/path/to/session.jsonl",
211
- "sessionId": "abc123",
212
- "sessionName": "my-feature-work",
213
- "autoCompactionEnabled": true,
214
- "messageCount": 5,
215
- "pendingMessageCount": 0
216
- }
217
- }
218
- ```
94
+ #### get_state
219
95
 
220
- The `model` field is a full [Model](#model) object or `null`. Its `contextWindow` is the model's token budget. The `sessionName` field is the display name set via `set_session_name`, or omitted if not set.
96
+ Moved to [RPC protocol](/rpc/protocol#get_state).
221
97
 
222
98
  #### get_messages
223
99
 
224
- Get all messages in the conversation.
225
-
226
- ```json
227
- {"type": "get_messages"}
228
- ```
229
-
230
- Response:
231
- ```json
232
- {
233
- "type": "response",
234
- "command": "get_messages",
235
- "success": true,
236
- "data": {"messages": [...]}
237
- }
238
- ```
239
-
240
- Messages are `AgentMessage` objects (see [Types](#types)).
100
+ Moved to [RPC protocol](/rpc/protocol#get_messages).
241
101
 
242
102
  ### Model
243
103
 
244
- #### set_model
245
-
246
- Switch to a specific model. Omit `persist` (or set it false) to change only the current session. Set `"persist": true` to also save `defaultProvider`, `defaultModel`, and the effective thinking level in settings, matching an interactive `/model` selection.
104
+ Moved to [RPC protocol](/rpc/protocol#model).
247
105
 
248
- ```json
249
- {"type": "set_model", "provider": "anthropic", "modelId": "claude-sonnet-4-20250514"}
250
- ```
251
-
252
- Persist as the startup default:
253
- ```json
254
- {"type": "set_model", "provider": "anthropic", "modelId": "claude-sonnet-4-20250514", "persist": true}
255
- ```
106
+ #### set_model
256
107
 
257
- Response contains the full [Model](#model) object:
258
- ```json
259
- {
260
- "type": "response",
261
- "command": "set_model",
262
- "success": true,
263
- "data": {...}
264
- }
265
- ```
108
+ Moved to [RPC protocol](/rpc/protocol#set_model).
266
109
 
267
110
  #### cycle_model
268
111
 
269
- Cycle to the next available model. Returns `null` when fewer than two authenticated models are available in the active scope or catalog. When an unsupported saved default is blocking prompts, a successful cycle that returns a different model clears that condition; a `null` or unchanged result does not. Set `"persist": true` to also write the cycled model as the startup default.
270
-
271
- ```json
272
- {"type": "cycle_model"}
273
- ```
274
-
275
- Response:
276
- ```json
277
- {
278
- "type": "response",
279
- "command": "cycle_model",
280
- "success": true,
281
- "data": {
282
- "model": {...},
283
- "thinkingLevel": "medium",
284
- "isScoped": false
285
- }
286
- }
287
- ```
288
-
289
- The `model` field is a full [Model](#model) object.
112
+ Moved to [RPC protocol](/rpc/protocol#cycle_model).
290
113
 
291
114
  #### get_available_models
292
115
 
293
- List all configured models.
294
-
295
- ```json
296
- {"type": "get_available_models"}
297
- ```
298
-
299
- Response contains an array of full [Model](#model) objects:
300
- ```json
301
- {
302
- "type": "response",
303
- "command": "get_available_models",
304
- "success": true,
305
- "data": {
306
- "models": [...]
307
- }
308
- }
309
- ```
310
-
311
- The subprocess protocol returns full `Model` objects. The exported TypeScript `RpcClient.getAvailableModels()` keeps its smaller backward-compatible `ModelInfo` shape (`provider`, `id`, `contextWindow`, `reasoning`) and adds optional `compat`. When present, `compat` exposes constrained-sampling capability claims including `supportsStrictTools`, `supportsStrictMode`, canonical `supportsOpenAIGrammarTools`, and Atomic's synchronized `supportsGrammarTools` alias. Treat absence as unknown/unsupported; do not infer enforcement from the provider name.
312
-
313
- ```typescript
314
- const models = await client.getAvailableModels();
315
- const capabilities = models[0]?.compat;
316
- if (capabilities?.supportsStrictTools) {
317
- // The selected model advertises Anthropic/Bedrock strict-tool support.
318
- }
319
- ```
116
+ Moved to [RPC protocol](/rpc/protocol#get_available_models).
320
117
 
321
118
  #### logout_provider
322
119
 
323
- Remove a provider's stored credential in the authoritative agent process, refresh its available-model catalog, and return the remaining authentication status and new catalog. Environment variables and `models.json` authentication are reported but are not modified.
324
-
325
- ```json
326
- {"type": "logout_provider", "provider": "github-copilot"}
327
- ```
328
-
329
- Response:
330
-
331
- ```json
332
- {
333
- "type": "response",
334
- "command": "logout_provider",
335
- "success": true,
336
- "data": {
337
- "provider": "github-copilot",
338
- "authStatus": {"configured": false},
339
- "models": [],
340
- "scopedModels": []
341
- }
342
- }
343
- ```
344
-
345
- `models` preserves the refreshed catalog order. `scopedModels` is optional. If authentication remains through an environment variable, `authStatus.source` is `"environment"` and `authStatus.label` names the variable.
346
-
120
+ Moved to [RPC protocol](/rpc/protocol#logout_provider).
347
121
 
348
122
  ### Thinking
349
123
 
350
- #### set_thinking_level
124
+ Moved to [RPC protocol](/rpc/protocol#thinking).
351
125
 
352
- Set the reasoning/thinking level for models that support it. Omit `persist` (or set it false) to change only the current session. Set `"persist": true` to also save `defaultThinkingLevel` and, when a model is active, its per-model override. Interactive `/thinking` choices request persistence automatically.
353
-
354
- ```json
355
- {"type": "set_thinking_level", "level": "high"}
356
- ```
357
-
358
- Persist as the startup default:
359
- ```json
360
- {"type": "set_thinking_level", "level": "high", "persist": true}
361
- ```
362
-
363
- Levels: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"`, `"max"`.
364
-
365
- `xhigh` and `max` are available only when the active model's capability mapping supports them; unsupported levels are clamped by the session model controls.
366
-
367
- Response may omit `data` for compatibility with older clients:
368
- ```json
369
- {"type": "response", "command": "set_thinking_level", "success": true}
370
- ```
371
-
372
- Current engines include the effective level after capability clamping and, when a model is active, the provider/model the engine persisted against:
373
- ```json
374
- {"type": "response", "command": "set_thinking_level", "success": true, "data": {"level": "high", "provider": "anthropic", "modelId": "claude-sonnet-4-20250514"}}
375
- ```
126
+ #### set_thinking_level
376
127
 
377
- Isolated interactive hosts must apply a persisted thinking default using that ACK target, not the host session model at callback time. A later `model_changed` event must not re-key the saved override. A later `thinking_level_changed` event must keep the host session's effective level even if an older ACK settles afterward. `RpcClient.setThinkingLevel(level)` stays one-argument `Promise<void>`; isolated persist reads the ACK through an internal client path.
128
+ Moved to [RPC protocol](/rpc/protocol#set_thinking_level).
378
129
 
379
130
  #### cycle_thinking_level
380
131
 
381
- Cycle through available thinking levels. Returns `null` data if model doesn't support thinking.
382
-
383
- ```json
384
- {"type": "cycle_thinking_level"}
385
- ```
386
-
387
- Response:
388
- ```json
389
- {
390
- "type": "response",
391
- "command": "cycle_thinking_level",
392
- "success": true,
393
- "data": {"level": "high"}
394
- }
395
- ```
132
+ Moved to [RPC protocol](/rpc/protocol#cycle_thinking_level).
396
133
 
397
134
  #### get_available_thinking_levels
398
135
 
399
- Return the thinking levels supported by the current model, in cycle order.
400
-
401
- ```json
402
- {"type": "get_available_thinking_levels"}
403
- ```
404
-
405
- Response:
406
- ```json
407
- {
408
- "type": "response",
409
- "command": "get_available_thinking_levels",
410
- "success": true,
411
- "data": {"levels": ["off", "low", "medium", "high"]}
412
- }
413
- ```
136
+ Moved to [RPC protocol](/rpc/protocol#get_available_thinking_levels).
414
137
 
415
138
  ### Queue Modes
416
139
 
417
- #### set_steering_mode
418
-
419
- Control how steering messages (from `steer`) are delivered.
420
-
421
- ```json
422
- {"type": "set_steering_mode", "mode": "one-at-a-time"}
423
- ```
140
+ Moved to [RPC protocol](/rpc/protocol#queue-modes).
424
141
 
425
- Modes:
426
- - `"all"`: Deliver all steering messages after the current assistant turn finishes executing its tool calls
427
- - `"one-at-a-time"`: Deliver one steering message per completed assistant turn (default)
142
+ #### set_steering_mode
428
143
 
429
- Response:
430
- ```json
431
- {"type": "response", "command": "set_steering_mode", "success": true}
432
- ```
144
+ Moved to [RPC protocol](/rpc/protocol#set_steering_mode).
433
145
 
434
146
  #### set_follow_up_mode
435
147
 
436
- Control how follow-up messages (from `follow_up`) are delivered.
437
-
438
- ```json
439
- {"type": "set_follow_up_mode", "mode": "one-at-a-time"}
440
- ```
441
-
442
- Modes:
443
- - `"all"`: Deliver all follow-up messages when agent finishes
444
- - `"one-at-a-time"`: Deliver one follow-up message per agent completion (default)
445
-
446
- Response:
447
- ```json
448
- {"type": "response", "command": "set_follow_up_mode", "success": true}
449
- ```
148
+ Moved to [RPC protocol](/rpc/protocol#set_follow_up_mode).
450
149
 
451
150
  ### Compaction
452
151
 
453
- #### compact
454
-
455
- Run Atomic's verbatim line compactor. The selected session model receives the complete active numbered transcript except for exactly the newest `preserve_recent` context-visible messages and returns bare `start,end` deletion records; Atomic validates them and mechanically reconstructs retained lines with `(filtered N lines)` markers. The default tail is two messages, with no user-turn alignment. A value of zero sends the entire active transcript and persists `firstKeptEntryId: null`. The command appends a durable `compaction` entry with `details.strategy: "verbatim-lines"`.
152
+ Moved to [RPC protocol](/rpc/protocol#compaction).
456
153
 
457
- ```json
458
- {"type": "compact"}
459
- ```
460
-
461
- Response:
462
- ```json
463
- {
464
- "type": "response",
465
- "command": "compact",
466
- "success": true,
467
- "data": {
468
- "compactedText": "[User]: fix the test\n(filtered 42 lines)\n[Assistant]: Fixed.",
469
- "firstKeptEntryId": "m7",
470
- "tokensBefore": 150000,
471
- "promptVersion": 3,
472
- "parameters": {
473
- "compression_ratio": 0.5,
474
- "preserve_recent": 2,
475
- "query": "fix the test"
476
- },
477
- "rung": "planned",
478
- "stats": {
479
- "linesBefore": 812,
480
- "linesDeleted": 417,
481
- "linesKept": 395,
482
- "rangeCount": 63,
483
- "tokensBefore": 150000,
484
- "tokensAfter": 72000,
485
- "percentReduction": 52
486
- },
487
- "backupPath": "/path/to/session.jsonl.2026-06-06T00-00-00-000Z.compact.bak"
488
- }
489
- }
490
- ```
154
+ #### compact
491
155
 
492
- `firstKeptEntryId` is a string when at least one ordinary message remains outside compaction and `null` when none does. RPC clients must accept both values.
156
+ Moved to [RPC protocol](/rpc/protocol#compact).
493
157
 
494
158
  #### set_auto_compaction
495
159
 
496
- Enable or disable automatic compaction when context is nearly full.
497
-
498
- ```json
499
- {"type": "set_auto_compaction", "enabled": true}
500
- ```
501
-
502
- Response:
503
- ```json
504
- {"type": "response", "command": "set_auto_compaction", "success": true}
505
- ```
160
+ Moved to [RPC protocol](/rpc/protocol#set_auto_compaction).
506
161
 
507
162
  ### Retry
508
163
 
509
- #### set_auto_retry
164
+ Moved to [RPC protocol](/rpc/protocol#retry).
510
165
 
511
- Enable or disable automatic retry on transient errors (overloaded, rate limit, 5xx).
512
-
513
- ```json
514
- {"type": "set_auto_retry", "enabled": true}
515
- ```
166
+ #### set_auto_retry
516
167
 
517
- Response:
518
- ```json
519
- {"type": "response", "command": "set_auto_retry", "success": true}
520
- ```
168
+ Moved to [RPC protocol](/rpc/protocol#set_auto_retry).
521
169
 
522
170
  #### abort_retry
523
171
 
524
- Abort an in-progress retry (cancel the delay and stop retrying).
525
-
526
- ```json
527
- {"type": "abort_retry"}
528
- ```
529
-
530
- Response:
531
- ```json
532
- {"type": "response", "command": "abort_retry", "success": true}
533
- ```
172
+ Moved to [RPC protocol](/rpc/protocol#abort_retry).
534
173
 
535
174
  ### Bash
536
175
 
537
- #### bash
538
-
539
- Execute a shell command and add output to conversation context.
540
-
541
- ```json
542
- {"type": "bash", "command": "ls -la"}
543
- ```
176
+ Moved to [RPC protocol](/rpc/protocol#bash).
544
177
 
545
- Response:
546
- ```json
547
- {
548
- "type": "response",
549
- "command": "bash",
550
- "success": true,
551
- "data": {
552
- "output": "total 48\ndrwxr-xr-x ...",
553
- "exitCode": 0,
554
- "cancelled": false,
555
- "truncated": false
556
- }
557
- }
558
- ```
559
-
560
- While the command runs, Atomic emits ordered deltas correlated by the command `id`:
561
-
562
- ```json
563
- {"type":"bash_execution_update","id":"req-1","channel":"stdout","delta":"building...\n"}
564
- {"type":"bash_execution_update","id":"req-1","channel":"stderr","delta":"warning\n"}
565
- ```
566
-
567
- `channel` is exactly `"stdout"` or `"stderr"`. Deltas preserve the order observed for that request; concurrent bash requests may interleave globally but never share IDs. Request ownership survives `new_session`, `switch_session`, `import_session`, fork, and clone while the command is running: later deltas still stream under the original ID, the replacement session is not contaminated, and exactly one ordinary `response` remains the terminal record for completion, cancellation, or error.
568
-
569
- If output was truncated, includes `fullOutputPath`. Persisted bash output lives in the owner- and session-scoped temp tree (`<tmpdir>/atomic-<uid>/<session-id>/`), not at the temp root — see [Tools](/tools#persisted-tool-output) for the layout, permissions, size cap, and retention:
570
- ```json
571
- {
572
- "type": "response",
573
- "command": "bash",
574
- "success": true,
575
- "data": {
576
- "output": "truncated output...",
577
- "exitCode": 0,
578
- "cancelled": false,
579
- "truncated": true,
580
- "fullOutputPath": "/tmp/atomic-501/019fdf86-cf98-7327-8a73-21365028f6ae/atomic-bash-abc123.log"
581
- }
582
- }
583
- ```
584
-
585
- `fullOutputPath` is `null` when the temp directory could not be created or the write was refused; treat it as absent rather than assuming a path exists.
586
-
587
- **How bash results reach the LLM:**
588
-
589
- The `bash` command executes immediately and returns a `BashResult`. Internally, a `BashExecutionMessage` is created and stored exactly once in the session where that request started, even if an RPC session replacement completes before the command. The message does NOT emit an event.
590
-
591
- When the next `prompt` command is sent, all messages (including `BashExecutionMessage`) are transformed before being sent to the LLM. The `BashExecutionMessage` is converted to a `UserMessage` with this format:
592
-
593
- ````
594
- Ran `ls -la`
595
- ```
596
- total 48
597
- drwxr-xr-x ...
598
- ```
599
- ````
178
+ #### bash
600
179
 
601
- This means:
602
- 1. Bash output is included in the LLM context on the **next prompt**, not immediately
603
- 2. Multiple bash commands can be executed before a prompt; all outputs will be included
604
- 3. No event is emitted for the `BashExecutionMessage` itself
180
+ Moved to [RPC protocol](/rpc/protocol#bash-2).
605
181
 
606
182
  #### abort_bash
607
183
 
608
- Abort running bash commands. Omit `requestId` to retain the legacy behavior of aborting every active RPC-owned bash request, including requests that began before a session replacement, or provide the target bash command's `id` to cancel only that request. Targeted and legacy cancellation remain isolated across concurrent IDs. Closing RPC cancels and drains remaining owned requests before shutdown.
609
-
610
- ```json
611
- {"id":"cancel-1","type":"abort_bash","requestId":"req-1"}
612
- ```
613
-
614
- Response:
615
- ```json
616
- {"id":"cancel-1","type":"response","command":"abort_bash","success":true}
617
- ```
184
+ Moved to [RPC protocol](/rpc/protocol#abort_bash).
618
185
 
619
186
  ### Session
620
187
 
621
- #### get_session_stats
622
-
623
- Get token usage, cost statistics, and current context window usage.
188
+ Moved to [RPC protocol](/rpc/protocol#session).
624
189
 
625
- ```json
626
- {"type": "get_session_stats"}
627
- ```
628
-
629
- Response:
630
- ```json
631
- {
632
- "type": "response",
633
- "command": "get_session_stats",
634
- "success": true,
635
- "data": {
636
- "sessionFile": "/path/to/session.jsonl",
637
- "sessionId": "abc123",
638
- "userMessages": 5,
639
- "assistantMessages": 5,
640
- "toolCalls": 12,
641
- "toolResults": 12,
642
- "totalMessages": 22,
643
- "tokens": {
644
- "input": 50000,
645
- "output": 10000,
646
- "cacheRead": 40000,
647
- "cacheWrite": 5000,
648
- "total": 105000
649
- },
650
- "cost": 0.45,
651
- "contextUsage": {
652
- "tokens": 60000,
653
- "contextWindow": 200000,
654
- "percent": 30
655
- }
656
- }
657
- }
658
- ```
659
-
660
- `tokens` contains assistant usage totals for the current session state. `contextUsage` contains the actual current context-window estimate used for compaction and footer display.
190
+ #### get_session_stats
661
191
 
662
- `contextUsage` is omitted when no model or context window is available. `contextUsage.tokens` and `contextUsage.percent` are `null` immediately after compaction until a fresh post-compaction assistant response provides valid usage data.
192
+ Moved to [RPC protocol](/rpc/protocol#get_session_stats).
663
193
 
664
194
  #### export_html
665
195
 
666
- Export session to an HTML file.
667
-
668
- ```json
669
- {"type": "export_html"}
670
- ```
671
-
672
- With custom path:
673
- ```json
674
- {"type": "export_html", "outputPath": "/tmp/session.html"}
675
- ```
676
-
677
- Response:
678
- ```json
679
- {
680
- "type": "response",
681
- "command": "export_html",
682
- "success": true,
683
- "data": {"path": "/tmp/session.html"}
684
- }
685
- ```
196
+ Moved to [RPC protocol](/rpc/protocol#export_html).
686
197
 
687
198
  #### switch_session
688
199
 
689
- Load a different session file. Can be cancelled by a `session_before_switch` extension event handler.
690
-
691
- ```json
692
- {"type": "switch_session", "sessionPath": "/path/to/session.jsonl"}
693
- ```
694
-
695
- Response:
696
- ```json
697
- {"type": "response", "command": "switch_session", "success": true, "data": {"cancelled": false}}
698
- ```
699
-
700
- If an extension cancelled the switch:
701
- ```json
702
- {"type": "response", "command": "switch_session", "success": true, "data": {"cancelled": true}}
703
- ```
200
+ Moved to [RPC protocol](/rpc/protocol#switch_session).
704
201
 
705
202
  #### fork
706
203
 
707
- Create a new fork from a previous user message on the active branch. Can be cancelled by a `session_before_fork` extension event handler. Returns the text of the message being forked from.
708
-
709
- ```json
710
- {"type": "fork", "entryId": "abc123"}
711
- ```
712
-
713
- Response:
714
- ```json
715
- {
716
- "type": "response",
717
- "command": "fork",
718
- "success": true,
719
- "data": {"text": "The original prompt text...", "cancelled": false}
720
- }
721
- ```
722
-
723
- If an extension cancelled the fork:
724
- ```json
725
- {
726
- "type": "response",
727
- "command": "fork",
728
- "success": true,
729
- "data": {"text": "The original prompt text...", "cancelled": true}
730
- }
731
- ```
204
+ Moved to [RPC protocol](/rpc/protocol#fork).
732
205
 
733
206
  #### clone
734
207
 
735
- Duplicate the current active branch into a new session at the current position. Can be cancelled by a `session_before_fork` extension event handler.
736
-
737
- ```json
738
- {"type": "clone"}
739
- ```
740
-
741
- Response:
742
- ```json
743
- {
744
- "type": "response",
745
- "command": "clone",
746
- "success": true,
747
- "data": {"cancelled": false}
748
- }
749
- ```
750
-
751
- If an extension cancelled the clone:
752
- ```json
753
- {
754
- "type": "response",
755
- "command": "clone",
756
- "success": true,
757
- "data": {"cancelled": true}
758
- }
759
- ```
208
+ Moved to [RPC protocol](/rpc/protocol#clone).
760
209
 
761
210
  #### get_fork_messages
762
211
 
763
- Get user messages available for forking.
764
-
765
- ```json
766
- {"type": "get_fork_messages"}
767
- ```
768
-
769
- Response:
770
- ```json
771
- {
772
- "type": "response",
773
- "command": "get_fork_messages",
774
- "success": true,
775
- "data": {
776
- "messages": [
777
- {"entryId": "abc123", "text": "First prompt..."},
778
- {"entryId": "def456", "text": "Second prompt..."}
779
- ]
780
- }
781
- }
782
- ```
212
+ Moved to [RPC protocol](/rpc/protocol#get_fork_messages).
783
213
 
784
214
  #### get_entries
785
215
 
786
- Get all session entries in append order (excluding the session header). The session is an append-only tree of entries with stable ids, so an entry id works as a durable cursor: pass the last entry id you have seen as `since` to get only entries strictly after it, even across client restarts. Unlike `get_messages`, this includes pre-compaction history and abandoned branches.
787
-
788
- ```json
789
- {"type": "get_entries"}
790
- ```
791
-
792
- With a cursor:
793
- ```json
794
- {"type": "get_entries", "since": "abc123"}
795
- ```
796
-
797
- Response:
798
- ```json
799
- {
800
- "type": "response",
801
- "command": "get_entries",
802
- "success": true,
803
- "data": {
804
- "entries": [
805
- {"type": "message", "id": "def456", "parentId": "abc123", "timestamp": "...", "message": {"role": "user", "...": "..."}}
806
- ],
807
- "leafId": "def456"
808
- }
809
- }
810
- ```
811
-
812
- `leafId` is the id of the current leaf entry (`null` for an empty session), so a client can tell in one round trip whether the active branch moved. If `since` does not match any entry id, the response is `success: false`.
216
+ Moved to [RPC protocol](/rpc/protocol#get_entries).
813
217
 
814
218
  #### get_tree
815
219
 
816
- Get the session as a tree of entries. Each node is `{entry, children, label?, labelTimestamp?}`. A well-formed session has a single root; orphaned entries (broken parent chain) also appear as roots.
817
-
818
- ```json
819
- {"type": "get_tree"}
820
- ```
821
-
822
- Response:
823
- ```json
824
- {
825
- "type": "response",
826
- "command": "get_tree",
827
- "success": true,
828
- "data": {
829
- "tree": [
830
- {
831
- "entry": {"type": "message", "id": "abc123", "parentId": null, "...": "..."},
832
- "children": [
833
- {"entry": {"type": "message", "id": "def456", "parentId": "abc123", "...": "..."}, "children": []}
834
- ]
835
- }
836
- ],
837
- "leafId": "def456"
838
- }
839
- }
840
- ```
220
+ Moved to [RPC protocol](/rpc/protocol#get_tree).
841
221
 
842
222
  #### get_last_assistant_text
843
223
 
844
- Get the text content of the last assistant message.
845
-
846
- ```json
847
- {"type": "get_last_assistant_text"}
848
- ```
849
-
850
- Response:
851
- ```json
852
- {
853
- "type": "response",
854
- "command": "get_last_assistant_text",
855
- "success": true,
856
- "data": {"text": "The assistant's response..."}
857
- }
858
- ```
859
-
860
- Returns `{"text": null}` if no assistant messages exist.
224
+ Moved to [RPC protocol](/rpc/protocol#get_last_assistant_text).
861
225
 
862
226
  #### set_session_name
863
227
 
864
- Set a display name for the current session. The name appears in session listings and helps identify sessions.
865
-
866
- ```json
867
- {"type": "set_session_name", "name": "my-feature-work"}
868
- ```
869
-
870
- Response:
871
- ```json
872
- {
873
- "type": "response",
874
- "command": "set_session_name",
875
- "success": true
876
- }
877
- ```
878
-
879
- The current session name is available via `get_state` in the `sessionName` field. To set the initial name when starting RPC mode, pass `--name <name>` or `-n <name>` to the `atomic --mode rpc` process.
228
+ Moved to [RPC protocol](/rpc/protocol#set_session_name).
880
229
 
881
230
  ### Commands
882
231
 
883
- #### get_commands
884
-
885
- Get available commands (extension commands, prompt templates, and skills). These can be invoked via the `prompt` command by prefixing with `/`.
886
-
887
- ```json
888
- {"type": "get_commands"}
889
- ```
232
+ Moved to [RPC protocol](/rpc/protocol#commands-2).
890
233
 
891
- Response:
892
- ```json
893
- {
894
- "type": "response",
895
- "command": "get_commands",
896
- "success": true,
897
- "data": {
898
- "commands": [
899
- {"name": "session-name", "description": "Set or clear session name", "source": "extension", "path": "/home/user/.atomic/agent/extensions/session.ts"},
900
- {"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "location": "project", "path": "/home/user/myproject/.atomic/prompts/fix-tests.md"},
901
- {"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "location": "user", "path": "/home/user/.atomic/agent/skills/brave-search/SKILL.md"}
902
- ]
903
- }
904
- }
905
- ```
234
+ #### get_commands
906
235
 
907
- Each command has:
908
- - `name`: Command name (invoke with `/name`)
909
- - `description`: Human-readable description (optional for extension commands)
910
- - `source`: What kind of command:
911
- - `"extension"`: Registered via `pi.registerCommand()` in an extension
912
- - `"prompt"`: Loaded from a prompt template `.md` file
913
- - `"skill"`: Loaded from a skill directory (name is prefixed with `skill:`)
914
- - `location`: Where it was loaded from (optional, not present for extensions):
915
- - `"user"`: User-level (`~/.atomic/agent/`)
916
- - `"project"`: Project-level (`./.atomic/`)
917
- - `"path"`: Explicit path via CLI or settings
918
- - `path`: Absolute file path to the command source (optional)
919
-
920
- **Note**: Built-in TUI commands (`/settings`, `/hotkeys`, etc.) are not included. They are handled only in interactive mode and would not execute if sent via `prompt`.
236
+ Moved to [RPC protocol](/rpc/protocol#get_commands).
921
237
 
922
238
  ## Events
923
239
 
924
- Events are streamed to stdout as JSON lines. Most events do not include an `id`; `bash_execution_update` is the deliberate exception and uses the originating bash request ID.
240
+ Moved to [RPC protocol](/rpc/protocol#events).
925
241
 
926
242
  ### Event Types
927
243
 
928
- | Event | Description |
929
- |-------|-------------|
930
- | `agent_start` | Agent begins processing |
931
- | `agent_end` | Agent completes (includes all generated messages) |
932
- | `turn_start` | New turn begins |
933
- | `turn_end` | Turn completes (includes assistant message and tool results) |
934
- | `message_start` | Message begins |
935
- | `message_update` | Streaming update (text/thinking/toolcall deltas) |
936
- | `message_end` | Message completes |
937
- | `tool_execution_start` | Tool begins execution; includes `toolCallId`, `toolName`, and initial arguments |
938
- | `tool_execution_update` | Tool execution progress (streaming output) |
939
- | `tool_execution_end` | Tool completes |
940
- | `bash_execution_update` | Correlated direct-bash stdout/stderr delta |
941
- | `queue_update` | Pending steering/follow-up queue changed |
942
- | `compaction_start` | Verbatim line compaction begins |
943
- | `compaction_end` | Verbatim line compaction completes |
944
- | `auto_retry_start` | Auto-retry begins (after transient error) |
945
- | `auto_retry_end` | Auto-retry completes (success or final failure) |
946
- | `summarization_retry_scheduled` | Retry scheduled for a transient compaction or branch-summary provider error |
947
- | `summarization_retry_attempt_start` | Retried summarization request starts |
948
- | `summarization_retry_finished` | Summarization retry loop completes |
949
- | `extension_error` | Extension threw an error |
244
+ Moved to [RPC protocol](/rpc/protocol#event-types).
950
245
 
951
246
  ### agent_start
952
247
 
953
- Emitted when the agent begins processing a prompt.
954
-
955
- ```json
956
- {"type": "agent_start"}
957
- ```
248
+ Moved to [RPC protocol](/rpc/protocol#agent_start).
958
249
 
959
250
  ### agent_end
960
251
 
961
- Emitted when the agent completes. Contains all messages generated during this run.
962
-
963
- ```json
964
- {
965
- "type": "agent_end",
966
- "messages": [...]
967
- }
968
- ```
252
+ Moved to [RPC protocol](/rpc/protocol#agent_end).
969
253
 
970
254
  ### turn_start / turn_end
971
255
 
972
- A turn consists of one assistant response plus any resulting tool calls and results.
973
-
974
- ```json
975
- {"type": "turn_start"}
976
- ```
977
-
978
- ```json
979
- {
980
- "type": "turn_end",
981
- "message": {...},
982
- "toolResults": [...]
983
- }
984
- ```
256
+ Moved to [RPC protocol](/rpc/protocol#turn_start-/-turn_end).
985
257
 
986
258
  ### message_start / message_end
987
259
 
988
- Emitted when a message begins and completes. The `message` field contains an `AgentMessage`.
989
-
990
- ```json
991
- {"type": "message_start", "message": {...}}
992
- {"type": "message_end", "message": {...}}
993
- ```
260
+ Moved to [RPC protocol](/rpc/protocol#message_start-/-message_end).
994
261
 
995
262
  ### message_update (Streaming)
996
263
 
997
- Emitted during streaming of assistant messages. Carries the streaming delta plus the latest cumulative usage.
998
-
999
- `message_update` deliberately omits the cumulative message snapshot: there is no `message`
1000
- field, and `assistantMessageEvent` has no `partial`. `message_start` provides the
1001
- initial message, the deltas build it, and `message_end` provides the final
1002
- authoritative message. Repeating a snapshot on every frame would make the bytes
1003
- written per assistant turn grow with the square of its length.
1004
-
1005
- The top-level `usage` field carries the latest cumulative provider-reported usage; it may
1006
- remain zero until completion when a provider does not report usage during streaming. When
1007
- the provider reports an explicit end-of-turn signal (pi-ai's `AssistantMessage.endTurn`,
1008
- for example OpenAI Codex `end_turn`), the update carries it as a top-level `endTurn`
1009
- boolean — present only when the provider reported one.
1010
-
1011
- ```json
1012
- {
1013
- "type": "message_update",
1014
- "usage": {
1015
- "input": 100,
1016
- "output": 1,
1017
- "cacheRead": 0,
1018
- "cacheWrite": 0,
1019
- "totalTokens": 101,
1020
- "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0, "total": 0}
1021
- },
1022
- "assistantMessageEvent": {
1023
- "type": "text_delta",
1024
- "contentIndex": 0,
1025
- "delta": "Hello "
1026
- }
1027
- }
1028
- ```
1029
-
1030
- The `assistantMessageEvent` field contains one of these delta types:
1031
-
1032
- | Type | Description |
1033
- |------|-------------|
1034
- | `start` | Message generation started |
1035
- | `text_start` | Text content block started |
1036
- | `text_delta` | Text content chunk |
1037
- | `text_end` | Text content block ended |
1038
- | `thinking_start` | Thinking block started |
1039
- | `thinking_delta` | Thinking content chunk |
1040
- | `thinking_end` | Thinking block ended |
1041
- | `toolcall_start` | Tool call started |
1042
- | `toolcall_delta` | Tool call arguments chunk |
1043
- | `toolcall_end` | Tool call ended (includes full `toolCall` object) |
1044
- | `done` | Message complete (reason: `"stop"`, `"length"`, `"toolUse"`) |
1045
- | `error` | Error occurred (reason: `"aborted"`, `"error"`) |
1046
-
1047
- Example streaming a text response:
1048
- ```json
1049
- {"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_start","contentIndex":0}}
1050
- {"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}}
1051
- {"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":" world"}}
1052
- {"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_end","contentIndex":0,"content":"Hello world"}}
1053
- ```
264
+ Moved to [RPC protocol](/rpc/protocol#message_update-streaming).
1054
265
 
1055
266
  ### tool_execution_start / tool_execution_update / tool_execution_end
1056
267
 
1057
- Emitted when a tool begins, streams progress, and completes execution.
1058
-
1059
- ```json
1060
- {
1061
- "type": "tool_execution_start",
1062
- "toolCallId": "call_abc123",
1063
- "toolName": "bash",
1064
- "args": {"command": "ls -la"}
1065
- }
1066
- ```
1067
-
1068
- During execution, `tool_execution_update` events stream partial results (e.g., bash output as it arrives):
1069
-
1070
- ```json
1071
- {
1072
- "type": "tool_execution_update",
1073
- "toolCallId": "call_abc123",
1074
- "toolName": "bash",
1075
- "args": {"command": "ls -la"},
1076
- "partialResult": {
1077
- "content": [{"type": "text", "text": "partial output so far..."}],
1078
- "details": {"truncation": null, "fullOutputPath": null}
1079
- }
1080
- }
1081
- ```
1082
-
1083
- When complete:
1084
-
1085
- ```json
1086
- {
1087
- "type": "tool_execution_end",
1088
- "toolCallId": "call_abc123",
1089
- "toolName": "bash",
1090
- "result": {
1091
- "content": [{"type": "text", "text": "total 48\n..."}],
1092
- "details": {...}
1093
- },
1094
- "isError": false
1095
- }
1096
- ```
1097
-
1098
- Use `toolCallId` to correlate events. The `partialResult` in `tool_execution_update` contains the accumulated output so far (not just the delta), allowing clients to simply replace their display on each update.
268
+ Moved to [RPC protocol](/rpc/protocol#tool_execution_start-/-tool_execution_update-/-tool_execution_end).
1099
269
 
1100
270
  ### bash_execution_update
1101
271
 
1102
- Emitted only for direct `bash` and non-intercepted `user_bash` RPC execution. Each event is `{type, id?, channel, delta}` where `channel` is `"stdout"` or `"stderr"`; use `id` to keep concurrent streams separate. Tool-call bash continues to use `tool_execution_update` and its `toolCallId`.
272
+ Moved to [RPC protocol](/rpc/protocol#bash_execution_update).
1103
273
 
1104
274
  ### queue_update
1105
275
 
1106
- Emitted whenever the pending steering or follow-up queue changes.
1107
-
1108
- ```json
1109
- {
1110
- "type": "queue_update",
1111
- "steering": ["Focus on error handling"],
1112
- "followUp": ["After that, summarize the result"]
1113
- }
1114
- ```
276
+ Moved to [RPC protocol](/rpc/protocol#queue_update).
1115
277
 
1116
278
  ### compaction_start / compaction_end
1117
279
 
1118
- Emitted when default Verbatim Compaction runs, whether manual or automatic. The result records deletion targets and stats rather than a generated summary.
1119
-
1120
- ```json
1121
- {"type": "compaction_start", "reason": "threshold"}
1122
- ```
1123
-
1124
- The `reason` field is `"manual"`, `"threshold"`, or `"overflow"`.
1125
-
1126
- ```json
1127
- {
1128
- "type": "compaction_end",
1129
- "reason": "threshold",
1130
- "result": {
1131
- "compactedText": "[User]: fix the test\n(filtered 42 lines)",
1132
- "firstKeptEntryId": "m7",
1133
- "tokensBefore": 150000,
1134
- "promptVersion": 3,
1135
- "parameters": {"compression_ratio": 0.5, "preserve_recent": 2, "query": "fix the test"},
1136
- "rung": "planned",
1137
- "stats": {
1138
- "linesBefore": 812,
1139
- "linesDeleted": 417,
1140
- "linesKept": 395,
1141
- "rangeCount": 63,
1142
- "tokensBefore": 150000,
1143
- "tokensAfter": 72000,
1144
- "percentReduction": 52
1145
- }
1146
- },
1147
- "aborted": false,
1148
- "willRetry": false
1149
- }
1150
- ```
1151
-
1152
- If `reason` was `"overflow"` and compaction succeeds, `willRetry` is `true` and the agent will automatically retry the prompt. Public prompt/RPC callers wait for that post-compaction continuation before the prompt is considered complete.
1153
-
1154
- If compaction was aborted, `result` is `null` and `aborted` is `true`.
1155
-
1156
- If compaction failed (e.g., API quota exceeded), `result` is `null`, `aborted` is `false`, and `errorMessage` contains the error description.
1157
-
1158
- `result` and `errorMessage` are independent. A mid-turn post-tool compaction can commit a boundary and *then* fail the provider hard-input-limit gate, so one `compaction_end` may carry both a non-null `result` and an `errorMessage`. Treat the result as a committed durable boundary in that case; the error describes the follow-up request that was not sent.
1159
-
1160
- If overflow recovery exhausts the same-model compact-and-retry attempt, `compaction_end` includes `"unresolvedOverflow": true` and an `errorMessage`. Workflow orchestration treats that signal as a context-length failure that can advance configured model fallback tiers.
1161
-
1162
- There is no `context_compact` command; Atomic reports it as an unknown command. Use `compact`. Only `compaction_start` and `compaction_end` events are emitted.
280
+ Moved to [RPC protocol](/rpc/protocol#compaction_start-/-compaction_end).
1163
281
 
1164
282
  ### auto_retry_start / auto_retry_end
1165
283
 
1166
- Emitted when automatic retry is triggered after a transient error (overloaded, rate limit, 5xx).
1167
-
1168
- ```json
1169
- {
1170
- "type": "auto_retry_start",
1171
- "attempt": 1,
1172
- "maxAttempts": 3,
1173
- "delayMs": 2000,
1174
- "errorMessage": "529 {\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"}}"
1175
- }
1176
- ```
1177
-
1178
- ```json
1179
- {
1180
- "type": "auto_retry_end",
1181
- "success": true,
1182
- "attempt": 2
1183
- }
1184
- ```
1185
-
1186
- On final failure (max retries exceeded):
1187
- ```json
1188
- {
1189
- "type": "auto_retry_end",
1190
- "success": false,
1191
- "attempt": 3,
1192
- "finalError": "529 overloaded_error: Overloaded"
1193
- }
1194
- ```
1195
-
284
+ Moved to [RPC protocol](/rpc/protocol#auto_retry_start-/-auto_retry_end).
1196
285
 
1197
286
  ### summarization_retry_scheduled / summarization_retry_attempt_start / summarization_retry_finished
1198
287
 
1199
- Emitted when compaction planning or branch summarization retries after a transient provider error. These events use the same retry settings as automatic assistant-turn retries.
1200
-
1201
- ```json
1202
- {
1203
- "type": "summarization_retry_scheduled",
1204
- "attempt": 1,
1205
- "maxAttempts": 3,
1206
- "delayMs": 2000,
1207
- "errorMessage": "terminated"
1208
- }
1209
- ```
1210
-
1211
- ```json
1212
- {
1213
- "type": "summarization_retry_attempt_start",
1214
- "source": "compaction",
1215
- "reason": "threshold"
1216
- }
1217
- ```
1218
-
1219
- For branch summaries, `source` is `"branchSummary"` and no `reason` is present. The loop then emits:
288
+ Moved to [RPC protocol](/rpc/protocol#summarization_retry_scheduled-/-summarization_retry_attempt_start-/-summarization_retry_finished).
1220
289
 
1221
- ```json
1222
- {"type": "summarization_retry_finished"}
1223
- ```
1224
290
  ### extension_error
1225
291
 
1226
- Emitted when an extension throws an error.
1227
-
1228
- ```json
1229
- {
1230
- "type": "extension_error",
1231
- "extensionPath": "/path/to/extension.ts",
1232
- "event": "tool_call",
1233
- "error": "Error message..."
1234
- }
1235
- ```
292
+ Moved to [RPC protocol](/rpc/protocol#extension_error).
1236
293
 
1237
294
  ## Extension UI Protocol
1238
295
 
1239
- Extensions can request user interaction via `ctx.ui.select()`, `ctx.ui.confirm()`, etc. In RPC mode, these are translated into a request/response sub-protocol on top of the base command/event flow.
1240
-
1241
- There are two categories of extension UI methods:
1242
-
1243
- - **Dialog methods** (`select`, `confirm`, `input`, `editor`): emit an `extension_ui_request` on stdout and block until the client sends back an `extension_ui_response` on stdin with the matching `id`.
1244
- - **Fire-and-forget methods** (`notify`, `setStatus`, `setWidget`, `setTitle`, `set_editor_text`): emit an `extension_ui_request` on stdout but do not expect a response. The client can display the information or ignore it.
1245
-
1246
- If a dialog method includes a `timeout` field, the agent-side will auto-resolve with a default value when the timeout expires. The client does not need to track timeouts.
1247
-
1248
- Some `ExtensionUIContext` methods are not supported or degraded in RPC mode because they require direct TUI access:
1249
- - `custom()` returns `undefined`
1250
- - `setWorkingMessage()`, `setWorkingIndicator()`, `setFooter()`, `setHeader()`, `setEditorComponent()` are no-ops
1251
- - `getEditorText()` returns `""`
1252
- - `setToolsExpanded()` and `getToolsExpanded()` maintain context-local expansion state; `getChatRenderSettings().toolOutputExpanded` reports the same value. A same-value `setToolsExpanded()` call is a no-op and does not request a custom-UI render. This state is not sent through the client extension-UI protocol.
1253
- - `pasteToEditor()` delegates to `setEditorText()` (no paste/collapse handling)
1254
- - `getAllThemes()` returns `[]`
1255
- - `getTheme()` returns `undefined`
1256
- - `setTheme()` returns `{ success: false, error: "..." }`
1257
-
1258
- Note: `ctx.mode` is `"rpc"` and `ctx.hasUI` is `true` in RPC mode because the dialog and fire-and-forget methods are functional via the extension UI sub-protocol. Use `ctx.mode === "tui"` to guard TUI-specific features like `custom()` that require a real terminal.
296
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#extension-ui-protocol).
1259
297
 
1260
298
  ### Extension UI Requests (stdout)
1261
299
 
1262
- All requests have `type: "extension_ui_request"`, a unique `id`, and a `method` field.
300
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#extension-ui-requests-stdout).
1263
301
 
1264
302
  #### select
1265
303
 
1266
- Prompt the user to choose from a list. Dialog methods with a `timeout` field include the timeout in milliseconds; the agent auto-resolves with `undefined` if the client doesn't respond in time.
1267
-
1268
- ```json
1269
- {
1270
- "type": "extension_ui_request",
1271
- "id": "uuid-1",
1272
- "method": "select",
1273
- "title": "Allow dangerous command?",
1274
- "options": ["Allow", "Block"],
1275
- "timeout": 10000
1276
- }
1277
- ```
1278
-
1279
- Expected response: `extension_ui_response` with `value` (the selected option string) or `cancelled: true`.
304
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#select).
1280
305
 
1281
306
  #### confirm
1282
307
 
1283
- Prompt the user for yes/no confirmation.
1284
-
1285
- ```json
1286
- {
1287
- "type": "extension_ui_request",
1288
- "id": "uuid-2",
1289
- "method": "confirm",
1290
- "title": "Clear session?",
1291
- "message": "All messages will be lost.",
1292
- "timeout": 5000
1293
- }
1294
- ```
1295
-
1296
- Expected response: `extension_ui_response` with `confirmed: true/false` or `cancelled: true`.
308
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#confirm).
1297
309
 
1298
310
  #### input
1299
311
 
1300
- Prompt the user for free-form text.
1301
-
1302
- ```json
1303
- {
1304
- "type": "extension_ui_request",
1305
- "id": "uuid-3",
1306
- "method": "input",
1307
- "title": "Enter a value",
1308
- "placeholder": "type something..."
1309
- }
1310
- ```
1311
-
1312
- Expected response: `extension_ui_response` with `value` (the entered text) or `cancelled: true`.
312
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#input).
1313
313
 
1314
314
  #### editor
1315
315
 
1316
- Open a multi-line text editor with optional prefilled content.
1317
-
1318
- ```json
1319
- {
1320
- "type": "extension_ui_request",
1321
- "id": "uuid-4",
1322
- "method": "editor",
1323
- "title": "Edit some text",
1324
- "prefill": "Line 1\nLine 2\nLine 3"
1325
- }
1326
- ```
1327
-
1328
- Expected response: `extension_ui_response` with `value` (the edited text) or `cancelled: true`.
316
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#editor).
1329
317
 
1330
318
  #### notify
1331
319
 
1332
- Display a notification. Fire-and-forget, no response expected.
1333
-
1334
- ```json
1335
- {
1336
- "type": "extension_ui_request",
1337
- "id": "uuid-5",
1338
- "method": "notify",
1339
- "message": "Command blocked by user",
1340
- "notifyType": "warning"
1341
- }
1342
- ```
1343
-
1344
- The `notifyType` field is `"info"`, `"warning"`, or `"error"`. Defaults to `"info"` if omitted.
320
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#notify).
1345
321
 
1346
322
  #### setStatus
1347
323
 
1348
- Set or clear a status entry in the footer/status bar. Fire-and-forget.
1349
-
1350
- ```json
1351
- {
1352
- "type": "extension_ui_request",
1353
- "id": "uuid-6",
1354
- "method": "setStatus",
1355
- "statusKey": "my-ext",
1356
- "statusText": "Turn 3 running..."
1357
- }
1358
- ```
1359
-
1360
- Send `statusText: undefined` (or omit it) to clear the status entry for that key.
324
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#setstatus).
1361
325
 
1362
326
  #### setWidget
1363
327
 
1364
- Set or clear a widget (block of text lines) displayed above or below the editor. Fire-and-forget.
1365
-
1366
- ```json
1367
- {
1368
- "type": "extension_ui_request",
1369
- "id": "uuid-7",
1370
- "method": "setWidget",
1371
- "widgetKey": "my-ext",
1372
- "widgetLines": ["--- My Widget ---", "Line 1", "Line 2"],
1373
- "widgetPlacement": "aboveEditor"
1374
- }
1375
- ```
1376
-
1377
- Send `widgetLines: undefined` (or omit it) to clear the widget. The `widgetPlacement` field is `"aboveEditor"` (default) or `"belowEditor"`. Only string arrays are supported in RPC mode; component factories are ignored.
328
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#setwidget).
1378
329
 
1379
330
  #### setTitle
1380
331
 
1381
- Set the terminal window/tab title. Fire-and-forget.
1382
-
1383
- ```json
1384
- {
1385
- "type": "extension_ui_request",
1386
- "id": "uuid-8",
1387
- "method": "setTitle",
1388
- "title": "atomic - my project"
1389
- }
1390
- ```
332
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#settitle).
1391
333
 
1392
334
  #### set_editor_text
1393
335
 
1394
- Set the text in the input editor. Fire-and-forget.
1395
-
1396
- ```json
1397
- {
1398
- "type": "extension_ui_request",
1399
- "id": "uuid-9",
1400
- "method": "set_editor_text",
1401
- "text": "prefilled text for the user"
1402
- }
1403
- ```
336
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#set_editor_text).
1404
337
 
1405
338
  ### Extension UI Responses (stdin)
1406
339
 
1407
- Responses are sent for dialog methods only (`select`, `confirm`, `input`, `editor`). The `id` must match the request.
340
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#extension-ui-responses-stdin).
1408
341
 
1409
342
  #### Value response (select, input, editor)
1410
343
 
1411
- ```json
1412
- {"type": "extension_ui_response", "id": "uuid-1", "value": "Allow"}
1413
- ```
344
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#value-response-select-input-editor).
1414
345
 
1415
346
  #### Confirmation response (confirm)
1416
347
 
1417
- ```json
1418
- {"type": "extension_ui_response", "id": "uuid-2", "confirmed": true}
1419
- ```
348
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#confirmation-response-confirm).
1420
349
 
1421
350
  #### Cancellation response (any dialog)
1422
351
 
1423
- Dismiss any dialog method. The extension receives `undefined` (for select/input/editor) or `false` (for confirm).
1424
-
1425
- ```json
1426
- {"type": "extension_ui_response", "id": "uuid-3", "cancelled": true}
1427
- ```
352
+ Moved to [RPC extension UI protocol](/rpc/extension-ui#cancellation-response-any-dialog).
1428
353
 
1429
354
  ## Error Handling
1430
355
 
1431
- Failed commands return a response with `success: false`:
1432
-
1433
- ```json
1434
- {
1435
- "type": "response",
1436
- "command": "set_model",
1437
- "success": false,
1438
- "error": "Model not found: invalid/model"
1439
- }
1440
- ```
1441
-
1442
- Parse errors:
1443
-
1444
- ```json
1445
- {
1446
- "type": "response",
1447
- "command": "parse",
1448
- "success": false,
1449
- "error": "Failed to parse command: Unexpected token..."
1450
- }
1451
- ```
356
+ Moved to [RPC protocol](/rpc/protocol#error-handling).
1452
357
 
1453
358
  ## Types
1454
359
 
1455
- Source files and installed definitions:
1456
- - `node_modules/@bastani/pi-ai/dist/types.d.ts` - `Model`, `UserMessage`, `AssistantMessage`, `ToolResultMessage`
1457
- - `node_modules/@earendil-works/pi-agent-core/dist/types.d.ts` - `AgentMessage`, `AgentEvent`
1458
- - [`src/core/messages.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/messages.ts) - `BashExecutionMessage`
1459
- - [`src/modes/rpc/rpc-types.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/modes/rpc/rpc-types.ts) - RPC command/response types, extension UI request/response types
360
+ Moved to [RPC protocol](/rpc/protocol#types).
1460
361
 
1461
362
  ### Model
1462
363
 
1463
- ```json
1464
- {
1465
- "id": "claude-sonnet-4-20250514",
1466
- "name": "Claude Sonnet 4",
1467
- "api": "anthropic-messages",
1468
- "provider": "anthropic",
1469
- "baseUrl": "https://api.anthropic.com",
1470
- "reasoning": true,
1471
- "input": ["text", "image"],
1472
- "contextWindow": 200000,
1473
- "maxTokens": 16384,
1474
- "cost": {
1475
- "input": 3.0,
1476
- "output": 15.0,
1477
- "cacheRead": 0.3,
1478
- "cacheWrite": 3.75
1479
- }
1480
- }
1481
- ```
1482
-
1483
- `contextWindow` is the model's token budget used by Atomic's local budgeting, footer/stats, and compaction logic.
364
+ Moved to [RPC protocol](/rpc/protocol#model-2).
1484
365
 
1485
366
  ### UserMessage
1486
367
 
1487
- ```json
1488
- {
1489
- "role": "user",
1490
- "content": "Hello!",
1491
- "timestamp": 1733234567890
1492
- }
1493
- ```
1494
-
1495
- The `content` field can be a string or an array of `TextContent`/`ImageContent` blocks.
368
+ Moved to [RPC protocol](/rpc/protocol#usermessage).
1496
369
 
1497
370
  ### AssistantMessage
1498
371
 
1499
- ```json
1500
- {
1501
- "role": "assistant",
1502
- "content": [
1503
- {"type": "text", "text": "Hello! How can I help?"},
1504
- {"type": "thinking", "thinking": "User is greeting me..."},
1505
- {"type": "toolCall", "id": "call_123", "name": "bash", "arguments": {"command": "ls"}}
1506
- ],
1507
- "api": "anthropic-messages",
1508
- "provider": "anthropic",
1509
- "model": "claude-sonnet-4-20250514",
1510
- "usage": {
1511
- "input": 100,
1512
- "output": 50,
1513
- "cacheRead": 0,
1514
- "cacheWrite": 0,
1515
- "cost": {"input": 0.0003, "output": 0.00075, "cacheRead": 0, "cacheWrite": 0, "total": 0.00105}
1516
- },
1517
- "stopReason": "stop",
1518
- "timestamp": 1733234567890
1519
- }
1520
- ```
1521
-
1522
- Stop reasons: `"stop"`, `"length"`, `"toolUse"`, `"error"`, `"aborted"`. A streaming message carries `"pending"` until the terminal event replaces it, so a client that switches on the reason needs that case; a completed message never carries it. On the wire the pending reason appears on the `message_start` message — `message_update` frames carry no message at all — and `message_end` carries the terminal reason. A provider that reports an explicit end-of-turn signal (pi-ai's `AssistantMessage.endTurn`, for example OpenAI Codex `end_turn`) sets `endTurn: true` on the assistant message; `message_update` frames echo it as a top-level boolean only when the provider reported one.
372
+ Moved to [RPC protocol](/rpc/protocol#assistantmessage).
1523
373
 
1524
374
  ### ToolResultMessage
1525
375
 
1526
- ```json
1527
- {
1528
- "role": "toolResult",
1529
- "toolCallId": "call_123",
1530
- "toolName": "bash",
1531
- "content": [{"type": "text", "text": "total 48\ndrwxr-xr-x ..."}],
1532
- "isError": false,
1533
- "timestamp": 1733234567890
1534
- }
1535
- ```
376
+ Moved to [RPC protocol](/rpc/protocol#toolresultmessage).
1536
377
 
1537
378
  ### BashExecutionMessage
1538
379
 
1539
- Created by the `bash` RPC command (not by LLM tool calls):
1540
-
1541
- ```json
1542
- {
1543
- "role": "bashExecution",
1544
- "command": "ls -la",
1545
- "output": "total 48\ndrwxr-xr-x ...",
1546
- "exitCode": 0,
1547
- "cancelled": false,
1548
- "truncated": false,
1549
- "fullOutputPath": null,
1550
- "timestamp": 1733234567890
1551
- }
1552
- ```
380
+ Moved to [RPC protocol](/rpc/protocol#bashexecutionmessage).
1553
381
 
1554
382
  ### Attachment
1555
383
 
1556
- ```json
1557
- {
1558
- "id": "img1",
1559
- "type": "image",
1560
- "fileName": "photo.jpg",
1561
- "mimeType": "image/jpeg",
1562
- "size": 102400,
1563
- "content": "base64-encoded-data...",
1564
- "extractedText": null,
1565
- "preview": null
1566
- }
1567
- ```
384
+ Moved to [RPC protocol](/rpc/protocol#attachment).
1568
385
 
1569
386
  ## Example: Basic Client (Python)
1570
387
 
@@ -1604,58 +421,4 @@ for event in read_events():
1604
421
 
1605
422
  ## Example: Interactive Client (Node.js)
1606
423
 
1607
- See [`test/rpc-example.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/test/rpc-example.ts) for a complete interactive example, or [`src/modes/rpc/rpc-client.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/modes/rpc/rpc-client.ts) for a typed client implementation.
1608
-
1609
- For a complete example of handling the extension UI protocol, see [`examples/rpc-extension-ui.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/examples/rpc-extension-ui.ts) which pairs with the [`examples/extensions/rpc-demo.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/examples/extensions/rpc-demo.ts) extension.
1610
-
1611
- ```javascript
1612
- const { spawn } = require("child_process");
1613
- const { StringDecoder } = require("string_decoder");
1614
-
1615
- const agent = spawn("atomic", ["--mode", "rpc", "--no-session"]);
1616
-
1617
- function attachJsonlReader(stream, onLine) {
1618
- const decoder = new StringDecoder("utf8");
1619
- let buffer = "";
1620
-
1621
- stream.on("data", (chunk) => {
1622
- buffer += typeof chunk === "string" ? chunk : decoder.write(chunk);
1623
-
1624
- while (true) {
1625
- const newlineIndex = buffer.indexOf("\n");
1626
- if (newlineIndex === -1) break;
1627
-
1628
- let line = buffer.slice(0, newlineIndex);
1629
- buffer = buffer.slice(newlineIndex + 1);
1630
- if (line.endsWith("\r")) line = line.slice(0, -1);
1631
- onLine(line);
1632
- }
1633
- });
1634
-
1635
- stream.on("end", () => {
1636
- buffer += decoder.end();
1637
- if (buffer.length > 0) {
1638
- onLine(buffer.endsWith("\r") ? buffer.slice(0, -1) : buffer);
1639
- }
1640
- });
1641
- }
1642
-
1643
- attachJsonlReader(agent.stdout, (line) => {
1644
- const event = JSON.parse(line);
1645
-
1646
- if (event.type === "message_update") {
1647
- const { assistantMessageEvent } = event;
1648
- if (assistantMessageEvent.type === "text_delta") {
1649
- process.stdout.write(assistantMessageEvent.delta);
1650
- }
1651
- }
1652
- });
1653
-
1654
- // Send prompt
1655
- agent.stdin.write(JSON.stringify({ type: "prompt", message: "Hello" }) + "\n");
1656
-
1657
- // Abort on CTRL+C
1658
- process.on("SIGINT", () => {
1659
- agent.stdin.write(JSON.stringify({ type: "abort" }) + "\n");
1660
- });
1661
- ```
424
+ Moved to [RPC client examples](/rpc/examples#example-interactive-client-node-js).