@adecore/agents 0.31.9 → 0.31.11

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.
@@ -0,0 +1,475 @@
1
+ {
2
+ "version": "Grok 1.0.62, `grok --no-auto-update agent stdio`",
3
+ "source": "Recorded from the real CLI on 2026-10-21 in an empty folder: initialize, session/new and one session/prompt for \"Reply with the single word ok.\". Only session/update frames are kept, each with the _meta of its notification, which is where the CLI counts the context; the notifications it sends under _x.ai are left out. The command list is cut, the _meta of initialize and session/new left out, the session id and the folder replaced. Every other field is as the CLI sent it.",
4
+ "sessionId": "grok-session-1",
5
+ "initialize": {
6
+ "protocolVersion": 1,
7
+ "agentCapabilities": {
8
+ "loadSession": true,
9
+ "promptCapabilities": {
10
+ "image": false,
11
+ "audio": false,
12
+ "embeddedContext": true
13
+ },
14
+ "mcpCapabilities": {
15
+ "http": true,
16
+ "sse": true
17
+ },
18
+ "sessionCapabilities": {
19
+ "list": {},
20
+ "resume": {},
21
+ "close": {}
22
+ },
23
+ "auth": {},
24
+ "_meta": {
25
+ "x.ai/fs_notify": true,
26
+ "x.ai/hooks": {
27
+ "blockingEvents": [
28
+ "pre_tool_use",
29
+ "stop",
30
+ "subagent_stop"
31
+ ],
32
+ "decisions": [
33
+ "deny",
34
+ "block"
35
+ ],
36
+ "stopSignals": [
37
+ "continue",
38
+ "stopReason",
39
+ "additionalContext"
40
+ ]
41
+ },
42
+ "x.ai/capabilities": {
43
+ "toolOverrides": {
44
+ "x_keyword_search": true,
45
+ "x_semantic_search": true,
46
+ "x_user_search": false,
47
+ "x_thread_fetch": false
48
+ }
49
+ }
50
+ }
51
+ },
52
+ "authMethods": [
53
+ {
54
+ "id": "cached_token",
55
+ "name": "cached_token",
56
+ "description": "Cached token from ~/.grok/auth.json"
57
+ },
58
+ {
59
+ "id": "grok.com",
60
+ "name": "Grok",
61
+ "description": "Sign in with Grok"
62
+ }
63
+ ]
64
+ },
65
+ "sessionNew": {
66
+ "sessionId": "grok-session-1",
67
+ "models": {
68
+ "currentModelId": "grok-4.7",
69
+ "availableModels": [
70
+ {
71
+ "modelId": "grok-4.7",
72
+ "name": "Grok 4.7",
73
+ "description": "SpaceXAI's latest frontier model",
74
+ "_meta": {
75
+ "totalContextTokens": 256000,
76
+ "agentType": "grok-build-plan",
77
+ "supportsReasoningEffort": true,
78
+ "reasoningEffort": "high",
79
+ "reasoningEfforts": [
80
+ {
81
+ "id": "xhigh",
82
+ "value": "xhigh",
83
+ "label": "Extra High",
84
+ "description": "Maximum reasoning for the hardest tasks.",
85
+ "default": false
86
+ },
87
+ {
88
+ "id": "high",
89
+ "value": "high",
90
+ "label": "High",
91
+ "description": "Thorough reasoning and quality. Recommended.",
92
+ "default": true
93
+ },
94
+ {
95
+ "id": "medium",
96
+ "value": "medium",
97
+ "label": "Medium",
98
+ "description": "Strong quality with a faster turnaround.",
99
+ "default": false
100
+ },
101
+ {
102
+ "id": "low",
103
+ "value": "low",
104
+ "label": "Low",
105
+ "description": "Fastest responses. Best for simple tasks.",
106
+ "default": false
107
+ }
108
+ ],
109
+ "contextWindows": [
110
+ 256000,
111
+ 500000
112
+ ]
113
+ }
114
+ },
115
+ {
116
+ "modelId": "grok-4.7-build-fast",
117
+ "name": "Grok 4.7 Fast",
118
+ "description": "Fast variant. 2x the price.",
119
+ "_meta": {
120
+ "totalContextTokens": 256000,
121
+ "agentType": "grok-build-plan",
122
+ "supportsReasoningEffort": true,
123
+ "reasoningEffort": "high",
124
+ "reasoningEfforts": [
125
+ {
126
+ "id": "xhigh",
127
+ "value": "xhigh",
128
+ "label": "Extra High",
129
+ "description": "Maximum reasoning for the hardest tasks.",
130
+ "default": false
131
+ },
132
+ {
133
+ "id": "high",
134
+ "value": "high",
135
+ "label": "High",
136
+ "description": "Thorough reasoning and quality. Recommended.",
137
+ "default": true
138
+ },
139
+ {
140
+ "id": "medium",
141
+ "value": "medium",
142
+ "label": "Medium",
143
+ "description": "Strong quality with a faster turnaround.",
144
+ "default": false
145
+ },
146
+ {
147
+ "id": "low",
148
+ "value": "low",
149
+ "label": "Low",
150
+ "description": "Fastest responses. Best for simple tasks.",
151
+ "default": false
152
+ }
153
+ ],
154
+ "contextWindows": [
155
+ 256000,
156
+ 500000
157
+ ]
158
+ }
159
+ },
160
+ {
161
+ "modelId": "grok-4.6",
162
+ "name": "Grok 4.6",
163
+ "_meta": {
164
+ "totalContextTokens": 256000,
165
+ "agentType": "grok-build-plan",
166
+ "supportsReasoningEffort": true,
167
+ "reasoningEffort": "high",
168
+ "reasoningEfforts": [
169
+ {
170
+ "id": "xhigh",
171
+ "value": "xhigh",
172
+ "label": "Extra High",
173
+ "description": "Highest effort and reasoning level",
174
+ "default": false
175
+ },
176
+ {
177
+ "id": "high",
178
+ "value": "high",
179
+ "label": "High",
180
+ "description": "Higher implementation quality with extensive reasoning",
181
+ "default": true
182
+ },
183
+ {
184
+ "id": "medium",
185
+ "value": "medium",
186
+ "label": "Medium",
187
+ "description": "Balanced effort with standard implementation and testing",
188
+ "default": false
189
+ },
190
+ {
191
+ "id": "low",
192
+ "value": "low",
193
+ "label": "Low",
194
+ "description": "Quick, fast implementations",
195
+ "default": false
196
+ }
197
+ ],
198
+ "contextWindows": [
199
+ 256000,
200
+ 500000
201
+ ]
202
+ }
203
+ },
204
+ {
205
+ "modelId": "grok-4.5",
206
+ "name": "Grok 4.5",
207
+ "_meta": {
208
+ "totalContextTokens": 256000,
209
+ "agentType": "grok-build-plan",
210
+ "supportsReasoningEffort": true,
211
+ "reasoningEffort": "high",
212
+ "reasoningEfforts": [
213
+ {
214
+ "id": "high",
215
+ "value": "high",
216
+ "label": "High",
217
+ "description": "Highest implementation quality with extensive reasoning",
218
+ "default": true
219
+ },
220
+ {
221
+ "id": "medium",
222
+ "value": "medium",
223
+ "label": "Medium",
224
+ "description": "Balanced effort with standard implementation and testing",
225
+ "default": false
226
+ },
227
+ {
228
+ "id": "low",
229
+ "value": "low",
230
+ "label": "Low",
231
+ "description": "Quick, fast implementations",
232
+ "default": false
233
+ }
234
+ ],
235
+ "contextWindows": [
236
+ 256000,
237
+ 500000
238
+ ]
239
+ }
240
+ }
241
+ ]
242
+ },
243
+ "configOptions": [
244
+ {
245
+ "id": "model",
246
+ "name": "Model",
247
+ "category": "model",
248
+ "type": "select",
249
+ "currentValue": "grok-4.7",
250
+ "options": [
251
+ {
252
+ "value": "grok-4.7",
253
+ "name": "Grok 4.7"
254
+ },
255
+ {
256
+ "value": "grok-4.7-build-fast",
257
+ "name": "Grok 4.7 Fast"
258
+ },
259
+ {
260
+ "value": "grok-4.6",
261
+ "name": "Grok 4.6"
262
+ },
263
+ {
264
+ "value": "grok-4.5",
265
+ "name": "Grok 4.5"
266
+ }
267
+ ]
268
+ },
269
+ {
270
+ "id": "reasoning_effort",
271
+ "name": "Reasoning Effort",
272
+ "category": "thought_level",
273
+ "type": "select",
274
+ "currentValue": "high",
275
+ "options": [
276
+ {
277
+ "value": "xhigh",
278
+ "name": "Extra High",
279
+ "description": "Maximum reasoning for the hardest tasks."
280
+ },
281
+ {
282
+ "value": "high",
283
+ "name": "High",
284
+ "description": "Thorough reasoning and quality. Recommended."
285
+ },
286
+ {
287
+ "value": "medium",
288
+ "name": "Medium",
289
+ "description": "Strong quality with a faster turnaround."
290
+ },
291
+ {
292
+ "value": "low",
293
+ "name": "Low",
294
+ "description": "Fastest responses. Best for simple tasks."
295
+ }
296
+ ]
297
+ }
298
+ ]
299
+ },
300
+ "commands": [
301
+ {
302
+ "name": "compact",
303
+ "description": "Compress conversation history to save context window",
304
+ "input": null
305
+ },
306
+ {
307
+ "name": "context",
308
+ "description": "Show context window usage and session stats",
309
+ "input": null
310
+ }
311
+ ],
312
+ "setConfigOption": {},
313
+ "promptUpdates": [
314
+ {
315
+ "update": {
316
+ "sessionUpdate": "agent_thought_chunk",
317
+ "content": {
318
+ "type": "text",
319
+ "text": "The user wants a single-word"
320
+ }
321
+ },
322
+ "_meta": {
323
+ "totalTokens": 1457,
324
+ "requestTrimmedTokens": 0,
325
+ "eventId": "grok-session-1-6",
326
+ "agentTimestampMs": 1792595946046,
327
+ "promptId": "05ec1787-0632-4aaf-a44a-22a97595a865",
328
+ "streamStartMs": 1792595945078,
329
+ "turnStartMs": 1792595943704,
330
+ "updateType": "AgentThoughtChunk",
331
+ "chunkId": 1
332
+ }
333
+ },
334
+ {
335
+ "update": {
336
+ "sessionUpdate": "agent_thought_chunk",
337
+ "content": {
338
+ "type": "text",
339
+ "text": " reply: \"ok\"."
340
+ }
341
+ },
342
+ "_meta": {
343
+ "totalTokens": 1457,
344
+ "requestTrimmedTokens": 0,
345
+ "eventId": "grok-session-1-7",
346
+ "agentTimestampMs": 1792595946062,
347
+ "promptId": "05ec1787-0632-4aaf-a44a-22a97595a865",
348
+ "streamStartMs": 1792595945078,
349
+ "turnStartMs": 1792595943704,
350
+ "updateType": "AgentThoughtChunk",
351
+ "chunkId": 2
352
+ }
353
+ },
354
+ {
355
+ "update": {
356
+ "sessionUpdate": "agent_message_chunk",
357
+ "content": {
358
+ "type": "text",
359
+ "text": "ok"
360
+ }
361
+ },
362
+ "_meta": {
363
+ "totalTokens": 1457,
364
+ "requestTrimmedTokens": 0,
365
+ "eventId": "grok-session-1-8",
366
+ "agentTimestampMs": 1792595946065,
367
+ "promptId": "05ec1787-0632-4aaf-a44a-22a97595a865",
368
+ "streamStartMs": 1792595945078,
369
+ "turnStartMs": 1792595943704,
370
+ "updateType": "AgentMessageChunk",
371
+ "chunkId": 3
372
+ }
373
+ },
374
+ {
375
+ "update": {
376
+ "sessionUpdate": "available_commands_update",
377
+ "availableCommands": [
378
+ {
379
+ "name": "compact",
380
+ "description": "Compress conversation history to save context window",
381
+ "input": null
382
+ },
383
+ {
384
+ "name": "context",
385
+ "description": "Show context window usage and session stats",
386
+ "input": null
387
+ }
388
+ ],
389
+ "_meta": {
390
+ "tools": [
391
+ "run_terminal_command",
392
+ "read_file",
393
+ "search_replace",
394
+ "list_dir",
395
+ "grep",
396
+ "kill_command_or_subagent",
397
+ "todo_write",
398
+ "get_command_or_subagent_output",
399
+ "spawn_subagent",
400
+ "scheduler_create",
401
+ "scheduler_delete",
402
+ "scheduler_list",
403
+ "monitor",
404
+ "search_tool",
405
+ "use_tool",
406
+ "workflow",
407
+ "enter_plan_mode",
408
+ "exit_plan_mode",
409
+ "ask_user_question",
410
+ "send_feedback",
411
+ "web_search",
412
+ "web_fetch",
413
+ "image_gen",
414
+ "image_edit",
415
+ "image_to_video",
416
+ "reference_to_video",
417
+ "write"
418
+ ]
419
+ }
420
+ },
421
+ "_meta": {
422
+ "totalTokens": 21939,
423
+ "requestTrimmedTokens": 0,
424
+ "eventId": "grok-session-1-9",
425
+ "agentTimestampMs": 1792595946147,
426
+ "promptId": "05ec1787-0632-4aaf-a44a-22a97595a865",
427
+ "streamStartMs": 1792595945078,
428
+ "turnStartMs": 1792595943704,
429
+ "updateType": "AvailableCommandsUpdate",
430
+ "updateParams": {
431
+ "commandsCount": 63
432
+ }
433
+ }
434
+ }
435
+ ],
436
+ "promptResponse": {
437
+ "stopReason": "end_turn",
438
+ "_meta": {
439
+ "sessionId": "grok-session-1",
440
+ "requestId": "05ec1787-0632-4aaf-a44a-22a97595a865",
441
+ "promptId": "05ec1787-0632-4aaf-a44a-22a97595a865",
442
+ "totalTokens": 21939,
443
+ "modelId": "grok-4.7",
444
+ "inputTokens": 21847,
445
+ "outputTokens": 83,
446
+ "cachedReadTokens": 2176,
447
+ "reasoningTokens": 82,
448
+ "usage": {
449
+ "inputTokens": 21847,
450
+ "outputTokens": 83,
451
+ "totalTokens": 21930,
452
+ "cachedReadTokens": 2176,
453
+ "cacheCreationTokens": 0,
454
+ "reasoningTokens": 82,
455
+ "modelCalls": 1,
456
+ "apiDurationMs": 2092,
457
+ "costUsdTicks": 409280000,
458
+ "modelUsage": {
459
+ "grok-4.7-build": {
460
+ "inputTokens": 21847,
461
+ "outputTokens": 83,
462
+ "totalTokens": 21930,
463
+ "cachedReadTokens": 2176,
464
+ "cacheCreationTokens": 0,
465
+ "reasoningTokens": 82,
466
+ "modelCalls": 1,
467
+ "apiDurationMs": 2092,
468
+ "costUsdTicks": 409280000
469
+ }
470
+ },
471
+ "numTurns": 1
472
+ }
473
+ }
474
+ }
475
+ }
@@ -11,6 +11,19 @@ function adoptableModels(info) {
11
11
  .filter((model) => model.id !== '' && !model.id.startsWith('-'))
12
12
  .map((model) => ({ slug: model.id, name: model.name, ...(model.contextWindow === null ? {} : { contextWindow: model.contextWindow }) }));
13
13
  }
