/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

// version: 3

declare module 'vscode' {

	export interface ChatParticipant {
		readonly onDidPerformAction: Event<ChatUserActionEvent>;
	}

	/**
	 * Now only used for the "intent detection" API below
	 */
	export interface ChatCommand {
		readonly name: string;
		readonly description: string;
	}

	export interface ChatVulnerability {
		title: string;
		description: string;
		// id: string; // Later we will need to be able to link these across multiple content chunks.
	}

	export class ChatResponseMarkdownWithVulnerabilitiesPart {
		value: MarkdownString;
		vulnerabilities: ChatVulnerability[];
		constructor(value: string | MarkdownString, vulnerabilities: ChatVulnerability[]);
	}

	export class ChatResponseCodeblockUriPart {
		isEdit?: boolean;
		value: Uri;
		undoStopId?: string;
		constructor(value: Uri, isEdit?: boolean, undoStopId?: string);
	}

	/**
	 * Displays a {@link Command command} as a button in the chat response.
	 */
	export interface ChatCommandButton {
		command: Command;
	}

	export interface ChatDocumentContext {
		uri: Uri;
		version: number;
		ranges: Range[];
	}

	export class ChatResponseTextEditPart {
		uri: Uri;
		edits: TextEdit[];
		isDone?: boolean;
		constructor(uri: Uri, done: true);
		constructor(uri: Uri, edits: TextEdit | TextEdit[]);
	}

	export class ChatResponseNotebookEditPart {
		uri: Uri;
		edits: NotebookEdit[];
		isDone?: boolean;
		constructor(uri: Uri, done: true);
		constructor(uri: Uri, edits: NotebookEdit | NotebookEdit[]);
	}

	/**
	 * Represents a file-level edit (creation, deletion, or rename).
	 */
	export interface ChatWorkspaceFileEdit {
		/**
		 * The original file URI (undefined for new files).
		 */
		oldResource?: Uri;

		/**
		 * The new file URI (undefined for deleted files).
		 */
		newResource?: Uri;
	}

	/**
	 * Represents a workspace edit containing file-level operations.
	 */
	export class ChatResponseWorkspaceEditPart {
		edits: ChatWorkspaceFileEdit[];
		constructor(edits: ChatWorkspaceFileEdit[]);
	}

	export class ChatResponseConfirmationPart {
		title: string;
		message: string | MarkdownString;
		data: any;
		buttons?: string[];
		constructor(title: string, message: string | MarkdownString, data: any, buttons?: string[]);
	}

	/**
	 * An option for a question in a carousel.
	 */
	export interface ChatQuestionOption {
		/**
		 * Unique identifier for the option.
		 */
		id: string;
		/**
		 * The display label for the option.
		 */
		label: string;
		/**
		 * The value returned when this option is selected.
		 */
		value: unknown;
	}

	/**
	 * The type of question for a chat question carousel.
	 */
	export enum ChatQuestionType {
		/**
		 * A free-form text input question.
		 */
		Text = 1,
		/**
		 * A single-select question with radio buttons.
		 */
		SingleSelect = 2,
		/**
		 * A multi-select question with checkboxes.
		 */
		MultiSelect = 3
	}

	/**
	 * A question to be displayed in a question carousel.
	 */
	export class ChatQuestion {
		/**
		 * Unique identifier for the question.
		 */
		id: string;
		/**
		 * The type of question: Text for free-form input, SingleSelect for radio buttons, MultiSelect for checkboxes.
		 */
		type: ChatQuestionType;
		/**
		 * The title/header of the question.
		 */
		title: string;
		/**
		 * Optional detailed message or description for the question.
		 */
		message?: string | MarkdownString;
		/**
		 * Options for singleSelect or multiSelect questions.
		 */
		options?: ChatQuestionOption[];
		/**
		 * The id(s) of the default selected option(s).
		 * For SingleSelect, this should be a single option id.
		 * For MultiSelect, this can be an array of option ids.
		 */
		defaultValue?: string | string[];
		/**
		 * Whether to allow free-form text input in addition to predefined options.
		 * When true, users can provide their own text answer even for SingleSelect or MultiSelect questions.
		 */
		allowFreeformInput?: boolean;

		constructor(
			id: string,
			type: ChatQuestionType,
			title: string,
			options?: {
				message?: string | MarkdownString;
				options?: ChatQuestionOption[];
				defaultValue?: string | string[];
				allowFreeformInput?: boolean;
			}
		);
	}

