mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-17 23:35:54 +01:00
Agent Debug: Enable Claude Code session url and filter untitled sessions (#302903)
* Claude and filter * feedback updates
This commit is contained in:
@@ -17,7 +17,7 @@ import { defaultButtonStyles } from '../../../../../platform/theme/browser/defau
|
|||||||
import { IChatDebugService } from '../../common/chatDebugService.js';
|
import { IChatDebugService } from '../../common/chatDebugService.js';
|
||||||
import { IChatService } from '../../common/chatService/chatService.js';
|
import { IChatService } from '../../common/chatService/chatService.js';
|
||||||
import { AGENT_DEBUG_LOG_ENABLED_SETTING } from '../../common/promptSyntax/promptTypes.js';
|
import { AGENT_DEBUG_LOG_ENABLED_SETTING } from '../../common/promptSyntax/promptTypes.js';
|
||||||
import { LocalChatSessionUri } from '../../common/model/chatUri.js';
|
import { getChatSessionType, isUntitledChatSession, LocalChatSessionUri } from '../../common/model/chatUri.js';
|
||||||
import { IChatWidgetService } from '../chat.js';
|
import { IChatWidgetService } from '../chat.js';
|
||||||
import { IPreferencesService } from '../../../../services/preferences/common/preferences.js';
|
import { IPreferencesService } from '../../../../services/preferences/common/preferences.js';
|
||||||
|
|
||||||
@@ -88,7 +88,12 @@ export class ChatDebugHomeView extends Disposable {
|
|||||||
// List sessions that have debug event data.
|
// List sessions that have debug event data.
|
||||||
// Use the debug service as the source of truth — it includes sessions
|
// Use the debug service as the source of truth — it includes sessions
|
||||||
// whose chat models may have been archived (e.g. when a new chat was started).
|
// whose chat models may have been archived (e.g. when a new chat was started).
|
||||||
const sessionResources = [...this.chatDebugService.getSessionResources()].reverse();
|
const cliSessionTypes = new Set(['copilotcli', 'claude-code']);
|
||||||
|
const sessionResources = [...this.chatDebugService.getSessionResources()].reverse()
|
||||||
|
// Hide untitled bootstrap sessions for CLI session types (e.g. copilotcli, claude-code).
|
||||||
|
// These are transient sessions created during async session setup that only contain
|
||||||
|
// a single "Load Hooks" event and would confuse users.
|
||||||
|
.filter(r => !cliSessionTypes.has(getChatSessionType(r)) || !isUntitledChatSession(r));
|
||||||
|
|
||||||
// Sort: active session first
|
// Sort: active session first
|
||||||
if (activeSessionResource) {
|
if (activeSessionResource) {
|
||||||
@@ -122,10 +127,14 @@ export class ChatDebugHomeView extends Disposable {
|
|||||||
sessionTitle = localize('chatDebug.newSession', "New Chat");
|
sessionTitle = localize('chatDebug.newSession', "New Chat");
|
||||||
} else if (importedTitle) {
|
} else if (importedTitle) {
|
||||||
sessionTitle = localize('chatDebug.importedSession', "Imported: {0}", importedTitle);
|
sessionTitle = localize('chatDebug.importedSession', "Imported: {0}", importedTitle);
|
||||||
} else if (sessionResource.scheme === 'copilotcli') {
|
} else if (getChatSessionType(sessionResource) === 'copilotcli') {
|
||||||
const pathId = sessionResource.path.replace(/^\//, '').split('-')[0];
|
const pathId = sessionResource.path.replace(/^\//, '').split('-')[0];
|
||||||
const shortId = pathId || sessionResource.authority || sessionResource.toString();
|
const shortId = pathId || sessionResource.authority || sessionResource.toString();
|
||||||
sessionTitle = localize('chatDebug.copilotCliSessionWithId', "Copilot CLI: {0}", shortId);
|
sessionTitle = localize('chatDebug.copilotCliSessionWithId', "Copilot CLI: {0}", shortId);
|
||||||
|
} else if (getChatSessionType(sessionResource) === 'claude-code') {
|
||||||
|
const pathId = sessionResource.path.replace(/^\//, '').split('-')[0];
|
||||||
|
const shortId = pathId || sessionResource.authority || sessionResource.toString();
|
||||||
|
sessionTitle = localize('chatDebug.claudeCodeSessionWithId', "Claude Code: {0}", shortId);
|
||||||
} else {
|
} else {
|
||||||
sessionTitle = localize('chatDebug.newSession', "New Chat");
|
sessionTitle = localize('chatDebug.newSession', "New Chat");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ export class ChatDebugServiceImpl extends Disposable implements IChatDebugServic
|
|||||||
private static readonly _debugEligibleSchemes = new Set([
|
private static readonly _debugEligibleSchemes = new Set([
|
||||||
LocalChatSessionUri.scheme, // vscode-chat-session (local sessions)
|
LocalChatSessionUri.scheme, // vscode-chat-session (local sessions)
|
||||||
'copilotcli', // Copilot CLI background sessions
|
'copilotcli', // Copilot CLI background sessions
|
||||||
|
'claude-code', // Claude Code CLI sessions
|
||||||
]);
|
]);
|
||||||
|
|
||||||
private _isDebugEligibleSession(sessionResource: URI): boolean {
|
private _isDebugEligibleSession(sessionResource: URI): boolean {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ suite('ChatDebugServiceImpl', () => {
|
|||||||
const sessionGeneric = URI.parse('vscode-chat-session://local/session');
|
const sessionGeneric = URI.parse('vscode-chat-session://local/session');
|
||||||
const nonLocalSession = URI.parse('some-other-scheme://authority/session-1');
|
const nonLocalSession = URI.parse('some-other-scheme://authority/session-1');
|
||||||
const copilotCliSession = URI.parse('copilotcli:/test-session-id');
|
const copilotCliSession = URI.parse('copilotcli:/test-session-id');
|
||||||
|
const claudeCodeSession = URI.parse('claude-code:/test-session-id');
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
service = disposables.add(new ChatDebugServiceImpl());
|
service = disposables.add(new ChatDebugServiceImpl());
|
||||||
@@ -168,6 +169,16 @@ suite('ChatDebugServiceImpl', () => {
|
|||||||
assert.strictEqual(firedEvents.length, 1);
|
assert.strictEqual(firedEvents.length, 1);
|
||||||
assert.strictEqual(service.getEvents(copilotCliSession).length, 1);
|
assert.strictEqual(service.getEvents(copilotCliSession).length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should log events for claude-code sessions', () => {
|
||||||
|
const firedEvents: IChatDebugEvent[] = [];
|
||||||
|
disposables.add(service.onDidAddEvent(e => firedEvents.push(e)));
|
||||||
|
|
||||||
|
service.log(claudeCodeSession, 'claude-event', 'details');
|
||||||
|
|
||||||
|
assert.strictEqual(firedEvents.length, 1);
|
||||||
|
assert.strictEqual(service.getEvents(claudeCodeSession).length, 1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
suite('getSessionResources', () => {
|
suite('getSessionResources', () => {
|
||||||
@@ -492,6 +503,29 @@ suite('ChatDebugServiceImpl', () => {
|
|||||||
assert.ok(service.getEvents(copilotCliSession).length > 0);
|
assert.ok(service.getEvents(copilotCliSession).length > 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should invoke providers for claude-code sessions', async () => {
|
||||||
|
let providerCalled = false;
|
||||||
|
|
||||||
|
const provider: IChatDebugLogProvider = {
|
||||||
|
provideChatDebugLog: async () => {
|
||||||
|
providerCalled = true;
|
||||||
|
return [{
|
||||||
|
kind: 'generic',
|
||||||
|
sessionResource: claudeCodeSession,
|
||||||
|
created: new Date(),
|
||||||
|
name: 'claude-provider-event',
|
||||||
|
level: ChatDebugLogLevel.Info,
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
disposables.add(service.registerProvider(provider));
|
||||||
|
await service.invokeProviders(claudeCodeSession);
|
||||||
|
|
||||||
|
assert.strictEqual(providerCalled, true);
|
||||||
|
assert.ok(service.getEvents(claudeCodeSession).length > 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('newly registered provider should be invoked for active sessions', async () => {
|
test('newly registered provider should be invoked for active sessions', async () => {
|
||||||
// Start an invocation before the provider is registered
|
// Start an invocation before the provider is registered
|
||||||
const firstProvider: IChatDebugLogProvider = {
|
const firstProvider: IChatDebugLogProvider = {
|
||||||
|
|||||||
Reference in New Issue
Block a user