confused-ai-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/FEATURES.md +169 -0
  2. package/package.json +119 -0
  3. package/src/agent.ts +187 -0
  4. package/src/agentic/index.ts +87 -0
  5. package/src/agentic/runner.ts +386 -0
  6. package/src/agentic/types.ts +91 -0
  7. package/src/artifacts/artifact.ts +417 -0
  8. package/src/artifacts/index.ts +42 -0
  9. package/src/artifacts/media.ts +304 -0
  10. package/src/cli/index.ts +122 -0
  11. package/src/core/base-agent.ts +151 -0
  12. package/src/core/context-builder.ts +106 -0
  13. package/src/core/index.ts +8 -0
  14. package/src/core/schemas.ts +17 -0
  15. package/src/core/types.ts +158 -0
  16. package/src/create-agent.ts +309 -0
  17. package/src/debug-logger.ts +188 -0
  18. package/src/dx/agent.ts +88 -0
  19. package/src/dx/define-agent.ts +183 -0
  20. package/src/dx/dev-logger.ts +57 -0
  21. package/src/dx/index.ts +11 -0
  22. package/src/errors.ts +175 -0
  23. package/src/execution/engine.ts +522 -0
  24. package/src/execution/graph-builder.ts +362 -0
  25. package/src/execution/index.ts +8 -0
  26. package/src/execution/types.ts +257 -0
  27. package/src/execution/worker-pool.ts +308 -0
  28. package/src/extensions/index.ts +123 -0
  29. package/src/guardrails/allowlist.ts +155 -0
  30. package/src/guardrails/index.ts +17 -0
  31. package/src/guardrails/types.ts +159 -0
  32. package/src/guardrails/validator.ts +265 -0
  33. package/src/index.ts +74 -0
  34. package/src/knowledge/index.ts +5 -0
  35. package/src/knowledge/types.ts +52 -0
  36. package/src/learning/in-memory-store.ts +72 -0
  37. package/src/learning/index.ts +6 -0
  38. package/src/learning/types.ts +42 -0
  39. package/src/llm/cache.ts +300 -0
  40. package/src/llm/index.ts +22 -0
  41. package/src/llm/model-resolver.ts +81 -0
  42. package/src/llm/openai-provider.ts +313 -0
  43. package/src/llm/openrouter-provider.ts +29 -0
  44. package/src/llm/types.ts +131 -0
  45. package/src/memory/in-memory-store.ts +255 -0
  46. package/src/memory/index.ts +7 -0
  47. package/src/memory/types.ts +193 -0
  48. package/src/memory/vector-store.ts +251 -0
  49. package/src/observability/console-logger.ts +123 -0
  50. package/src/observability/index.ts +12 -0
  51. package/src/observability/metrics.ts +85 -0
  52. package/src/observability/otlp-exporter.ts +417 -0
  53. package/src/observability/tracer.ts +105 -0
  54. package/src/observability/types.ts +341 -0
  55. package/src/orchestration/agent-adapter.ts +33 -0
  56. package/src/orchestration/index.ts +34 -0
  57. package/src/orchestration/load-balancer.ts +151 -0
  58. package/src/orchestration/mcp-types.ts +59 -0
  59. package/src/orchestration/message-bus.ts +192 -0
  60. package/src/orchestration/orchestrator.ts +349 -0
  61. package/src/orchestration/pipeline.ts +66 -0
  62. package/src/orchestration/supervisor.ts +107 -0
  63. package/src/orchestration/swarm.ts +1099 -0
  64. package/src/orchestration/toolkit.ts +47 -0
  65. package/src/orchestration/types.ts +339 -0
  66. package/src/planner/classical-planner.ts +383 -0
  67. package/src/planner/index.ts +8 -0
  68. package/src/planner/llm-planner.ts +353 -0
  69. package/src/planner/types.ts +227 -0
  70. package/src/planner/validator.ts +297 -0
  71. package/src/production/circuit-breaker.ts +290 -0
  72. package/src/production/graceful-shutdown.ts +251 -0
  73. package/src/production/health.ts +333 -0
  74. package/src/production/index.ts +57 -0
  75. package/src/production/latency-eval.ts +62 -0
  76. package/src/production/rate-limiter.ts +287 -0
  77. package/src/production/resumable-stream.ts +289 -0
  78. package/src/production/types.ts +81 -0
  79. package/src/sdk/index.ts +374 -0
  80. package/src/session/db-driver.ts +50 -0
  81. package/src/session/in-memory-store.ts +235 -0
  82. package/src/session/index.ts +12 -0
  83. package/src/session/sql-store.ts +315 -0
  84. package/src/session/sqlite-store.ts +61 -0
  85. package/src/session/types.ts +153 -0
  86. package/src/tools/base-tool.ts +223 -0
  87. package/src/tools/browser-tool.ts +123 -0
  88. package/src/tools/calculator-tool.ts +265 -0
  89. package/src/tools/file-tools.ts +394 -0
  90. package/src/tools/github-tool.ts +432 -0
  91. package/src/tools/hackernews-tool.ts +187 -0
  92. package/src/tools/http-tool.ts +118 -0
  93. package/src/tools/index.ts +99 -0
  94. package/src/tools/jira-tool.ts +373 -0
  95. package/src/tools/notion-tool.ts +322 -0
  96. package/src/tools/openai-tool.ts +236 -0
  97. package/src/tools/registry.ts +131 -0
  98. package/src/tools/serpapi-tool.ts +234 -0
  99. package/src/tools/shell-tool.ts +118 -0
  100. package/src/tools/slack-tool.ts +327 -0
  101. package/src/tools/telegram-tool.ts +127 -0
  102. package/src/tools/types.ts +229 -0
  103. package/src/tools/websearch-tool.ts +335 -0
  104. package/src/tools/wikipedia-tool.ts +177 -0
  105. package/src/tools/yfinance-tool.ts +33 -0
  106. package/src/voice/index.ts +17 -0
  107. package/src/voice/voice-provider.ts +228 -0
  108. package/tests/artifact.test.ts +241 -0
  109. package/tests/circuit-breaker.test.ts +171 -0
  110. package/tests/health.test.ts +192 -0
  111. package/tests/llm-cache.test.ts +186 -0
  112. package/tests/rate-limiter.test.ts +161 -0
  113. package/tsconfig.json +29 -0
  114. package/vitest.config.ts +47 -0
