chain of thought API (#259939)

* cot api and rendering

* working progress streaminig

* streaming working

* collapsable thinking block

* some better styling

* fix merge conflict

* some cleaned up styling, removing copilot css

* label updates

* some vibe coded timer work

* fix anotha merge conflict

* thinking part with timer better

* render tools inside thinking container

* render markdown in container

* revert and remove majority ui changes

* fix some merge conflicts

* some cleanup

* hygiene
This commit is contained in:
Justin Chen
2025-08-06 00:47:36 -07:00
committed by GitHub
parent 737ca765b7
commit 43a9dc0df3
16 changed files with 313 additions and 9 deletions
+1
View File
@@ -25,6 +25,7 @@ export const enum MarshalledId {
ChatViewContext,
LanguageModelToolResult,
LanguageModelTextPart,
LanguageModelThinkingPart,
LanguageModelPromptTsxPart,
LanguageModelDataPart,
ChatSessionContext,
@@ -251,6 +251,10 @@ const _allApiProposals = {
languageModelSystem: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageModelSystem.d.ts',
},
languageModelThinkingPart: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageModelThinkingPart.d.ts',
version: 1
},
languageModelToolResultAudience: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageModelToolResultAudience.d.ts',
},
@@ -1843,6 +1843,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
ChatResponseAnchorPart: extHostTypes.ChatResponseAnchorPart,
ChatResponseProgressPart: extHostTypes.ChatResponseProgressPart,
ChatResponseProgressPart2: extHostTypes.ChatResponseProgressPart2,
ChatResponseThinkingProgressPart: extHostTypes.ChatResponseThinkingProgressPart,
ChatResponseReferencePart: extHostTypes.ChatResponseReferencePart,
ChatResponseReferencePart2: extHostTypes.ChatResponseReferencePart,
ChatResponseCodeCitationPart: extHostTypes.ChatResponseCodeCitationPart,
@@ -1880,6 +1881,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
LanguageModelPartAudience: extHostTypes.LanguageModelPartAudience,
ToolResultAudience: extHostTypes.LanguageModelPartAudience, // back compat
LanguageModelToolCallPart: extHostTypes.LanguageModelToolCallPart,
LanguageModelThinkingPart: extHostTypes.LanguageModelThinkingPart,
LanguageModelError: extHostTypes.LanguageModelError,
LanguageModelToolResult: extHostTypes.LanguageModelToolResult,
LanguageModelToolResult2: extHostTypes.LanguageModelToolResult2,
@@ -191,6 +191,14 @@ export class ChatAgentResponseStream {
_report(dto, task);
return this;
},
thinkingProgress(value, id?, metadata?) {
throwIfDone(this.thinkingProgress);
checkProposedApiEnabled(that._extension, 'chatParticipantAdditions');
const part = new extHostTypes.ChatResponseThinkingProgressPart(value, id, metadata);
const dto = typeConvert.ChatResponseThinkingProgressPart.from(part);
_report(dto);
return this;
},
warning(value) {
throwIfDone(this.progress);
checkProposedApiEnabled(that._extension, 'chatParticipantAdditions');
@@ -296,6 +304,7 @@ export class ChatAgentResponseStream {
part instanceof extHostTypes.ChatResponseCodeCitationPart ||
part instanceof extHostTypes.ChatResponseMovePart ||
part instanceof extHostTypes.ChatResponseExtensionsPart ||
part instanceof extHostTypes.ChatResponseThinkingProgressPart ||
part instanceof extHostTypes.ChatResponsePullRequestPart ||
part instanceof extHostTypes.ChatResponseProgressPart2
) {
@@ -308,6 +317,9 @@ export class ChatAgentResponseStream {
} else if (part instanceof extHostTypes.ChatResponseProgressPart2) {
const dto = part.task ? typeConvert.ChatTask.from(part) : typeConvert.ChatResponseProgressPart.from(part);
_report(dto, part.task);
} else if (part instanceof extHostTypes.ChatResponseThinkingProgressPart) {
const dto = typeConvert.ChatResponseThinkingProgressPart.from(part);
_report(dto);
} else if (part instanceof extHostTypes.ChatResponseAnchorPart) {
const dto = typeConvert.ChatResponseAnchorPart.from(part);
@@ -38,7 +38,7 @@ type LanguageModelProviderData = {
readonly provider: vscode.LanguageModelChatProvider2;
};
type LMResponsePart = vscode.LanguageModelTextPart | vscode.LanguageModelToolCallPart | vscode.LanguageModelDataPart;
type LMResponsePart = vscode.LanguageModelTextPart | vscode.LanguageModelToolCallPart | vscode.LanguageModelDataPart | vscode.LanguageModelThinkingPart;
class LanguageModelResponseStream {
@@ -102,6 +102,9 @@ class LanguageModelResponse {
let out: LMResponsePart;
if (fragment.part.type === 'text') {
out = new extHostTypes.LanguageModelTextPart(fragment.part.value, fragment.part.audience);
} else if (fragment.part.type === 'thinking') {
out = new extHostTypes.LanguageModelThinkingPart(fragment.part.value, fragment.part.id, fragment.part.metadata);
} else if (fragment.part.type === 'data') {
out = new extHostTypes.LanguageModelDataPart(fragment.part.data.buffer, fragment.part.mimeType, fragment.part.audience);
} else {
@@ -301,6 +304,8 @@ export class ExtHostLanguageModels implements ExtHostLanguageModelsShape {
part = { type: 'text', value: fragment.part.value, audience: fragment.part.audience };
} else if (fragment.part instanceof extHostTypes.LanguageModelDataPart) {
part = { type: 'data', mimeType: fragment.part.mimeType, data: VSBuffer.wrap(fragment.part.data), audience: fragment.part.audience };
} else if (fragment.part instanceof extHostTypes.LanguageModelThinkingPart) {
part = { type: 'thinking', value: fragment.part.value, id: fragment.part.id, metadata: fragment.part.metadata };
}
if (!part) {
@@ -41,7 +41,7 @@ import { IViewBadge } from '../../common/views.js';
import { IChatAgentRequest, IChatAgentResult } from '../../contrib/chat/common/chatAgents.js';
import { IChatRequestDraft } from '../../contrib/chat/common/chatEditingService.js';
import { IChatRequestVariableEntry, isImageVariableEntry } from '../../contrib/chat/common/chatVariableEntries.js';
import { IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatExtensionsContent, IChatFollowup, IChatMarkdownContent, IChatMoveMessage, IChatMultiDiffData, IChatPrepareToolInvocationPart, IChatProgressMessage, IChatPullRequestContent, IChatResponseCodeblockUriPart, IChatTaskDto, IChatTaskResult, IChatTextEdit, IChatTreeData, IChatUserActionEvent, IChatWarningMessage } from '../../contrib/chat/common/chatService.js';
import { IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatExtensionsContent, IChatFollowup, IChatMarkdownContent, IChatMoveMessage, IChatMultiDiffData, IChatPrepareToolInvocationPart, IChatProgressMessage, IChatPullRequestContent, IChatResponseCodeblockUriPart, IChatTaskDto, IChatTaskResult, IChatTextEdit, IChatThinkingPart, IChatTreeData, IChatUserActionEvent, IChatWarningMessage } from '../../contrib/chat/common/chatService.js';
import { IToolResult, IToolResultInputOutputDetails, IToolResultOutputDetails, ToolDataSource } from '../../contrib/chat/common/languageModelToolsService.js';
import * as chatProvider from '../../contrib/chat/common/languageModels.js';
import { IChatMessageDataPart, IChatResponseDataPart, IChatResponsePromptTsxPart, IChatResponseTextPart } from '../../contrib/chat/common/languageModels.js';
@@ -2699,6 +2699,20 @@ export namespace ChatResponseProgressPart {
}
}
export namespace ChatResponseThinkingProgressPart {
export function from(part: vscode.ChatResponseThinkingProgressPart): Dto<IChatThinkingPart> {
return {
kind: 'thinking',
value: part.value,
id: part.id,
metadata: part.metadata
};
}
export function to(part: Dto<IChatThinkingPart>): vscode.ChatResponseThinkingProgressPart {
return new types.ChatResponseThinkingProgressPart(part.value);
}
}
export namespace ChatResponseWarningPart {
export function from(part: vscode.ChatResponseWarningPart): Dto<IChatWarningMessage> {
return {
@@ -2999,6 +3013,8 @@ export namespace ChatResponsePart {
return ChatResponseReferencePart.from(part);
} else if (part instanceof types.ChatResponseProgressPart) {
return ChatResponseProgressPart.from(part);
} else if (part instanceof types.ChatResponseThinkingProgressPart) {
return ChatResponseThinkingProgressPart.from(part);
} else if (part instanceof types.ChatResponseFileTreePart) {
return ChatResponseFilesPart.from(part);
} else if (part instanceof types.ChatResponseMultiDiffPart) {
@@ -3260,7 +3276,9 @@ export namespace ChatAgentResult {
if (value.$mid === MarshalledId.LanguageModelToolResult) {
return new types.LanguageModelToolResult(cloneAndChange(value.content, reviveMetadata));
} else if (value.$mid === MarshalledId.LanguageModelTextPart) {
return new types.LanguageModelTextPart(value.value, value.audience);
return new types.LanguageModelTextPart(value.value);
} else if (value.$mid === MarshalledId.LanguageModelThinkingPart) {
return new types.LanguageModelThinkingPart(value.value, value.id, value.metadata);
} else if (value.$mid === MarshalledId.LanguageModelPromptTsxPart) {
return new types.LanguageModelPromptTsxPart(value.value);
}
@@ -4648,6 +4648,17 @@ export class ChatResponseProgressPart2 {
}
}
export class ChatResponseThinkingProgressPart {
value: string;
id?: string;
metadata?: string;
constructor(value: string, id?: string, metadata?: string) {
this.value = value;
this.id = id;
this.metadata = metadata;
}
}
export class ChatResponseWarningPart {
value: vscode.MarkdownString;
constructor(value: string | vscode.MarkdownString) {
@@ -5096,6 +5107,28 @@ export enum ChatImageMimeType {
BMP = 'image/bmp',
}
export class LanguageModelThinkingPart implements vscode.LanguageModelThinkingPart {
value: string;
id?: string;
metadata?: string;
constructor(value: string, id?: string, metadata?: string) {
this.value = value;
this.id = id;
this.metadata = metadata;
}
toJSON() {
return {
$mid: MarshalledId.LanguageModelThinkingPart,
value: this.value,
id: this.id,
metadata: this.metadata,
};
}
}
export class LanguageModelPromptTsxPart {
value: unknown;
@@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { $, clearNode } from '../../../../../base/browser/dom.js';
import { Emitter } from '../../../../../base/common/event.js';
import { Disposable } from '../../../../../base/common/lifecycle.js';
import { IChatThinkingPart } from '../../common/chatService.js';
import { IChatContentPartRenderContext, IChatContentPart } from './chatContentParts.js';
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
import { MarkdownString } from '../../../../../base/common/htmlContent.js';
import { MarkdownRenderer, IMarkdownRenderResult } from '../../../../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js';
export class ChatThinkingContentPart extends Disposable implements IChatContentPart {
readonly domNode: HTMLElement;
public readonly codeblocks: undefined;
public readonly codeblocksPartId: undefined;
private readonly _onDidChangeHeight = this._register(new Emitter<void>());
readonly onDidChangeHeight = this._onDidChangeHeight.event;
private currentThinkingValue: string;
private readonly renderer: MarkdownRenderer;
private textContainer!: HTMLElement;
private markdownResult: IMarkdownRenderResult | undefined;
constructor(
content: IChatThinkingPart,
_context: IChatContentPartRenderContext,
@IInstantiationService instantiationService: IInstantiationService,
) {
super();
this.renderer = instantiationService.createInstance(MarkdownRenderer, {});
this.currentThinkingValue = this.parseContent(content.value || '');
this.domNode = $('.chat-thinking-box');
this.domNode.tabIndex = 0;
this.renderContent();
}
private parseContent(content: string): string {
// Remove <|im_sep|>**** and similar markers
return content
.replace(/<\|im_sep\|>\*{4,}/g, '')
.replace(/<\|lim_sep\|>\*{4,}/g, '')
.trim();
}
private renderContent(): void {
this.textContainer = $('.chat-thinking-text.markdown-content');
this.domNode.appendChild(this.textContainer);
if (this.currentThinkingValue) {
this.renderMarkdown(this.currentThinkingValue);
}
}
private renderMarkdown(content: string): void {
if (this.markdownResult) {
this.markdownResult.dispose();
this.markdownResult = undefined;
}
const cleanedContent = this.parseContent(content);
if (!cleanedContent) {
return;
}
clearNode(this.textContainer);
this.markdownResult = this.renderer.render(new MarkdownString(cleanedContent));
this.textContainer.appendChild(this.markdownResult.element);
}
hasSameContent(other: any): boolean {
if (other.kind !== 'thinking') {
return false;
}
return true;
}
override dispose(): void {
if (this.markdownResult) {
this.markdownResult.dispose();
this.markdownResult = undefined;
}
super.dispose();
}
}
@@ -49,7 +49,7 @@ import { IChatAgentMetadata } from '../common/chatAgents.js';
import { ChatContextKeys } from '../common/chatContextKeys.js';
import { IChatTextEditGroup } from '../common/chatModel.js';
import { chatSubcommandLeader } from '../common/chatParserTypes.js';
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatErrorLevel, IChatChangesSummary, IChatConfirmation, IChatContentReference, IChatElicitationRequest, IChatExtensionsContent, IChatFollowup, IChatMarkdownContent, IChatPullRequestContent, IChatMultiDiffData, IChatTask, IChatTaskSerialized, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop } from '../common/chatService.js';
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatErrorLevel, IChatChangesSummary, IChatConfirmation, IChatContentReference, IChatElicitationRequest, IChatExtensionsContent, IChatFollowup, IChatMarkdownContent, IChatPullRequestContent, IChatMultiDiffData, IChatTask, IChatTaskSerialized, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatThinkingPart } from '../common/chatService.js';
import { IChatChangesSummaryPart, IChatCodeCitations, IChatErrorDetailsPart, IChatReferences, IChatRendererContent, IChatRequestViewModel, IChatResponseViewModel, IChatViewModel, IChatWorkingProgress, isRequestVM, isResponseVM } from '../common/chatViewModel.js';
import { getNWords } from '../common/chatWordCounter.js';
import { CodeBlockModelCollection } from '../common/codeBlockModelCollection.js';
@@ -86,6 +86,7 @@ import { alert } from '../../../../base/browser/ui/aria/aria.js';
import { CodiconActionViewItem } from '../../notebook/browser/view/cellParts/cellActionView.js';
import { ChatPullRequestContentPart } from './chatContentParts/chatPullRequestContentPart.js';
import { ChatCheckpointFileChangesSummaryContentPart } from './chatContentParts/chatChangesSummaryPart.js';
import { ChatThinkingContentPart } from './chatContentParts/chatThinkingContentPart.js';
const $ = dom.$;
@@ -1144,6 +1145,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
return this.renderChatErrorDetails(context, content, templateData);
} else if (content.kind === 'elicitation') {
return this.renderElicitation(context, content, templateData);
} else if (content.kind === 'thinking') {
return this.renderThinking(context, content, templateData);
} else if (content.kind === 'changesSummary') {
return this.renderChangesSummary(content, context, templateData);
}
@@ -1341,6 +1344,18 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
return part;
}
private renderThinking(context: IChatContentPartRenderContext, thinking: IChatThinkingPart, templateData: IChatListItemTemplate): IChatContentPart {
const thinkingPart = templateData.instantiationService.createInstance(
ChatThinkingContentPart,
thinking,
context
);
thinkingPart.domNode.classList.add('chat-thinking-part');
return thinkingPart;
}
private renderChangesSummary(content: IChatChangesSummaryPart, context: IChatContentPartRenderContext, templateData: IChatListItemTemplate): IChatContentPart {
const part = this.instantiationService.createInstance(ChatCheckpointFileChangesSummaryContentPart, content, context);
part.addDisposable(part.onDidChangeHeight(() => { this.updateItemHeight(templateData); }));
@@ -2466,3 +2466,21 @@ have to be updated for changes to the rules above, or to support more deeply nes
color: var(--vscode-foreground);
flex-grow: 1;
}
.interactive-session .interactive-response .chat-thinking-box {
border: 1px solid var(--vscode-panel-border);
border-radius: 4px;
padding: 0px 8px;
margin: 4px 0;
background-color: var(--vscode-editor-background);
.chat-thinking-text {
font-size: inherit;
line-height: inherit;
display: flex;
align-items: flex-start;
}
}
@@ -26,7 +26,7 @@ import { CellUri, ICellEditOperation } from '../../notebook/common/notebookCommo
import { IChatAgentCommand, IChatAgentData, IChatAgentResult, IChatAgentService, reviveSerializedAgent } from './chatAgents.js';
import { IChatEditingService, IChatEditingSession } from './chatEditingService.js';
import { ChatRequestTextPart, IParsedChatRequest, reviveParsedChatRequest } from './chatParserTypes.js';
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatClearToPreviousToolInvocation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatEditingSessionAction, IChatElicitationRequest, IChatExtensionsContent, IChatFollowup, IChatLocationData, IChatMarkdownContent, IChatMultiDiffData, IChatNotebookEdit, IChatPrepareToolInvocationPart, IChatProgress, IChatProgressMessage, IChatPullRequestContent, IChatResponseCodeblockUriPart, IChatResponseProgressFileTreeData, IChatTask, IChatTaskSerialized, IChatTextEdit, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatUsedContext, IChatWarningMessage, isIUsedContext, ChatResponseClearToPreviousToolInvocationReason } from './chatService.js';
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatClearToPreviousToolInvocation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatEditingSessionAction, IChatElicitationRequest, IChatExtensionsContent, IChatFollowup, IChatLocationData, IChatMarkdownContent, IChatMultiDiffData, IChatNotebookEdit, IChatPrepareToolInvocationPart, IChatProgress, IChatProgressMessage, IChatPullRequestContent, IChatResponseCodeblockUriPart, IChatResponseProgressFileTreeData, IChatTask, IChatTaskSerialized, IChatTextEdit, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatUsedContext, IChatWarningMessage, isIUsedContext, ChatResponseClearToPreviousToolInvocationReason } from './chatService.js';
import { IChatRequestVariableEntry } from './chatVariableEntries.js';
import { ChatAgentLocation, ChatModeKind } from './constants.js';
@@ -118,6 +118,7 @@ export type IChatProgressHistoryResponseContent =
| IChatNotebookEditGroup
| IChatConfirmation
| IChatExtensionsContent
| IChatThinkingPart
| IChatPullRequestContent;
/**
@@ -365,6 +366,7 @@ class AbstractResponse implements IResponse {
case 'undoStop':
case 'prepareToolInvocation':
case 'elicitation':
case 'thinking':
case 'multiDiffData':
// Ignore
continue;
@@ -518,6 +520,20 @@ export class Response extends AbstractResponse implements IDisposable {
this._responseParts[idx] = { ...lastResponsePart, content: appendMarkdownString(lastResponsePart.content, progress.content) };
}
this._updateRepr(quiet);
} else if (progress.kind === 'thinking') {
// TODO: @justschen merge thinking and markdown handling
const lastResponsePart = this._responseParts
.filter(p => p.kind !== 'textEditGroup')
.at(-1);
if (!lastResponsePart || lastResponsePart.kind !== 'thinking' || !canMergeMarkdownStrings(new MarkdownString(lastResponsePart.value), new MarkdownString(progress.value))) {
this._responseParts.push(progress);
} else {
const idx = this._responseParts.indexOf(lastResponsePart);
this._responseParts[idx] = { ...lastResponsePart, value: appendMarkdownString(new MarkdownString(lastResponsePart.value), new MarkdownString(progress.value)).value };
}
this._updateRepr(quiet);
} else if (progress.kind === 'textEdit' || progress.kind === 'notebookEdit') {
// If the progress.uri is a cell Uri, its possible its part of the inline chat.
// Old approach of notebook inline chat would not start and end with notebook Uri, so we need to check for old approach.
@@ -1736,6 +1752,13 @@ export class ChatModel extends Disposable implements IChatModel {
return item.treeData;
} else if (item.kind === 'markdownContent') {
return item.content;
} else if (item.kind === 'thinking') {
return {
kind: 'thinking',
value: item.value,
id: item.id,
metadata: item.metadata
};
} else {
return item as any; // TODO
}
@@ -271,6 +271,13 @@ export interface IChatElicitationRequest {
onDidRequestHide: Event<void>;
}
export interface IChatThinkingPart {
kind: 'thinking';
value: string;
id?: string;
metadata?: string;
}
export interface IChatTerminalToolInvocationData {
kind: 'terminal';
commandLine: {
@@ -391,6 +398,7 @@ export type IChatProgress =
| IChatPullRequestContent
| IChatUndoStop
| IChatPrepareToolInvocationPart
| IChatThinkingPart
| IChatTaskSerialized
| IChatElicitationRequest;
@@ -123,6 +123,13 @@ export interface IChatResponseToolUsePart {
parameters: any;
}
export interface IChatResponseThinkingPart {
type: 'thinking';
value: string;
id?: string;
metadata?: string;
}
export interface IChatResponsePullRequestPart {
type: 'pullRequest';
uri: URI;
@@ -132,9 +139,9 @@ export interface IChatResponsePullRequestPart {
linkTag: string;
}
export type IExtendedChatResponsePart = IChatResponsePullRequestPart;
export type IChatResponsePart = IChatResponseTextPart | IChatResponseToolUsePart | IChatResponseDataPart | IChatResponseThinkingPart;
export type IChatResponsePart = IChatResponseTextPart | IChatResponseToolUsePart | IChatResponseDataPart;
export type IExtendedChatResponsePart = IChatResponsePullRequestPart;
export interface IChatResponseFragment {
index: number;
@@ -149,7 +149,7 @@ declare module 'vscode' {
constructor(value: ChatResponseDiffEntry[], title: string);
}
export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatPrepareToolInvocationPart | ChatToolInvocationPart | ChatResponseMultiDiffPart;
export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatPrepareToolInvocationPart | ChatToolInvocationPart | ChatResponseMultiDiffPart | ChatResponseThinkingProgressPart;
export class ChatResponseWarningPart {
value: MarkdownString;
constructor(value: string | MarkdownString);
@@ -161,6 +161,23 @@ declare module 'vscode' {
constructor(value: string, task?: (progress: Progress<ChatResponseWarningPart | ChatResponseReferencePart>) => Thenable<string | void>);
}
/**
* A specialized progress part for displaying thinking/reasoning steps.
*/
export class ChatResponseThinkingProgressPart extends ChatResponseProgressPart {
value: string;
id?: string;
metadata?: string;
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, id?: string, metadata?: string, task?: (progress: Progress<LanguageModelThinkingPart>) => Thenable<string | void>);
}
export class ChatResponseReferencePart2 {
/**
* The reference target.
@@ -256,6 +273,8 @@ declare module 'vscode' {
*/
progress(value: string, task?: (progress: Progress<ChatResponseWarningPart | ChatResponseReferencePart>) => Thenable<string | void>): void;
thinkingProgress(value: string, id?: string, metadata?: string): void;
textEdit(target: Uri, edits: TextEdit | TextEdit[]): void;
textEdit(target: Uri, isDone: true): void;
+1 -1
View File
@@ -139,6 +139,6 @@ declare module 'vscode' {
export interface ChatResponseFragment2 {
index: number;
part: LanguageModelTextPart | LanguageModelToolCallPart | LanguageModelDataPart;
part: LanguageModelTextPart | LanguageModelToolCallPart | LanguageModelDataPart | LanguageModelThinkingPart;
}
}
@@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 1
declare module 'vscode' {
/**
* A language model response part containing thinking/reasoning content.
* Thinking tokens represent the model's internal reasoning process that
* typically streams before the final response.
*/
export class LanguageModelThinkingPart {
/**
* The thinking/reasoning text content.
*/
value: string;
/**
* Optional unique identifier for this thinking sequence.
* This ID is typically provided at the end of the thinking stream
* and can be used for retrieval or reference purposes.
*/
id?: string;
/**
* Optional metadata associated with this thinking sequence.
*/
metadata?: string;
/**
* Construct a thinking part with the given content.
* @param value The thinking text content.
* @param id Optional unique identifier for this thinking sequence.
* @param metadata Optional metadata associated with this thinking sequence.
*/
constructor(value: string, id?: string, metadata?: string);
}
export interface LanguageModelChatResponse {
/**
* An async iterable that is a stream of text, thinking, and tool-call parts forming the overall response.
* This includes {@link LanguageModelThinkingPart} which represents the model's internal reasoning process.
*/
stream: AsyncIterable<LanguageModelTextPart | LanguageModelThinkingPart | LanguageModelToolCallPart | unknown>;
}
}