	/**
	 * A carousel view for presenting multiple questions inline in the chat.
	 * The UI is displayed but does not block the chat input.
	 */
	export class ChatResponseQuestionCarouselPart {
		/**
		 * The questions to display in the carousel.
		 */
		questions: ChatQuestion[];
		/**
		 * Whether users can skip answering the questions.
		 */
		allowSkip: boolean;

		constructor(questions: ChatQuestion[], allowSkip?: boolean);
	}

	export class ChatResponseCodeCitationPart {
		value: Uri;
		license: string;
		snippet: string;
		constructor(value: Uri, license: string, snippet: string);
	}

	export interface ChatToolInvocationStreamData {
		/**
		 * Partial or not-yet-validated arguments that have streamed from the language model.
		 * Tools may use this to render interim UI while the full invocation input is collected.
		 */
		readonly partialInput?: unknown;
	}

	export interface ChatTerminalToolInvocationData {
		commandLine: {
			original: string;
			userEdited?: string;
			toolEdited?: string;
		};
		language: string;

		/**
		 * Overrides for how the command is presented in the UI.
		 * For example, when a `cd <dir> && <command>` prefix is detected,
		 * the presentation can show only the actual command.
		 */
		presentationOverrides?: {
			commandLine: string;
			language?: string;
		};

		/**
		 * Terminal command output. Displayed when the terminal is no longer available.
		 */
		output?: {
			/** The raw output text, may include ANSI escape codes. */
			text: string;
		};

		/**
		 * Command execution state.
		 */
		state?: {
			/** Exit code of the command. */
			exitCode?: number;
			/** Duration of execution in milliseconds. */
			duration?: number;
		};
	}

	export class McpToolInvocationContentData {
		/**
		 * The mime type which determines how the data property is interpreted.
		 */
		mimeType: string;

		/**
		 * The byte data for this part.
		 */
		data: Uint8Array;

		/**
		 * Construct a generic data part with the given content.
		 * @param data The byte data for this part.
		 * @param mimeType The mime type of the data.
		 */
		constructor(data: Uint8Array, mimeType: string);
	}

	export interface ChatMcpToolInvocationData {
		input: string;
		output: McpToolInvocationContentData[];
	}

	export enum ChatTodoStatus {
		NotStarted = 1,
		InProgress = 2,
		Completed = 3
	}

	export interface ChatTodoToolInvocationData {
		todoList: Array<{
			id: number;
			title: string;
			status: ChatTodoStatus;
		}>;
	}

	/**
	 * Generic tool result data that displays input and output in collapsible sections.
	 */
	export interface ChatSimpleToolResultData {
		/**
		 * The input to display.
		 */
		input: string;
		/**
		 * The output to display.
		 */
		output: string;
	}


	export interface ChatToolResourcesInvocationData {
		/**
		 * Array of file URIs or locations to display as a collapsible list
		 */
		values: Array<Uri | Location>;
	}

	export class ChatSubagentToolInvocationData {
		/**
		 * A description of the subagent's purpose or task.
		 */
		description?: string;

		/**
		 * The name of the subagent being invoked.
		 */
		agentName?: string;

		/**
		 * The prompt given to the subagent.
		 */
		prompt?: string;

		/**
		 * The result text from the subagent after completion.
		 */
		result?: string;

		constructor(description?: string, agentName?: string, prompt?: string, result?: string);
	}

	export class ChatToolInvocationPart {
		toolName: string;
		toolCallId: string;
		isError?: boolean;
		invocationMessage?: string | MarkdownString;
		originMessage?: string | MarkdownString;
		pastTenseMessage?: string | MarkdownString;
		isConfirmed?: boolean;
		isComplete?: boolean;
		toolSpecificData?: ChatTerminalToolInvocationData | ChatMcpToolInvocationData | ChatTodoToolInvocationData | ChatSimpleToolResultData | ChatToolResourcesInvocationData | ChatSubagentToolInvocationData;
		subAgentInvocationId?: string;
		presentation?: 'hidden' | 'hiddenAfterComplete' | undefined;

		/**
		 * If this flag is set, this will be treated as an update to any previous tool call with the same id.
		 */
		enablePartialUpdate?: boolean;

		constructor(toolName: string, toolCallId: string, errorMessage?: string);
	}

