UNPKG

semem

Version:

Semantic Memory for Intelligent Agents

163 lines (144 loc) 5.44 kB
import BaseAPI from '../common/BaseAPI.js' import APIRegistry from '../common/APIRegistry.js' import { logger } from '../../Utils.js' export default class ActiveHandler extends BaseAPI { constructor(config = {}) { super(config) this.registry = new APIRegistry() this.contextWindow = config.contextWindow || 3 this.similarityThreshold = config.similarityThreshold || 40 } async executeOperation(operation, params) { switch (operation) { case 'interact': return this.handleInteraction(params) case 'search': return this.handleSearch(params) case 'analyze': return this.handleAnalysis(params) default: throw new Error(`Unknown operation: ${operation}`) } } async handleInteraction({ prompt, context = [], options = {} }) { try { const memoryManager = this.registry.get('memory') const passive = this.registry.get('passive') // Get relevant past interactions const retrievals = await memoryManager.retrieveRelevantInteractions( prompt, this.similarityThreshold ) // Generate response using chat const response = await passive.executeOperation('chat', { prompt, context: this._buildContext(context, retrievals), ...options }) // Store interaction const embedding = await memoryManager.generateEmbedding( `${prompt} ${response}` ) const concepts = await memoryManager.extractConcepts( `${prompt} ${response}` ) await memoryManager.addInteraction(prompt, response, embedding, concepts) this._emitMetric('interaction.count', 1) return { response, concepts, retrievals } } catch (error) { this._emitMetric('interaction.errors', 1) throw error } } async handleSearch({ query, type = 'semantic', limit = 10 }) { try { const memoryManager = this.registry.get('memory') const passive = this.registry.get('passive') let results if (type === 'semantic') { const embedding = await memoryManager.generateEmbedding(query) results = await memoryManager.retrieveRelevantInteractions( query, this.similarityThreshold, 0, limit ) } else { results = await passive.executeOperation('query', { sparql: this._buildSearchQuery(query, limit) }) } this._emitMetric('search.count', 1) return results } catch (error) { this._emitMetric('search.errors', 1) throw error } } async handleAnalysis({ content, type = 'concept' }) { try { const memoryManager = this.registry.get('memory') let results switch (type) { case 'concept': results = await memoryManager.extractConcepts(content) break case 'embedding': results = await memoryManager.generateEmbedding(content) break default: throw new Error(`Unknown analysis type: ${type}`) } this._emitMetric('analysis.count', 1) return results } catch (error) { this._emitMetric('analysis.errors', 1) throw error } } _buildContext(context, retrievals) { return { previous: context.slice(-this.contextWindow), relevant: retrievals .slice(0, this.contextWindow) .map(r => ({ prompt: r.interaction.prompt, response: r.interaction.output })) } } _buildSearchQuery(query, limit) { return ` PREFIX semem: <http://purl.org/stuff/semem/> SELECT ?interaction ?prompt ?output ?timestamp WHERE { ?interaction a semem:Interaction ; semem:prompt ?prompt ; semem:output ?output ; semem:timestamp ?timestamp . FILTER(CONTAINS(LCASE(?prompt), LCASE("${query}")) || CONTAINS(LCASE(?output), LCASE("${query}"))) } ORDER BY DESC(?timestamp) LIMIT ${limit} ` } async getMetrics() { const baseMetrics = await super.getMetrics() return { ...baseMetrics, operations: { interaction: await this._getOperationMetrics('interaction'), search: await this._getOperationMetrics('search'), analysis: await this._getOperationMetrics('analysis') } } } async _getOperationMetrics(operation) { return { count: await this._getMetricValue(`${operation}.count`), errors: await this._getMetricValue(`${operation}.errors`), latency: await this._getMetricValue(`${operation}.latency`) } } }