14
+ /*
15
+ * An agent may name its choices in lowercase, as Copilot CLI 1.0.101 names its efforts; a person reads them with a
16
+ * capital like every other label. Also applied to what a store kept from before, so only the labels change, never the ids.
17
+ */
18
+ function capitalized(option) {
19
+ if (option.type !== 'select') {
20
+ return option;
21
+ }
22
+ return {
23
+ ...option,
24
+ choices: option.choices.map((choice) => ({ ...choice, label: choice.label.charAt(0).toLocaleUpperCase('en') + choice.label.slice(1) }))
25
+ };
26
+ }
14
27
  /* The reasoning effort a session offers, as the `effort` option the composer draws for every provider. */
15
28
  function effortOption(info) {
16
29
  const level = info.thoughtLevel;
@@ -138,7 +151,7 @@ export class AcpAgentState {
138
151
  return false;
139
152
  }
140
153
  this.adopted = adopted;
141
- return this.options.catalog.adopt(adopted.models, adopted.defaultModel, adopted.options);
154
+ return this.options.catalog.adopt(adopted.models, adopted.defaultModel, adopted.options.map(capitalized));
142
155
  }
143
156
  /* Saves and tells the listeners once something changed. */
144
157
  settle(changed) {
@@ -69,7 +69,8 @@ export class ModelCatalog {
69
69
  legacy: model.legacy === true,
70
70
  isDefault: model.slug === this.data.defaultModel,
71
71
  options: this.profileOf(model.slug)?.options ?? [],
72
- ...(model.minCliVersion === undefined ? {} : { minCliVersion: model.minCliVersion })
72
+ ...(model.minCliVersion === undefined ? {} : { minCliVersion: model.minCliVersion }),
73
+ ...(model.tools === undefined ? {} : { tools: model.tools })
73
74
  }));
