mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-06 14:34:17 +01:00
[cherry-pick] sessions: Refresh chat status after background completion (#333808)
sessions: Refresh chat status after background completion Reacquire the owning session state when a chat turn completes so main and hidden chat statuses do not remain stale after the idle subscription expires. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot
parent
c8ea8df522
commit
0ebfc317d9
@@ -4934,6 +4934,17 @@ export abstract class BaseAgentHostSessionsProvider extends Disposable implement
|
||||
);
|
||||
}
|
||||
|
||||
private _keepChatSessionStateAlive(chatChannel: string): void {
|
||||
const parsedChat = parseChatUri(chatChannel);
|
||||
if (!parsedChat) {
|
||||
return;
|
||||
}
|
||||
const cached = this._sessionCache.get(AgentSession.id(parsedChat.session));
|
||||
if (cached) {
|
||||
this._keepSessionStateAlive(cached.sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily acquire a session-state subscription for `sessionId` so that
|
||||
* `_runningSessionConfigs` is seeded from the AHP `SessionState.config`
|
||||
@@ -5625,6 +5636,7 @@ export abstract class BaseAgentHostSessionsProvider extends Disposable implement
|
||||
return;
|
||||
}
|
||||
if (e.action.type === ActionType.ChatTurnComplete && isChatAction(e.action)) {
|
||||
this._keepChatSessionStateAlive(e.channel);
|
||||
this._refreshSessions();
|
||||
} else if (e.action.type === ActionType.SessionTitleChanged && isSessionAction(e.action)) {
|
||||
this._handleTitleChanged(e.channel, e.action.title);
|
||||
|
||||
+46
@@ -5467,6 +5467,52 @@ suite('LocalAgentHostSessionsProvider', () => {
|
||||
defaultChatTitle: 'Renamed Default',
|
||||
});
|
||||
});
|
||||
|
||||
test('turn completion refreshes main chat status after the session-state subscription expires', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const provider = createProvider(disposables, agentHost);
|
||||
const session = setupMultiChatSession(provider, 'multi-complete');
|
||||
const sessionUri = AgentSession.uri('copilotcli', 'multi-complete').toString();
|
||||
const defaultChat = buildDefaultChatUri(sessionUri);
|
||||
const subagentChat = buildSubagentChatUri(sessionUri, 'tc-1');
|
||||
const stateWithStatus = (status: ProtocolSessionStatus): SessionState => makeState([
|
||||
makeChatSummary(defaultChat, '', status),
|
||||
{
|
||||
...makeChatSummary(subagentChat, 'Reviewer', status),
|
||||
origin: { kind: ProtocolChatOriginKind.Tool, chat: defaultChat, toolCallId: 'tc-1' },
|
||||
},
|
||||
], { defaultChat });
|
||||
|
||||
agentHost.setSessionState('multi-complete', 'copilotcli', stateWithStatus(ProtocolSessionStatus.InProgress));
|
||||
await timeout(31_000);
|
||||
agentHost.setSessionState('multi-complete', 'copilotcli', stateWithStatus(ProtocolSessionStatus.Idle));
|
||||
const staleStatus = session.mainChat.get().status.get();
|
||||
|
||||
agentHost.fireAction({
|
||||
channel: subagentChat,
|
||||
action: {
|
||||
type: ActionType.ChatTurnComplete,
|
||||
turnId: 'turn-1',
|
||||
duration: 1000,
|
||||
},
|
||||
serverSeq: 1,
|
||||
origin: undefined,
|
||||
} as ActionEnvelope);
|
||||
await timeout(0);
|
||||
|
||||
assert.deepStrictEqual({
|
||||
staleStatus,
|
||||
updatedStatus: session.mainChat.get().status.get(),
|
||||
subagentStatus: session.chats.get().find(chat => chat.origin?.kind === ChatOriginKind.Tool)?.status.get(),
|
||||
subscribeCount: agentHost.sessionSubscribeCounts.get(sessionUri),
|
||||
unsubscribeCount: agentHost.sessionUnsubscribeCounts.get(sessionUri),
|
||||
}, {
|
||||
staleStatus: SessionStatus.InProgress,
|
||||
updatedStatus: SessionStatus.Completed,
|
||||
subagentStatus: SessionStatus.Completed,
|
||||
subscribeCount: 2,
|
||||
unsubscribeCount: 1,
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
// ---- Title change from server -------
|
||||
|
||||
Reference in New Issue
Block a user