	/**
	 * Represents a single file diff entry in a multi diff view.
	 */
	export interface ChatResponseDiffEntry {
		/**
		 * The original file URI (undefined for new files).
		 */
		originalUri?: Uri;

		/**
		 * The modified file URI (undefined for deleted files).
		 */
		modifiedUri?: Uri;

		/**
		 * Optional URI to navigate to when clicking on the file.
		 */
		goToFileUri?: Uri;

		/**
		 * Added data (e.g. line numbers) to show in the UI
		 */
		added?: number;

		/**
		 * Removed data (e.g. line numbers) to show in the UI
		 */
		removed?: number;
	}

	/**
	 * Represents a part of a chat response that shows multiple file diffs.
	 */
	export class ChatResponseMultiDiffPart {
		/**
		 * Array of file diff entries to display.
		 */
		value: ChatResponseDiffEntry[];

		/**
		 * The title for the multi diff editor.
		 */
		title: string;

		/**
		 * Whether the multi diff editor should be read-only.
		 * When true, users cannot open individual files or interact with file navigation.
		 */
		readOnly?: boolean;

		/**
		 * Create a new ChatResponseMultiDiffPart.
		 * @param value Array of file diff entries.
		 * @param title The title for the multi diff editor.
		 * @param readOnly Optional flag to make the multi diff editor read-only.
		 */
		constructor(value: ChatResponseDiffEntry[], title: string, readOnly?: boolean);
	}

	export class ChatResponseExternalEditPart {
		uris: Uri[];
		callback: () => Thenable<unknown>;
		applied: Thenable<string>;
		constructor(uris: Uri[], callback: () => Thenable<unknown>);
	}

	/**
	 * Internal type that lists all the proposed chat response parts. This is used to generate `ExtendedChatResponsePart`
	 * which is the actual type used in this API. This is done so that other proposals can easily add their own response parts
	 * without having to modify this file.
	 */
	export interface ExtendedChatResponseParts {
		ChatResponsePart: ChatResponsePart;
		ChatResponseTextEditPart: ChatResponseTextEditPart;
		ChatResponseNotebookEditPart: ChatResponseNotebookEditPart;
		ChatResponseWorkspaceEditPart: ChatResponseWorkspaceEditPart;
		ChatResponseConfirmationPart: ChatResponseConfirmationPart;
		ChatResponseCodeCitationPart: ChatResponseCodeCitationPart;
		ChatResponseReferencePart2: ChatResponseReferencePart2;
		ChatResponseMovePart: ChatResponseMovePart;
		ChatResponseExtensionsPart: ChatResponseExtensionsPart;
		ChatResponsePullRequestPart: ChatResponsePullRequestPart;
		ChatToolInvocationPart: ChatToolInvocationPart;
		ChatResponseMultiDiffPart: ChatResponseMultiDiffPart;
		ChatResponseThinkingProgressPart: ChatResponseThinkingProgressPart;
		ChatResponseExternalEditPart: ChatResponseExternalEditPart;
		ChatResponseQuestionCarouselPart: ChatResponseQuestionCarouselPart;
	}

	export type ExtendedChatResponsePart = ExtendedChatResponseParts[keyof ExtendedChatResponseParts];

	export class ChatResponseWarningPart {
		value: MarkdownString;
		constructor(value: string | MarkdownString);
	}

	export class ChatResponseProgressPart2 extends ChatResponseProgressPart {
		value: string;
		task?: (progress: Progress<ChatResponseWarningPart | ChatResponseReferencePart>) => Thenable<string | void>;
		constructor(value: string, task?: (progress: Progress<ChatResponseWarningPart | ChatResponseReferencePart>) => Thenable<string | void>);
	}

	/**
	 * A specialized progress part for displaying thinking/reasoning steps.
	 */
	export class ChatResponseThinkingProgressPart {
		value: string | string[];
		id?: string;
		metadata?: { readonly [key: string]: any };
		task?: (progress: Progress<LanguageModelThinkingPart>) => Thenable<string | void>;

		/**
		 * Creates a new thinking progress part.
		 * @param value An initial progress message
		 * @param task A task that will emit thinking parts during its execution
		 */
		constructor(value: string | string[], id?: string, metadata?: { readonly [key: string]: any }, task?: (progress: Progress<LanguageModelThinkingPart>) => Thenable<string | void>);
	}

	export class ChatResponseReferencePart2 {
		/**
		 * The reference target.
		 */
		value: Uri | Location | { variableName: string; value?: Uri | Location } | string;

