import { Event } from "../../../../../base/common/event.js"; import { IMarkdownString } from "../../../../../base/common/htmlContent.js"; import { Disposable, IDisposable } from "../../../../../base/common/lifecycle.js"; import { IObservable } from "../../../../../base/common/observable.js"; import { URI, UriDto } from "../../../../../base/common/uri.js"; import { IRange } from "../../../../../editor/common/core/range.js"; import { ISelection } from "../../../../../editor/common/core/selection.js"; import { TextEdit } from "../../../../../editor/common/languages.js"; import { EditSuggestionId } from "../../../../../editor/common/textModelEditSource.js"; import { ILogService } from "../../../../../platform/log/common/log.service.js"; import { ICellEditOperation } from "../../../notebook/common/notebookCommon.js"; import { ChatRequestToolReferenceEntry, IChatRequestVariableEntry } from "../attachments/chatVariableEntries.js"; import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatRequestQueueKind, IChatAgentMarkdownContentWithVulnerability, IChatClearToPreviousToolInvocation, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatDisabledClaudeHooksPart, IChatEditingSessionAction, IChatElicitationRequest, IChatElicitationRequestSerialized, IChatExternalToolInvocationUpdate, IChatExtensionsContent, IChatFollowup, IChatHookPart, IChatLocationData, IChatMarkdownContent, IChatMcpServersStarting, IChatMcpServersStartingSerialized, IChatMultiDiffData, IChatMultiDiffDataSerialized, IChatNotebookEdit, IChatProgress, IChatProgressMessage, IChatPullRequestContent, IChatQuestionCarousel, IChatResponseCodeblockUriPart, IChatResponseProgressFileTreeData, IChatSendRequestOptions, IChatSessionContext, IChatSessionTiming, IChatTask, IChatTaskSerialized, IChatTextEdit, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatUsage, IChatUsedContext, IChatWarningMessage, IChatWorkspaceEdit, ResponseModelState } from "../chatService/chatService.js"; import { IChatService } from "../chatService/chatService.service.js"; import { ChatAgentLocation, ChatModeKind, ChatPermissionLevel } from "../constants.js"; import { IChatEditingSession } from "../editing/chatEditingService.js"; import { IChatEditingService } from "../editing/chatEditingService.service.js"; import { ILanguageModelChatMetadata, ILanguageModelChatMetadataAndIdentifier } from "../languageModels.js"; import { IChatAgentCommand, IChatAgentData, IChatAgentResult, UserSelectedTools } from "../participants/chatAgents.js"; import { IChatAgentService } from "../participants/chatAgents.service.js"; import { IParsedChatRequest } from "../requestParser/chatParserTypes.js"; import { ObjectMutationLog } from "@codingame/monaco-vscode-chat-service-override/vscode/vs/workbench/contrib/chat/common/model/objectMutationLog"; /** * Represents a queued chat request waiting to be processed. */ export interface IChatPendingRequest { readonly request: IChatRequestModel; readonly kind: ChatRequestQueueKind; /** * The options that were passed to sendRequest when this request was queued. * userSelectedTools is snapshotted to a static observable at queue time. */ readonly sendOptions: IChatSendRequestOptions; } /** * Serializable version of IChatSendRequestOptions for pending requests. * Excludes observables and non-serializable fields. */ export interface ISerializableSendOptions { modeInfo?: IChatRequestModeInfo; userSelectedModelId?: string; /** Static snapshot of user-selected tools (not an observable) */ userSelectedTools?: UserSelectedTools; location?: ChatAgentLocation; locationData?: IChatLocationData; attempt?: number; noCommandDetection?: boolean; agentId?: string; agentIdSilent?: string; slashCommand?: string; confirmation?: string; } /** * Serializable representation of a pending chat request. */ export interface ISerializablePendingRequestData { id: string; request: ISerializableChatRequestData; kind: ChatRequestQueueKind; sendOptions: ISerializableSendOptions; } export declare const CHAT_ATTACHABLE_IMAGE_MIME_TYPES: Record; export declare function getAttachableImageExtension(mimeType: string): string | undefined; export interface IChatRequestVariableData { variables: readonly IChatRequestVariableEntry[]; } export declare namespace IChatRequestVariableData { function toExport(data: IChatRequestVariableData): IChatRequestVariableData; } export interface IChatRequestModel { readonly id: string; readonly timestamp: number; readonly version: number; readonly modeInfo?: IChatRequestModeInfo; readonly session: IChatModel; readonly message: IParsedChatRequest; readonly attempt: number; readonly variableData: IChatRequestVariableData; readonly confirmation?: string; readonly locationData?: IChatLocationData; readonly attachedContext?: IChatRequestVariableEntry[]; readonly isCompleteAddedRequest: boolean; readonly response?: IChatResponseModel; readonly editedFileEvents?: IChatAgentEditedFileEvent[]; shouldBeRemovedOnSend: IChatRequestDisablement | undefined; readonly shouldBeBlocked: IObservable; setShouldBeBlocked(value: boolean): void; readonly modelId?: string; readonly userSelectedTools?: UserSelectedTools; } export interface ICodeBlockInfo { readonly suggestionId: EditSuggestionId; } export interface IChatTextEditGroupState { sha1: string; applied: number; } export interface IChatTextEditGroup { uri: URI; edits: TextEdit[][]; state?: IChatTextEditGroupState; kind: "textEditGroup"; done: boolean | undefined; isExternalEdit?: boolean; } export declare function isCellTextEditOperation(value: unknown): value is ICellTextEditOperation; export declare function isCellTextEditOperationArray(value: ICellTextEditOperation[] | ICellEditOperation[]): value is ICellTextEditOperation[]; export interface ICellTextEditOperation { edit: TextEdit; uri: URI; } export interface IChatNotebookEditGroup { uri: URI; edits: (ICellTextEditOperation[] | ICellEditOperation[])[]; state?: IChatTextEditGroupState; kind: "notebookEditGroup"; done: boolean | undefined; isExternalEdit?: boolean; } /** * Progress kinds that are included in the history of a response. * Excludes "internal" types that are included in history. */ export type IChatProgressHistoryResponseContent = IChatMarkdownContent | IChatAgentMarkdownContentWithVulnerability | IChatResponseCodeblockUriPart | IChatTreeData | IChatMultiDiffDataSerialized | IChatContentInlineReference | IChatProgressMessage | IChatCommandButton | IChatWarningMessage | IChatTask | IChatTaskSerialized | IChatTextEditGroup | IChatNotebookEditGroup | IChatConfirmation | IChatQuestionCarousel | IChatExtensionsContent | IChatThinkingPart | IChatHookPart | IChatPullRequestContent | IChatWorkspaceEdit; /** * "Normal" progress kinds that are rendered as parts of the stream of content. */ export type IChatProgressResponseContent = IChatProgressHistoryResponseContent | IChatToolInvocation | IChatToolInvocationSerialized | IChatMultiDiffData | IChatUndoStop | IChatElicitationRequest | IChatElicitationRequestSerialized | IChatClearToPreviousToolInvocation | IChatMcpServersStarting | IChatMcpServersStartingSerialized | IChatDisabledClaudeHooksPart; export type IChatProgressResponseContentSerialized = Exclude; export declare function toChatHistoryContent(content: ReadonlyArray): IChatProgressHistoryResponseContent[]; export type IChatProgressRenderableResponseContent = Exclude; export interface IResponse { readonly value: ReadonlyArray; getMarkdown(): string; toString(): string; } export interface IChatResponseModel { readonly onDidChange: Event; readonly id: string; readonly requestId: string; readonly request: IChatRequestModel | undefined; readonly username: string; readonly session: IChatModel; readonly agent?: IChatAgentData; readonly usedContext: IChatUsedContext | undefined; readonly contentReferences: ReadonlyArray; readonly codeCitations: ReadonlyArray; readonly progressMessages: ReadonlyArray; readonly slashCommand?: IChatAgentCommand; readonly agentOrSlashCommandDetected: boolean; /** View of the response shown to the user, may have parts omitted from undo stops. */ readonly response: IResponse; /** Entire response from the model. */ readonly entireResponse: IResponse; /** Milliseconds timestamp when this chat response was created. */ readonly timestamp: number; /** Milliseconds timestamp when this chat response was completed or cancelled. */ readonly completedAt?: number; /** The state of this response */ readonly state: ResponseModelState; /** @internal */ readonly stateT: ResponseModelStateT; /** * Adjusted millisecond timestamp that excludes the duration during which * the model was pending user confirmation. `Date.now() - confirmationAdjustedTimestamp` * will return the amount of time the response was busy generating content. * This is updated only when `isPendingConfirmation` changes state. */ readonly confirmationAdjustedTimestamp: IObservable; readonly isComplete: boolean; readonly isCanceled: boolean; readonly isPendingConfirmation: IObservable<{ startedWaitingAt: number; detail?: string; } | undefined>; readonly isInProgress: IObservable; readonly shouldBeRemovedOnSend: IChatRequestDisablement | undefined; readonly shouldBeBlocked: IObservable; readonly isCompleteAddedRequest: boolean; /** A stale response is one that has been persisted and rehydrated, so e.g. Commands that have their arguments stored in the EH are gone. */ readonly isStale: boolean; readonly vote: ChatAgentVoteDirection | undefined; readonly voteDownReason: ChatAgentVoteDownReason | undefined; readonly followups?: IChatFollowup[] | undefined; readonly result?: IChatAgentResult; readonly usage?: IChatUsage; readonly codeBlockInfos: ICodeBlockInfo[] | undefined; initializeCodeBlockInfos(codeBlockInfo: ICodeBlockInfo[]): void; addUndoStop(undoStop: IChatUndoStop): void; setVote(vote: ChatAgentVoteDirection): void; setVoteDownReason(reason: ChatAgentVoteDownReason | undefined): void; setUsage(usage: IChatUsage): void; setEditApplied(edit: IChatTextEditGroup, editCount: number): boolean; updateContent(progress: IChatProgressResponseContent | IChatTextEdit | IChatNotebookEdit | IChatTask | IChatExternalToolInvocationUpdate, quiet?: boolean): void; /** * Adopts any partially-undo {@link response} as the {@link entireResponse}. * Only valid when {@link isComplete}. This is needed because otherwise an * undone and then diverged state would start showing old data because the * undo stops would no longer exist in the model. */ finalizeUndoState(): void; } export type ChatResponseModelChangeReason = { reason: "other"; } | { reason: "completedRequest"; } | { reason: "undoStop"; id: string; }; export declare const defaultChatResponseModelChangeReason: ChatResponseModelChangeReason; export interface IChatRequestModeInfo { kind: ChatModeKind | undefined; isBuiltin: boolean; modeInstructions: IChatRequestModeInstructions | undefined; modeId: "ask" | "agent" | "edit" | "custom" | "applyCodeBlock" | undefined; modeName?: string; applyCodeBlockSuggestionId: EditSuggestionId | undefined; permissionLevel?: ChatPermissionLevel; } export interface IChatRequestModeInstructions { readonly uri?: URI; readonly name: string; readonly content: string; readonly toolReferences: readonly ChatRequestToolReferenceEntry[]; readonly metadata?: Record; readonly isBuiltin?: boolean; } export interface IChatRequestModelParameters { session: ChatModel; message: IParsedChatRequest; variableData: IChatRequestVariableData; timestamp: number; attempt?: number; modeInfo?: IChatRequestModeInfo; confirmation?: string; locationData?: IChatLocationData; attachedContext?: IChatRequestVariableEntry[]; isCompleteAddedRequest?: boolean; modelId?: string; restoredId?: string; editedFileEvents?: IChatAgentEditedFileEvent[]; userSelectedTools?: UserSelectedTools; } export declare class ChatRequestModel implements IChatRequestModel { readonly id: string; response: ChatResponseModel | undefined; shouldBeRemovedOnSend: IChatRequestDisablement | undefined; readonly timestamp: number; readonly message: IParsedChatRequest; readonly isCompleteAddedRequest: boolean; readonly modelId?: string; readonly modeInfo?: IChatRequestModeInfo; readonly userSelectedTools?: UserSelectedTools; private readonly _shouldBeBlocked; get shouldBeBlocked(): IObservable; setShouldBeBlocked(value: boolean): void; private _session; private readonly _attempt; private _variableData; private readonly _confirmation?; private readonly _locationData?; private readonly _attachedContext?; private readonly _editedFileEvents?; get session(): ChatModel; get attempt(): number; get variableData(): IChatRequestVariableData; set variableData(v: IChatRequestVariableData); get confirmation(): string | undefined; get locationData(): IChatLocationData | undefined; get attachedContext(): IChatRequestVariableEntry[] | undefined; get editedFileEvents(): IChatAgentEditedFileEvent[] | undefined; private _version; get version(): number; constructor(params: IChatRequestModelParameters); adoptTo(session: ChatModel): void; } declare class AbstractResponse implements IResponse { protected _responseParts: IChatProgressResponseContent[]; /** * A stringified representation of response data which might be presented to a screenreader or used when copying a response. */ protected _responseRepr: string; /** * Just the markdown content of the response, used for determining the rendering rate of markdown */ protected _markdownContent: string; get value(): IChatProgressResponseContent[]; constructor(value: IChatProgressResponseContent[]); toString(): string; /** * _Just_ the content of markdown parts in the response */ getMarkdown(): string; protected _updateRepr(): void; private partsToRepr; private inlineRefToRepr; private getToolInvocationText; private uriToRepr; } export declare class Response extends AbstractResponse implements IDisposable { private _onDidChangeValue; get onDidChangeValue(): Event; private _citations; constructor(value: IMarkdownString | ReadonlyArray); dispose(): void; clear(): void; clearToPreviousToolInvocation(message?: string): void; updateContent(progress: IChatProgressResponseContent | IChatTextEdit | IChatNotebookEdit | IChatTask | IChatExternalToolInvocationUpdate, quiet?: boolean): void; addCitation(citation: IChatCodeCitation): void; private _mergeOrPushTextEditGroup; private _mergeOrPushNotebookEditGroup; private _handleExternalToolInvocationUpdate; protected _updateRepr(quiet?: boolean): void; } export interface IChatResponseModelParameters { responseContent: IMarkdownString | ReadonlyArray; session: ChatModel; agent?: IChatAgentData; slashCommand?: IChatAgentCommand; requestId: string; timestamp?: number; vote?: ChatAgentVoteDirection; voteDownReason?: ChatAgentVoteDownReason; result?: IChatAgentResult; followups?: ReadonlyArray; isCompleteAddedRequest?: boolean; shouldBeRemovedOnSend?: IChatRequestDisablement; shouldBeBlocked?: boolean; restoredId?: string; modelState?: ResponseModelStateT; timeSpentWaiting?: number; /** * undefined means it will be set later. */ codeBlockInfos: ICodeBlockInfo[] | undefined; } export type ResponseModelStateT = { value: ResponseModelState.Pending; } | { value: ResponseModelState.NeedsInput; } | { value: ResponseModelState.Complete | ResponseModelState.Cancelled | ResponseModelState.Failed; completedAt: number; }; export declare class ChatResponseModel extends Disposable implements IChatResponseModel { private readonly _onDidChange; readonly onDidChange: Event; readonly id: string; readonly requestId: string; private _session; private _agent; private _slashCommand; private _modelState; private _vote?; private _voteDownReason?; private _result?; private _usage?; private _shouldBeRemovedOnSend; readonly isCompleteAddedRequest: boolean; private readonly _shouldBeBlocked; private readonly _timestamp; private _timeSpentWaitingAccumulator; confirmationAdjustedTimestamp: IObservable; get shouldBeBlocked(): IObservable; get request(): IChatRequestModel | undefined; get session(): ChatModel; get shouldBeRemovedOnSend(): IChatRequestDisablement | undefined; get isComplete(): boolean; get timestamp(): number; set shouldBeRemovedOnSend(disablement: IChatRequestDisablement | undefined); get isCanceled(): boolean; get completedAt(): number | undefined; get state(): ResponseModelState; get stateT(): ResponseModelStateT; get vote(): ChatAgentVoteDirection | undefined; get voteDownReason(): ChatAgentVoteDownReason | undefined; get followups(): IChatFollowup[] | undefined; private _response; private _finalizedResponse?; get entireResponse(): IResponse; get result(): IChatAgentResult | undefined; get usage(): IChatUsage | undefined; get username(): string; private _followups?; get agent(): IChatAgentData | undefined; get slashCommand(): IChatAgentCommand | undefined; private _agentOrSlashCommandDetected; get agentOrSlashCommandDetected(): boolean; private _usedContext; get usedContext(): IChatUsedContext | undefined; private readonly _contentReferences; get contentReferences(): ReadonlyArray; private readonly _codeCitations; get codeCitations(): ReadonlyArray; private readonly _progressMessages; get progressMessages(): ReadonlyArray; private _isStale; get isStale(): boolean; readonly isPendingConfirmation: IObservable<{ startedWaitingAt: number; detail?: string; } | undefined>; readonly isInProgress: IObservable; private _responseView?; get response(): IResponse; private _codeBlockInfos; get codeBlockInfos(): ICodeBlockInfo[] | undefined; constructor(params: IChatResponseModelParameters); initializeCodeBlockInfos(codeBlockInfo: ICodeBlockInfo[]): void; setBlockedState(isBlocked: boolean): void; /** * Apply a progress update to the actual response content. */ updateContent(responsePart: IChatProgressResponseContent | IChatTextEdit | IChatNotebookEdit | IChatExternalToolInvocationUpdate, quiet?: boolean): void; /** * Adds an undo stop at the current position in the stream. */ addUndoStop(undoStop: IChatUndoStop): void; /** * Apply one of the progress updates that are not part of the actual response content. */ applyReference(progress: IChatUsedContext | IChatContentReference): void; applyCodeCitation(progress: IChatCodeCitation): void; setAgent(agent: IChatAgentData, slashCommand?: IChatAgentCommand): void; setResult(result: IChatAgentResult): void; setUsage(usage: IChatUsage): void; complete(): void; cancel(): void; setFollowups(followups: IChatFollowup[] | undefined): void; setVote(vote: ChatAgentVoteDirection): void; setVoteDownReason(reason: ChatAgentVoteDownReason | undefined): void; setEditApplied(edit: IChatTextEditGroup, editCount: number): boolean; adoptTo(session: ChatModel): void; finalizeUndoState(): void; toJSON(): ISerializableChatResponseData; } export interface IChatRequestDisablement { requestId: string; afterUndoStop?: string; } /** * Information about a chat request that needs user input to continue. */ export interface IChatRequestNeedsInputInfo { /** The chat session title */ readonly title: string; /** Optional detail message, e.g., " needs approval to run." */ readonly detail?: string; } export interface IChatModel extends IDisposable { readonly onDidDispose: Event; readonly onDidChange: Event; /** @deprecated Use {@link sessionResource} instead */ readonly sessionId: string; /** Milliseconds timestamp this chat model was created. */ readonly timestamp: number; readonly timing: IChatSessionTiming; readonly sessionResource: URI; readonly initialLocation: ChatAgentLocation; readonly title: string; readonly hasCustomTitle: boolean; readonly responderUsername: string; /** True whenever a request is currently running */ readonly requestInProgress: IObservable; /** Provides session information when a request needs user interaction to continue */ readonly requestNeedsInput: IObservable; readonly inputPlaceholder?: string; readonly editingSession?: IChatEditingSession | undefined; readonly checkpoint: IChatRequestModel | undefined; startEditingSession(isGlobalEditingSession?: boolean, transferFromSession?: IChatEditingSession): void; /** Input model for managing input state */ readonly inputModel: IInputModel; readonly hasRequests: boolean; readonly lastRequest: IChatRequestModel | undefined; /** Whether this model will be kept alive while it is running or has edits */ readonly willKeepAlive: boolean; readonly lastRequestObs: IObservable; getRequests(): IChatRequestModel[]; setCheckpoint(requestId: string | undefined): void; toExport(): IExportableChatData; toJSON(): ISerializableChatData; readonly contributedChatSession: IChatSessionContext | undefined; setContributedChatSession(session: IChatSessionContext | undefined): void; readonly repoData: IExportableRepoData | undefined; setRepoData(data: IExportableRepoData | undefined): void; readonly onDidChangePendingRequests: Event; getPendingRequests(): readonly IChatPendingRequest[]; } export interface ISerializableChatsData { [sessionId: string]: ISerializableChatData; } export type ISerializableChatAgentData = UriDto; interface ISerializableChatResponseData { responseId?: string; result?: IChatAgentResult; responseMarkdownInfo?: ISerializableMarkdownInfo[]; followups?: ReadonlyArray; modelState?: ResponseModelStateT; vote?: ChatAgentVoteDirection; voteDownReason?: ChatAgentVoteDownReason; timestamp?: number; slashCommand?: IChatAgentCommand; /** For backward compat: should be optional */ usedContext?: IChatUsedContext; contentReferences?: ReadonlyArray; codeCitations?: ReadonlyArray; timeSpentWaiting?: number; } export type SerializedChatResponsePart = IMarkdownString | IChatResponseProgressFileTreeData | IChatContentInlineReference | IChatAgentMarkdownContentWithVulnerability | IChatThinkingPart | IChatProgressResponseContentSerialized | IChatQuestionCarousel | IChatDisabledClaudeHooksPart; export interface ISerializableChatRequestData extends ISerializableChatResponseData { requestId: string; message: string | IParsedChatRequest; /** Is really like "prompt data". This is the message in the format in which the agent gets it + variable values. */ variableData: IChatRequestVariableData; response: ReadonlyArray | undefined; /**Old, persisted name for shouldBeRemovedOnSend */ isHidden?: boolean; shouldBeRemovedOnSend?: IChatRequestDisablement; agent?: ISerializableChatAgentData; /** @deprecated modelState is used instead now */ isCanceled?: boolean; timestamp?: number; confirmation?: string; editedFileEvents?: IChatAgentEditedFileEvent[]; modelId?: string; } export interface ISerializableMarkdownInfo { readonly suggestionId: EditSuggestionId; } /** * Repository state captured for chat session export. * Enables reproducing the workspace state by cloning, checking out the commit, and applying diffs. */ export interface IExportableRepoData { /** * Classification of the workspace's version control state. * - `remote-git`: Git repo with a configured remote URL * - `local-git`: Git repo without any remote (local only) * - `plain-folder`: Not a git repository */ workspaceType: "remote-git" | "local-git" | "plain-folder"; /** * Sync status between local and remote. * - `synced`: Local HEAD matches remote tracking branch (fully pushed) * - `unpushed`: Local has commits not pushed to the remote tracking branch * - `unpublished`: Local branch has no remote tracking branch configured * - `local-only`: No remote configured (local git repo only) * - `no-git`: Not a git repository */ syncStatus: "synced" | "unpushed" | "unpublished" | "local-only" | "no-git"; /** * Remote URL of the repository (e.g., https://github.com/org/repo.git). * Undefined if no remote is configured. */ remoteUrl?: string; /** * Vendor/host of the remote repository. * Undefined if no remote is configured. */ remoteVendor?: "github" | "ado" | "other"; /** * Remote tracking branch for the current branch (e.g., "origin/feature/my-work"). * Undefined if branch is unpublished or no remote. */ remoteTrackingBranch?: string; /** * Default remote branch used as base for unpublished branches (e.g., "origin/main"). * Helpful for computing merge-base when branch has no tracking. */ remoteBaseBranch?: string; /** * Commit hash of the remote tracking branch HEAD. * Undefined if branch has no remote tracking branch. */ remoteHeadCommit?: string; /** * Name of the current local branch (e.g., "feature/my-work"). */ localBranch?: string; /** * Commit hash of the local HEAD when captured. */ localHeadCommit?: string; /** * Working tree diffs (uncommitted changes). */ diffs?: IExportableRepoDiff[]; /** * Status of the diffs collection. * - `included`: Diffs were successfully captured and included * - `tooManyChanges`: Diffs skipped because >100 files changed (degenerate case like mass renames) * - `tooLarge`: Diffs skipped because total size exceeded 900KB * - `trimmedForStorage`: Diffs were trimmed to save storage (older session) * - `noChanges`: No working tree changes detected * - `notCaptured`: Diffs not captured (default/undefined case) */ diffsStatus?: "included" | "tooManyChanges" | "tooLarge" | "trimmedForStorage" | "noChanges" | "notCaptured"; /** * Number of changed files detected, even if diffs were not included. */ changedFileCount?: number; } /** * A file change exported as a unified diff patch compatible with `git apply`. */ export interface IExportableRepoDiff { relativePath: string; changeType: "added" | "modified" | "deleted" | "renamed"; oldRelativePath?: string; unifiedDiff?: string; status: string; } export interface IExportableChatData { initialLocation: ChatAgentLocation | undefined; requests: ISerializableChatRequestData[]; responderUsername: string; } export interface ISerializableChatData1 extends IExportableChatData { sessionId: string; creationDate: number; } export interface ISerializableChatData2 extends ISerializableChatData1 { version: 2; computedTitle: string | undefined; } export interface ISerializableChatData3 extends Omit { version: 3; customTitle: string | undefined; /** * Whether the session had pending edits when it was stored. * todo@connor4312 This will be cleaned up with the globalization of edits. */ hasPendingEdits?: boolean; /** Current draft input state (added later, fully backwards compatible) */ inputState?: ISerializableChatModelInputState; repoData?: IExportableRepoData; /** Pending requests that were queued but not yet processed */ pendingRequests?: ISerializablePendingRequestData[]; } /** * Input model for managing chat input state independently from the chat model. * This keeps display logic separated from the core chat model. * * The input model: * - Manages the current draft state (text, attachments, mode, model selection, cursor/selection) * - Provides an observable interface for reactive UI updates * - Automatically persists through the chat model's serialization * - Enables bidirectional sync between the UI (ChatInputPart) and the model * - Uses `undefined` state to indicate no persisted state (new/empty chat) * * This architecture ensures that: * - Input state is preserved when moving chats between editor/sidebar/window * - No manual state transfer is needed when switching contexts * - The UI stays in sync with the persisted state * - New chats use UI defaults (persisted preferences) instead of hardcoded values */ export interface IInputModel { /** Observable for current input state (undefined for new/uninitialized chats) */ readonly state: IObservable; /** Update the input state (partial update) */ setState(state: Partial): void; /** Clear input state (after sending or clearing) */ clearState(): void; /** Serializes the state */ toJSON(): ISerializableChatModelInputState | undefined; } /** * Represents the current state of the chat input that hasn't been sent yet. * This is the "draft" state that should be preserved across sessions. */ export interface IChatModelInputState { /** Current attachments in the input */ attachments: readonly IChatRequestVariableEntry[]; /** Currently selected chat mode */ mode: { /** Mode ID (e.g., 'ask', 'edit', 'agent', or custom mode ID) */ id: string; /** Mode kind for builtin modes */ kind: ChatModeKind | undefined; }; /** Currently selected language model, if any */ selectedModel: ILanguageModelChatMetadataAndIdentifier | undefined; /** Current input text */ inputText: string; /** Current selection ranges */ selections: ISelection[]; /** Contributed stored state */ contrib: Record; } /** * Serializable version of IChatModelInputState */ export interface ISerializableChatModelInputState { attachments: readonly IChatRequestVariableEntry[]; mode: { id: string; kind: ChatModeKind | undefined; }; selectedModel: { identifier: string; metadata: ILanguageModelChatMetadata; } | undefined; inputText: string; selections: ISelection[]; contrib: Record; } /** * Chat data that has been parsed and normalized to the current format. */ export type ISerializableChatData = ISerializableChatData3; export type IChatDataSerializerLog = ObjectMutationLog; export interface ISerializedChatDataReference { value: ISerializableChatData | IExportableChatData; serializer: IChatDataSerializerLog; } /** * Chat data that has been loaded but not normalized, and could be any format */ export type ISerializableChatDataIn = ISerializableChatData1 | ISerializableChatData2 | ISerializableChatData3; /** * Normalize chat data from storage to the current format. * TODO- ChatModel#_deserialize and reviveSerializedAgent also still do some normalization and maybe that should be done in here too. */ export declare function normalizeSerializableChatData(raw: ISerializableChatDataIn): ISerializableChatData; export declare function isExportableSessionData(obj: unknown): obj is IExportableChatData; export declare function isSerializableSessionData(obj: unknown): obj is ISerializableChatData; export type IChatChangeEvent = IChatInitEvent | IChatAddRequestEvent | IChatChangedRequestEvent | IChatRemoveRequestEvent | IChatAddResponseEvent | IChatSetAgentEvent | IChatMoveEvent | IChatSetHiddenEvent | IChatCompletedRequestEvent | IChatSetCustomTitleEvent; export interface IChatAddRequestEvent { kind: "addRequest"; request: IChatRequestModel; } export interface IChatChangedRequestEvent { kind: "changedRequest"; request: IChatRequestModel; } export interface IChatCompletedRequestEvent { kind: "completedRequest"; request: IChatRequestModel; } export interface IChatAddResponseEvent { kind: "addResponse"; response: IChatResponseModel; } export declare enum ChatRequestRemovalReason { /** * "Normal" remove */ Removal = 0, /** * Removed because the request will be resent */ Resend = 1, /** * Remove because the request is moving to another model */ Adoption = 2 } export interface IChatRemoveRequestEvent { kind: "removeRequest"; requestId: string; responseId?: string; reason: ChatRequestRemovalReason; } export interface IChatSetHiddenEvent { kind: "setHidden"; } export interface IChatMoveEvent { kind: "move"; target: URI; range: IRange; } export interface IChatSetAgentEvent { kind: "setAgent"; agent: IChatAgentData; command?: IChatAgentCommand; } export interface IChatSetCustomTitleEvent { kind: "setCustomTitle"; title: string; } export interface IChatInitEvent { kind: "initialize"; } /** * Internal implementation of IInputModel */ declare class InputModel implements IInputModel { private readonly _state; readonly state: IObservable; constructor(initialState: IChatModelInputState | undefined); setState(state: Partial): void; clearState(): void; toJSON(): ISerializableChatModelInputState | undefined; } export declare class ChatModel extends Disposable implements IChatModel { private readonly logService; private readonly chatAgentService; private readonly chatEditingService; private readonly chatService; static getDefaultTitle(requests: (ISerializableChatRequestData | IChatRequestModel)[]): string; private readonly _onDidDispose; readonly onDidDispose: Event; private readonly _onDidChange; readonly onDidChange: Event; private readonly _pendingRequests; private readonly _onDidChangePendingRequests; readonly onDidChangePendingRequests: Event; private _requests; private _contributedChatSession; get contributedChatSession(): IChatSessionContext | undefined; setContributedChatSession(session: IChatSessionContext | undefined): void; private _repoData; get repoData(): IExportableRepoData | undefined; setRepoData(data: IExportableRepoData | undefined): void; getPendingRequests(): readonly IChatPendingRequest[]; setPendingRequests(requests: readonly { requestId: string; kind: ChatRequestQueueKind; }[]): void; /** * @internal Used by ChatService to add a request to the queue. * Steering messages are placed before queued messages. */ addPendingRequest(request: ChatRequestModel, kind: ChatRequestQueueKind, sendOptions: IChatSendRequestOptions): IChatPendingRequest; /** * @internal Used by ChatService to remove a pending request */ removePendingRequest(id: string): void; /** * @internal Used by ChatService to dequeue the next pending request */ dequeuePendingRequest(): IChatPendingRequest | undefined; /** * @internal Used by ChatService to dequeue all consecutive steering requests at the front of the queue. * Returns an empty array if the first pending request is not a steering request. */ dequeueAllSteeringRequests(): IChatPendingRequest[]; /** * @internal Used by ChatService to clear all pending requests */ clearPendingRequests(): void; readonly lastRequestObs: IObservable; private readonly _sessionId; /** @deprecated Use {@link sessionResource} instead */ get sessionId(): string; private readonly _sessionResource; get sessionResource(): URI; readonly requestInProgress: IObservable; readonly requestNeedsInput: IObservable; /** Input model for managing input state */ readonly inputModel: InputModel; get hasRequests(): boolean; get lastRequest(): ChatRequestModel | undefined; private _timestamp; get timestamp(): number; get timing(): IChatSessionTiming; get lastMessageDate(): number; private get _defaultAgent(); private readonly _initialResponderUsername; get responderUsername(): string; private _isImported; get isImported(): boolean; private _customTitle; get customTitle(): string | undefined; get title(): string; get hasCustomTitle(): boolean; private _editingSession; get editingSession(): IChatEditingSession | undefined; private readonly _initialLocation; get initialLocation(): ChatAgentLocation; private readonly _canUseTools; get canUseTools(): boolean; private _disableBackgroundKeepAlive; get willKeepAlive(): boolean; dataSerializer?: IChatDataSerializerLog; constructor(dataRef: ISerializedChatDataReference | undefined, initialModelProps: { initialLocation: ChatAgentLocation; canUseTools: boolean; inputState?: ISerializableChatModelInputState; resource?: URI; disableBackgroundKeepAlive?: boolean; }, logService: ILogService, chatAgentService: IChatAgentService, chatEditingService: IChatEditingService, chatService: IChatService); startEditingSession(isGlobalEditingSession?: boolean, transferFromSession?: IChatEditingSession): void; private currentEditedFileEvents; notifyEditingAction(action: IChatEditingSessionAction): void; private _deserialize; private _deserializeRequest; private reviveVariableData; private getParsedRequestFromString; /** * Hydrates pending requests from serialized data. * For each serialized pending request, finds the matching request model and adds it to the pending queue. */ private _deserializePendingRequests; getRequests(): ChatRequestModel[]; resetCheckpoint(): void; setCheckpoint(requestId: string | undefined): void; private _checkpoint; get checkpoint(): ChatRequestModel | undefined; private _setDisabledRequests; addRequest(message: IParsedChatRequest, variableData: IChatRequestVariableData, attempt: number, modeInfo?: IChatRequestModeInfo, chatAgent?: IChatAgentData, slashCommand?: IChatAgentCommand, confirmation?: string, locationData?: IChatLocationData, attachments?: IChatRequestVariableEntry[], isCompleteAddedRequest?: boolean, modelId?: string, userSelectedTools?: UserSelectedTools, id?: string): ChatRequestModel; setCustomTitle(title: string): void; updateRequest(request: ChatRequestModel, variableData: IChatRequestVariableData): void; adoptRequest(request: ChatRequestModel): void; acceptResponseProgress(request: ChatRequestModel, progress: IChatProgress, quiet?: boolean): void; removeRequest(id: string, reason?: ChatRequestRemovalReason): void; cancelRequest(request: ChatRequestModel): void; setResponse(request: ChatRequestModel, result: IChatAgentResult): void; setFollowups(request: ChatRequestModel, followups: IChatFollowup[] | undefined): void; setResponseModel(request: ChatRequestModel, response: ChatResponseModel): void; toExport(): IExportableChatData; toJSON(): ISerializableChatData; dispose(): void; } export declare function updateRanges(variableData: IChatRequestVariableData, diff: number): IChatRequestVariableData; export declare function canMergeMarkdownStrings(md1: IMarkdownString, md2: IMarkdownString): boolean; export declare function appendMarkdownString(md1: IMarkdownString, md2: IMarkdownString | string): IMarkdownString; export declare function getCodeCitationsMessage(citations: ReadonlyArray): string; /** * Converts IChatSendRequestOptions to a serializable format by extracting only * serializable fields and converting observables to static values. */ export declare function serializeSendOptions(options: IChatSendRequestOptions): ISerializableSendOptions; export declare enum ChatRequestEditedFileEventKind { Keep = 1, Undo = 2, UserModification = 3 } export interface IChatAgentEditedFileEvent { readonly uri: URI; readonly eventKind: ChatRequestEditedFileEventKind; } /** URI for a resource embedded in a chat request/response */ export declare namespace ChatResponseResource { const scheme = "vscode-chat-response-resource"; function createUri(sessionResource: URI, toolCallId: string, index: number, basename?: string): URI; function parseUri(uri: URI): undefined | { sessionResource: URI; toolCallId: string; index: number; }; } export {};