Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,64 @@
]
}
},
{
"displayName": "%copilot.tools.memory.name%",
"name": "copilot_memory",
"tags": [],
"canBeReferencedInPrompt": true,
"toolReferenceName": "memory",
"modelDescription": "Store, search, and manage persistent memory across chat sessions. This tool allows you to save important information, retrieve relevant context, and maintain continuity across conversations. Use this tool to:\n\n1. Store important user preferences, facts, or context\n2. Search for previously stored information\n3. List existing memories\n4. Store conversation summaries for later reference\n5. Delete outdated or incorrect memories\n\nMemories persist across chat sessions and can include tags for better organization.",
"inputSchema": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"store",
"search",
"list",
"delete",
"storeConversation"
],
"description": "The action to perform with memory"
},
"content": {
"type": "string",
"description": "Content to store (required for store action)"
},
"query": {
"type": "string",
"description": "Search query (required for search action)"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags to associate with memory or filter by"
},
"memoryId": {
"type": "string",
"description": "Memory ID (required for delete action)"
},
"maxResults": {
"type": "number",
"description": "Maximum number of results to return (default: 10)"
},
"conversationSummary": {
"type": "string",
"description": "Summary of conversation to store"
},
"conversationContext": {
"type": "string",
"description": "Additional context about the conversation"
}
},
"required": [
"action"
]
}
},
{
"name": "copilot_findFiles",
"toolReferenceName": "fileSearch",
Expand Down Expand Up @@ -2283,6 +2341,11 @@
"terminal"
]
},
"copilot.memoryStoragePath": {
"type": "string",
"default": "",
"description": "Optional path or file:// URI to store Copilot memories (including embeddings). If empty, uses workspace storage or extension global storage. Can be an absolute path or file URI. Relative paths are resolved against the first workspace folder if present."
},
"github.copilot.chat.scopeSelection": {
"type": "boolean",
"default": false,
Expand Down
3 changes: 3 additions & 0 deletions src/extension/extension/vscode-node/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ import { IWorkspaceListenerService } from '../../workspaceRecorder/common/worksp
import { WorkspacListenerService } from '../../workspaceRecorder/vscode-node/workspaceListenerService';
import { registerServices as registerCommonServices } from '../vscode/services';
import { NativeEnvServiceImpl } from '../../../platform/env/vscode-node/nativeEnvServiceImpl';
import { IMemoryService } from '../../memory/common/memoryService';
import { MemoryServiceImpl } from '../../memory/node/memoryServiceImpl';

// ###########################################################################################
// ### ###
Expand Down Expand Up @@ -195,6 +197,7 @@ export function registerServices(builder: IInstantiationServiceBuilder, extensio
builder.define(IWorkspaceListenerService, new SyncDescriptor(WorkspacListenerService));
builder.define(ICodeSearchAuthenticationService, new SyncDescriptor(VsCodeCodeSearchAuthenticationService));
builder.define(ITodoListContextProvider, new SyncDescriptor(TodoListContextProvider));
builder.define(IMemoryService, new SyncDescriptor(MemoryServiceImpl));
}

function setupMSFTExperimentationService(builder: IInstantiationServiceBuilder, extensionContext: ExtensionContext) {
Expand Down
102 changes: 102 additions & 0 deletions src/extension/memory/common/memoryService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { createDecorator } from '../../../util/vs/platform/instantiation/common/instantiation';
import { Embedding } from '../../../platform/embeddings/common/embeddingsComputer';

export interface IMemoryItem {
id: string;
content: string;
tags: string[];
timestamp: Date;
source: string;
embedding?: Embedding;
metadata?: Record<string, any>;
}

export interface IMemorySearchOptions {
maxResults?: number;
tags?: string[];
semanticSearch?: boolean;
textSearch?: boolean;
threshold?: number;
dateRange?: {
start?: Date;
end?: Date;
};
}

export interface IMemorySearchResult {
memory: IMemoryItem;
similarity: number;
matchType: 'semantic' | 'text' | 'tag';
}

export interface IMemoryListOptions {
tags?: string[];
limit?: number;
offset?: number;
sortBy?: 'timestamp' | 'content' | 'relevance';
sortOrder?: 'asc' | 'desc';
}

export interface IMemoryStoreOptions {
generateEmbedding?: boolean;
metadata?: Record<string, any>;
}

export const IMemoryService = createDecorator<IMemoryService>('memoryService');

export interface IMemoryService {
/**
* Store a new memory item
*/
storeMemory(memory: Omit<IMemoryItem, 'id' | 'embedding'>, options?: IMemoryStoreOptions): Promise<IMemoryItem>;

/**
* Search memories using semantic and/or text search
*/
searchMemories(query: string, options?: IMemorySearchOptions): Promise<IMemorySearchResult[]>;

/**
* List memories with filtering and sorting
*/
listMemories(options?: IMemoryListOptions): Promise<IMemoryItem[]>;

/**
* Get a specific memory by ID
*/
getMemory(id: string): Promise<IMemoryItem | undefined>;

/**
* Update an existing memory
*/
updateMemory(id: string, updates: Partial<Omit<IMemoryItem, 'id'>>): Promise<IMemoryItem>;

/**
* Delete a memory
*/
deleteMemory(id: string): Promise<void>;

/**
* Get all unique tags
*/
getTags(): Promise<string[]>;

/**
* Clear all memories (with optional tag filter)
*/
clearMemories(tags?: string[]): Promise<void>;

/**
* Export memories to a format (JSON, markdown, etc.)
*/
exportMemories(format: 'json' | 'markdown', options?: IMemoryListOptions): Promise<string>;

/**
* Import memories from a format
*/
importMemories(data: string, format: 'json' | 'markdown'): Promise<IMemoryItem[]>;
}
Loading