		/**
		 * The icon for the reference.
		 */
		iconPath?: Uri | ThemeIcon | {
			/**
			 * The icon path for the light theme.
			 */
			light: Uri;
			/**
			 * The icon path for the dark theme.
			 */
			dark: Uri;
		};
		options?: { status?: { description: string; kind: ChatResponseReferencePartStatusKind } };

		/**
		 * Create a new ChatResponseReferencePart.
		 * @param value A uri or location
		 * @param iconPath Icon for the reference shown in UI
		 */
		constructor(value: Uri | Location | { variableName: string; value?: Uri | Location } | string, iconPath?: Uri | ThemeIcon | {
			/**
			 * The icon path for the light theme.
			 */
			light: Uri;
			/**
			 * The icon path for the dark theme.
			 */
			dark: Uri;
		}, options?: { status?: { description: string; kind: ChatResponseReferencePartStatusKind } });
	}

	export class ChatResponseMovePart {

		readonly uri: Uri;
		readonly range: Range;

		constructor(uri: Uri, range: Range);
	}

	export interface ChatResponseAnchorPart {
		/**
		 * The target of this anchor.
		 *
		 * If this is a {@linkcode Uri} or {@linkcode Location}, this is rendered as a normal link.
		 *
		 * If this is a {@linkcode SymbolInformation}, this is rendered as a symbol link.
		 *
		 * TODO mjbvz: Should this be a full `SymbolInformation`? Or just the parts we need?
		 * TODO mjbvz: Should we allow a `SymbolInformation` without a location? For example, until `resolve` completes?
		 */
		value2: Uri | Location | SymbolInformation;

		/**
		 * Optional method which fills in the details of the anchor.
		 *
		 * THis is currently only implemented for symbol links.
		 */
		resolve?(token: CancellationToken): Thenable<void>;
	}

	export class ChatResponseExtensionsPart {

		readonly extensions: string[];

		constructor(extensions: string[]);
	}

	export class ChatResponsePullRequestPart {
		/**
		 * @deprecated use `command` instead
		 */
		readonly uri?: Uri;
		readonly command: Command;
		readonly linkTag: string;
		readonly title: string;
		readonly description: string;
		readonly author: string;
		constructor(uriOrCommand: Uri | Command, title: string, description: string, author: string, linkTag: string);
	}

	export interface ChatResponseStream {

		/**
		 * Push a progress part to this stream. Short-hand for
		 * `push(new ChatResponseProgressPart(value))`.
		*
		* @param value A progress message
		* @param task If provided, a task to run while the progress is displayed. When the Thenable resolves, the progress will be marked complete in the UI, and the progress message will be updated to the resolved string if one is specified.
		* @returns This stream.
		*/
		progress(value: string, task?: (progress: Progress<ChatResponseWarningPart | ChatResponseReferencePart>) => Thenable<string | void>): void;

		thinkingProgress(thinkingDelta: ThinkingDelta): void;

		textEdit(target: Uri, edits: TextEdit | TextEdit[]): void;

		textEdit(target: Uri, isDone: true): void;

		notebookEdit(target: Uri, edits: NotebookEdit | NotebookEdit[]): void;

		notebookEdit(target: Uri, isDone: true): void;

		/**
		 * Push a workspace edit containing file-level operations (create, delete, rename).
		 * @param edits Array of file-level edits to apply
		 */
		workspaceEdit(edits: ChatWorkspaceFileEdit[]): void;

		/**
		 * Makes an external edit to one or more resources. Changes to the
		 * resources made within the `callback` and before it resolves will be
		 * tracked as agent edits. This can be used to track edits made from
		 * external tools that don't generate simple {@link textEdit textEdits}.
		 */
		externalEdit(target: Uri | Uri[], callback: () => Thenable<unknown>): Thenable<string>;

		markdownWithVulnerabilities(value: string | MarkdownString, vulnerabilities: ChatVulnerability[]): void;
		codeblockUri(uri: Uri, isEdit?: boolean): void;
		push(part: ChatResponsePart | ChatResponseTextEditPart | ChatResponseWarningPart | ChatResponseProgressPart2): void;