@@ -0,0 +1,255 @@
1
+ /**
2
+ * In-memory memory store implementation
3
+ */
4
+
5
+ import {
6
+ MemoryStore,
7
+ MemoryEntry,
8
+ MemoryQuery,
9
+ MemoryFilter,
10
+ MemoryType,
11
+ MemorySearchResult,
12
+ MemoryStoreConfig,
13
+ } from './types.js';
14
+ import type { EntityId } from '../core/types.js';
15
+ import { DebugLogger, createDebugLogger } from '../debug-logger.js';
16
+
17
+ /**
18
+ * Default configuration for in-memory store
19
+ */
20
+ const DEFAULT_CONFIG: Required<MemoryStoreConfig> = {
21
+ maxShortTermEntries: 100,
22
+ defaultQueryLimit: 10,
23
+ similarityThreshold: 0.7,
24
+ embeddingDimension: 1536,
25
+ debug: false,
26
+ };
27
+
28
+ /**
29
+ * In-memory implementation of MemoryStore
30
+ * Suitable for development and testing
31
+ */
32
+ export class InMemoryStore implements MemoryStore {
33
+ private memories: Map<EntityId, MemoryEntry> = new Map();
34
+ private config: Required<MemoryStoreConfig>;
35
+ private logger: DebugLogger;
36
+
37
+ constructor(config: MemoryStoreConfig = {}) {
38
+ this.config = { ...DEFAULT_CONFIG, ...config };
39
+ this.logger = createDebugLogger('MemoryStore', this.config.debug);
40
+ this.logger.debug('InMemoryStore initialized', undefined, this.config);
41
+ }
42
+
43
+ async store(entry: Omit<MemoryEntry, 'id' | 'createdAt'>): Promise<MemoryEntry> {
44
+ const id = this.generateId();
45
+ const createdAt = new Date();
46
+
47
+ const fullEntry: MemoryEntry = {
48
+ ...entry,
49
+ id,
50
+ createdAt,
51
+ };
52
+
53
+ this.memories.set(id, fullEntry);
54
+ this.logger.debug('Stored memory entry', undefined, {
55
+ id,
56
+ type: entry.type,
57
+ tags: entry.metadata.tags,
58
+ agentId: entry.metadata.agentId,
59
+ sessionId: entry.metadata.sessionId,
60
+ });
61
+
62
+ // Enforce short-term memory limits
63
+ if (entry.type === MemoryType.SHORT_TERM) {
64
+ this.enforceShortTermLimit();
65
+ }
66
+
67
+ return fullEntry;
68
+ }
69
+
70
+ async retrieve(query: MemoryQuery): Promise<MemorySearchResult[]> {
71
+ const limit = query.limit ?? this.config.defaultQueryLimit;
72
+ const threshold = query.threshold ?? this.config.similarityThreshold;
73
+
74
+ let entries = Array.from(this.memories.values());
75
+
76
+ // Filter by type
77
+ if (query.type) {
78
+ entries = entries.filter(e => e.type === query.type);
79
+ }
80
+
81
+ // Apply filters
82
+ if (query.filter) {
83
+ entries = this.applyFilter(entries, query.filter);
84
+ }
85
+
86
+ // Calculate similarity scores (simplified - just keyword matching for in-memory)
87
+ const scored = entries.map(entry => ({
88
+ entry,
89
+ score: this.calculateSimilarity(query.query, entry.content),
90
+ }));
91
+
92
+ // Filter by threshold and sort by score
93
+ const results = scored
94
+ .filter(r => r.score >= threshold)
95
+ .sort((a, b) => b.score - a.score)
96
+ .slice(0, limit);
97
+
98
+ this.logger.debug('Retrieved memory results', undefined, {
99
+ query: query.query.slice(0, 50),
100
+ type: query.type,
101
+ filter: query.filter,
102
+ totalMatches: results.length,
103
+ limit: limit,
104
+ threshold: threshold,
105
+ });
106
+
107
+ return results;
108
+ }
109
+
110
+ async get(id: EntityId): Promise<MemoryEntry | null> {
111
+ const entry = this.memories.get(id) ?? null;
112
+ if (entry) {
113
+ this.logger.debug('Retrieved memory entry', undefined, { id, type: entry.type });
114
+ } else {
115
+ this.logger.debug('Memory entry not found', undefined, { id });
116
+ }
117
+ return entry;
118
+ }
119
+
120
+ async update(
121
+ id: EntityId,
122
+ updates: Partial<Omit<MemoryEntry, 'id' | 'createdAt'>>
123
+ ): Promise<MemoryEntry> {
124
+ const existing = this.memories.get(id);
125
+ if (!existing) {
126
+ throw new Error(`Memory entry not found: ${id}`);
127
+ }
128
+
129
+ const updated: MemoryEntry = {
130
+ ...existing,
131
+ ...updates,
132
+ id: existing.id,
133
+ createdAt: existing.createdAt,
134
+ };
135
+
136
+ this.memories.set(id, updated);
137
+ return updated;
138
+ }
139
+
140
+ async delete(id: EntityId): Promise<boolean> {
141
+ return this.memories.delete(id);
142
+ }
143
+
144
+ async clear(type?: MemoryType): Promise<void> {
145
+ if (type) {
146
+ for (const [id, entry] of this.memories) {
147
+ if (entry.type === type) {
148
+ this.memories.delete(id);
149
+ }
150
+ }
151
+ } else {
152
+ this.memories.clear();
153
+ }
154
+ }
155
+
156
+ async getRecent(limit: number, type?: MemoryType): Promise<MemoryEntry[]> {
157
+ let entries = Array.from(this.memories.values());
158
+
159
+ if (type) {
160
+ entries = entries.filter(e => e.type === type);
161
+ }
162
+
163
+ return entries
164
+ .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
165
+ .slice(0, limit);
166
+ }
167
+
168
+ async snapshot(): Promise<MemoryEntry[]> {
169
+ return Array.from(this.memories.values());
170
+ }
171
+
172
+ /**
173
+ * Get the number of stored memories
174
+ */
175
+ size(): number {
176
+ return this.memories.size;
177
+ }
178
+
179
+ /**
180
+ * Generate a unique ID
181
+ */
182
+ private generateId(): EntityId {
183
+ return `mem-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
184
+ }
185
+
186
+ /**
187
+ * Apply filter to memory entries
188
+ */
189
+ private applyFilter(entries: MemoryEntry[], filter: MemoryFilter): MemoryEntry[] {
190
+ return entries.filter(entry => {
191
+ if (filter.tags && filter.tags.length > 0) {
192
+ const entryTags = entry.metadata.tags ?? [];
193
+ if (!filter.tags.some(tag => entryTags.includes(tag))) {
194
+ return false;
195
+ }
196
+ }
197
+
198
+ if (filter.source && entry.metadata.source !== filter.source) {
199
+ return false;
200
+ }
201
+
202
+ if (filter.agentId && entry.metadata.agentId !== filter.agentId) {
203
+ return false;
204
+ }
205
+
206
+ if (filter.sessionId && entry.metadata.sessionId !== filter.sessionId) {
207
+ return false;
208
+ }
209
+
210
+ if (filter.before && entry.createdAt > filter.before) {
211
+ return false;
212
+ }
213
+
214
+ if (filter.after && entry.createdAt < filter.after) {
215
+ return false;
216
+ }
217
+
218
+ return true;
219
+ });
220
+ }
221
+
222
+ /**
223
+ * Calculate simple similarity score between query and content
224
+ * In production, use proper embeddings
225
+ */
226
+ private calculateSimilarity(query: string, content: string): number {
227
+ const queryWords = query.toLowerCase().split(/\s+/);
228
+ const contentWords = content.toLowerCase().split(/\s+/);
229
+
230
+ let matches = 0;
231
+ for (const word of queryWords) {
232
+ if (contentWords.some(cw => cw.includes(word) || word.includes(cw))) {
233
+ matches++;
234
+ }
235
+ }
236
+
237
+ return matches / Math.max(queryWords.length, 1);
238
+ }
239
+
240
+ /**
241
+ * Enforce short-term memory entry limit
242
+ */
243
+ private enforceShortTermLimit(): void {
244
+ const shortTermEntries = Array.from(this.memories.values())
245
+ .filter(e => e.type === MemoryType.SHORT_TERM)
246
+ .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
247
+
248
+ const excess = shortTermEntries.length - this.config.maxShortTermEntries;
249
+ if (excess > 0) {
250
+ for (let i = 0; i < excess; i++) {
251
+ this.memories.delete(shortTermEntries[i].id);
252
+ }
253
+ }
254
+ }
255
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Memory module exports
3
+ */
4
+
5
+ export * from './types.js';
6
+ export { InMemoryStore } from './in-memory-store.js';
7
+ export { VectorMemoryStore } from './vector-store.js';
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Memory store types and interfaces
3
+ */
4
+
5
+ import type { EntityId } from '../core/types.js';
6
+
7
+ /**
8
+ * Types of memory supported
9
+ */
10
+ export enum MemoryType {
11
+ SHORT_TERM = 'short_term',
12
+ LONG_TERM = 'long_term',
13
+ EPISODIC = 'episodic',
14
+ SEMANTIC = 'semantic',
15
+ }
16
+
17
+ /**
18
+ * A memory entry
19
+ */
20
+ export interface MemoryEntry {
21
+ readonly id: EntityId;
22
+ readonly type: MemoryType;
23
+ readonly content: string;
24
+ readonly embedding?: number[];
25
+ readonly metadata: MemoryMetadata;
26
+ readonly createdAt: Date;
27
+ readonly expiresAt?: Date;
28
+ }
29
+
30
+ /**
31
+ * Metadata for memory entries
32
+ */
33
+ export interface MemoryMetadata {
34
+ readonly source?: string;
35
+ readonly importance?: number;
36
+ readonly tags?: string[];
37
+ readonly agentId?: EntityId;
38
+ readonly sessionId?: string;
39
+ readonly custom?: Record<string, unknown>;
40
+ }
41
+
42
+ /**
43
+ * Query options for memory retrieval
44
+ */
45
+ export interface MemoryQuery {
46
+ readonly query: string;
47
+ readonly type?: MemoryType;
48
+ readonly limit?: number;
49
+ readonly threshold?: number;
50
+ readonly filter?: MemoryFilter;
51
+ readonly includeEmbeddings?: boolean;
52
+ }
53
+
54
+ /**
55
+ * Filter for memory queries
56
+ */
57
+ export interface MemoryFilter {
58
+ readonly tags?: string[];
59
+ readonly source?: string;
60
+ readonly agentId?: EntityId;
61
+ readonly sessionId?: string;
62
+ readonly before?: Date;
63
+ readonly after?: Date;
64
+ readonly custom?: Record<string, unknown>;
65
+ }
66
+
67
+ /**
68
+ * Configuration for memory store
69
+ */
70
+ export interface MemoryStoreConfig {
71
+ readonly maxShortTermEntries?: number;
72
+ readonly defaultQueryLimit?: number;
73
+ readonly similarityThreshold?: number;
74
+ readonly embeddingDimension?: number;
75
+ /** Enable debug logging */
76
+ readonly debug?: boolean;
77
+ }
78
+
79
+ /**
80
+ * Result from memory search
81
+ */
82
+ export interface MemorySearchResult {
83
+ readonly entry: MemoryEntry;
84
+ readonly score: number;
85
+ }
86
+
87
+ /**
88
+ * Abstract memory store interface
89
+ */
90
+ export interface MemoryStore {
91
+ /**
92
+ * Store a new memory entry
93
+ */
94
+ store(entry: Omit<MemoryEntry, 'id' | 'createdAt'>): Promise<MemoryEntry>;
95
+
96
+ /**
97
+ * Retrieve memories by query (semantic search)
98
+ */
99
+ retrieve(query: MemoryQuery): Promise<MemorySearchResult[]>;
100
+
101
+ /**
102
+ * Get a specific memory by ID
103
+ */
104
+ get(id: EntityId): Promise<MemoryEntry | null>;
105
+
106
+ /**
107
+ * Update an existing memory
108
+ */
109
+ update(id: EntityId, updates: Partial<Omit<MemoryEntry, 'id' | 'createdAt'>>): Promise<MemoryEntry>;
110
+
111
+ /**
112
+ * Delete a memory by ID
113
+ */
114
+ delete(id: EntityId): Promise<boolean>;
115
+
116
+ /**
117
+ * Clear all memories (optionally filtered by type)
118
+ */
119
+ clear(type?: MemoryType): Promise<void>;
120
+
121
+ /**
122
+ * Get recent memories
123
+ */
124
+ getRecent(limit: number, type?: MemoryType): Promise<MemoryEntry[]>;
125
+
126
+ /**
127
+ * Create a snapshot of current memories
128
+ */
129
+ snapshot(): Promise<MemoryEntry[]>;
130
+ }
131
+
132
+ /**
133
+ * Embedding provider interface for vector operations
134
+ */
135
+ export interface EmbeddingProvider {
136
+ /**
137
+ * Generate embeddings for text
138
+ */
139
+ embed(text: string): Promise<number[]>;
140
+
141
+ /**
142
+ * Generate embeddings for multiple texts
143
+ */
144
+ embedBatch(texts: string[]): Promise<number[][]>;
145
+
146
+ /**
147
+ * Get the dimension of embeddings
148
+ */
149
+ getDimension(): number;
150
+ }
151
+
152
+ /**
153
+ * Vector store adapter interface
154
+ */
155
+ export interface VectorStoreAdapter {
156
+ /**
157
+ * Store vectors with metadata
158
+ */
159
+ upsert(vectors: VectorEntry[]): Promise<void>;
160
+
161
+ /**
162
+ * Search for similar vectors
163
+ */
164
+ search(query: number[], limit: number, filter?: Record<string, unknown>): Promise<VectorSearchResult[]>;
165
+
166
+ /**
167
+ * Delete vectors by ID
168
+ */
169
+ delete(ids: EntityId[]): Promise<void>;
170
+
171
+ /**
172
+ * Clear all vectors
173
+ */
174
+ clear(): Promise<void>;
175
+ }
176
+
177
+ /**
178
+ * Vector entry for storage
179
+ */
180
+ export interface VectorEntry {
181
+ readonly id: EntityId;
182
+ readonly vector: number[];
183
+ readonly metadata: Record<string, unknown>;
184
+ }
185
+
186
+ /**
187
+ * Vector search result
188
+ */
189
+ export interface VectorSearchResult {
190
+ readonly id: EntityId;
191
+ readonly score: number;
192
+ readonly metadata: Record<string, unknown>;
193
+ }
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Vector-based memory store implementation
3
+ */
4
+
5
+ import {
6
+ MemoryStore,
7
+ MemoryEntry,
8
+ MemoryQuery,
9
+ MemoryFilter,
10
+ MemoryType,
11
+ MemorySearchResult,
12
+ MemoryStoreConfig,
13
+ VectorStoreAdapter,
14
+ EmbeddingProvider,
15
+ } from './types.js';
16
+ import type { EntityId } from '../core/types.js';
17
+
18
+ /**
19
+ * Configuration for vector memory store
20
+ */
21
+ export interface VectorMemoryStoreConfig extends MemoryStoreConfig {
22
+ vectorStore: VectorStoreAdapter;
23
+ embeddingProvider: EmbeddingProvider;
24
+ }
25
+
26
+ /**
27
+ * Vector-based memory store using external vector database
28
+ */
29
+ export class VectorMemoryStore implements MemoryStore {
30
+ private config: Required<MemoryStoreConfig>;
31
+ private vectorStore: VectorStoreAdapter;
32
+ private embeddingProvider: EmbeddingProvider;
33
+ private entryCache: Map<EntityId, MemoryEntry> = new Map();
34
+
35
+ constructor(config: VectorMemoryStoreConfig) {
36
+ this.vectorStore = config.vectorStore;
37
+ this.embeddingProvider = config.embeddingProvider;
38
+ this.config = {
39
+ maxShortTermEntries: config.maxShortTermEntries ?? 100,
40
+ defaultQueryLimit: config.defaultQueryLimit ?? 10,
41
+ similarityThreshold: config.similarityThreshold ?? 0.7,
42
+ embeddingDimension: config.embeddingDimension ?? this.embeddingProvider.getDimension(),
43
+ debug: config.debug ?? false,
44
+ };
45
+ }
46
+
47
+ async store(entry: Omit<MemoryEntry, 'id' | 'createdAt'>): Promise<MemoryEntry> {
48
+ const id = this.generateId();
49
+ const createdAt = new Date();
50
+
51
+ // Generate embedding for the content
52
+ const embedding = await this.embeddingProvider.embed(entry.content);
53
+
54
+ const fullEntry: MemoryEntry = {
55
+ ...entry,
56
+ id,
57
+ createdAt,
58
+ embedding,
59
+ };
60
+
61
+ // Store in vector database
62
+ await this.vectorStore.upsert([
63
+ {
64
+ id,
65
+ vector: embedding,
66
+ metadata: {
67
+ type: entry.type,
68
+ content: entry.content,
69
+ createdAt: createdAt.toISOString(),
70
+ ...entry.metadata,
71
+ },
72
+ },
73
+ ]);
74
+
75
+ // Cache locally
76
+ this.entryCache.set(id, fullEntry);
77
+
78
+ return fullEntry;
79
+ }
80
+
81
+ async retrieve(query: MemoryQuery): Promise<MemorySearchResult[]> {
82
+ const limit = query.limit ?? this.config.defaultQueryLimit;
83
+
84
+ // Generate embedding for the query
85
+ const queryEmbedding = await this.embeddingProvider.embed(query.query);
86
+
87
+ // Build filter for vector store
88
+ const filter: Record<string, unknown> = {};
89
+ if (query.type) {
90
+ filter.type = query.type;
91
+ }
92
+ if (query.filter) {
93
+ Object.assign(filter, this.convertFilter(query.filter));
94
+ }
95
+
96
+ // Search vector store
97
+ const results = await this.vectorStore.search(queryEmbedding, limit, filter);
98
+
99
+ // Convert to MemorySearchResult
100
+ return results.map(r => {
101
+ const entry = this.entryCache.get(r.id) ?? this.reconstructEntry(r.id, r.metadata);
102
+ return {
103
+ entry,
104
+ score: r.score,
105
+ };
106
+ });
107
+ }
108
+
109
+ async get(id: EntityId): Promise<MemoryEntry | null> {
110
+ // Check cache first
111
+ const cached = this.entryCache.get(id);
112
+ if (cached) {
113
+ return cached;
114
+ }
115
+
116
+ // Would need to implement get by ID in vector store
117
+ // For now, return null
118
+ return null;
119
+ }
120
+
121
+ async update(
122
+ id: EntityId,
123
+ updates: Partial<Omit<MemoryEntry, 'id' | 'createdAt'>>
124
+ ): Promise<MemoryEntry> {
125
+ const existing = await this.get(id);
126
+ if (!existing) {
127
+ throw new Error(`Memory entry not found: ${id}`);
128
+ }
129
+
130
+ // If content is updated, regenerate embedding
131
+ let embedding = existing.embedding;
132
+ if (updates.content && updates.content !== existing.content) {
133
+ embedding = await this.embeddingProvider.embed(updates.content);
134
+ }
135
+
136
+ const updated: MemoryEntry = {
137
+ ...existing,
138
+ ...updates,
139
+ id: existing.id,
140
+ createdAt: existing.createdAt,
141
+ embedding: embedding ?? existing.embedding,
142
+ };
143
+
144
+ // Update in vector store
145
+ await this.vectorStore.upsert([
146
+ {
147
+ id,
148
+ vector: updated.embedding ?? [],
149
+ metadata: {
150
+ type: updated.type,
151
+ content: updated.content,
152
+ createdAt: updated.createdAt.toISOString(),
153
+ ...updated.metadata,
154
+ },
155
+ },
156
+ ]);
157
+
158
+ // Update cache
159
+ this.entryCache.set(id, updated);
160
+
161
+ return updated;
162
+ }
163
+
164
+ async delete(id: EntityId): Promise<boolean> {
165
+ await this.vectorStore.delete([id]);
166
+ this.entryCache.delete(id);
167
+ return true;
168
+ }
169
+
170
+ async clear(type?: MemoryType): Promise<void> {
171
+ if (type) {
172
+ // Vector stores typically don't support clearing by metadata filter
173
+ // This would need to be implemented in the adapter
174
+ const allEntries = Array.from(this.entryCache.values());
175
+ const toDelete = allEntries.filter(e => e.type === type).map(e => e.id);
176
+ await this.vectorStore.delete(toDelete);
177
+ for (const id of toDelete) {
178
+ this.entryCache.delete(id);
179
+ }
180
+ } else {
181
+ await this.vectorStore.clear();
182
+ this.entryCache.clear();
183
+ }
184
+ }
185
+
186
+ async getRecent(limit: number, type?: MemoryType): Promise<MemoryEntry[]> {
187
+ // Get all cached entries sorted by date
188
+ let entries = Array.from(this.entryCache.values());
189
+
190
+ if (type) {
191
+ entries = entries.filter(e => e.type === type);
192
+ }
193
+
194
+ return entries
195
+ .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
196
+ .slice(0, limit);
197
+ }
198
+
199
+ async snapshot(): Promise<MemoryEntry[]> {
200
+ return Array.from(this.entryCache.values());
201
+ }
202
+
203
+ /**
204
+ * Generate a unique ID
205
+ */
206
+ private generateId(): EntityId {
207
+ return `vec-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
208
+ }
209
+
210
+ /**
211
+ * Convert memory filter to vector store filter
212
+ */
213
+ private convertFilter(filter: MemoryFilter): Record<string, unknown> {
214
+ const result: Record<string, unknown> = {};
215
+
216
+ if (filter.tags) {
217
+ result.tags = filter.tags;
218
+ }
219
+ if (filter.source) {
220
+ result.source = filter.source;
221
+ }
222
+ if (filter.agentId) {
223
+ result.agentId = filter.agentId;
224
+ }
225
+ if (filter.sessionId) {
226
+ result.sessionId = filter.sessionId;
227
+ }
228
+
229
+ return result;
230
+ }
231
+
232
+ /**
233
+ * Reconstruct a memory entry from vector store metadata
234
+ */
235
+ private reconstructEntry(id: EntityId, metadata: Record<string, unknown>): MemoryEntry {
236
+ return {
237
+ id,
238
+ type: (metadata.type as MemoryType) ?? MemoryType.SHORT_TERM,
239
+ content: (metadata.content as string) ?? '',
240
+ metadata: {
241
+ source: metadata.source as string,
242
+ importance: metadata.importance as number,
243
+ tags: metadata.tags as string[],
244
+ agentId: metadata.agentId as EntityId,
245
+ sessionId: metadata.sessionId as string,
246
+ custom: metadata.custom as Record<string, unknown>,
247
+ },
248
+ createdAt: new Date(metadata.createdAt as string),
249
+ };
250
+ }
251
+ }