1
>
/*---------------------------------------------------------------------------------------------
state.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
// allow-any-unicode-comment-file
7
>
// DO NOT EDIT -- auto-generated by scripts/sync-agent-host-protocol.ts
8
>
9
>
import type { ModelSelection } from '../channels-root/state.js';
10
>
import type { AgentSelection, McpAuthRequirement, SessionStatus } from '../channels-session/state.js';
11
>
import type { ContentRef, ErrorInfo, FileEdit, StringOrMarkdown, TextRange, TextSelection, URI, UsageInfo } from '../common/state.js';
12
>
13
>
// ─── Chat State ──────────────────────────────────────────────────────────────
14
>
15
>
/**
16
>
* Full state for a single chat, loaded when a client subscribes to the chat's
17
>
* URI.
18
>
*
19
>
* The lightweight catalog representation of a chat is {@link ChatSummary},
20
>
* carried in {@link SessionState.chats | `SessionState.chats`}. `ChatState`
21
>
* **denormalizes** every {@link ChatSummary} field directly onto itself so
22
>
* subscribers receive one flat object instead of having to merge a nested
23
>
* `summary` sub-object. Producers MUST keep the two representations
24
>
* consistent: any change to the inlined fields below SHOULD also be
25
>
* announced on the parent session via the matching
26
>
* {@link SessionChatUpdatedAction | `session/chatUpdated`} action.
27
>
*
28
>
* @category Chat State
29
>
*/
30
>
export interface ChatState {
31
>
// ── Summary fields (denormalized from ChatSummary) ─────────────────
32
>
/** Chat URI */
33
>
resource: URI;
34
>
/** Chat title */
35
>
title: string;
36
>
/** Current chat status (reuses SessionStatus shape) */
37
>
status: SessionStatus;
38
>
/** Human-readable description of what the chat is currently doing */
39
>
activity?: string;
40
>
/** Last modification timestamp (ISO 8601, e.g. `"2025-03-10T18:42:03.123Z"`) */
41
>
modifiedAt: string;
42
>
/** How this chat came into existence */
43
>
origin?: ChatOrigin;
44
>
/**
45
>
* How the user can interact with this chat. See {@link ChatInteractivity}.
46
>
*
47
>
* Supports agent-team patterns where worker chats are read-only or hidden.
48
>
* Absence defaults to {@link ChatInteractivity.Full} for backward
49
>
* compatibility.
50
>
*/
51
>
interactivity?: ChatInteractivity;
52
>
/**
53
>
* The subset of the session's
54
>
* {@link SessionState.workingDirectories | `workingDirectories`} that this
55
>
* chat's agent has tool access to. Every entry MUST be present in the owning
56
>
* session's `workingDirectories`; servers MUST reject a
57
>
* `chat/workingDirectorySet` action that violates this constraint.
58
>
*
59
>
* When absent, the chat inherits the full session set. When present but empty
60
>
* (not recommended), the chat has no working-directory tool access at all.
61
>
*
62
>
* Dispatch `chat/workingDirectorySet` / `chat/workingDirectoryRemoved` to
63
>
* update the subset on a running chat.
64
>
*/
65
>
workingDirectories?: URI[];
66
>
/**
67
>
* The chat's primary working directory — the distinguished root this chat is
68
>
* centered on (e.g. the agent's process root for this chat, the default
69
>
* location for relative paths). MUST be one of this chat's effective working
70
>
* directories ({@link workingDirectories}, or the session's set when that is
71
>
* absent). Present when the agent advertises
72
>
* {@link MultipleWorkingDirectoriesCapability.requiresPrimary}.
73
>
*
74
>
* **Read-only and fixed at creation.** It is set from
75
>
* {@link CreateChatParams.primaryWorkingDirectory} (or, for the session's
76
>
* default chat, {@link CreateSessionParams.primaryWorkingDirectory}) and does
77
>
* not change over the chat's lifetime — there is no action to mutate it, and
78
>
* it does not participate in `session/chatUpdated`.
79
>
*/
80
>
primaryWorkingDirectory?: URI;
81
>
82
>
// ── Conversation contents ──────────────────────────────────────────
83
>
/** Completed turns */
84
>
turns: Turn[];
85
>
/**
86
>
* Cursor for loading older completed turns into this chat state.
87
>
*
88
>
* Presence means `turns` is a tail window and more historical turns are
89
>
* available. Pass this opaque cursor to `fetchTurns`; the host MUST insert
90
>
* the loaded turns into state and update or clear this cursor before
91
>
* responding. Absence means the state contains all retained turns.
92
>
*/
93
>
turnsNextCursor?: string;
94
>
/** Currently in-progress turn */
95
>
activeTurn?: ActiveTurn;
96
>
/** Message to inject into the current turn at a convenient point */
97
>
steeringMessage?: PendingMessage;
98
>
/** Messages to send automatically as new turns after the current turn finishes */
99
>
queuedMessages?: PendingMessage[];
100
>
/**
101
>
* The user's in-progress draft input for this chat — the message they are
102
>
* composing but have not sent yet, including its
103
>
* {@link Message.model | model} / {@link Message.agent | agent} selection
104
>
* and attachments.
105
>
*
106
>
* Clients MAY periodically sync their local input state into this field so
107
>
* a draft survives reloads and is visible to other clients viewing the same
108
>
* chat. Eager syncing is **not** required — clients SHOULD debounce and MAY
109
>
* sync only at convenient points. When presenting input UI for an existing
110
>
* chat, clients SHOULD use any `draft` to initialize their input state.
111
>
* Cleared (set to `undefined`) once the message is sent.
112
>
*/
113
>
draft?: Message;
114
>
/**
115
>
* Additional provider-specific metadata for this chat.
116
>
*/
117
>
_meta?: Record<string, unknown>;
118
>
}
119
>
120
>
/**
121
>
* Lightweight catalog entry for a chat, carried in
122
>
* {@link SessionState.chats | `SessionState.chats`}. The full conversation
123
>
* lives in {@link ChatState}, which inlines (denormalizes) every field below.
124
>
*
125
>
* @category Chat State
126
>
*/
127
>
export interface ChatSummary {
128
>
/** Chat URI */
129
>
resource: URI;
130
>
/** Chat title */
131
>
title: string;
132
>
/** Current chat status (reuses SessionStatus shape) */
133
>
status: SessionStatus;
134
>
/** Human-readable description of what the chat is currently doing */
135
>
activity?: string;
136
>
/** Last modification timestamp (ISO 8601, e.g. `"2025-03-10T18:42:03.123Z"`) */
137
>
modifiedAt: string;
138
>
/** How this chat came into existence */
139
>
origin?: ChatOrigin;
140
>
/**
141
>
* How the user can interact with this chat. See {@link ChatInteractivity}.
142
>
*
143
>
* Supports agent-team patterns where worker chats are read-only or hidden.
144
>
* Absence defaults to {@link ChatInteractivity.Full} for backward
145
>
* compatibility.
146
>
*/
147
>
interactivity?: ChatInteractivity;
148
>
/**
149
>
* The subset of the session's working directories this chat uses.
150
>
* See {@link ChatState.workingDirectories} for the full semantics.
151
>
*/
152
>
workingDirectories?: URI[];
153
>
/**
154
>
* The chat's primary working directory.
155
>
* See {@link ChatState.primaryWorkingDirectory} for the full semantics.
156
>
*/
157
>
primaryWorkingDirectory?: URI;
158
>
}
159
>
160
>
/**
161
>
* Discriminant for {@link ChatOrigin} — how a chat came into existence.
162
>
*
163
>
* @category Chat State
164
>
*/
165
>
export const enum ChatOriginKind {
166
>
/** User created the chat explicitly (e.g. via the host UI). */
167
>
User = 'user',
168
>
/** Forked from an existing chat at a specific turn. */
169
>
Fork = 'fork',
170
>
/** Created as an independent side conversation from a specific turn. */
171
>
SideChat = 'sideChat',
172
>
/** Spawned by a tool call running in another chat (e.g. a sub-agent delegation). */
173
>
Tool = 'tool',
174
>
}
175
>
176
>
/**
177
>
* Immutable selected-text snapshot captured when a side chat is created.
178
>
*
179
>
* The host records this exact text when it accepts `createChat`; later changes
180
>
* to the source chat do not alter it.
181
>
*
182
>
* @category Chat State
183
>
*/
184
>
export interface SideChatSelection {
185
>
/**
186
>
* Exact selected-text snapshot captured at `createChat` acceptance.
187
>
*
188
>
* MUST be non-empty.
189
>
*/
190
>
text: string;
191
>
/**
192
>
* Optional provenance for the response part that contained {@link text} when
193
>
* the host took the snapshot.
194
>
*
195
>
* Advisory only: this is not a live range or offset and MUST NOT be used to
196
>
* recompute `text`.
197
>
*/
198
>
responsePartId?: string;
199
>
}
200
>
201
>
/**
202
>
* How a chat came into existence. Clients MAY use it to render
203
>
* contextual UI (parent indicators, fork markers, "spawned by tool" badges).
204
>
*
205
>
* Fork and side-chat origins both carry a stable top-level `turnId` alongside
206
>
* their discriminated `kind` value instead of snapshotting whether that turn
207
>
* was active or historical at creation time. Consumers resolve the identifier
208
>
* against the
209
>
* source chat's current `activeTurn` or retained `turns` as needed.
210
>
*
211
>
* When a host accepts side-chat creation from the source chat's current active
212
>
* turn, it snapshots the retained history plus that turn's current user
213
>
* message and any partial assistant response already available. Later
214
>
* source-turn deltas do not retroactively change the created side chat's
215
>
* starting context, and once the source turn completes it is still referenced
216
>
* by the same `turnId`. Side-chat origins MAY also retain an immutable
217
>
* {@link SideChatSelection | selected-text snapshot} captured at acceptance
218
>
* time; any `responsePartId` there is provenance only, not a range.
219
>
*
220
>
* The `tool` variant records a tool-spawned worker from the worker's side: its
221
>
* `chat`/`toolCallId` identify the spawning tool call in the parent chat. This
222
>
* is the canonical record of the spawn relationship. The same edge is surfaced
223
>
* from the parent's side by {@link ToolResultSubagentContent}, whose `resource`
224
>
* is this chat's URI; hosts MUST keep the two consistent.
225
>
*
226
>
* @category Chat State
227
>
*/
228
>
export type ChatOrigin =
229
>
| { kind: ChatOriginKind.User }
230
>
| { kind: ChatOriginKind.Fork; chat: URI; turnId: string }
231
>
| { kind: ChatOriginKind.SideChat; chat: URI; turnId: string; selection?: SideChatSelection }
232
>
| { kind: ChatOriginKind.Tool; chat: URI; toolCallId: string };
233
>
234
>
/**
235
>
* How a user can interact with a chat.
236
>
*
237
>
* - `Full` — user can send messages and watch (default when absent)
238
>
* - `ReadOnly` — user can watch but not send messages (e.g. agent team workers)
239
>
* - `Hidden` — internal worker not shown in UI at all
240
>
*
241
>
* Supports the agent-team pattern where a lead chat is fully interactive and
242
>
* worker chats are read-only (visible for observability) or hidden (internal
243
>
* implementation detail). The harness sets this based on the chat's role;
244
>
* the UI uses it to show appropriate controls.
245
>
*
246
>
* @category Chat State
247
>
*/
248
>
export const enum ChatInteractivity {
249
>
/** User can send messages and watch (default when absent) */
250
>
Full = 'full',
251
>
/** User can watch but not send messages */
252
>
ReadOnly = 'read-only',
253
>
/** Internal worker not shown in UI at all */
254
>
Hidden = 'hidden',
255
>
}
256
>
257
>
// ─── Pending Message Types ───────────────────────────────────────────────────
258
>
259
>
/**
260
>
* Discriminant for pending message kinds.
261
>
*
262
>
* @category Pending Message Types
263
>
*/
264
>
export const enum PendingMessageKind {
265
>
/** Injected into the current turn at a convenient point */
266
>
Steering = 'steering',
267
>
/** Sent automatically as a new turn after the current turn finishes */
268
>
Queued = 'queued',
269
>
}
270
>
271
>
/**
272
>
* A message queued for future delivery to the agent.
273
>
*
274
>
* Steering messages are injected into the current turn mid-flight.
275
>
* Queued messages are automatically started as new turns after the
276
>
* current turn naturally finishes.
277
>
*
278
>
* @category Pending Message Types
279
>
*/
280
>
export interface PendingMessage {
281
>
/** Unique identifier for this pending message */
282
>
id: string;
283
>
/** The message that will start the next turn */
284
>
message: Message;
285
>
}
286
>
287
>
288
>
// ─── Chat Input Types ────────────────────────────────────────────────────
289
>
290
>
/**
291
>
* How a client completed an input request.
292
>
*
293
>
* @category Chat Input Types
294
>
*/
295
>
export const enum ChatInputResponseKind {
296
>
Accept = 'accept',
297
>
Decline = 'decline',
298
>
Cancel = 'cancel',
299
>
}
300
>
301
>
/**
302
>
* Question/input control kind.
303
>
*
304
>
* @category Chat Input Types
305
>
*/
306
>
export const enum ChatInputQuestionKind {
307
>
Text = 'text',
308
>
Number = 'number',
309
>
Integer = 'integer',
310
>
Boolean = 'boolean',
311
>
SingleSelect = 'single-select',
312
>
MultiSelect = 'multi-select',
313
>
}
314
>
315
>
/**
316
>
* A choice in a select-style question.
317
>
*
318
>
* @category Chat Input Types
319
>
*/
320
>
export interface ChatInputOption {
321
>
/** Stable option identifier; for MCP enum values this is the enum string */
322
>
id: string;
323
>
/** Display label */
324
>
label: string;
325
>
/** Optional secondary text */
326
>
description?: string;
327
>
/** Whether this option is the recommended/default choice */
328
>
recommended?: boolean;
329
>
}
330
>
331
>
interface ChatInputQuestionBase {
332
>
/** Stable question identifier used as the key in `answers` */
333
>
id: string;
334
>
/** Short display title */
335
>
title?: string;
336
>
/** Prompt shown to the user */
337
>
message: string;
338
>
/** Whether the user must answer this question to accept the request */
339
>
required?: boolean;
340
>
}
341
>
342
>
/** Text question within a chat input request. */
343
>
export interface ChatInputTextQuestion extends ChatInputQuestionBase {
344
>
kind: ChatInputQuestionKind.Text;
345
>
/** Format hint for text questions, such as `email`, `uri`, `date`, or `date-time` */
346
>
format?: string;
347
>
/** Minimum string length */
348
>
min?: number;
349
>
/** Maximum string length */
350
>
max?: number;
351
>
/** Default text */
352
>
defaultValue?: string;
353
>
}
354
>
355
>
/** Numeric question within a chat input request. */
356
>
export interface ChatInputNumberQuestion extends ChatInputQuestionBase {
357
>
kind: ChatInputQuestionKind.Number | ChatInputQuestionKind.Integer;
358
>
/**
359
>
* Minimum value
360
>
* @format float
361
>
*/
362
>
min?: number;
363
>
/**
364
>
* Maximum value
365
>
* @format float
366
>
*/
367
>
max?: number;
368
>
/**
369
>
* Default numeric value
370
>
* @format float
371
>
*/
372
>
defaultValue?: number;
373
>
}
374
>
375
>
/** Boolean question within a chat input request. */
376
>
export interface ChatInputBooleanQuestion extends ChatInputQuestionBase {
377
>
kind: ChatInputQuestionKind.Boolean;
378
>
/** Default boolean value */
379
>
defaultValue?: boolean;
380
>
}
381
>
382
>
/** Single-select question within a chat input request. */
383
>
export interface ChatInputSingleSelectQuestion extends ChatInputQuestionBase {
384
>
kind: ChatInputQuestionKind.SingleSelect;
385
>
/** Options the user may select from */
386
>
options: ChatInputOption[];
387
>
/** Whether the user may enter text instead of selecting an option */
388
>
allowFreeformInput?: boolean;
389
>
}
390
>
391
>
/** Multi-select question within a chat input request. */
392
>
export interface ChatInputMultiSelectQuestion extends ChatInputQuestionBase {
393
>
kind: ChatInputQuestionKind.MultiSelect;
394
>
/** Options the user may select from */
395
>
options: ChatInputOption[];
396
>
/** Whether the user may enter text in addition to selecting options */
397
>
allowFreeformInput?: boolean;
398
>
/** Minimum selected item count */
399
>
min?: number;
400
>
/** Maximum selected item count */
401
>
max?: number;
402
>
}
403
>
404
>
/**
405
>
* One question within a chat input request.
406
>
*
407
>
* @category Chat Input Types
408
>
*/
409
>
export type ChatInputQuestion = ChatInputTextQuestion
410
>
| ChatInputNumberQuestion
411
>
| ChatInputBooleanQuestion
412
>
| ChatInputSingleSelectQuestion
413
>
| ChatInputMultiSelectQuestion;
414
>
415
>
/**
416
>
* The request payload carried by an {@link InputRequestResponsePart}.
417
>
*
418
>
* The server creates or replaces the containing response part with
419
>
* `chat/inputRequested`. Clients sync drafts with `chat/inputAnswerChanged`
420
>
* and submit responses with `chat/inputCompleted`.
421
>
*
422
>
* @category Chat Input Types
423
>
*/
424
>
export interface ChatInputRequest {
425
>
/** Stable request identifier */
426
>
id: string;
427
>
/** Display message for the request as a whole */
428
>
message?: string;
429
>
/** URL the user should review or open, for URL-style elicitations */
430
>
url?: URI;
431
>
/** Ordered questions to ask the user */
432
>
questions?: ChatInputQuestion[];
433
>
/** Current draft or submitted answers, keyed by question ID */
434
>
answers?: Record<string, ChatInputAnswer>;
435
>
}
436
>
437
>
/**
438
>
* Answer value kind.
439
>
*
440
>
* @category Chat Input Types
441
>
*/
442
>
export const enum ChatInputAnswerValueKind {
443
>
Text = 'text',
444
>
Number = 'number',
445
>
Boolean = 'boolean',
446
>
Selected = 'selected',
447
>
SelectedMany = 'selected-many',
448
>
}
449
>
450
>
/**
451
>
* Value captured for one answer.
452
>
*
453
>
* @category Chat Input Types
454
>
*/
455
>
export interface ChatInputTextAnswerValue {
456
>
kind: ChatInputAnswerValueKind.Text;
457
>
value: string;
458
>
}
459
>
460
>
export interface ChatInputNumberAnswerValue {
461
>
kind: ChatInputAnswerValueKind.Number;
462
>
/** @format float */
463
>
value: number;
464
>
}
465
>
466
>
export interface ChatInputBooleanAnswerValue {
467
>
kind: ChatInputAnswerValueKind.Boolean;
468
>
value: boolean;
469
>
}
470
>
471
>
export interface ChatInputSelectedAnswerValue {
472
>
kind: ChatInputAnswerValueKind.Selected;
473
>
value: string;
474
>
/** Free-form text entered instead of selecting an option */
475
>
freeformValues?: string[];
476
>
}
477
>
478
>
export interface ChatInputSelectedManyAnswerValue {
479
>
kind: ChatInputAnswerValueKind.SelectedMany;
480
>
value: string[];
481
>
/** Free-form text entered in addition to selected options */
482
>
freeformValues?: string[];
483
>
}
484
>
485
>
export type ChatInputAnswerValue = ChatInputTextAnswerValue
486
>
| ChatInputNumberAnswerValue
487
>
| ChatInputBooleanAnswerValue
488
>
| ChatInputSelectedAnswerValue
489
>
| ChatInputSelectedManyAnswerValue;
490
>
491
>
export interface ChatInputAnswered {
492
>
/** Answer state */
493
>
state: ChatInputAnswerState.Draft | ChatInputAnswerState.Submitted;
494
>
/** Answer value */
495
>
value: ChatInputAnswerValue;
496
>
}
497
>
498
>
export interface ChatInputSkipped {
499
>
/** Answer state */
500
>
state: ChatInputAnswerState.Skipped;
501
>
/** Free-form reason or value captured while skipping, if any */
502
>
freeformValues?: string[];
503
>
}
504
>
505
>
/**
506
>
* Answer lifecycle state.
507
>
*
508
>
* @category Chat Input Types
509
>
*/
510
>
export const enum ChatInputAnswerState {
511
>
Draft = 'draft',
512
>
Submitted = 'submitted',
513
>
Skipped = 'skipped',
514
>
}
515
>
516
>
/**
517
>
* Draft, submitted, or skipped answer for one question.
518
>
*
519
>
* @category Chat Input Types
520
>
*/
521
>
export type ChatInputAnswer = ChatInputAnswered | ChatInputSkipped;
522
>
523
>
524
>
// ─── Turn Types ──────────────────────────────────────────────────────────────
525
>
526
>
/**
527
>
* How a turn ended.
528
>
*
529
>
* @category Turn Types
530
>
*/
531
>
export const enum TurnState {
532
>
Complete = 'complete',
533
>
Cancelled = 'cancelled',
534
>
Error = 'error',
535
>
}
536
>
537
>
/**
538
>
* Discriminant for {@link MessageAttachment} variants.
539
>
*
540
>
* @category Turn Types
541
>
*/
542
>
export const enum MessageAttachmentKind {
543
>
/** A simple, opaque attachment whose representation is described by the producer. */
544
>
Simple = 'simple',
545
>
/** An attachment whose data is embedded inline as a base64 string. */
546
>
EmbeddedResource = 'embeddedResource',
547
>
/** An attachment that references a resource by URI. */
548
>
Resource = 'resource',
549
>
/** An attachment that references annotations on an annotations channel. */
550
>
Annotations = 'annotations',
551
>
/** An attachment that references a bounded transcript from another chat. */
552
>
Chat = 'chat',
553
>
}
554
>
555
>
/**
556
>
* A completed request/response cycle.
557
>
*
558
>
* @category Turn Types
559
>
*/
560
>
export interface Turn {
561
>
/** Turn identifier */
562
>
id: string;
563
>
/** ISO 8601 timestamp when this turn started. */
564
>
startedAt?: string;
565
>
/** Turn duration in milliseconds. */
566
>
duration?: number;
567
>
/** The message that initiated the turn */
568
>
message: Message;
569
>
/**
570
>
* All response content in stream order: text, tool calls, reasoning, and content refs.
571
>
*
572
>
* Consumers should derive display text by concatenating markdown parts,
573
>
* and find tool calls by filtering for `ToolCall` parts.
574
>
*/
575
>
responseParts: ResponsePart[];
576
>
/** Token usage info */
577
>
usage: UsageInfo | undefined;
578
>
/** How the turn ended */
579
>
state: TurnState;
580
>
/** Error details if state is `'error'` */
581
>
error?: ErrorInfo;
582
>
}
583
>
584
>
/**
585
>
* An in-progress turn — the assistant is actively streaming.
586
>
*
587
>
* @category Turn Types
588
>
*/
589
>
export interface ActiveTurn {
590
>
/** Turn identifier */
591
>
id: string;
592
>
/** ISO 8601 timestamp when this turn started. */
593
>
startedAt: string;
594
>
/** The message that initiated the turn */
595
>
message: Message;
596
>
/**
597
>
* All response content in stream order: text, tool calls, reasoning, and content refs.
598
>
*
599
>
* Tool call parts include `pendingPermissions` when permissions are awaiting user approval.
600
>
*/
601
>
responseParts: ResponsePart[];
602
>
/** Token usage info */
603
>
usage: UsageInfo | undefined;
604
>
}
605
>
606
>
/**
607
>
* Discriminant for {@link MessageOrigin} — identifies who produced a message.
608
>
*
609
>
* @category Turn Types
610
>
*/
611
>
export enum MessageKind {
612
>
/** Sent directly by the user. */
613
>
User = 'user',
614
>
/**
615
>
* Produced by the agent itself rather than the user — for example, an agent
616
>
* that seeds the first message of a chat it spawned.
617
>
*/
618
>
Agent = 'agent',
619
>
/**
620
>
* Produced by a tool rather than the user — for example, a tool that spawns a
621
>
* worker chat whose first message carries a seed prompt.
622
>
*/
623
>
Tool = 'tool',
624
>
/** A system-generated notification rather than a direct user message. */
625
>
SystemNotification = 'systemNotification',
626
>
}
627
>
628
>
/**
629
>
* Identifies the origin of a {@link Message} — who produced it. For the message
630
>
* that initiates a turn ({@link Turn.message}), this is also the origin of the
631
>
* turn; for steering or queued messages it is just the origin of that message.
632
>
*
633
>
* @category Turn Types
634
>
*/
635
>
export interface MessageOrigin {
636
>
/** The kind of actor that produced the message. */
637
>
kind: MessageKind;
638
>
}
639
>
640
>
/**
641
>
* A message that initiates or steers a turn. Messages can originate from the
642
>
* user, the agent, a tool, or be system-generated (see {@link MessageOrigin}).
643
>
*
644
>
* Attachments MAY be referenced inside {@link Message.text} via their
645
>
* {@link MessageAttachmentBase.range} field. Attachments without a range are
646
>
* still associated with the message but do not correspond to a specific span
647
>
* in the text.
648
>
*
649
>
* @category Turn Types
650
>
*/
651
>
export interface Message {
652
>
/** Message text */
653
>
text: string;
654
>
/** The origin of the message */
655
>
origin: MessageOrigin;
656
>
/** File/selection attachments */
657
>
attachments?: MessageAttachment[];
658
>
/**
659
>
* The model this message was, or will be, sent with.
660
>
*
661
>
* For historic user/agent messages this records the model actually used, so
662
>
* a client editing or resending the message can retain that selection. For a
663
>
* {@link ChatState.draft | draft} it carries the model the user picked for
664
>
* the message they are composing. Absent means the agent host's default
665
>
* model applies.
666
>
*/
667
>
model?: ModelSelection;
668
>
/**
669
>
* The custom agent this message was, or will be, sent with.
670
>
*
671
>
* For historic messages this records the agent actually used; for a
672
>
* {@link ChatState.draft | draft} it carries the agent the user picked.
673
>
* Absent means no custom agent — the provider's default behavior applies.
674
>
*/
675
>
agent?: AgentSelection;
676
>
/**
677
>
* Additional provider-specific metadata for this message.
678
>
*
679
>
* Clients MAY look for well-known keys here to provide enhanced UI, and
680
>
* agent hosts MAY use it to carry context that does not fit any other
681
>
* field. Mirrors the MCP `_meta` convention.
682
>
*/
683
>
_meta?: Record<string, unknown>;
684
>
}
685
>
686
>
/**
687
>
* Common fields shared by all {@link MessageAttachment} variants.
688
>
*
689
>
* @category Turn Types
690
>
*/
691
>
export interface MessageAttachmentBase {
692
>
/**
693
>
* A human-readable label for the attachment (e.g. the filename of a file
694
>
* attachment). Used for display in UI.
695
>
*/
696
>
label: string;
697
>
698
>
/**
699
>
* If defined, the range in {@link Message.text} that references this
700
>
* attachment. This is a text range, not a byte range.
701
>
*/
702
>
range?: TextRange;
703
>
704
>
/**
705
>
* Advisory display hint for clients rendering this attachment. Recognized
706
>
* values include:
707
>
*
708
>
* - `'image'`: the attachment is an image
709
>
* - `'document'`: the attachment is a textual document
710
>
* - `'symbol'`: the attachment is a code symbol (e.g. a function or class)
711
>
* - `'directory'`: the attachment is a folder
712
>
* - `'selection'`: the attachment is a selection within a document
713
>
*
714
>
* Implementations MAY provide additional values; clients SHOULD fall back
715
>
* to a reasonable default when an unknown value is encountered.
716
>
*/
717
>
displayKind?: string;
718
>
719
>
/**
720
>
* Additional implementation-defined metadata for the attachment.
721
>
*
722
>
* If the attachment was produced by the `completions` command, the client
723
>
* MUST preserve every property of `_meta` originally returned by the agent
724
>
* host when sending the user message containing the accepted completion.
725
>
*/
726
>
_meta?: Record<string, unknown>;
727
>
}
728
>
729
>
/**
730
>
* A simple, opaque attachment whose model representation is described by
731
>
* the producer.
732
>
*
733
>
* @category Turn Types
734
>
*/
735
>
export interface SimpleMessageAttachment extends MessageAttachmentBase {
736
>
/** Discriminant */
737
>
type: MessageAttachmentKind.Simple;
738
>
739
>
/**
740
>
* Representation of the attachment as it should be shown to the model.
741
>
*
742
>
* If the attachment was produced by the client, this property MUST be
743
>
* defined so the agent host can correctly interpret the attachment. This
744
>
* property MAY be omitted when the attachment originated from a
745
>
* `completions` response.
746
>
*/
747
>
modelRepresentation?: string;
748
>
}
749
>
750
>
/**
751
>
* An attachment whose data is embedded inline as a base64 string.
752
>
*
753
>
* Use this for small binary payloads (e.g. a pasted image) that should be
754
>
* delivered with the user message itself rather than fetched separately.
755
>
*
756
>
* @category Turn Types
757
>
*/
758
>
export interface MessageEmbeddedResourceAttachment extends MessageAttachmentBase {
759
>
/** Discriminant */
760
>
type: MessageAttachmentKind.EmbeddedResource;
761
>
/** Base64-encoded binary data */
762
>
data: string;
763
>
/** Content MIME type (e.g. `"image/png"`, `"application/pdf"`) */
764
>
contentType: string;
765
>
/**
766
>
* Optional selection within the attached textual resource.
767
>
*
768
>
* Only meaningful for textual resources.
769
>
*/
770
>
selection?: TextSelection;
771
>
}
772
>
773
>
/**
774
>
* An attachment that references a resource by URI. The content is not
775
>
* delivered inline; consumers can fetch it via `resourceRead` when needed.
776
>
*
777
>
* @category Turn Types
778
>
*/
779
>
export interface MessageResourceAttachment extends MessageAttachmentBase, ContentRef {
780
>
/** Discriminant */
781
>
type: MessageAttachmentKind.Resource;
782
>
/**
783
>
* Optional selection within the referenced textual resource.
784
>
*
785
>
* Only meaningful for textual resources.
786
>
*/
787
>
selection?: TextSelection;
788
>
}
789
>
790
>
/**
791
>
* An attachment that references annotations on a session's annotations
792
>
* channel (see {@link AnnotationsState}).
793
>
*
794
>
* When {@link annotationIds} is omitted the attachment references every
795
>
* annotation on the channel; when present it references only the listed
796
>
* {@link Annotation.id | annotation ids}.
797
>
*
798
>
* @category Turn Types
799
>
*/
800
>
export interface MessageAnnotationsAttachment extends MessageAttachmentBase {
801
>
/** Discriminant */
802
>
type: MessageAttachmentKind.Annotations;
803
>
/**
804
>
* The annotations channel URI (typically `ahp-session:/<uuid>/annotations`).
805
>
* Matches {@link AnnotationsSummary.resource}.
806
>
*/
807
>
resource: URI;
808
>
/**
809
>
* Specific {@link Annotation.id | annotation ids} to reference. When
810
>
* omitted, the attachment references all annotations on the channel.
811
>
*/
812
>
annotationIds?: string[];
813
>
}
814
>
815
>
/**
816
>
* An attachment that references a chat transcript through a fixed completed
817
>
* turn.
818
>
*
819
>
* The referenced chat MUST belong to the same session as the message's chat.
820
>
* The host resolves the transcript from its first retained turn through
821
>
* `endTurn`, inclusive, when accepting the message. Later turns do not
822
>
* change the context represented by an already-sent attachment.
823
>
*
824
>
* Hosts MUST NOT recursively expand chat attachments found inside the
825
>
* referenced transcript. Clients SHOULD keep rendering `label` if the
826
>
* referenced chat is later pruned, and treat opening `resource` as best-effort.
827
>
*
828
>
* @category Turn Types
829
>
*/
830
>
export interface MessageChatAttachment extends MessageAttachmentBase {
831
>
/** Discriminant */
832
>
type: MessageAttachmentKind.Chat;
833
>
/** URI of the referenced chat. */
834
>
resource: URI;
835
>
/** Last completed turn included in the referenced transcript. */
836
>
endTurn: string;
837
>
}
838
>
839
>
/**
840
>
* An attachment associated with a {@link Message}.
841
>
*
842
>
* @category Turn Types
843
>
*/
844
>
export type MessageAttachment =
845
>
| SimpleMessageAttachment
846
>
| MessageEmbeddedResourceAttachment
847
>
| MessageResourceAttachment
848
>
| MessageAnnotationsAttachment
849
>
| MessageChatAttachment;
850
>
851
>
// ─── Response Parts ──────────────────────────────────────────────────────────
852
>
853
>
/**
854
>
* Discriminant for response part types.
855
>
*
856
>
* @category Response Parts
857
>
*/
858
>
export const enum ResponsePartKind {
859
>
Markdown = 'markdown',
860
>
ContentRef = 'contentRef',
861
>
ToolCall = 'toolCall',
862
>
Reasoning = 'reasoning',
863
>
SystemNotification = 'systemNotification',
864
>
InputRequest = 'inputRequest',
865
>
}
866
>
867
>
/**
868
>
* @category Response Parts
869
>
*/
870
>
export interface MarkdownResponsePart {
871
>
/** Discriminant */
872
>
kind: ResponsePartKind.Markdown;
873
>
/** Part identifier, used by `chat/delta` to target this part for content appends */
874
>
id: string;
875
>
/** Markdown content */
876
>
content: string;
877
>
}
878
>
879
>
/**
880
>
* A content part that's a reference to large content stored outside the state tree.
881
>
*
882
>
* @category Response Parts
883
>
*/
884
>
export interface ResourceReponsePart extends ContentRef {
885
>
/** Discriminant */
886
>
kind: ResponsePartKind.ContentRef;
887
>
}
888
>
889
>
/**
890
>
* A tool call represented as a response part.
891
>
*
892
>
* Tool calls are part of the response stream, interleaved with text and
893
>
* reasoning. The `toolCall.toolCallId` serves as the part identifier for
894
>
* actions that target this part.
895
>
*
896
>
* @category Response Parts
897
>
*/
898
>
export interface ToolCallResponsePart {
899
>
/** Discriminant */
900
>
kind: ResponsePartKind.ToolCall;
901
>
/** Full tool call lifecycle state */
902
>
toolCall: ToolCallState;
903
>
}
904
>
905
>
/**
906
>
* Reasoning/thinking content from the model.
907
>
*
908
>
* @category Response Parts
909
>
*/
910
>
export interface ReasoningResponsePart {
911
>
/** Discriminant */
912
>
kind: ResponsePartKind.Reasoning;
913
>
/** Part identifier, used by `chat/reasoning` to target this part for content appends */
914
>
id: string;
915
>
/** Accumulated reasoning text */
916
>
content: string;
917
>
}
918
>
919
>
/**
920
>
* @category Response Parts
921
>
*/
922
>
export type ResponsePart =
923
>
| MarkdownResponsePart
924
>
| ResourceReponsePart
925
>
| ToolCallResponsePart
926
>
| ReasoningResponsePart
927
>
| SystemNotificationResponsePart
928
>
| InputRequestResponsePart;
929
>
930
>
/**
931
>
* A live or resolved input request (elicitation) in the turn response stream.
932
>
*
933
>
* The server inserts the part with `chat/inputRequested`. While
934
>
* {@link response} is absent, clients can update answer drafts with
935
>
* `chat/inputAnswerChanged` and submit a response with `chat/inputCompleted`.
936
>
* Completion updates this part in place so its stream position is stable and
937
>
* the full interaction remains durable and backfillable via `fetchTurns`.
938
>
*
939
>
* If the turn ends without a submitted response, the unresolved part remains
940
>
* in the completed turn transcript with {@link response} absent.
941
>
*
942
>
* @category Response Parts
943
>
*/
944
>
export interface InputRequestResponsePart {
945
>
/** Discriminant */
946
>
kind: ResponsePartKind.InputRequest;
947
>
/**
948
>
* The request, carrying its `id`, `message`, `url`, `questions`, and current
949
>
* draft or submitted `answers`.
950
>
*/
951
>
request: ChatInputRequest;
952
>
/**
953
>
* How the request was resolved. Absent until a client submits `accept`,
954
>
* `decline`, or `cancel` with `chat/inputCompleted`.
955
>
*/
956
>
response?: ChatInputResponseKind;
957
>
}
958
>
959
>
/**
960
>
* A system notification surfaced as part of the response stream.
961
>
*
962
>
* System notifications are messages authored by the agent harness
963
>
* that need to be visible to both the agent (for situational awareness) and
964
>
* the user (for transcript continuity). Examples include "background subagent
965
>
* X completed" or "task Y was cancelled".
966
>
*
967
>
* @category Response Parts
968
>
*/
969
>
export interface SystemNotificationResponsePart {
970
>
/** Discriminant */
971
>
kind: ResponsePartKind.SystemNotification;
972
>
/** The text of the system notification */
973
>
content: StringOrMarkdown;
974
>
/**
975
>
* Additional provider-specific metadata for this notification.
976
>
*
977
>
* A host MAY attach a machine-readable descriptor of what triggered the
978
>
* notification so clients can categorize, icon, group, filter, or localize
979
>
* it without parsing `content`. Clients MAY look for well-known keys here to
980
>
* provide enhanced UI, and MUST render coherently from `content` alone when
981
>
* `_meta` is absent or unrecognized.
982
>
*/
983
>
_meta?: Record<string, unknown>;
984
>
}
985
>
986
>
987
>
// ─── Tool Call Types ─────────────────────────────────────────────────────────
988
>
989
>
/**
990
>
* Status of a tool call in the lifecycle state machine.
991
>
*
992
>
* @category Tool Call Types
993
>
*/
994
>
export const enum ToolCallStatus {
995
>
Streaming = 'streaming',
996
>
PendingConfirmation = 'pending-confirmation',
997
>
Running = 'running',
998
>
/**
999
>
* Running paused because the MCP server backing this call needs
1000
>
* authentication (typically step-up auth for insufficient scope,
1001
>
* surfacing mid-execution). See {@link ToolCallAuthRequiredState}.
1002
>
*/
1003
>
AuthRequired = 'auth-required',
1004
>
PendingResultConfirmation = 'pending-result-confirmation',
1005
>
Completed = 'completed',
1006
>
Cancelled = 'cancelled',
1007
>
}
1008
>
1009
>
/**
1010
>
* How a tool call was confirmed for execution.
1011
>
*
1012
>
* - `NotNeeded` — No confirmation required (auto-approved)
1013
>
* - `UserAction` — User explicitly approved
1014
>
* - `Setting` — Approved by a persistent user setting
1015
>
*
1016
>
* @category Tool Call Types
1017
>
*/
1018
>
export const enum ToolCallConfirmationReason {
1019
>
NotNeeded = 'not-needed',
1020
>
UserAction = 'user-action',
1021
>
Setting = 'setting',
1022
>
}
1023
>
1024
>
/**
1025
>
* Identifies a model judge as the source of a confirmation requirement.
1026
>
*
1027
>
* @category Tool Call Types
1028
>
*/
1029
>
export const enum ToolCallRiskAssessmentKind {
1030
>
Judge = 'judge',
1031
>
}
1032
>
1033
>
/**
1034
>
* Lifecycle status of an asynchronous model-judge confirmation decision.
1035
>
*
1036
>
* @category Tool Call Types
1037
>
*/
1038
>
export const enum ToolCallRiskAssessmentStatus {
1039
>
Loading = 'loading',
1040
>
Complete = 'complete',
1041
>
}
1042
>
1043
>
interface ToolCallRiskAssessmentBase {
1044
>
kind: ToolCallRiskAssessmentKind;
1045
>
}
1046
>
1047
>
/**
1048
>
* The model judge is still evaluating the tool call.
1049
>
*
1050
>
* @category Tool Call Types
1051
>
*/
1052
>
export interface ToolCallRiskAssessmentLoadingState extends ToolCallRiskAssessmentBase {
1053
>
status: ToolCallRiskAssessmentStatus.Loading;
1054
>
}
1055
>
1056
>
/**
1057
>
* The model judge has completed its evaluation.
1058
>
*
1059
>
* @category Tool Call Types
1060
>
*/
1061
>
export interface ToolCallRiskAssessmentCompleteState extends ToolCallRiskAssessmentBase {
1062
>
status: ToolCallRiskAssessmentStatus.Complete;
1063
>
reason: StringOrMarkdown;
1064
>
/**
1065
>
* The judge's normalized safety score, where `0` is unsafe and `1` is safe.
1066
>
* @format float
1067
>
*/
1068
>
safety: number;
1069
>
}
1070
>
1071
>
export type ToolCallRiskAssessment =
1072
>
| ToolCallRiskAssessmentLoadingState
1073
>
| ToolCallRiskAssessmentCompleteState;
1074
>
1075
>
/**
1076
>
* Why a tool call was cancelled.
1077
>
*
1078
>
* @category Tool Call Types
1079
>
*/
1080
>
export const enum ToolCallCancellationReason {
1081
>
Denied = 'denied',
1082
>
Skipped = 'skipped',
1083
>
ResultDenied = 'result-denied',
1084
>
}
1085
>
1086
>
/**
1087
>
* Whether a confirmation option represents an approval or denial action.
1088
>
*
1089
>
* @category Tool Call Types
1090
>
*/
1091
>
export const enum ConfirmationOptionKind {
1092
>
Approve = 'approve',
1093
>
Deny = 'deny',
1094
>
}
1095
>
1096
>
/**
1097
>
* A confirmation option that the server offers for a tool call awaiting
1098
>
* approval. Allows richer choices beyond simple approve/deny — for example,
1099
>
* "Approve in this Session" or "Deny with reason."
1100
>
*
1101
>
* @category Tool Call Types
1102
>
*/
1103
>
export interface ConfirmationOption {
1104
>
/** Unique identifier for the option, returned in the confirmed action */
1105
>
id: string;
1106
>
/** Human-readable label displayed to the user */
1107
>
label: string;
1108
>
/** Whether this option represents an approval or denial */
1109
>
kind: ConfirmationOptionKind;
1110
>
/**
1111
>
* Logical group number for visual categorisation.
1112
>
*
1113
>
* Clients SHOULD display options in the order they are defined and MAY
1114
>
* use differing group numbers to insert dividers between logical clusters
1115
>
* of options.
1116
>
*/
1117
>
group?: number;
1118
>
}
1119
>
1120
>
export const enum ToolCallContributorKind {
1121
>
Client = 'client',
1122
>
MCP = 'mcp',
1123
>
}
1124
>
1125
>
export interface ToolCallClientContributor {
1126
>
kind: ToolCallContributorKind.Client;
1127
>
/**
1128
>
* If this tool is provided by a client, the `clientId` of the owning client.
1129
>
* Absent for server-side tools.
1130
>
*
1131
>
* When set, the identified client is responsible for executing the tool and
1132
>
* dispatching `chat/toolCallComplete` with the result.
1133
>
*/
1134
>
clientId: string;
1135
>
}
1136
>
1137
>
export interface ToolCallMcpContributor {
1138
>
kind: ToolCallContributorKind.MCP;
1139
>
/**
1140
>
* Customization ID of the corresponding MCP server in {@link SessionState.customizations}.
1141
>
*/
1142
>
customizationId: string;
1143
>
}
1144
>
1145
>
export type ToolCallContributor = ToolCallClientContributor | ToolCallMcpContributor;
1146
>
1147
>
/**
1148
>
* Metadata common to all tool call states.
1149
>
*
1150
>
* @category Tool Call Types
1151
>
* @remarks
1152
>
* Fields like `toolName` carry agent-specific identifiers on the wire despite the
1153
>
* agent-agnostic design principle. These exist for debugging and logging purposes.
1154
>
* A future version may move these to a separate diagnostic channel or namespace them
1155
>
* more clearly.
1156
>
*/
1157
>
interface ToolCallBase {
1158
>
/** Unique tool call identifier */
1159
>
toolCallId: string;
1160
>
/** Internal tool name (for debugging/logging) */
1161
>
toolName: string;
1162
>
/** Human-readable tool name */
1163
>
displayName: string;
1164
>
/** Human-readable description of what the tool invocation intends to do */
1165
>
intention?: string;
1166
>
/**
1167
>
* Reference to the contributor of the tool being called.
1168
>
*/
1169
>
contributor?: ToolCallContributor;
1170
>
/**
1171
>
* Additional provider-specific metadata for this tool call.
1172
>
*
1173
>
* This MAY include a `ui` field corresponding to the MCP Apps (SEP-1865)
1174
>
* `McpUiToolMeta` found in MCP tool calls, which may be used in combination
1175
>
* with the {@link contributor} to serve MCP Apps.
1176
>
*/
1177
>
_meta?: Record<string, unknown>;
1178
>
}
1179
>
1180
>
/**
1181
>
* Properties available once tool call parameters are fully received.
1182
>
*
1183
>
* @category Tool Call Types
1184
>
*/
1185
>
interface ToolCallParameterFields {
1186
>
/** Message describing what the tool will do */
1187
>
invocationMessage: StringOrMarkdown;
1188
>
/** Raw tool input */
1189
>
toolInput?: string;
1190
>
}
1191
>
1192
>
/**
1193
>
* Tool execution result details, available after execution completes.
1194
>
*
1195
>
* @category Tool Call Types
1196
>
*/
1197
>
export interface ToolCallResult {
1198
>
/** Whether the tool succeeded */
1199
>
success: boolean;
1200
>
/** Past-tense description of what the tool did */
1201
>
pastTenseMessage: StringOrMarkdown;
1202
>
/**
1203
>
* Unstructured result content blocks.
1204
>
*
1205
>
* This mirrors the `content` field of MCP `CallToolResult`.
1206
>
*/
1207
>
content?: ToolResultContent[];
1208
>
/**
1209
>
* Optional structured result object.
1210
>
*
1211
>
* This mirrors the `structuredContent` field of MCP `CallToolResult`.
1212
>
*/
1213
>
structuredContent?: Record<string, unknown>;
1214
>
/** Error details if the tool failed */
1215
>
error?: { message: string; code?: string };
1216
>
}
1217
>
1218
>
/**
1219
>
* LM is streaming the tool call parameters.
1220
>
*
1221
>
* @category Tool Call Types
1222
>
*/
1223
>
export interface ToolCallStreamingState extends ToolCallBase {
1224
>
status: ToolCallStatus.Streaming;
1225
>
/** Partial parameters accumulated so far */
1226
>
partialInput?: string;
1227
>
/** Progress message shown while parameters are streaming */
1228
>
invocationMessage?: StringOrMarkdown;
1229
>
}
1230
>
1231
>
/**
1232
>
* Parameters are complete, or a running tool requires re-confirmation
1233
>
* (e.g. a mid-execution permission check).
1234
>
*
1235
>
* @category Tool Call Types
1236
>
*/
1237
>
export interface ToolCallPendingConfirmationState extends ToolCallBase, ToolCallParameterFields {
1238
>
status: ToolCallStatus.PendingConfirmation;
1239
>
/** Short title for the confirmation prompt (e.g. `"Run in terminal"`, `"Write file"`) */
1240
>
confirmationTitle?: StringOrMarkdown;
1241
>
/** Risk assessment that informed the confirmation requirement. */
1242
>
riskAssessment?: ToolCallRiskAssessment;
1243
>
/** File edits that this tool call will perform, for preview before confirmation */
1244
>
edits?: { items: FileEdit[] };
1245
>
/** Whether the agent host allows the client to edit the tool's input parameters before confirming */
1246
>
editable?: boolean;
1247
>
/**
1248
>
* Options the server offers for this confirmation. When present, the client
1249
>
* SHOULD render these instead of a plain approve/deny UI. Each option
1250
>
* belongs to a {@link ConfirmationOptionGroup} so the client can still
1251
>
* categorise the choices.
1252
>
*/
1253
>
options?: ConfirmationOption[];
1254
>
}
1255
>
1256
>
/**
1257
>
* Fields present on every tool call state that exists **after** confirmation
1258
>
* has been resolved: {@link ToolCallRunningState}, {@link ToolCallAuthRequiredState},
1259
>
* {@link ToolCallPendingResultConfirmationState}, and {@link ToolCallCompletedState}.
1260
>
* `ToolCallPendingConfirmationState` (not yet confirmed) and
1261
>
* `ToolCallCancelledState` (the denial path — never ran) don't satisfy this
1262
>
* invariant, so they keep their own `selectedOption` field independently
1263
>
* rather than extending this one.
1264
>
*
1265
>
* @category Tool Call Types
1266
>
*/
1267
>
interface ToolCallPostConfirmationFields {
1268
>
/** How the tool was confirmed for execution */
1269
>
confirmed: ToolCallConfirmationReason;
1270
>
/** The confirmation option the user selected, if confirmation options were provided */
1271
>
selectedOption?: ConfirmationOption;
1272
>
}
1273
>
1274
>
/**
1275
>
* Tool is actively executing.
1276
>
*
1277
>
* @category Tool Call Types
1278
>
*/
1279
>
export interface ToolCallRunningState extends ToolCallBase, ToolCallParameterFields, ToolCallPostConfirmationFields {
1280
>
status: ToolCallStatus.Running;
1281
>
/**
1282
>
* Partial content produced while the tool is still executing.
1283
>
*
1284
>
* For example, a terminal content block lets clients subscribe to live
1285
>
* output before the tool completes.
1286
>
*/
1287
>
content?: ToolResultContent[];
1288
>
}
1289
>
1290
>
/**
1291
>
* A running tool call is paused because the MCP server backing it needs
1292
>
* authentication — most commonly {@link McpAuthRequirement.reason |
1293
>
* `insufficientScope`} step-up auth triggered by the `tools/call` request
1294
>
* itself. Only ever reached from {@link ToolCallRunningState}, and normally
1295
>
* returns there once authenticated: `running` → `auth-required` → `running`
1296
>
* → …. A client MAY instead cancel the invocation without authenticating by
1297
>
* dispatching a `chat/toolCallComplete` with a **failed** result, always
1298
>
* moving straight to {@link ToolCallCompletedState} —
1299
>
* `requiresResultConfirmation` is ignored on this path, so it can never
1300
>
* enter {@link ToolCallPendingResultConfirmationState}. A **successful**
1301
>
* result dispatched from this state is invalid and MUST be rejected/ignored
1302
>
* as a no-op by the reducer, since execution never resumed after the
1303
>
* challenge.
1304
>
*
1305
>
* This is the tool-call-level counterpart to
1306
>
* {@link McpServerAuthRequiredState} — that state means the MCP *server*
1307
>
* cannot serve any request; this one means *this specific invocation* is
1308
>
* waiting on the same kind of challenge. The two are dispatched
1309
>
* independently and MAY be true at the same time, or not: an
1310
>
* `insufficientScope` challenge triggered by a single tool call, for
1311
>
* example, need not block the whole server.
1312
>
*
1313
>
* Because the challenge is always resolved by pushing a token via the
1314
>
* existing `authenticate` command, this state can only originate from a
1315
>
* tool call {@link ToolCallContributorKind.MCP | contributed by an MCP
1316
>
* server} — `contributor` is narrowed accordingly (unlike the optional,
1317
>
* multi-kind `contributor` on other tool call states).
1318
>
*
1319
>
* @category Tool Call Types
1320
>
*/
1321
>
export interface ToolCallAuthRequiredState extends ToolCallBase, ToolCallParameterFields, ToolCallPostConfirmationFields {
1322
>
status: ToolCallStatus.AuthRequired;
1323
>
/** The MCP server that contributed this tool call — always MCP, never a client tool. */
1324
>
contributor: ToolCallMcpContributor;
1325
>
/** The authentication challenge blocking this invocation. */
1326
>
auth: McpAuthRequirement;
1327
>
/** Partial content produced before the call paused for authentication. */
1328
>
content?: ToolResultContent[];
1329
>
}
1330
>
1331
>
/**
1332
>
* Tool finished executing, waiting for client to approve the result.
1333
>
*
1334
>
* @category Tool Call Types
1335
>
*/
1336
>
export interface ToolCallPendingResultConfirmationState extends ToolCallBase, ToolCallParameterFields, ToolCallResult, ToolCallPostConfirmationFields {
1337
>
status: ToolCallStatus.PendingResultConfirmation;
1338
>
}
1339
>
1340
>
/**
1341
>
* Tool completed successfully or with an error.
1342
>
*
1343
>
* @category Tool Call Types
1344
>
*/
1345
>
export interface ToolCallCompletedState extends ToolCallBase, ToolCallParameterFields, ToolCallResult, ToolCallPostConfirmationFields {
1346
>
status: ToolCallStatus.Completed;
1347
>
}
1348
>
1349
>
/**
1350
>
* Tool call was cancelled before execution.
1351
>
*
1352
>
* @category Tool Call Types
1353
>
*/
1354
>
export interface ToolCallCancelledState extends ToolCallBase, ToolCallParameterFields {
1355
>
status: ToolCallStatus.Cancelled;
1356
>
/** Why the tool was cancelled */
1357
>
reason: ToolCallCancellationReason;
1358
>
/** Optional message explaining the cancellation */
1359
>
reasonMessage?: StringOrMarkdown;
1360
>
/** What the user suggested doing instead */
1361
>
userSuggestion?: Message;
1362
>
/** The confirmation option the user selected, if confirmation options were provided */
1363
>
selectedOption?: ConfirmationOption;
1364
>
}
1365
>
1366
>
/**
1367
>
* Discriminated union of all tool call lifecycle states.
1368
>
*
1369
>
* See the [state model guide](/guide/state-model.html#tool-call-lifecycle)
1370
>
* for the full state machine diagram.
1371
>
*
1372
>
* @category Tool Call Types
1373
>
*/
1374
>
export type ToolCallState =
1375
>
| ToolCallStreamingState
1376
>
| ToolCallPendingConfirmationState
1377
>
| ToolCallRunningState
1378
>
| ToolCallAuthRequiredState
1379
>
| ToolCallPendingResultConfirmationState
1380
>
| ToolCallCompletedState
1381
>
| ToolCallCancelledState;
1382
>
1383
>
/**
1384
>
* The two tool-call states that block on a client confirmation: parameter
1385
>
* confirmation before execution ({@link ToolCallPendingConfirmationState}) and
1386
>
* result confirmation after execution
1387
>
* ({@link ToolCallPendingResultConfirmationState}).
1388
>
*
1389
>
* {@link ToolCallAuthRequiredState} is intentionally **not** part of this
1390
>
* union: it doesn't block on a `chat/toolCallConfirmed`-style client
1391
>
* decision, it blocks on the client completing an OAuth flow and calling
1392
>
* `authenticate`. See {@link SessionToolAuthenticationRequest} for its
1393
>
* session-level surfacing.
1394
>
*
1395
>
* Surfaced at the session level by {@link SessionToolConfirmationRequest}.
1396
>
*
1397
>
* @category Tool Call Types
1398
>
*/
1399
>
export type ToolCallConfirmationState =
1400
>
| ToolCallPendingConfirmationState
1401
>
| ToolCallPendingResultConfirmationState;
1402
>
1403
>
1404
>
// ─── Tool Result Content ─────────────────────────────────────────────────────
1405
>
1406
>
/**
1407
>
* Discriminant for tool result content types.
1408
>
*
1409
>
* @category Tool Result Content
1410
>
*/
1411
>
export const enum ToolResultContentType {
1412
>
Text = 'text',
1413
>
EmbeddedResource = 'embeddedResource',
1414
>
Resource = 'resource',
1415
>
FileEdit = 'fileEdit',
1416
>
Terminal = 'terminal',
1417
>
Subagent = 'subagent',
1418
>
}
1419
>
1420
>
/**
1421
>
* Text content in a tool result.
1422
>
*
1423
>
* Mirrors MCP `TextContent`.
1424
>
*
1425
>
* @category Tool Result Content
1426
>
*/
1427
>
export interface ToolResultTextContent {
1428
>
type: ToolResultContentType.Text;
1429
>
/** The text content */
1430
>
text: string;
1431
>
}
1432
>
1433
>
/**
1434
>
* Base64-encoded binary content embedded in a tool result.
1435
>
*
1436
>
* Mirrors MCP `EmbeddedResource` for inline binary data.
1437
>
*
1438
>
* @category Tool Result Content
1439
>
*/
1440
>
export interface ToolResultEmbeddedResourceContent {
1441
>
type: ToolResultContentType.EmbeddedResource;
1442
>
/** Base64-encoded data */
1443
>
data: string;
1444
>
/** Content type (e.g. `"image/png"`, `"application/pdf"`) */
1445
>
contentType: string;
1446
>
}
1447
>
1448
>
/**
1449
>
* A reference to a resource stored outside the tool result.
1450
>
*
1451
>
* Wraps {@link ContentRef} for lazy-loading large results.
1452
>
*
1453
>
* @category Tool Result Content
1454
>
*/
1455
>
export interface ToolResultResourceContent extends ContentRef {
1456
>
type: ToolResultContentType.Resource;
1457
>
}
1458
>
1459
>
/**
1460
>
* Describes a file modification performed by a tool.
1461
>
*
1462
>
* @category Tool Result Content
1463
>
*/
1464
>
export interface ToolResultFileEditContent extends FileEdit {
1465
>
type: ToolResultContentType.FileEdit;
1466
>
}
1467
>
1468
>
/**
1469
>
* A reference to a terminal whose output is relevant to this tool result.
1470
>
*
1471
>
* Clients can subscribe to the terminal's URI to stream its output in real
1472
>
* time, providing live feedback while a tool is executing.
1473
>
*
1474
>
* When the command exits, {@link result} is filled in on the completed
1475
>
* result, retaining the outcome for clients that did not subscribe. This
1476
>
* records the command's exit, not the terminal's — the terminal may keep
1477
>
* running afterwards.
1478
>
*
1479
>
* @category Tool Result Content
1480
>
*/
1481
>
export interface ToolResultTerminalContent {
1482
>
type: ToolResultContentType.Terminal;
1483
>
/** Terminal URI (subscribable for full terminal state) */
1484
>
resource: URI;
1485
>
/** Display title for the terminal content */
1486
>
title: string;
1487
>
/**
1488
>
* Whether this terminal-style resource is backed by a pseudoterminal.
1489
>
* When `false`, output is plain text and clients do not need to parse
1490
>
* VT sequences.
1491
>
*/
1492
>
isPty?: boolean;
1493
>
/** Outcome of the command, present once it has exited. */
1494
>
result?: TerminalCommandResult;
1495
>
}
1496
>
1497
>
/**
1498
>
* Outcome of a command run in a terminal-style tool, filled in on
1499
>
* {@link ToolResultTerminalContent.result} once the command exits.
1500
>
*
1501
>
* @category Tool Result Content
1502
>
*/
1503
>
export interface TerminalCommandResult {
1504
>
/** Exit code from the completed command, if reported by the runtime */
1505
>
exitCode?: number;
1506
>
/**
1507
>
* Preview of the command's output, for clients that are not subscribed
1508
>
* to the terminal or that arrive after it is disposed. When `isPty` is
1509
>
* `true` the preview may contain VT sequences; when `false` it is plain
1510
>
* text.
1511
>
*/
1512
>
preview?: string;
1513
>
/** Whether `preview` is known to be incomplete or truncated */
1514
>
truncated?: boolean;
1515
>
}
1516
>
1517
>
/**
1518
>
* A reference, embedded in a tool result, to a worker chat spawned by the tool
1519
>
* call (a sub-agent delegation), referenced by a chat URI (`ahp-chat:/...`).
1520
>
*
1521
>
* This is the spawning tool call's forward view of the worker. The worker chat
1522
>
* records the same edge in reverse via its {@link ChatOrigin} (`kind: 'tool'`),
1523
>
* whose `toolCallId` identifies the tool call that emitted this content.
1524
>
*
1525
>
* @category Tool Result Content
1526
>
*/
1527
>
export interface ToolResultSubagentContent {
1528
>
type: ToolResultContentType.Subagent;
1529
>
/** Worker chat URI (subscribable for full chat state) */
1530
>
resource: URI;
1531
>
/** Display title for the subagent */
1532
>
title: string;
1533
>
/** Internal agent name */
1534
>
agentName?: string;
1535
>
/** Human-readable description of the subagent's task */
1536
>
description?: string;
1537
>
}
1538
>
1539
>
/**
1540
>
* Content block in a tool result.
1541
>
*
1542
>
* Mirrors the content blocks in MCP `CallToolResult.content`, plus
1543
>
* `ToolResultResourceContent` for lazy-loading large results,
1544
>
* `ToolResultFileEditContent` for file edit diffs,
1545
>
* `ToolResultTerminalContent` for live terminal output and
1546
>
* command completion metadata, and
1547
>
* `ToolResultSubagentContent` for tool-spawned worker chats (AHP extensions).
1548
>
*
1549
>
* @category Tool Result Content
1550
>
*/
1551
>
export type ToolResultContent =
1552
>
| ToolResultTextContent
1553
>
| ToolResultEmbeddedResourceContent
1554
>
| ToolResultResourceContent
1555
>
| ToolResultFileEditContent
1556
>
| ToolResultTerminalContent
1557
>
| ToolResultSubagentContent;