		/**
		 * Show an inline message in the chat view asking the user to confirm an action.
		 * Multiple confirmations may be shown per response. The UI might show "Accept All" / "Reject All" actions.
		 * @param title The title of the confirmation entry
		 * @param message An extra message to display to the user
		 * @param data An arbitrary JSON-stringifiable object that will be included in the ChatRequest when
		 * the confirmation is accepted or rejected
		 * TODO@API should this be MarkdownString?
		 * TODO@API should actually be a more generic function that takes an array of buttons
		 */
		confirmation(title: string, message: string | MarkdownString, data: any, buttons?: string[]): void;

		/**
		 * Show an inline carousel of questions to gather information from the user.
		 * This is a blocking call that waits for the user to submit or skip the questions.
		 * @param questions Array of questions to display to the user
		 * @param allowSkip Whether the user can skip questions without answering
		 * @returns A promise that resolves with the user's answers, or undefined if skipped
		 */
		questionCarousel(questions: ChatQuestion[], allowSkip?: boolean): Thenable<Record<string, unknown> | undefined>;

		/**
		 * Push a warning to this stream. Short-hand for
		 * `push(new ChatResponseWarningPart(message))`.
		 *
		 * @param message A warning message
		 * @returns This stream.
		 */
		warning(message: string | MarkdownString): void;

		reference(value: Uri | Location | { variableName: string; value?: Uri | Location }, iconPath?: Uri | ThemeIcon | { light: Uri; dark: Uri }): void;

		reference2(value: Uri | Location | string | { variableName: string; value?: Uri | Location }, iconPath?: Uri | ThemeIcon | { light: Uri; dark: Uri }, options?: { status?: { description: string; kind: ChatResponseReferencePartStatusKind } }): void;

		codeCitation(value: Uri, license: string, snippet: string): void;

		/**
		 * Begin a tool invocation in streaming mode. This creates a tool invocation that will
		 * display streaming progress UI until the tool is actually invoked.
		 * @param toolCallId Unique identifier for this tool call, used to correlate streaming updates and final invocation.
		 * @param toolName The name of the tool being invoked.
		 * @param streamData Optional initial streaming data with partial arguments.
		 */
		beginToolInvocation(toolCallId: string, toolName: string, streamData?: ChatToolInvocationStreamData & { subagentInvocationId?: string }): void;

		/**
		 * Update the streaming data for a tool invocation that was started with `beginToolInvocation`.
		 * @param toolCallId The tool call ID that was passed to `beginToolInvocation`.
		 * @param streamData New streaming data with updated partial arguments.
		 */
		updateToolInvocation(toolCallId: string, streamData: ChatToolInvocationStreamData): void;

		push(part: ExtendedChatResponsePart): void;

		clearToPreviousToolInvocation(reason: ChatResponseClearToPreviousToolInvocationReason): void;

		/**
		 * Report token usage information for this request.
		 * This is typically called when the underlying language model provides usage statistics.
		 * @param usage Token usage information including prompt and completion tokens
		 */
		usage(usage: ChatResultUsage): void;
	}

	export enum ChatResponseReferencePartStatusKind {
		Complete = 1,
		Partial = 2,
		Omitted = 3
	}

	export type ThinkingDelta = {
		text?: string | string[];
		id: string;
		metadata?: { readonly [key: string]: any };
	} | {
		text?: string | string[];
		id?: string;
		metadata: { readonly [key: string]: any };
	} |
	{
		text: string | string[];
		id?: string;
		metadata?: { readonly [key: string]: any };
	};

	export enum ChatResponseClearToPreviousToolInvocationReason {
		NoReason = 0,
		FilteredContentRetry = 1,
		CopyrightContentRetry = 2,
	}

	/**
	 * Does this piggy-back on the existing ChatRequest, or is it a different type of request entirely?
	 * Does it show up in history?
	 */
	export interface ChatRequest {
		/**
		 * The `data` for any confirmations that were accepted
		 */
		acceptedConfirmationData?: any[];

		/**
		 * The `data` for any confirmations that were rejected
		 */
		rejectedConfirmationData?: any[];
	}

	export interface ChatRequest {

		/**
		 * A map of all tools that should (`true`) and should not (`false`) be used in this request.
		 */
		readonly tools: Map<LanguageModelToolInformation, boolean>;
	}

	export namespace lm {
		/**
		 * Fired when the set of tools on a chat request changes.
		 */
		export const onDidChangeChatRequestTools: Event<ChatRequest>;
	}

	export class LanguageModelToolExtensionSource {
		/**
		 * ID of the extension that published the tool.
		 */
		readonly id: string;

		/**
		 * Label of the extension that published the tool.
		 */
		readonly label: string;

