252
};
253
}
255
>
256
>
export interface IChatProgressMessage {
257
>
content: IMarkdownString;
258
>
kind: 'progressMessage';
259
>
shimmer?: boolean;
260
>
}
261
>
262
>
export interface IChatSystemNotificationPart {
263
>
content: IMarkdownString;
264
>
kind: 'systemNotification';
265
>
}
266
>
267
>
export interface IChatTask extends IChatTaskDto {
268
>
deferred: DeferredPromise<string | void>;
269
>
progress: (IChatWarningMessage | IChatContentReference)[];
270
>
readonly onDidAddProgress: Event<IChatWarningMessage | IChatContentReference>;
271
>
add(progress: IChatWarningMessage | IChatContentReference): void;
272
>
273
>
complete: (result: string | void) => void;
274
>
task: () => Promise<string | void>;
275
>
isSettled: () => boolean;
276
>
toJSON(): IChatTaskSerialized;
277
>
}
278
>
279
>
export interface IChatUndoStop {
280
>
kind: 'undoStop';
281
>
id: string;
282
>
}
283
>
284
>
export interface IChatExternalEditsDto {
285
>
kind: 'externalEdits';
286
>
undoStopId: string;
287
>
start: boolean; /** true=start, false=stop */
288
>
resources: UriComponents[];
289
>
/**
290
>
* When present, these URIs are read instead of the `resources` URIs
291
>
* (by-index) when capturing file snapshots. Used by the agent host
292
>
* to provide before/after content from the remote filesystem
293
>
* or from stored snapshots.
294
>
*/
295
>
contentFor?: UriComponents[];
296
>
}
297
>
298
>
export interface IChatTaskDto {
299
>
content: IMarkdownString;
300
>
kind: 'progressTask';
301
>
}
302
>
303
>
export interface IChatTaskSerialized {
304
>
content: IMarkdownString;
305
>
progress: (IChatWarningMessage | IChatContentReference)[];
306
>
kind: 'progressTaskSerialized';
307
>
}
308
>
309
>
export interface IChatTaskResult {
310
>
content: IMarkdownString | void;
311
>
kind: 'progressTaskResult';
312
>
}
313
>
314
>
export interface IChatWarningMessage {
315
>
content: IMarkdownString;
316
>
kind: 'warning';
317
>
}
318
>
319
>
export interface IChatInfoMessage {
320
>
content: IMarkdownString;
321
>
kind: 'info';
322
>
}
323
>
324
>
export interface IChatAgentVulnerabilityDetails {
325
>
title: string;
326
>
description: string;
327
>
}
328
>
329
>
export interface IChatResponseCodeblockUriPart {
330
>
kind: 'codeblockUri';
331
>
uri: URI;
332
>
isEdit?: boolean;
333
>
undoStopId?: string;
334
>
subAgentInvocationId?: string;
335
>
}
336
>
337
>
export interface IChatAgentMarkdownContentWithVulnerability {
338
>
content: IMarkdownString;
339
>
vulnerabilities: IChatAgentVulnerabilityDetails[];
340
>
kind: 'markdownVuln';
341
>
}
342
>
343
>
export interface IChatCommandButton {
344
>
command: Command;
345
>
kind: 'command';
346
>
additionalCommands?: Command[]; // rendered as secondary buttons
347
>
}
348
>
349
>
export interface IChatMoveMessage {
350
>
uri: URI;
351
>
range: IRange;
352
>
kind: 'move';
353
>
}
354
>
355
>
export interface IChatTextEdit {
356
>
uri: URI;
357
>
edits: TextEdit[];
358
>
kind: 'textEdit';
359
>
done?: boolean;
360
>
isExternalEdit?: boolean;
361
>
}
362
>
363
>
export interface IChatClearToPreviousToolInvocation {
364
>
kind: 'clearToPreviousToolInvocation';
365
>
reason: ChatResponseClearToPreviousToolInvocationReason;
366
>
}
367
>
368
>
export interface IChatNotebookEdit {
369
>
uri: URI;
370
>
edits: ICellEditOperation[];
371
>
kind: 'notebookEdit';
372
>
done?: boolean;
373
>
isExternalEdit?: boolean;
374
>
}
375
>
376
>
export interface IChatWorkspaceFileEdit {
377
>
oldResource?: URI;
378
>
newResource?: URI;
379
>
}
380
>
381
>
export interface IChatWorkspaceEdit {
382
>
kind: 'workspaceEdit';
383
>
edits: IChatWorkspaceFileEdit[];
384
>
}
385
>
386
>
/**
387
>
* The kind of file operation an {@link IChatExternalEdit} represents.
388
>
*/
389
>
export type ChatExternalEditKind = 'create' | 'delete' | 'rename' | 'edit';
390
>
391
>
/**
392
>
* A summary of a file edit that has been performed externally (i.e. by an
393
>
* agent or tool outside of chat's own editing pipeline). Carries everything
394
>
* needed to render a static "edit pill" without round-tripping through
395
>
* {@link IChatEditingSession} for diff computation: the producer already
396
>
* knows the URIs and diff stats up-front.
397
>
*/
398
>
export interface IChatExternalEdit {
399
>
kind: 'externalEdit';
400
>
/** The resulting file URI (after-URI for create/edit/rename, before-URI for delete). */
401
>
uri: URI;
402
>
/** The kind of file operation. */
403
>
editKind: ChatExternalEditKind;
404
>
/** For renames, the file URI before the operation. */
405
>
originalUri?: URI;
406
>
/** URI from which the "before" content can be read (for diff viewing). Absent for creates. */
407
>
beforeContentUri?: URI;
408
>
/** URI from which the "after" content can be read (for diff viewing). Absent for deletes. */
409
>
afterContentUri?: URI;
410
>
/** Pre-computed diff display metadata. */
411
>
diff?: { added: number; removed: number };
412
>
/** Optional undo-stop id (typically the tool call id) for grouping. */
413
>
undoStopId?: string;
414
>
}
415
>
416
>
export interface IChatConfirmation {
417
>
title: string;
418
>
message: string | IMarkdownString;
419
>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
420
>
data: any;
421
>
buttons?: string[];
422
>
isUsed?: boolean;
423
>
kind: 'confirmation';
424
>
}
425
>
426
>
/**
427
>
* Validation rules for a question in a question carousel.
428
>
*/
429
>
export interface IChatQuestionValidation {
430
>
minLength?: number;
431
>
maxLength?: number;
432
>
format?: 'email' | 'uri' | 'date' | 'date-time';
433
>
minimum?: number;
434
>
maximum?: number;
435
>
isInteger?: boolean;
436
>
}
437
>
438
>
/**
439
>
* Represents an individual question in a question carousel.
440
>
*/
441
>
export interface IChatQuestion {
442
>
id: string;
443
>
type: 'text' | 'singleSelect' | 'multiSelect';
444
>
title: string;
445
>
message?: string | IMarkdownString;
446
>
description?: string;
447
>
options?: { id: string; label: string; value: string }[];
448
>
defaultValue?: string | string[];
449
>
allowFreeformInput?: boolean;
450
>
required?: boolean;
451
>
validation?: IChatQuestionValidation;
452
>
detailedMessage?: string | IMarkdownString;
453
>
}
454
>
455
>
/** Answer shape for a single-select question. */
456
>
export interface IChatSingleSelectAnswer {
457
>
selectedValue?: string;
458
>
freeformValue?: string;
459
>
}
460
>
461
>
/** Answer shape for a multi-select question. */
462
>
export interface IChatMultiSelectAnswer {
463
>
selectedValues: string[];
464
>
freeformValue?: string;
465
>
}
466
>
467
>
/** Union of all possible answer values in a question carousel. */
468
>
export type IChatQuestionAnswerValue = string | IChatSingleSelectAnswer | IChatMultiSelectAnswer;
469
>
470
>
/** Record mapping question IDs to their typed answer values. */
471
>
export type IChatQuestionAnswers = Record<string, IChatQuestionAnswerValue>;
472
>
473
>
/**
474
>
* A carousel for presenting multiple questions inline in the chat response.
475
>
* Users can navigate between questions and submit their answers.
476
>
*/
477
>
export interface IChatQuestionCarousel {
478
>
questions: IChatQuestion[];
479
>
allowSkip: boolean;
480
>
/** Unique identifier for resolving the carousel answers back to the extension */
481
>
resolveId?: string;
482
>
/** Storage for collected answers when user submits */
483
>
data?: IChatQuestionAnswers;
484
>
/** Whether the carousel has been submitted/skipped */
485
>
isUsed?: boolean;
486
>
/** True when accepted/answered outside the carousel UI (e.g. via voice) without structured answers. */
487
>
answeredExternally?: boolean;
488
>
/** Top-level message shown above the questions (e.g. from MCP elicitation message) */
489
>
message?: string | IMarkdownString;
490
>
/** Source attribution (e.g. MCP server) */
491
>
source?: ToolDataSource;
492
>
/** Terminal ID when the carousel was triggered by a terminal needing input */
493
>
terminalId?: string;
494
>
kind: 'questionCarousel';
495
>
}
496
>
497
>
export const enum ElicitationState {
498
>
Pending = 'pending',
499
>
Accepted = 'accepted',
500
>
Rejected = 'rejected',
501
>
}
502
>
503
>
export interface IChatElicitationRequest {
504
>
kind: 'elicitation2'; // '2' because initially serialized data used the same kind
505
>
title: string | IMarkdownString;
506
>
message: string | IMarkdownString;
507
>
acceptButtonLabel: string;
508
>
rejectButtonLabel: string | undefined;
509
>
subtitle?: string | IMarkdownString;
510
>
source?: ToolDataSource;
511
>
state: IObservable<ElicitationState>;
512
>
acceptedResult?: Record<string, unknown>;
513
>
moreActions?: IAction[];
514
>
riskAssessment?: { toolId: string; parameters: unknown };
515
>
accept(value: IAction | true): Promise<void>;
516
>
reject?: () => Promise<void>;
517
>
isHidden?: IObservable<boolean>;
518
>
hide?(): void;
519
>
toJSON(): IChatElicitationRequestSerialized;
520
>
}
521
>
522
>
export interface IChatElicitationRequestSerialized {
523
>
kind: 'elicitationSerialized';
524
>
title: string | IMarkdownString;
525
>
message: string | IMarkdownString;
526
>
subtitle: string | IMarkdownString | undefined;
527
>
source: ToolDataSource | undefined;
528
>
state: ElicitationState.Accepted | ElicitationState.Rejected;
529
>
isHidden: boolean;
530
>
acceptedResult?: Record<string, unknown>;
531
>
}
532
>
533
>
export interface IChatThinkingPart {
534
>
kind: 'thinking';
535
>
value?: string | string[];
536
>
id?: string;
537
>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
538
>
metadata?: { readonly [key: string]: any };
539
>
generatedTitle?: string;
540
>
/** Elapsed reasoning time in milliseconds, persisted so the duration survives reload. */
541
>
reasoningDurationMs?: number;
542
>
}
543
>
544
>
/**
545
>
* A progress part representing an auto-mode model routing resolution.
546
>
* Shown as a collapsible widget in the chat stream: collapsed displays
547
>
* "Routed to <model>", expanded shows routing details and confidence.
548
>
*/
549
>
export interface IChatAutoModeResolutionPart {
550
>
kind: 'autoModeResolution';
551
>
/** The model ID that was selected by the router */
552
>
resolvedModel: string;
553
>
/** The user-facing display name of the resolved model */
554
>
resolvedModelName: string;
555
>
/** The router's classification label */
556
>
predictedLabel: 'needs_reasoning' | 'no_reasoning' | 'fallback';
557
>
/** Confidence score (0-1) from the router */
558
>
confidence: number;
559
>
}
560
>
561
>
/**
562
>
* A progress part representing the execution result of a hook.
563
>
* Aligned with the hook output JSON structure: { stopReason, systemMessage, hookSpecificOutput }.
564
>
* If {@link stopReason} is set, the hook blocked/denied the operation.
565
>
*/
566
>
export interface IChatHookPart {
567
>
kind: 'hook';
568
>
/** The type of hook that was executed */
569
>
hookType: HookTypeValue;
570
>
/** If set, the hook blocked processing. This message is shown to the user. */
571
>
stopReason?: string;
572
>
/** Warning/system message from the hook, shown to the user */
573
>
systemMessage?: string;
574
>
/** Display name of the tool that was affected by the hook */
575
>
toolDisplayName?: string;
576
>
metadata?: { readonly [key: string]: unknown };
577
>
/** If set, this hook was executed within a subagent invocation and should be grouped with it. */
578
>
subAgentInvocationId?: string;
579
>
}
580
>
581
>
export interface IChatTerminalToolInvocationData {
582
>
kind: 'terminal';
583
>
commandLine: {
584
>
original: string;
585
>
userEdited?: string;
586
>
toolEdited?: string;
587
>
// command to show in the chat UI (potentially different from what is actually run in the terminal)
588
>
forDisplay?: string;
589
>
// isSandboxWrapped boolean to run in the terminal (potentially different from original command)
590
>
isSandboxWrapped?: boolean;
591
>
};
592
>
/**
593
>
* LM-generated intention describing why the command is being run, shown
594
>
* above the command in the terminal tool card. Set by the Agent Host; the
595
>
* built-in terminal tool leaves this unset.
596
>
*/
597
>
intention?: string;
598
>
/** The working directory URI for the terminal */
599
>
cwd?: UriComponents;
600
>
/**
601
>
* Pre-computed confirmation display data (localization must happen at source).
602
>
* Contains the command line to show in confirmation (potentially without cd prefix)
603
>
* and the formatted cwd label if a cd prefix was extracted.
604
>
*/
605
>
confirmation?: {
606
>
/** The command line to display in the confirmation editor */
607
>
commandLine: string;
608
>
/** The formatted cwd label to show in title (if cd was extracted) */
609
>
cwdLabel?: string;
610
>
/** The cd prefix to prepend back when user edits */
611
>
cdPrefix?: string;
612
>
};
613
>
/**
614
>
* Overrides to apply to the presentation of the tool call only, but not actually change the
615
>
* command that gets run. For example, python -c "print('hello')" can be presented as just
616
>
* the Python code with Python syntax highlighting.
617
>
*/
618
>
presentationOverrides?: {
619
>
/** The command line to display in the UI */
620
>
commandLine: string;
621
>
/** The language for syntax highlighting */
622
>
language?: string;
623
>
};
624
>
/** Message for model recommending the use of an alternative tool */
625
>
alternativeRecommendation?: string;
626
>
language: string;
627
>
terminalToolSessionId?: string;
628
>
/** False for output-only data that must not create a workbench terminal instance. */
629
>
isPty?: boolean;
630
>
/** The predefined command ID that will be used for this terminal command */
631
>
terminalCommandId?: string;
632
>
/** Whether the terminal command was started as a background execution */
633
>
isBackground?: boolean;
634
>
/** Whether the command was explicitly approved to run outside the sandbox */
635
>
requestUnsandboxedExecution?: boolean;
636
>
/** The model-provided reason for requesting sandbox bypass */
637
>
requestUnsandboxedExecutionReason?: string;
638
>
/** Whether the terminal command was approved to run sandboxed with unrestricted network access */
639
>
requestAllowNetwork?: boolean;
640
>
/** The model-provided reason for requesting unrestricted network access within the sandbox */
641
>
requestAllowNetworkReason?: string;
642
>
/** Serialized URI for the command that was executed in the terminal */
643
>
terminalCommandUri?: UriComponents;
644
>
/** Serialized output of the executed command */
645
>
terminalCommandOutput?: {
646
>
text: string;
647
>
truncated?: boolean;
648
>
lineCount?: number;
649
>
};
650
>
/** Stored theme colors at execution time to style detached output */
651
>
terminalTheme?: {
652
>
background?: string;
653
>
foreground?: string;
654
>
};
655
>
/** Stored command state to restore decorations after reload */
656
>
terminalCommandState?: {
657
>
exitCode?: number;
658
>
timestamp?: number;
659
>
duration?: number;
660
>
};
661
>
/** Whether the user chose to continue in background for this tool invocation */
662
>
didContinueInBackground?: boolean;
663
>
autoApproveInfo?: IMarkdownString;
664
>
/** Names of missing sandbox dependencies that the user may choose to install */
665
>
missingSandboxDependencies?: string[];
666
>
/** Approved repair actions that may make an installed but unusable sandbox dependency work. */
667
>
sandboxRemediations?: string[];
668
>
/** User-visible reason a sandbox prerequisite cannot be repaired automatically. */
669
>
sandboxPrerequisiteFailure?: string;
670
>
}
671
>
672
>
/**
673
>
* @deprecated This is the old API shape, we should support this for a while before removing it so
674
>
* we don't break existing chats
675
>
*/
676
>
export interface ILegacyChatTerminalToolInvocationData {
677
>
kind: 'terminal';
678
>
command: string;
679
>
language: string;
680
>
}
681
>
682
>
export function isLegacyChatTerminalToolInvocationData(data: unknown): data is ILegacyChatTerminalToolInvocationData {
683
return !!data && typeof data === 'object' && 'command' in data && 'language' in data;
684
}
686
>
/**
687
>
* Routing information for an MCP App's webview sub-RPCs. The kind
688
>
* determines where `tools/call`, `resources/read`,
689
>
* `sampling/createMessage`, etc. are sent:
690
>
*
691
>
* - `local`: resolves the MCP server via {@link IMcpService} from a
692
>
* `serverDefinitionId` + `collectionId`. Used for locally-configured
693
>
* MCP servers whose state lives in the workbench.
694
>
* - `agentHost`: routes through {@link IAgentHostService.handleMcpRequest}
695
>
* on an AHP `mcp://` side channel. Used for MCP servers owned by an
696
>
* agent host (e.g. Copilot CLI).
697
>
*/
698
>
export type ChatMcpAppData =
699
>
| {
700
>
kind: 'local';
701
>
/** URI of the UI resource for rendering (e.g., "ui://weather-server/dashboard") */
702
>
resourceUri: string;
703
>
/** Reference to the server definition for reconnection */
704
>
serverDefinitionId: string;
705
>
/** Reference to the collection containing the server */
706
>
collectionId: string;
707
>
}
708
>
| {
709
>
kind: 'agentHost';
710
>
/** URI of the UI resource for rendering (e.g., "ui://weather-server/dashboard") */
711
>
resourceUri: string;
712
>
/** AHP `mcp://` channel URI for the originating server. */
713
>
channel: string;
714
>
/**
715
>
* Stable identifier for the originating server, used as the
716
>
* additional key when computing the webview origin. Typically the
717
>
* AHP customization id. For top-level (bare) MCP servers this id
718
>
* is currently session-scoped, so see {@link ChatMcpAppModel} for
719
>
* how it avoids growing persistent application storage on every
720
>
* new session.
721
>
*/
722
>
serverId: string;
723
>
};
724
>
725
>
export interface IChatToolInputInvocationData {
726
>
kind: 'input';
727
>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
728
>
rawInput: any;
729
>
/** Optional MCP App UI metadata for rendering during and after tool execution */
730
>
mcpAppData?: ChatMcpAppData;
731
>
}
732
>
733
>
export const enum ToolConfirmKind {
734
>
Denied,
735
>
ConfirmationNotNeeded,
736
>
Setting,
737
>
LmServicePerTool,
738
>
UserAction,
739
>
Skipped
740
>
}
741
>
742
>
export type ConfirmedReason =
743
>
| { type: ToolConfirmKind.Denied }
744
>
| { type: ToolConfirmKind.ConfirmationNotNeeded; reason?: string | IMarkdownString }
745
>
| { type: ToolConfirmKind.Setting; id: string }
746
>
| { type: ToolConfirmKind.LmServicePerTool; scope: 'session' | 'workspace' | 'profile' }
747
>
| { type: ToolConfirmKind.UserAction; selectedButton?: string; selectedButtonKind?: ConfirmationOptionKind }
748
>
| { type: ToolConfirmKind.Skipped };
749
>
750
>
/**
751
>
* Active-only controls for a tool call executing on another connected client.
752
>
*/
753
>
export interface IChatToolInvocationOtherClientData {
754
>
readonly cancel: () => void;
755
>
}
756
>
757
>
export interface IChatToolInvocation {
758
>
readonly presentation: IPreparedToolInvocation['presentation'];
759
>
readonly toolSpecificData?: IChatTerminalToolInvocationData | ILegacyChatTerminalToolInvocationData | IChatToolInputInvocationData | IChatExtensionsContent | IChatPullRequestContent | IChatTodoListContent | IChatSubagentToolInvocationData | IChatSimpleToolInvocationData | IChatSearchToolInvocationData | IChatToolResourcesInvocationData | IChatModifiedFilesConfirmationData | IChatAgentFeedbackReviewConfirmationData | IChatSessionCreatedData | IChatAutomationConfigurationData | IChatAutomationConfiguredData;
760
>
/** Active-only metadata that is omitted when the invocation is serialized. */
761
>
readonly otherClientToolCall?: IChatToolInvocationOtherClientData;
762
>
/**
763
>
* Observable that tracks the `kind` of `toolSpecificData`. Used by the
764
>
* tool invocation part to re-render when the kind changes (e.g. from
765
>
* `'input'` to `'terminal'` when terminal content arrives).
766
>
*/
767
>
readonly toolSpecificDataKind: IObservable<string | undefined>;
768
>
readonly originMessage: string | IMarkdownString | undefined;
769
>
readonly invocationMessage: string | IMarkdownString;
770
>
readonly pastTenseMessage: string | IMarkdownString | undefined;
771
>
readonly source: ToolDataSource;
772
>
readonly toolId: string;
773
>
readonly toolCallId: string;
774
>
readonly subAgentInvocationId?: string;
775
>
readonly icon?: ThemeIcon;
776
>
readonly state: IObservable<IChatToolInvocation.State>;
777
>
generatedTitle?: string;
778
>
isAttachedToThinking: boolean;
779
>
780
>
kind: 'toolInvocation';
781
>
782
>
toJSON(): IChatToolInvocationSerialized;
783
>
}
784
>
785
>
export namespace IChatToolInvocation {
786
>
export const enum StateKind {
787
>
/** Tool call is streaming partial input from the LM */
788
>
Streaming,
789
>
WaitingForConfirmation,
790
>
Executing,
791
>
WaitingForPostApproval,
792
>
Completed,
793
>
Cancelled,
794
>
WaitingForAuthentication,
795
>
}
796
>
797
>
interface IChatToolInvocationStateBase {
798
>
type: StateKind;
799
>
}
800
>
801
>
export interface IChatToolInvocationStreamingState extends IChatToolInvocationStateBase {
802
>
type: StateKind.Streaming;
803
>
/** Observable partial input from the LM stream */
804
>
readonly partialInput: IObservable<unknown>;
805
>
/** Custom invocation message from handleToolStream */
806
>
readonly streamingMessage: IObservable<string | IMarkdownString | undefined>;
807
>
}
808
>
809
>
/** Properties available after streaming is complete */
810
>
interface IChatToolInvocationPostStreamState {
811
>
readonly parameters: unknown;
812
>
readonly confirmationMessages?: IToolConfirmationMessages;
813
>
}
814
>
815
>
interface IChatToolInvocationWaitingForConfirmationState extends IChatToolInvocationStateBase, IChatToolInvocationPostStreamState {
816
>
type: StateKind.WaitingForConfirmation;
817
>
confirm(reason: ConfirmedReason): void;
818
>
}
819
>
820
>
interface IChatToolInvocationPostConfirmState extends IChatToolInvocationPostStreamState {
821
>
confirmed: ConfirmedReason;
822
>
}
823
>
824
>
interface IChatToolInvocationExecutingState extends IChatToolInvocationStateBase, IChatToolInvocationPostConfirmState {
825
>
type: StateKind.Executing;
826
>
progress: IObservable<{ message?: string | IMarkdownString; progress: number | undefined }>;
827
>
}
828
>
829
>
export interface IChatToolInvocationWaitingForAuthenticationState extends IChatToolInvocationStateBase, IChatToolInvocationPostConfirmState {
830
>
type: StateKind.WaitingForAuthentication;
831
>
readonly server: IChatMcpAuthenticationRequiredServer;
832
>
cancel(): void;
833
>
}
834
>
835
>
interface IChatToolInvocationPostExecuteState extends IChatToolInvocationPostConfirmState {
836
>
resultDetails: IToolResult['toolResultDetails'];
837
>
}
838
>
839
>
interface IChatToolWaitingForPostApprovalState extends IChatToolInvocationStateBase, IChatToolInvocationPostExecuteState {
840
>
type: StateKind.WaitingForPostApproval;
841
>
confirm(reason: ConfirmedReason): void;
842
>
contentForModel: IToolResult['content'];
843
>
}
844
>
845
>
interface IChatToolInvocationCompleteState extends IChatToolInvocationStateBase, IChatToolInvocationPostExecuteState {
846
>
type: StateKind.Completed;
847
>
postConfirmed: ConfirmedReason | undefined;
848
>
contentForModel: IToolResult['content'];
849
>
}
850
>
851
>
interface IChatToolInvocationCancelledState extends IChatToolInvocationStateBase, IChatToolInvocationPostStreamState {
852
>
type: StateKind.Cancelled;
853
>
reason: ToolConfirmKind.Denied | ToolConfirmKind.Skipped;
854
>
/** Optional message explaining why the tool was cancelled (e.g., from hook denial) */
855
>
reasonMessage?: string | IMarkdownString;
856
>
}
857
>
858
>
export type State =
859
>
| IChatToolInvocationStreamingState
860
>
| IChatToolInvocationWaitingForConfirmationState
861
>
| IChatToolInvocationExecutingState
862
>
| IChatToolInvocationWaitingForAuthenticationState
863
>
| IChatToolWaitingForPostApprovalState
864
>
| IChatToolInvocationCompleteState
865
>
| IChatToolInvocationCancelledState;
866
>
867
>
export function executionConfirmedOrDenied(invocation: IChatToolInvocation | IChatToolInvocationSerialized, reader?: IReader): ConfirmedReason | undefined {
868
if (invocation.kind === 'toolInvocationSerialized') {
869
if (invocation.isConfirmed === undefined || typeof invocation.isConfirmed === 'boolean') {