74
75
  }
75
76
  /* What a person reads for a model, so an error in a thread names it the way the picker does. */
@@ -7,5 +7,6 @@ export interface AcpCapture {
7
7
  setConfigOption: unknown;
8
8
  promptUpdates: unknown[];
9
9
  promptResponse: unknown;
10
+ titleFromPrompt?: boolean;
10
11
  }
11
- export declare function fakeAcpCapture(capture: AcpCapture): FakeCli;
12
+ export declare function fakeAcpCapture(capture: AcpCapture, answers?: unknown[]): FakeCli;
@@ -1,18 +1,43 @@
1
- export function fakeAcpCapture(capture) {
1
+ /* `answers` collects the client's answer to every permission request, in order. */
2
+ export function fakeAcpCapture(capture, answers = []) {
2
3
  return (io) => {
3
4
  const send = (frame) => {
4
5
  io.out({ jsonrpc: '2.0', ...frame });
5
6
  };
6
7
  const update = (fields) => {
7
- send({ method: 'session/update', params: { sessionId: capture.sessionId, update: fields } });
8
+ const notification = fields.update === undefined ? { update: fields } : fields;
9
+ send({ method: 'session/update', params: { sessionId: capture.sessionId, ...notification } });
10
+ };
11
+ let waiting = null;
12
+ let nextRpcId = 0;
13
+ const play = (updates, promptId, text) => {
14
+ for (const [index, fields] of updates.entries()) {
15
+ const permission = fields.permission;
16
+ if (permission !== undefined) {
17
+ const rpcId = nextRpcId++;
18
+ waiting = { rpcId, rest: updates.slice(index + 1), promptId, text };
19
+ send({ id: rpcId, method: 'session/request_permission', params: permission });
20
+ return;
21
+ }
22
+ const named = capture.titleFromPrompt === true && fields.sessionUpdate === 'session_info_update';
23
+ update(named ? { ...fields, title: text } : fields);
24
+ }
25
+ send({ id: promptId, result: capture.promptResponse });
8
26
  };
9
27
  return {
10
28
  onLine: (line) => {
11
29
  const frame = JSON.parse(line);
12
30
  const id = frame.id;
13
31
  switch (frame.method) {
14
- case undefined:
32
+ case undefined: {
33
+ const answered = waiting;
34
+ if (answered !== null && id === answered.rpcId) {
35
+ waiting = null;
36
+ answers.push(frame.result ?? frame.error);
37
+ play(answered.rest, answered.promptId, answered.text);
38
+ }
15
39
  return;
40
+ }
16
41
  case 'initialize':
17
42
  send({ id, result: capture.initialize });
18
43
  return;
@@ -29,12 +54,7 @@ export function fakeAcpCapture(capture) {
29
54
  return;
30
55
  case 'session/prompt': {
31
56
  const blocks = Array.isArray(frame.params?.prompt) ? frame.params.prompt : [];
32
- const text = blocks.find((block) => block.type === 'text')?.text;
33
- for (const fields of capture.promptUpdates) {
34
- const named = fields.sessionUpdate === 'session_info_update';
35
- update(named ? { ...fields, title: text } : fields);
36
- }
37
- send({ id, result: capture.promptResponse });
57
+ play(capture.promptUpdates, id, blocks.find((block) => block.type === 'text')?.text);
38
58
  return;
39
59
  }
40
60
  case 'session/cancel':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/agents",
3
- "version": "0.31.9",
3
+ "version": "0.31.11",
4
4
  "description": "Node-compatible agent chat hosts, providers, accounts, usage and durable task coordination.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -81,8 +81,8 @@
81
81
  "test": "bun --conditions=source test"
82
82
  },
83
83
  "dependencies": {
84
- "@adecore/agent-contracts": "0.31.9",
85
- "@adecore/intelligent-ui": "0.31.9",
84
+ "@adecore/agent-contracts": "0.31.11",
85
+ "@adecore/intelligent-ui": "0.31.11",
86
86
  "zod": "^4.6.5"
87
87
  },
88
88
  "devDependencies": {
@@ -63,6 +63,9 @@ export interface AcpAgentSpec {
63
63
  onContextReport?(): void;
64
64
  // The slash commands a session offers (without the slash), each time the agent lists them.
65
65
  onCommands?(commands: string[]): void;
66
+ // True takes the session titles the agent sends (`session_info_update`) as the chat's suggested title. Absent leaves
67
+ // naming the chat to the host, since an agent may rename the session after every turn.
68
+ adoptTitles?: boolean;
66
69
  // A permission request the host answers itself, in any runtime mode: true allows it once without asking the
67
70
  // person, for a call the host already guards. A throw counts as false.
68
71
  autoAllow?(request: AcpPermissionRequest): boolean;
@@ -121,7 +124,7 @@ export class AcpBackend implements ChatBackend {
121
124
  this.host = host;
122
125
  this.spec = spec;
123
126
  this.client = spec.client ?? DEFAULT_ACP_CLIENT;
124
- this.protocol = new AcpProtocol(launch.generation, spec.modes ?? {}, acpStopWords(spec.name));
127
+ this.protocol = new AcpProtocol(launch.generation, spec.modes ?? {}, acpStopWords(spec.name), spec.adoptTitles === true);
125
128
  }
126
129
 
127
130
  get running(): boolean {
@@ -420,7 +423,7 @@ export class AcpBackend implements ChatBackend {
420
423
  if (this.transport === transport && this.prompt === turn) {
421
424
  this.prompt = null;
422
425
  this.report(result);
423
- this.emitAll(this.protocol.finish(turn.cancelled ? { stopReason: 'cancelled' } : result, turn.promptId));
426
+ this.emitAll(this.protocol.finish(result, turn.promptId, turn.cancelled));
424
427
  }
425
428
  })
426
429
  .catch((error: unknown) => {
@@ -469,7 +472,11 @@ export class AcpBackend implements ChatBackend {
469
472
  if (!answer) {
470
473
  return false;
471
474
  }
472
- return this.respond(requestId, answer.rpcId, answer.result);
475
+ if (!this.respond(requestId, answer.rpcId, answer.result)) {
476
+ return false;
477
+ }
478
+ this.emitAll(answer.events);
479
+ return true;
473
480
  }
474
481
 
475
482
  /* ACP asks no questions of its own; an agent asks in its message and the next prompt answers. */