		private constructor(id: string, label: string);
	}

	export class LanguageModelToolMCPSource {
		/**
		 * Editor-configured label of the MCP server that published the tool.
		 */
		readonly label: string;

		/**
		 * Server-defined name of the MCP server.
		 */
		readonly name: string;

		/**
		 * Server-defined instructions for MCP tool use.
		 */
		readonly instructions?: string;

		private constructor(label: string, name: string, instructions?: string);
	}

	export interface LanguageModelToolInformation {
		source: LanguageModelToolExtensionSource | LanguageModelToolMCPSource | undefined;
	}

	// TODO@API fit this into the stream
	export interface ChatUsedContext {
		documents: ChatDocumentContext[];
	}

	export interface ChatParticipant {
		/**
		 * Provide a set of variables that can only be used with this participant.
		 */
		participantVariableProvider?: { provider: ChatParticipantCompletionItemProvider; triggerCharacters: string[] };

		/**
		 * Event that fires when a request is paused or unpaused.
		 * Chat requests are initially unpaused in the {@link requestHandler}.
		 */
		readonly onDidChangePauseState: Event<ChatParticipantPauseStateEvent>;
	}

	export interface ChatParticipantPauseStateEvent {
		request: ChatRequest;
		isPaused: boolean;
	}

	export interface ChatParticipantCompletionItemProvider {
		provideCompletionItems(query: string, token: CancellationToken): ProviderResult<ChatCompletionItem[]>;
	}

	export class ChatCompletionItem {
		id: string;
		label: string | CompletionItemLabel;
		values: ChatVariableValue[];
		fullName?: string;
		icon?: ThemeIcon;
		insertText?: string;
		detail?: string;
		documentation?: string | MarkdownString;
		command?: Command;

		constructor(id: string, label: string | CompletionItemLabel, values: ChatVariableValue[]);
	}

	export type ChatExtendedRequestHandler = (request: ChatRequest, context: ChatContext, response: ChatResponseStream, token: CancellationToken) => ProviderResult<ChatResult | void>;

	/**
	 * Details about the prompt token usage by category and label.
	 */
	export interface ChatResultPromptTokenDetail {
		/**
		 * The category this token usage belongs to (e.g., "System", "Context", "Conversation").
		 */
		readonly category: string;

		/**
		 * The label for this specific token usage (e.g., "System prompt", "Attached files").
		 */
		readonly label: string;

		/**
		 * The percentage of the total prompt tokens this represents (0-100).
		 */
		readonly percentageOfPrompt: number;
	}

	/**
	 * Token usage information for a chat request.
	 */
	export interface ChatResultUsage {
		/**
		 * The number of prompt tokens used in this request.
		 */
		readonly promptTokens: number;

		/**
		 * The number of completion tokens generated in this response.
		 */
		readonly completionTokens: number;

		/**
		 * Optional breakdown of prompt token usage by category and label.
		 * If the percentages do not sum to 100%, the remaining will be shown as "Uncategorized".
		 */
		readonly promptTokenDetails?: readonly ChatResultPromptTokenDetail[];
	}

	export interface ChatResult {
		nextQuestion?: {
			prompt: string;
			participant?: string;
			command?: string;
		};
		/**
		 * An optional detail string that will be rendered at the end of the response in certain UI contexts.
		 */
		details?: string;
	}

	export namespace chat {
		/**
		 * Create a chat participant with the extended progress type
		 */
		export function createChatParticipant(id: string, handler: ChatExtendedRequestHandler): ChatParticipant;
	}

	/*
	 * User action events
	 */

	export enum ChatCopyKind {
		// Keyboard shortcut or context menu
		Action = 1,
		Toolbar = 2
	}

