@lanonasis/cli 2.0.9 → 3.0.2

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.
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Memory State Management System
3
+ * Implements comprehensive memory lifecycle management inspired by mem0's state system
4
+ */
5
+ export declare enum MemoryState {
6
+ ACTIVE = "active",
7
+ PAUSED = "paused",
8
+ ARCHIVED = "archived",
9
+ DELETED = "deleted"
10
+ }
11
+ export interface MemoryStateTransition {
12
+ id: string;
13
+ memory_id: string;
14
+ from_state: MemoryState;
15
+ to_state: MemoryState;
16
+ reason?: string;
17
+ metadata?: Record<string, any>;
18
+ timestamp: string;
19
+ user_id: string;
20
+ }
21
+ export interface LanonasisMemory {
22
+ id: string;
23
+ user_id: string;
24
+ app_id: string;
25
+ title: string;
26
+ content: string;
27
+ state: MemoryState;
28
+ metadata: Record<string, any>;
29
+ categories: string[];
30
+ created_at: string;
31
+ updated_at: string;
32
+ archived_at?: string;
33
+ deleted_at?: string;
34
+ }
35
+ export interface BulkOperationResult {
36
+ memory_id: string;
37
+ success: boolean;
38
+ previous_state: MemoryState;
39
+ new_state: MemoryState;
40
+ error?: string;
41
+ }
42
+ export declare class MemoryStateManager {
43
+ private config;
44
+ private stateTransitions;
45
+ constructor();
46
+ initialize(): Promise<void>;
47
+ /**
48
+ * Update memory state with validation and history tracking
49
+ */
50
+ updateMemoryState(memoryId: string, newState: MemoryState, reason?: string, metadata?: Record<string, any>): Promise<MemoryStateTransition>;
51
+ /**
52
+ * Bulk state update operations
53
+ */
54
+ bulkUpdateState(memoryIds: string[], operation: 'pause' | 'delete' | 'archive'): Promise<BulkOperationResult[]>;
55
+ /**
56
+ * Get memory state history
57
+ */
58
+ getMemoryStateHistory(memoryId: string): MemoryStateTransition[];
59
+ /**
60
+ * Get memories by state
61
+ */
62
+ getMemoriesByState(state: MemoryState, userId?: string, appId?: string, limit?: number): Promise<LanonasisMemory[]>;
63
+ /**
64
+ * Archive old memories based on policy
65
+ */
66
+ archiveOldMemories(beforeDate: string, userId?: string, appId?: string): Promise<BulkOperationResult[]>;
67
+ /**
68
+ * Restore memories from archived/paused state
69
+ */
70
+ restoreMemories(memoryIds: string[]): Promise<BulkOperationResult[]>;
71
+ /**
72
+ * Private helper methods
73
+ */
74
+ private isValidTransition;
75
+ private operationToState;
76
+ private getMemory;
77
+ private updateMemoryViaAPI;
78
+ private callMemoryAPI;
79
+ private getCurrentUserId;
80
+ private generateTransitionId;
81
+ }
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Memory State Management System
3
+ * Implements comprehensive memory lifecycle management inspired by mem0's state system
4
+ */
5
+ import { CLIConfig } from '../utils/config.js';
6
+ import { logger } from './logger.js';
7
+ export var MemoryState;
8
+ (function (MemoryState) {
9
+ MemoryState["ACTIVE"] = "active";
10
+ MemoryState["PAUSED"] = "paused";
11
+ MemoryState["ARCHIVED"] = "archived";
12
+ MemoryState["DELETED"] = "deleted";
13
+ })(MemoryState || (MemoryState = {}));
14
+ export class MemoryStateManager {
15
+ config;
16
+ stateTransitions = [];
17
+ constructor() {
18
+ this.config = new CLIConfig();
19
+ }
20
+ async initialize() {
21
+ logger.info('Memory State Manager initialized');
22
+ }
23
+ /**
24
+ * Update memory state with validation and history tracking
25
+ */
26
+ async updateMemoryState(memoryId, newState, reason, metadata) {
27
+ try {
28
+ // Get current memory state
29
+ const memory = await this.getMemory(memoryId);
30
+ if (!memory) {
31
+ throw new Error(`Memory ${memoryId} not found`);
32
+ }
33
+ const currentState = memory.state;
34
+ // Validate state transition
35
+ if (!this.isValidTransition(currentState, newState)) {
36
+ throw new Error(`Invalid state transition from ${currentState} to ${newState}`);
37
+ }
38
+ // Create state transition record
39
+ const transition = {
40
+ id: this.generateTransitionId(),
41
+ memory_id: memoryId,
42
+ from_state: currentState,
43
+ to_state: newState,
44
+ reason,
45
+ metadata,
46
+ timestamp: new Date().toISOString(),
47
+ user_id: await this.getCurrentUserId()
48
+ };
49
+ // Update memory state via API
50
+ await this.updateMemoryViaAPI(memoryId, {
51
+ state: newState,
52
+ updated_at: transition.timestamp,
53
+ archived_at: newState === MemoryState.ARCHIVED
54
+ ? transition.timestamp
55
+ : null,
56
+ deleted_at: newState === MemoryState.DELETED
57
+ ? transition.timestamp
58
+ : null
59
+ });
60
+ // Record transition
61
+ this.stateTransitions.push(transition);
62
+ logger.info('Memory state updated', {
63
+ memoryId,
64
+ fromState: currentState,
65
+ toState: newState,
66
+ reason
67
+ });
68
+ return transition;
69
+ }
70
+ catch (error) {
71
+ logger.error('Failed to update memory state', { error, memoryId, newState });
72
+ throw error;
73
+ }
74
+ }
75
+ /**
76
+ * Bulk state update operations
77
+ */
78
+ async bulkUpdateState(memoryIds, operation) {
79
+ const results = [];
80
+ const targetState = this.operationToState(operation);
81
+ for (const memoryId of memoryIds) {
82
+ try {
83
+ const memory = await this.getMemory(memoryId);
84
+ if (!memory) {
85
+ results.push({
86
+ memory_id: memoryId,
87
+ success: false,
88
+ previous_state: MemoryState.ACTIVE,
89
+ new_state: targetState,
90
+ error: 'Memory not found'
91
+ });
92
+ continue;
93
+ }
94
+ const previousState = memory.state;
95
+ // Skip if already in target state
96
+ if (previousState === targetState) {
97
+ results.push({
98
+ memory_id: memoryId,
99
+ success: true,
100
+ previous_state: previousState,
101
+ new_state: targetState
102
+ });
103
+ continue;
104
+ }
105
+ // Perform state transition
106
+ await this.updateMemoryState(memoryId, targetState, `Bulk ${operation} operation`);
107
+ results.push({
108
+ memory_id: memoryId,
109
+ success: true,
110
+ previous_state: previousState,
111
+ new_state: targetState
112
+ });
113
+ }
114
+ catch (error) {
115
+ results.push({
116
+ memory_id: memoryId,
117
+ success: false,
118
+ previous_state: MemoryState.ACTIVE,
119
+ new_state: targetState,
120
+ error: error instanceof Error ? error.message : 'Unknown error'
121
+ });
122
+ }
123
+ }
124
+ logger.info('Bulk state update completed', {
125
+ operation,
126
+ totalMemories: memoryIds.length,
127
+ successful: results.filter(r => r.success).length,
128
+ failed: results.filter(r => !r.success).length
129
+ });
130
+ return results;
131
+ }
132
+ /**
133
+ * Get memory state history
134
+ */
135
+ getMemoryStateHistory(memoryId) {
136
+ return this.stateTransitions
137
+ .filter(t => t.memory_id === memoryId)
138
+ .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
139
+ }
140
+ /**
141
+ * Get memories by state
142
+ */
143
+ async getMemoriesByState(state, userId, appId, limit = 100) {
144
+ try {
145
+ const params = new URLSearchParams({
146
+ state,
147
+ limit: limit.toString(),
148
+ ...(userId && { user_id: userId }),
149
+ ...(appId && { app_id: appId })
150
+ });
151
+ const memories = await this.callMemoryAPI('GET', `/memory?${params}`);
152
+ return memories.memories || [];
153
+ }
154
+ catch (error) {
155
+ logger.error('Failed to get memories by state', { error, state, userId, appId });
156
+ return [];
157
+ }
158
+ }
159
+ /**
160
+ * Archive old memories based on policy
161
+ */
162
+ async archiveOldMemories(beforeDate, userId, appId) {
163
+ try {
164
+ // Get memories created before the specified date
165
+ const params = new URLSearchParams({
166
+ before: beforeDate,
167
+ state: MemoryState.ACTIVE,
168
+ ...(userId && { user_id: userId }),
169
+ ...(appId && { app_id: appId })
170
+ });
171
+ const memories = await this.callMemoryAPI('GET', `/memory?${params}`);
172
+ const memoryIds = memories.memories?.map((m) => m.id) || [];
173
+ if (memoryIds.length === 0) {
174
+ return [];
175
+ }
176
+ return await this.bulkUpdateState(memoryIds, 'archive');
177
+ }
178
+ catch (error) {
179
+ logger.error('Failed to archive old memories', { error, beforeDate, userId, appId });
180
+ return [];
181
+ }
182
+ }
183
+ /**
184
+ * Restore memories from archived/paused state
185
+ */
186
+ async restoreMemories(memoryIds) {
187
+ const results = [];
188
+ for (const memoryId of memoryIds) {
189
+ try {
190
+ const memory = await this.getMemory(memoryId);
191
+ if (!memory) {
192
+ results.push({
193
+ memory_id: memoryId,
194
+ success: false,
195
+ previous_state: MemoryState.ARCHIVED,
196
+ new_state: MemoryState.ACTIVE,
197
+ error: 'Memory not found'
198
+ });
199
+ continue;
200
+ }
201
+ const previousState = memory.state;
202
+ // Only restore from paused or archived states
203
+ if (previousState !== MemoryState.PAUSED && previousState !== MemoryState.ARCHIVED) {
204
+ results.push({
205
+ memory_id: memoryId,
206
+ success: false,
207
+ previous_state: previousState,
208
+ new_state: MemoryState.ACTIVE,
209
+ error: `Cannot restore from ${previousState} state`
210
+ });
211
+ continue;
212
+ }
213
+ await this.updateMemoryState(memoryId, MemoryState.ACTIVE, 'Memory restoration');
214
+ results.push({
215
+ memory_id: memoryId,
216
+ success: true,
217
+ previous_state: previousState,
218
+ new_state: MemoryState.ACTIVE
219
+ });
220
+ }
221
+ catch (error) {
222
+ results.push({
223
+ memory_id: memoryId,
224
+ success: false,
225
+ previous_state: MemoryState.ARCHIVED,
226
+ new_state: MemoryState.ACTIVE,
227
+ error: error instanceof Error ? error.message : 'Unknown error'
228
+ });
229
+ }
230
+ }
231
+ return results;
232
+ }
233
+ /**
234
+ * Private helper methods
235
+ */
236
+ isValidTransition(fromState, toState) {
237
+ const validTransitions = {
238
+ [MemoryState.ACTIVE]: [MemoryState.PAUSED, MemoryState.ARCHIVED, MemoryState.DELETED],
239
+ [MemoryState.PAUSED]: [MemoryState.ACTIVE, MemoryState.ARCHIVED, MemoryState.DELETED],
240
+ [MemoryState.ARCHIVED]: [MemoryState.ACTIVE, MemoryState.DELETED],
241
+ [MemoryState.DELETED]: [] // No transitions from deleted state
242
+ };
243
+ return validTransitions[fromState]?.includes(toState) || false;
244
+ }
245
+ operationToState(operation) {
246
+ switch (operation) {
247
+ case 'pause':
248
+ return MemoryState.PAUSED;
249
+ case 'archive':
250
+ return MemoryState.ARCHIVED;
251
+ case 'delete':
252
+ return MemoryState.DELETED;
253
+ default:
254
+ throw new Error(`Unknown operation: ${operation}`);
255
+ }
256
+ }
257
+ async getMemory(memoryId) {
258
+ try {
259
+ const response = await this.callMemoryAPI('GET', `/memory/${memoryId}`);
260
+ return response;
261
+ }
262
+ catch (error) {
263
+ logger.error('Failed to get memory', { error, memoryId });
264
+ return null;
265
+ }
266
+ }
267
+ async updateMemoryViaAPI(memoryId, updates) {
268
+ await this.callMemoryAPI('PUT', `/memory/${memoryId}`, updates);
269
+ }
270
+ async callMemoryAPI(method, endpoint, data) {
271
+ const apiUrl = this.config.get('apiUrl') || 'https://api.lanonasis.com';
272
+ const token = this.config.get('token');
273
+ const axios = (await import('axios')).default;
274
+ const response = await axios({
275
+ method,
276
+ url: `${apiUrl}/api/v1${endpoint}`,
277
+ headers: {
278
+ 'Authorization': `Bearer ${token}`,
279
+ 'Content-Type': 'application/json'
280
+ },
281
+ data
282
+ });
283
+ return response.data;
284
+ }
285
+ async getCurrentUserId() {
286
+ const token = this.config.get('token');
287
+ if (token && typeof token === 'string') {
288
+ try {
289
+ const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
290
+ return payload.sub || payload.user_id || 'anonymous';
291
+ }
292
+ catch {
293
+ return 'anonymous';
294
+ }
295
+ }
296
+ return 'anonymous';
297
+ }
298
+ generateTransitionId() {
299
+ return `transition_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
300
+ }
301
+ }
@@ -175,11 +175,11 @@ export declare const ApiKeyRevokeSchema: z.ZodObject<{
175
175
  key_id: z.ZodString;
176
176
  reason: z.ZodOptional<z.ZodString>;
177
177
  }, "strip", z.ZodTypeAny, {
178
- key_id?: string;
179
178
  reason?: string;
180
- }, {
181
179
  key_id?: string;
180
+ }, {
182
181
  reason?: string;
182
+ key_id?: string;
183
183
  }>;
184
184
  export declare const SystemHealthSchema: z.ZodObject<{
185
185
  verbose: z.ZodDefault<z.ZodBoolean>;
@@ -217,13 +217,13 @@ export declare const BulkOperationSchema: z.ZodObject<{
217
217
  transaction: z.ZodDefault<z.ZodBoolean>;
218
218
  }, "strip", z.ZodTypeAny, {
219
219
  operation?: "create" | "delete" | "update";
220
- entity_type?: "topic" | "memory" | "apikey";
221
220
  items?: Record<string, any>[];
221
+ entity_type?: "topic" | "memory" | "apikey";
222
222
  transaction?: boolean;
223
223
  }, {
224
224
  operation?: "create" | "delete" | "update";
225
- entity_type?: "topic" | "memory" | "apikey";
226
225
  items?: Record<string, any>[];
226
+ entity_type?: "topic" | "memory" | "apikey";
227
227
  transaction?: boolean;
228
228
  }>;
229
229
  export declare const ImportExportSchema: z.ZodObject<{
@@ -551,11 +551,11 @@ export declare const MCPSchemas: {
551
551
  key_id: z.ZodString;
552
552
  reason: z.ZodOptional<z.ZodString>;
553
553
  }, "strip", z.ZodTypeAny, {
554
- key_id?: string;
555
554
  reason?: string;
556
- }, {
557
555
  key_id?: string;
556
+ }, {
558
557
  reason?: string;
558
+ key_id?: string;
559
559
  }>;
560
560
  };
561
561
  system: {
@@ -597,13 +597,13 @@ export declare const MCPSchemas: {
597
597
  transaction: z.ZodDefault<z.ZodBoolean>;
598
598
  }, "strip", z.ZodTypeAny, {
599
599
  operation?: "create" | "delete" | "update";
600
- entity_type?: "topic" | "memory" | "apikey";
601
600
  items?: Record<string, any>[];
601
+ entity_type?: "topic" | "memory" | "apikey";
602
602
  transaction?: boolean;
603
603
  }, {
604
604
  operation?: "create" | "delete" | "update";
605
- entity_type?: "topic" | "memory" | "apikey";
606
605
  items?: Record<string, any>[];
606
+ entity_type?: "topic" | "memory" | "apikey";
607
607
  transaction?: boolean;
608
608
  }>;
609
609
  importExport: z.ZodObject<{
@@ -18,7 +18,7 @@ export class LanonasisMCPServer {
18
18
  // Initialize server with metadata
19
19
  this.server = new Server({
20
20
  name: options.name || "lanonasis-maas-server",
21
- version: options.version || "2.0.8"
21
+ version: options.version || "3.0.1"
22
22
  }, {
23
23
  capabilities: {
24
24
  tools: {},
@@ -580,7 +580,7 @@ Please choose an option (1-4):`
580
580
  const health = {
581
581
  status: 'healthy',
582
582
  server: this.options.name || 'lanonasis-maas-server',
583
- version: this.options.version || '2.0.8',
583
+ version: this.options.version || '3.0.1',
584
584
  timestamp: new Date().toISOString()
585
585
  };
586
586
  if (verbose) {
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Vector Store Integration
3
+ * Supports multiple vector stores with configurable embedding models
4
+ */
5
+ export interface VectorStoreConfig {
6
+ provider: 'local' | 'qdrant' | 'chroma';
7
+ url?: string;
8
+ apiKey?: string;
9
+ collection?: string;
10
+ dimensions?: number;
11
+ }
12
+ export interface SearchResult {
13
+ id: string;
14
+ score: number;
15
+ metadata: any;
16
+ }
17
+ export declare class LanonasisVectorStore {
18
+ private config;
19
+ private storeConfig;
20
+ private isInitialized;
21
+ private localEmbeddings;
22
+ constructor();
23
+ initialize(): Promise<void>;
24
+ isConfigured(): boolean;
25
+ addMemory(memoryId: string, content: string, metadata: any): Promise<void>;
26
+ searchMemories(query: string, options?: any): Promise<SearchResult[]>;
27
+ findRelatedMemories(memoryId: string, options?: any): Promise<SearchResult[]>;
28
+ private generateSimpleEmbedding;
29
+ private simpleHash;
30
+ private cosineSimilarity;
31
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Vector Store Integration
3
+ * Supports multiple vector stores with configurable embedding models
4
+ */
5
+ import { CLIConfig } from '../utils/config.js';
6
+ import { logger } from './logger.js';
7
+ export class LanonasisVectorStore {
8
+ config;
9
+ storeConfig;
10
+ isInitialized = false;
11
+ localEmbeddings = new Map();
12
+ constructor() {
13
+ this.config = new CLIConfig();
14
+ this.storeConfig = {
15
+ provider: 'local',
16
+ collection: 'lanonasis_memories',
17
+ dimensions: 384
18
+ };
19
+ }
20
+ async initialize() {
21
+ this.isInitialized = true;
22
+ logger.info('Vector store initialized', { provider: this.storeConfig.provider });
23
+ }
24
+ isConfigured() {
25
+ return this.isInitialized;
26
+ }
27
+ async addMemory(memoryId, content, metadata) {
28
+ const embedding = this.generateSimpleEmbedding(content);
29
+ this.localEmbeddings.set(memoryId, { embedding, metadata, content });
30
+ logger.debug('Memory added to vector store', { memoryId });
31
+ }
32
+ async searchMemories(query, options = {}) {
33
+ const queryEmbedding = this.generateSimpleEmbedding(query);
34
+ const results = [];
35
+ // Only consider memories the caller is allowed to see
36
+ const allowedIds = options.memoryIds
37
+ ? new Set(options.memoryIds)
38
+ : undefined;
39
+ for (const [id, data] of this.localEmbeddings) {
40
+ if (allowedIds && !allowedIds.has(id))
41
+ continue;
42
+ const similarity = this.cosineSimilarity(queryEmbedding, data.embedding);
43
+ if (similarity >= (options.threshold || 0.7)) {
44
+ results.push({ id, score: similarity, metadata: data.metadata });
45
+ }
46
+ }
47
+ return results
48
+ .sort((a, b) => b.score - a.score)
49
+ .slice(0, options.limit || 10);
50
+ }
51
+ async findRelatedMemories(memoryId, options = {}) {
52
+ const memory = this.localEmbeddings.get(memoryId);
53
+ if (!memory)
54
+ return [];
55
+ const results = [];
56
+ for (const [id, data] of this.localEmbeddings) {
57
+ if (id === memoryId)
58
+ continue;
59
+ const similarity = this.cosineSimilarity(memory.embedding, data.embedding);
60
+ if (similarity >= (options.threshold || 0.6)) {
61
+ results.push({ id, score: similarity, metadata: data.metadata });
62
+ }
63
+ }
64
+ return results.sort((a, b) => b.score - a.score).slice(0, options.limit || 5);
65
+ }
66
+ generateSimpleEmbedding(text) {
67
+ const words = text.toLowerCase().split(/\s+/);
68
+ const embedding = new Array(this.storeConfig.dimensions ?? 384).fill(0);
69
+ words.forEach((word, index) => {
70
+ const hash = this.simpleHash(word);
71
+ const position = Math.abs(hash) % embedding.length;
72
+ embedding[position] += 1 / (index + 1);
73
+ });
74
+ const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
75
+ return embedding.map(val => magnitude > 0 ? val / magnitude : 0);
76
+ }
77
+ simpleHash(str) {
78
+ let hash = 0;
79
+ for (let i = 0; i < str.length; i++) {
80
+ const char = str.charCodeAt(i);
81
+ hash = ((hash << 5) - hash) + char;
82
+ hash = hash & hash;
83
+ }
84
+ return hash;
85
+ }
86
+ cosineSimilarity(a, b) {
87
+ const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
88
+ const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
89
+ const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
90
+ return magnitudeA && magnitudeB ? dotProduct / (magnitudeA * magnitudeB) : 0;
91
+ }
92
+ }
@@ -86,7 +86,7 @@ export class MCPClient {
86
86
  });
87
87
  this.client = new Client({
88
88
  name: '@lanonasis/cli',
89
- version: '2.0.0'
89
+ version: '3.0.1'
90
90
  });
91
91
  await this.client.connect(localTransport);
92
92
  this.isConnected = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lanonasis/cli",
3
- "version": "2.0.9",
3
+ "version": "3.0.2",
4
4
  "description": "LanOnasis Enterprise CLI - Memory as a Service, API Key Management, and Infrastructure Orchestration",
5
5
  "main": "dist/index-simple.js",
6
6
  "bin": {