lanonasis-memory
Version:
Memory as a Service integration - AI-powered memory management with semantic search (Compatible with CLI v3.0.6+)
197 lines • 7.87 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryCompletionProvider = void 0;
const vscode = __importStar(require("vscode"));
class MemoryCompletionProvider {
constructor(memoryService) {
this.memoryService = memoryService;
this.cache = new Map();
this.cacheTimeout = 5 * 60 * 1000; // 5 minutes
}
async provideCompletionItems(document, position, _token, context) {
if (!this.memoryService.isAuthenticated()) {
return [];
}
// Get the current line and extract context
const line = document.lineAt(position);
const lineText = line.text.substring(0, position.character);
// Look for trigger characters and extract query
const query = this.extractQuery(lineText, context.triggerCharacter);
if (!query || query.length < 2) {
return [];
}
try {
const memories = await this.searchWithCache(query);
return this.createCompletionItems(memories, query, context.triggerCharacter, document.languageId);
}
catch (error) {
console.error('Memory completion error:', error);
return [];
}
}
extractQuery(lineText, triggerCharacter) {
if (!triggerCharacter) {
return '';
}
const lastTriggerIndex = lineText.lastIndexOf(triggerCharacter);
if (lastTriggerIndex === -1) {
return '';
}
return lineText.substring(lastTriggerIndex + 1).trim();
}
async searchWithCache(query) {
const cacheKey = query.toLowerCase();
const cached = this.cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
return cached.results;
}
const results = await this.memoryService.searchMemories(query, {
limit: 10,
threshold: 0.6
});
this.cache.set(cacheKey, {
results,
timestamp: Date.now()
});
// Clean old cache entries
this.cleanCache();
return results;
}
cleanCache() {
const now = Date.now();
for (const [key, value] of this.cache.entries()) {
if (now - value.timestamp > this.cacheTimeout) {
this.cache.delete(key);
}
}
}
createCompletionItems(memories, _query, triggerCharacter, languageId = 'typescript') {
return memories.map((memory, index) => {
const item = new vscode.CompletionItem(memory.title, vscode.CompletionItemKind.Snippet);
// Create different insertion text based on trigger character
let insertText;
let documentation;
switch (triggerCharacter) {
case '@':
// For @mentions, insert a reference
insertText = `@memory:${memory.id} (${memory.title})`;
documentation = `**Memory Reference**\n\n${memory.content.substring(0, 300)}${memory.content.length > 300 ? '...' : ''}`;
break;
case '#':
// For #tags, insert memory content as a comment block
insertText = this.formatAsComment(memory, languageId);
documentation = `**Insert Memory as Comment**\n\n${memory.content}`;
break;
case '//':
// For // comments, insert relevant memory snippet
insertText = this.formatAsSnippet(memory);
documentation = `**Code Snippet from Memory**\n\n${memory.content}`;
break;
default:
insertText = memory.content;
documentation = memory.content;
}
item.insertText = insertText;
item.documentation = new vscode.MarkdownString(documentation);
item.detail = `${memory.memory_type} • ${new Date(memory.created_at).toLocaleDateString()} • Score: ${Math.round(memory.similarity_score * 100)}%`;
// Add tags to filter text for better search
item.filterText = `${memory.title} ${memory.tags?.join(' ')} ${memory.memory_type}`;
// Sort by relevance score
item.sortText = String(1 - memory.similarity_score).padStart(5, '0') + String(index).padStart(3, '0');
// Add command to open full memory
item.command = {
command: 'lanonasis.openMemory',
title: 'Open Memory',
arguments: [memory]
};
return item;
});
}
formatAsComment(memory, languageId) {
const commentPrefix = this.getCommentPrefix(languageId);
const lines = memory.content.split('\n');
return lines.map(line => `${commentPrefix} ${line}`).join('\n');
}
formatAsSnippet(memory) {
// Try to extract code blocks from memory content
const codeBlockRegex = /```[\s\S]*?```/g;
const codeBlocks = memory.content.match(codeBlockRegex);
if (codeBlocks && codeBlocks.length > 0) {
// Return the first code block without markdown formatting
return codeBlocks[0].replace(/```\w*\n?/g, '').replace(/```$/g, '');
}
// If no code blocks, return content with some formatting
return memory.content.substring(0, 500);
}
getCommentPrefix(languageId) {
const commentPrefixes = {
'javascript': '//',
'typescript': '//',
'java': '//',
'c': '//',
'cpp': '//',
'csharp': '//',
'go': '//',
'rust': '//',
'swift': '//',
'kotlin': '//',
'scala': '//',
'python': '#',
'ruby': '#',
'perl': '#',
'shell': '#',
'bash': '#',
'powershell': '#',
'yaml': '#',
'dockerfile': '#',
'html': '<!--',
'xml': '<!--',
'css': '/*',
'scss': '//',
'less': '//',
'sql': '--',
'lua': '--',
'vim': '"',
'r': '#'
};
return commentPrefixes[languageId] || '//';
}
resolveCompletionItem(item, _token) {
return item;
}
}
exports.MemoryCompletionProvider = MemoryCompletionProvider;
//# sourceMappingURL=MemoryCompletionProvider.js.map