	export interface ChatCopyAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'copy';
		codeBlockIndex: number;
		copyKind: ChatCopyKind;
		copiedCharacters: number;
		totalCharacters: number;
		copiedText: string;
		totalLines: number;
		copiedLines: number;
		modelId: string;
		languageId?: string;
	}

	export interface ChatInsertAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'insert';
		codeBlockIndex: number;
		totalCharacters: number;
		totalLines: number;
		languageId?: string;
		modelId: string;
		newFile?: boolean;
	}

	export interface ChatApplyAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'apply';
		codeBlockIndex: number;
		totalCharacters: number;
		totalLines: number;
		languageId?: string;
		modelId: string;
		newFile?: boolean;
		codeMapper?: string;
	}

	export interface ChatTerminalAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'runInTerminal';
		codeBlockIndex: number;
		languageId?: string;
	}

	export interface ChatCommandAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'command';
		commandButton: ChatCommandButton;
	}

	export interface ChatFollowupAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'followUp';
		followup: ChatFollowup;
	}

	export interface ChatBugReportAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'bug';
	}

	export interface ChatEditorAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'editor';
		accepted: boolean;
	}

	export interface ChatEditingSessionAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'chatEditingSessionAction';
		uri: Uri;
		hasRemainingEdits: boolean;
		outcome: ChatEditingSessionActionOutcome;
	}

	export interface ChatEditingHunkAction {
		// eslint-disable-next-line local/vscode-dts-string-type-literals
		kind: 'chatEditingHunkAction';
		uri: Uri;
		lineCount: number;
		linesAdded: number;
		linesRemoved: number;
		outcome: ChatEditingSessionActionOutcome;
		hasRemainingEdits: boolean;
	}

	export enum ChatEditingSessionActionOutcome {
		Accepted = 1,
		Rejected = 2,
		Saved = 3
	}

	export interface ChatUserActionEvent {
		readonly result: ChatResult;
		readonly action: ChatCopyAction | ChatInsertAction | ChatApplyAction | ChatTerminalAction | ChatCommandAction | ChatFollowupAction | ChatBugReportAction | ChatEditorAction | ChatEditingSessionAction | ChatEditingHunkAction;
	}

	export interface ChatPromptReference {
		/**
		 * TODO Needed for now to drive the variableName-type reference, but probably both of these should go away in the future.
		 */
		readonly name: string;

		/**
		 * The list of tools were referenced in the value of the reference
		 */
		readonly toolReferences?: readonly ChatLanguageModelToolReference[];
	}

	export interface ChatResultFeedback {
		readonly unhelpfulReason?: string;
	}

	export namespace lm {
		export function fileIsIgnored(uri: Uri, token?: CancellationToken): Thenable<boolean>;
	}

	export interface ChatVariableValue {
		/**
		 * The detail level of this chat variable value. If possible, variable resolvers should try to offer shorter values that will consume fewer tokens in an LLM prompt.
		 */
		level: ChatVariableLevel;

		/**
		 * The variable's value, which can be included in an LLM prompt as-is, or the chat participant may decide to read the value and do something else with it.
		 */
		value: string | Uri;

		/**
		 * A description of this value, which could be provided to the LLM as a hint.
		 */
		description?: string;
	}

	/**
	 * The detail level of this chat variable value.
	 */
	export enum ChatVariableLevel {
		Short = 1,
		Medium = 2,
		Full = 3
	}

	export interface LanguageModelToolInvocationOptions<T> {
		model?: LanguageModelChat;
		chatStreamToolCallId?: string;
	}

	export interface LanguageModelToolInvocationStreamOptions<T> {
		/**
		 * Raw argument payload, such as the streamed JSON fragment from the language model.
		 */
		readonly rawInput?: unknown;

		readonly chatRequestId?: string;
		readonly chatSessionResource?: Uri;
		readonly chatInteractionId?: string;
	}

	export interface LanguageModelToolStreamResult {
		/**
		 * A customized progress message to show while the tool runs.
		 */
		invocationMessage?: string | MarkdownString;
	}

	export interface LanguageModelTool<T> {
		/**
		 * Called zero or more times before {@link LanguageModelTool.prepareInvocation} while the
		 * language model streams argument data for the invocation. Use this to update progress
		 * or UI with the partial arguments that have been generated so far.
		 *
		 * Implementations must be free of side-effects and should be resilient to receiving
		 * malformed or incomplete input.
		 */
		handleToolStream?(options: LanguageModelToolInvocationStreamOptions<T>, token: CancellationToken): ProviderResult<LanguageModelToolStreamResult>;
	}

	export interface ChatRequest {
		readonly modeInstructions?: string;
		readonly modeInstructions2?: ChatRequestModeInstructions;
	}

	export interface ChatRequestModeInstructions {
		readonly name: string;
		readonly content: string;
		readonly toolReferences?: readonly ChatLanguageModelToolReference[];
		readonly metadata?: Record<string, boolean | string | number>;
		/**
		 * Whether the mode is a builtin mode (e.g. Ask, Edit, Agent) rather than a user or extension-defined custom mode.
		 */
		readonly isBuiltin?: boolean;
	}
}
