@@ -14,6 +14,7 @@ import { isVscodeLanguageModelTool } from '../common/toolsRegistry';
1414import { IToolsService } from '../common/toolsService' ;
1515import { IToolGroupingCache , IToolGroupingService } from '../common/virtualTools/virtualToolTypes' ;
1616import '../node/allTools' ;
17+ import { extractSessionId } from '../node/memoryTool' ;
1718import './allTools' ;
1819
1920export class ToolsContribution extends Disposable {
@@ -52,21 +53,127 @@ export class ToolsContribution extends Disposable {
5253 vscode . window . showInformationMessage ( l10n . t ( 'Tool groups have been reset. They will be regenerated on the next agent request.' ) ) ;
5354 } ) ) ;
5455
55- this . _register ( vscode . commands . registerCommand ( 'github.copilot.chat.tools.memory.openFolder' , async ( ) => {
56+ this . _register ( vscode . commands . registerCommand ( 'github.copilot.chat.tools.memory.showMemories' , async ( ) => {
57+ const globalStorageUri = this . extensionContext . globalStorageUri ;
5658 const storageUri = this . extensionContext . storageUri ;
57- if ( ! storageUri ) {
58- vscode . window . showErrorMessage ( l10n . t ( 'No workspace is currently open. Memory operations require an active workspace.' ) ) ;
59+
60+ interface MemoryItem extends vscode . QuickPickItem {
61+ fileUri ?: URI ;
62+ }
63+
64+ const items : MemoryItem [ ] = [ ] ;
65+
66+ // Collect user-scoped memories from globalStorageUri/memory-tool/memories/
67+ if ( globalStorageUri ) {
68+ const userMemoryUri = URI . joinPath ( globalStorageUri , 'memory-tool/memories' ) ;
69+ try {
70+ const entries = await vscode . workspace . fs . readDirectory ( vscode . Uri . from ( userMemoryUri ) ) ;
71+ const fileEntries = entries . filter ( ( [ name , type ] ) => type === vscode . FileType . File && ! name . startsWith ( '.' ) ) ;
72+ if ( fileEntries . length > 0 ) {
73+ items . push ( { label : '/memories' , kind : vscode . QuickPickItemKind . Separator } ) ;
74+ for ( const [ name ] of fileEntries ) {
75+ items . push ( {
76+ label : `$(file) ${ name } ` ,
77+ description : 'user' ,
78+ fileUri : URI . joinPath ( userMemoryUri , name ) ,
79+ } ) ;
80+ }
81+ }
82+ } catch {
83+ // User memory directory may not exist yet
84+ }
85+ }
86+
87+ // Collect session-scoped memories from storageUri/memory-tool/memories/<sessionId>/
88+ const sessionResource = vscode . window . activeChatPanelSessionResource ;
89+ if ( storageUri && sessionResource ) {
90+ const sessionId = extractSessionId ( sessionResource . toString ( ) ) ;
91+ const sessionMemoryUri = URI . joinPath ( storageUri , 'memory-tool/memories' , sessionId ) ;
92+ try {
93+ const entries = await vscode . workspace . fs . readDirectory ( vscode . Uri . from ( sessionMemoryUri ) ) ;
94+ const fileEntries = entries . filter ( ( [ name , type ] ) => type === vscode . FileType . File && ! name . startsWith ( '.' ) ) ;
95+ if ( fileEntries . length > 0 ) {
96+ items . push ( { label : '/memories/session' , kind : vscode . QuickPickItemKind . Separator } ) ;
97+ for ( const [ name ] of fileEntries ) {
98+ items . push ( {
99+ label : `$(file) ${ name } ` ,
100+ description : 'session' ,
101+ fileUri : URI . joinPath ( sessionMemoryUri , name ) ,
102+ } ) ;
103+ }
104+ }
105+ } catch {
106+ // Session memory directory may not exist yet
107+ }
108+ }
109+
110+ if ( items . length === 0 ) {
111+ vscode . window . showInformationMessage ( l10n . t ( 'No memories found.' ) ) ;
59112 return ;
60113 }
61- const memoryFolderUri = URI . joinPath ( storageUri , 'memory-tool/memories' ) ;
62- try {
63- const stat = await vscode . workspace . fs . stat ( vscode . Uri . from ( memoryFolderUri ) ) ;
64- if ( stat . type === vscode . FileType . Directory ) {
65- return vscode . env . openExternal ( vscode . Uri . from ( memoryFolderUri ) ) ;
114+
115+ const selected = await vscode . window . showQuickPick ( items , {
116+ title : l10n . t ( 'Memory' ) ,
117+ placeHolder : l10n . t ( 'Select a memory file to view' ) ,
118+ } ) ;
119+
120+ if ( selected ?. fileUri ) {
121+ await vscode . commands . executeCommand ( 'vscode.open' , vscode . Uri . from ( selected . fileUri ) ) ;
122+ }
123+ } ) ) ;
124+
125+ this . _register ( vscode . commands . registerCommand ( 'github.copilot.chat.tools.memory.clearMemories' , async ( ) => {
126+ const confirm = await vscode . window . showWarningMessage (
127+ l10n . t ( 'Are you sure you want to clear all memories? This cannot be undone.' ) ,
128+ { modal : true } ,
129+ l10n . t ( 'Clear All' ) ,
130+ ) ;
131+ if ( confirm !== l10n . t ( 'Clear All' ) ) {
132+ return ;
133+ }
134+
135+ const globalStorageUri = this . extensionContext . globalStorageUri ;
136+ const storageUri = this . extensionContext . storageUri ;
137+ let hasError = false ;
138+ let hasDeleted = false ;
139+
140+ // Clear user-scoped memories
141+ if ( globalStorageUri ) {
142+ const userMemoryUri = URI . joinPath ( globalStorageUri , 'memory-tool/memories' ) ;
143+ try {
144+ await vscode . workspace . fs . delete ( vscode . Uri . from ( userMemoryUri ) , { recursive : true } ) ;
145+ hasDeleted = true ;
146+ } catch ( e ) {
147+ if ( e instanceof vscode . FileSystemError && e . code === 'FileNotFound' ) {
148+ // Nothing to delete
149+ } else {
150+ hasError = true ;
151+ }
66152 }
67- } catch {
68153 }
69- vscode . window . showInformationMessage ( l10n . t ( 'No memories have been saved yet. The memory folder will be created when the first memory is saved.' ) ) ;
154+
155+ // Clear all session memories
156+ if ( storageUri ) {
157+ const sessionMemoryUri = URI . joinPath ( storageUri , 'memory-tool/memories' ) ;
158+ try {
159+ await vscode . workspace . fs . delete ( vscode . Uri . from ( sessionMemoryUri ) , { recursive : true } ) ;
160+ hasDeleted = true ;
161+ } catch ( e ) {
162+ if ( e instanceof vscode . FileSystemError && e . code === 'FileNotFound' ) {
163+ // Nothing to delete
164+ } else {
165+ hasError = true ;
166+ }
167+ }
168+ }
169+
170+ if ( hasError ) {
171+ vscode . window . showErrorMessage ( l10n . t ( 'Some memories could not be cleared. Please try again.' ) ) ;
172+ } else if ( ! hasDeleted ) {
173+ vscode . window . showInformationMessage ( l10n . t ( 'No memories found.' ) ) ;
174+ } else {
175+ vscode . window . showInformationMessage ( l10n . t ( 'All memories have been cleared.' ) ) ;
176+ }
70177 } ) ) ;
71178
72179 this . _register ( autorun ( reader => {
0 commit comments