mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-10 00:27:05 -06:00
Merge pull request #282324 from microsoft/roblou/irrelevant-anaconda
Store lastResponseState in metadata
This commit is contained in:
commit
da9c9d69cb
@ -61,7 +61,7 @@ import { ChatContextKeys } from '../../common/chatContextKeys.js';
|
||||
import { ModifiedFileEntryState } from '../../common/chatEditingService.js';
|
||||
import { IChatModel, IChatResponseModel } from '../../common/chatModel.js';
|
||||
import { ChatMode, IChatMode, IChatModeService } from '../../common/chatModes.js';
|
||||
import { IChatDetail, IChatService } from '../../common/chatService.js';
|
||||
import { IChatDetail, IChatService, ResponseModelState } from '../../common/chatService.js';
|
||||
import { IChatSessionItem, IChatSessionsService, localChatSessionType } from '../../common/chatSessionsService.js';
|
||||
import { ISCMHistoryItemChangeRangeVariableEntry, ISCMHistoryItemChangeVariableEntry } from '../../common/chatVariableEntries.js';
|
||||
import { IChatRequestViewModel, IChatResponseViewModel, isRequestVM } from '../../common/chatViewModel.js';
|
||||
@ -766,6 +766,7 @@ export function registerChatActions() {
|
||||
title: session.label,
|
||||
isActive: false,
|
||||
lastMessageDate: 0,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
},
|
||||
buttons,
|
||||
};
|
||||
|
||||
@ -12,7 +12,7 @@ import { ResourceSet } from '../../../../../base/common/map.js';
|
||||
import { Schemas } from '../../../../../base/common/network.js';
|
||||
import { IWorkbenchContribution } from '../../../../common/contributions.js';
|
||||
import { IChatModel } from '../../common/chatModel.js';
|
||||
import { IChatDetail, IChatService } from '../../common/chatService.js';
|
||||
import { IChatDetail, IChatService, ResponseModelState } from '../../common/chatService.js';
|
||||
import { ChatSessionStatus, IChatSessionItem, IChatSessionItemProvider, IChatSessionsService, localChatSessionType } from '../../common/chatSessionsService.js';
|
||||
import { ChatSessionItemWithProvider } from '../chatSessions/common.js';
|
||||
|
||||
@ -147,7 +147,9 @@ export class LocalAgentsSessionsProvider extends Disposable implements IChatSess
|
||||
provider: this,
|
||||
label: chat.title,
|
||||
description,
|
||||
status: model ? this.modelToStatus(model) : undefined,
|
||||
status: model ?
|
||||
this.modelToStatus(model) :
|
||||
chatResponseStateToSessionStatus(chat.lastResponseState),
|
||||
iconPath: Codicon.chatSparkle,
|
||||
timing: {
|
||||
startTime,
|
||||
@ -161,3 +163,15 @@ export class LocalAgentsSessionsProvider extends Disposable implements IChatSess
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function chatResponseStateToSessionStatus(state: ResponseModelState): ChatSessionStatus {
|
||||
switch (state) {
|
||||
case ResponseModelState.Cancelled:
|
||||
case ResponseModelState.Complete:
|
||||
return ChatSessionStatus.Completed;
|
||||
case ResponseModelState.Failed:
|
||||
return ChatSessionStatus.Failed;
|
||||
case ResponseModelState.Pending:
|
||||
return ChatSessionStatus.InProgress;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ import { migrateLegacyTerminalToolSpecificData } from './chat.js';
|
||||
import { IChatAgentCommand, IChatAgentData, IChatAgentResult, IChatAgentService, UserSelectedTools, reviveSerializedAgent } from './chatAgents.js';
|
||||
import { IChatEditingService, IChatEditingSession, ModifiedFileEntryState, editEntriesToMultiDiffData } from './chatEditingService.js';
|
||||
import { ChatRequestTextPart, IParsedChatRequest, reviveParsedChatRequest } from './chatParserTypes.js';
|
||||
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatResponseClearToPreviousToolInvocationReason, ElicitationState, IChatAgentMarkdownContentWithVulnerability, IChatClearToPreviousToolInvocation, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatEditingSessionAction, IChatElicitationRequest, IChatElicitationRequestSerialized, IChatExtensionsContent, IChatFollowup, IChatLocationData, IChatMarkdownContent, IChatMcpServersStarting, IChatModelReference, IChatMultiDiffData, IChatMultiDiffDataSerialized, IChatNotebookEdit, IChatPrepareToolInvocationPart, IChatProgress, IChatProgressMessage, IChatPullRequestContent, IChatResponseCodeblockUriPart, IChatResponseProgressFileTreeData, IChatService, IChatSessionContext, IChatTask, IChatTaskSerialized, IChatTextEdit, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatUsedContext, IChatWarningMessage, isIUsedContext } from './chatService.js';
|
||||
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, ChatResponseClearToPreviousToolInvocationReason, ElicitationState, IChatAgentMarkdownContentWithVulnerability, IChatClearToPreviousToolInvocation, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatEditingSessionAction, IChatElicitationRequest, IChatElicitationRequestSerialized, IChatExtensionsContent, IChatFollowup, IChatLocationData, IChatMarkdownContent, IChatMcpServersStarting, IChatModelReference, IChatMultiDiffData, IChatMultiDiffDataSerialized, IChatNotebookEdit, IChatPrepareToolInvocationPart, IChatProgress, IChatProgressMessage, IChatPullRequestContent, IChatResponseCodeblockUriPart, IChatResponseProgressFileTreeData, IChatService, IChatSessionContext, IChatTask, IChatTaskSerialized, IChatTextEdit, IChatThinkingPart, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatUsedContext, IChatWarningMessage, ResponseModelState, isIUsedContext } from './chatService.js';
|
||||
import { LocalChatSessionUri } from './chatUri.js';
|
||||
import { ChatRequestToolReferenceEntry, IChatRequestVariableEntry } from './chatVariableEntries.js';
|
||||
import { ChatAgentLocation, ChatModeKind } from './constants.js';
|
||||
@ -194,6 +194,8 @@ export interface IChatResponseModel {
|
||||
readonly timestamp: number;
|
||||
/** Milliseconds timestamp when this chat response was completed or cancelled. */
|
||||
readonly completedAt?: number;
|
||||
/** The state of this response */
|
||||
readonly state: ResponseModelState;
|
||||
/**
|
||||
* Adjusted millisecond timestamp that excludes the duration during which
|
||||
* the model was pending user confirmation. `Date.now() - confirmationAdjustedTimestamp`
|
||||
@ -772,15 +774,9 @@ export interface IChatResponseModelParameters {
|
||||
codeBlockInfos: ICodeBlockInfo[] | undefined;
|
||||
}
|
||||
|
||||
const enum ResponseModelState {
|
||||
Pending,
|
||||
Complete,
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
type ResponseModelStateT =
|
||||
| { value: ResponseModelState.Pending }
|
||||
| { value: ResponseModelState.Complete | ResponseModelState.Cancelled; completedAt: number };
|
||||
| { value: ResponseModelState.Complete | ResponseModelState.Cancelled | ResponseModelState.Failed; completedAt: number };
|
||||
|
||||
export class ChatResponseModel extends Disposable implements IChatResponseModel {
|
||||
private readonly _onDidChange = this._register(new Emitter<ChatResponseModelChangeReason>());
|
||||
@ -838,12 +834,22 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel
|
||||
|
||||
public get completedAt(): number | undefined {
|
||||
const state = this._modelState.get();
|
||||
if (state.value === ResponseModelState.Complete || state.value === ResponseModelState.Cancelled) {
|
||||
if (state.value === ResponseModelState.Complete || state.value === ResponseModelState.Cancelled || state.value === ResponseModelState.Failed) {
|
||||
return state.completedAt;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public get state(): ResponseModelState {
|
||||
const state = this._modelState.get().value;
|
||||
if (state === ResponseModelState.Complete && !!this._result?.errorDetails && this.result?.errorDetails?.code !== 'canceled') {
|
||||
// This check covers sessions created in previous vscode versions which saved a failed response as 'Complete'
|
||||
return ResponseModelState.Failed;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
public get vote(): ChatAgentVoteDirection | undefined {
|
||||
return this._vote;
|
||||
}
|
||||
@ -1073,7 +1079,9 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel
|
||||
this._response.clear();
|
||||
}
|
||||
|
||||
this._modelState.set({ value: ResponseModelState.Complete, completedAt: Date.now() }, undefined);
|
||||
// Canceled sessions can be considered 'Complete'
|
||||
const state = !!this._result?.errorDetails && this._result.errorDetails.code !== 'canceled' ? ResponseModelState.Failed : ResponseModelState.Complete;
|
||||
this._modelState.set({ value: state, completedAt: Date.now() }, undefined);
|
||||
this._onDidChange.fire({ reason: 'completedRequest' });
|
||||
}
|
||||
|
||||
|
||||
@ -916,12 +916,20 @@ export interface IChatSessionStats {
|
||||
removed: number;
|
||||
}
|
||||
|
||||
export const enum ResponseModelState {
|
||||
Pending,
|
||||
Complete,
|
||||
Cancelled,
|
||||
Failed
|
||||
}
|
||||
|
||||
export interface IChatDetail {
|
||||
sessionResource: URI;
|
||||
title: string;
|
||||
lastMessageDate: number;
|
||||
isActive: boolean;
|
||||
stats?: IChatSessionStats;
|
||||
lastResponseState: ResponseModelState;
|
||||
}
|
||||
|
||||
export interface IChatProviderInfo {
|
||||
|
||||
@ -36,7 +36,7 @@ import { ChatModel, ChatRequestModel, ChatRequestRemovalReason, IChatModel, ICha
|
||||
import { ChatModelStore, IStartSessionProps } from './chatModelStore.js';
|
||||
import { chatAgentLeader, ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestTextPart, chatSubcommandLeader, getPromptText, IParsedChatRequest } from './chatParserTypes.js';
|
||||
import { ChatRequestParser } from './chatRequestParser.js';
|
||||
import { ChatMcpServersStarting, IChatCompleteResponse, IChatDetail, IChatFollowup, IChatModelReference, IChatProgress, IChatSendRequestData, IChatSendRequestOptions, IChatSendRequestResponseState, IChatService, IChatSessionContext, IChatSessionStartOptions, IChatTransferredSessionData, IChatUserActionEvent } from './chatService.js';
|
||||
import { ChatMcpServersStarting, IChatCompleteResponse, IChatDetail, IChatFollowup, IChatModelReference, IChatProgress, IChatSendRequestData, IChatSendRequestOptions, IChatSendRequestResponseState, IChatService, IChatSessionContext, IChatSessionStartOptions, IChatTransferredSessionData, IChatUserActionEvent, ResponseModelState } from './chatService.js';
|
||||
import { ChatRequestTelemetry, ChatServiceTelemetry } from './chatServiceTelemetry.js';
|
||||
import { IChatSessionsService } from './chatSessionsService.js';
|
||||
import { ChatSessionStore, IChatSessionEntryMetadata, IChatTransfer2 } from './chatSessionStore.js';
|
||||
@ -401,6 +401,7 @@ export class ChatService extends Disposable implements IChatService {
|
||||
lastMessageDate: session.lastMessageDate,
|
||||
isActive: true,
|
||||
stats: await awaitStatsForSession(session),
|
||||
lastResponseState: session.lastRequest?.response?.state ?? ResponseModelState.Pending,
|
||||
};
|
||||
}));
|
||||
}
|
||||
@ -419,6 +420,8 @@ export class ChatService extends Disposable implements IChatService {
|
||||
...entry,
|
||||
sessionResource,
|
||||
isActive: this._sessionModels.has(sessionResource),
|
||||
// TODO@roblourens- missing for old data- normalize inside the store
|
||||
lastResponseState: entry.lastResponseState ?? ResponseModelState.Complete,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -431,6 +434,8 @@ export class ChatService extends Disposable implements IChatService {
|
||||
...metadata,
|
||||
sessionResource,
|
||||
isActive: this._sessionModels.has(sessionResource),
|
||||
// TODO@roblourens- missing for old data- normalize inside the store
|
||||
lastResponseState: metadata.lastResponseState ?? ResponseModelState.Complete,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import { ILifecycleService } from '../../../services/lifecycle/common/lifecycle.
|
||||
import { awaitStatsForSession } from './chat.js';
|
||||
import { ModifiedFileEntryState } from './chatEditingService.js';
|
||||
import { ChatModel, IChatModelInputState, ISerializableChatData, ISerializableChatDataIn, ISerializableChatsData, normalizeSerializableChatData } from './chatModel.js';
|
||||
import { IChatSessionStats } from './chatService.js';
|
||||
import { IChatSessionStats, ResponseModelState } from './chatService.js';
|
||||
import { LocalChatSessionUri } from './chatUri.js';
|
||||
import { ChatAgentLocation } from './constants.js';
|
||||
|
||||
@ -433,6 +433,7 @@ export interface IChatSessionEntryMetadata {
|
||||
initialLocation?: ChatAgentLocation;
|
||||
hasPendingEdits?: boolean;
|
||||
stats?: IChatSessionStats;
|
||||
lastResponseState?: ResponseModelState;
|
||||
|
||||
/**
|
||||
* This only exists because the migrated data from the storage service had empty sessions persisted, and it's impossible to know which ones are
|
||||
@ -505,7 +506,10 @@ async function getSessionMetadata(session: ChatModel | ISerializableChatData): P
|
||||
hasPendingEdits: session instanceof ChatModel ? (session.editingSession?.entries.get().some(e => e.state.get() === ModifiedFileEntryState.Modified)) : false,
|
||||
isEmpty: session instanceof ChatModel ? session.getRequests().length === 0 : session.requests.length === 0,
|
||||
stats,
|
||||
isExternal: session instanceof ChatModel && !LocalChatSessionUri.parseLocalSessionId(session.sessionResource)
|
||||
isExternal: session instanceof ChatModel && !LocalChatSessionUri.parseLocalSessionId(session.sessionResource),
|
||||
lastResponseState: session instanceof ChatModel ?
|
||||
(session.lastRequest?.response?.state ?? ResponseModelState.Complete) :
|
||||
ResponseModelState.Complete
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ import { workbenchInstantiationService } from '../../../../test/browser/workbenc
|
||||
import { LocalAgentsSessionsProvider } from '../../browser/agentSessions/localAgentSessionsProvider.js';
|
||||
import { ModifiedFileEntryState } from '../../common/chatEditingService.js';
|
||||
import { IChatModel, IChatRequestModel, IChatResponseModel } from '../../common/chatModel.js';
|
||||
import { IChatDetail, IChatService, IChatSessionStartOptions } from '../../common/chatService.js';
|
||||
import { IChatDetail, IChatService, IChatSessionStartOptions, ResponseModelState } from '../../common/chatService.js';
|
||||
import { ChatSessionStatus, IChatSessionsService, localChatSessionType } from '../../common/chatSessionsService.js';
|
||||
import { LocalChatSessionUri } from '../../common/chatUri.js';
|
||||
import { ChatAgentLocation } from '../../common/constants.js';
|
||||
@ -321,7 +321,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Test Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -342,7 +343,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'History Session',
|
||||
lastMessageDate: Date.now() - 10000,
|
||||
isActive: false
|
||||
isActive: false,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -366,13 +368,15 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Live Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
mockChatService.setHistorySessionItems([{
|
||||
sessionResource,
|
||||
title: 'History Session',
|
||||
lastMessageDate: Date.now() - 10000,
|
||||
isActive: false
|
||||
isActive: false,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -398,7 +402,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'In Progress Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -426,7 +431,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Completed Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -453,7 +459,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Canceled Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -480,7 +487,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Error Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -523,6 +531,7 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
title: 'Stats Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete,
|
||||
stats: {
|
||||
added: 30,
|
||||
removed: 8,
|
||||
@ -565,7 +574,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'No Stats Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -593,7 +603,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Timing Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -614,7 +625,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'History Timing Session',
|
||||
lastMessageDate,
|
||||
isActive: false
|
||||
isActive: false,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -641,7 +653,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'EndTime Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
@ -667,7 +680,8 @@ suite('LocalAgentsSessionsProvider', () => {
|
||||
sessionResource,
|
||||
title: 'Icon Session',
|
||||
lastMessageDate: Date.now(),
|
||||
isActive: true
|
||||
isActive: true,
|
||||
lastResponseState: ResponseModelState.Complete
|
||||
}]);
|
||||
|
||||
const sessions = await provider.provideChatSessionItems(CancellationToken.None);
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
responseMarkdownInfo: undefined,
|
||||
followups: undefined,
|
||||
modelState: {
|
||||
value: 1,
|
||||
value: 3,
|
||||
completedAt: undefined
|
||||
},
|
||||
vote: undefined,
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
responseMarkdownInfo: undefined,
|
||||
followups: undefined,
|
||||
modelState: {
|
||||
value: 1,
|
||||
value: 3,
|
||||
completedAt: undefined
|
||||
},
|
||||
vote: undefined,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user