@lanonasis/mem-intel-sdk 1.1.0 → 2.0.1

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 (45) hide show
  1. package/CHANGELOG.md +230 -15
  2. package/README.md +258 -4
  3. package/dist/core/client.d.ts +51 -0
  4. package/dist/core/client.d.ts.map +1 -1
  5. package/dist/core/index.cjs +146 -13
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.ts +1 -0
  8. package/dist/core/index.d.ts.map +1 -1
  9. package/dist/core/index.js +145 -14
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/core/prediction-types.d.ts +270 -0
  12. package/dist/core/prediction-types.d.ts.map +1 -0
  13. package/dist/core/types.d.ts +62 -39
  14. package/dist/core/types.d.ts.map +1 -1
  15. package/dist/index.cjs +106 -13
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.js +106 -13
  18. package/dist/index.js.map +1 -1
  19. package/dist/node/client.d.ts.map +1 -1
  20. package/dist/node/index.cjs +107 -13
  21. package/dist/node/index.cjs.map +1 -1
  22. package/dist/node/index.js +107 -13
  23. package/dist/node/index.js.map +1 -1
  24. package/dist/react/context/MemoryIntelligenceProvider.d.ts +4 -3
  25. package/dist/react/context/MemoryIntelligenceProvider.d.ts.map +1 -1
  26. package/dist/react/hooks/useMemoryIntelligence.d.ts +83 -0
  27. package/dist/react/hooks/useMemoryIntelligence.d.ts.map +1 -1
  28. package/dist/react/index.cjs +125 -21
  29. package/dist/react/index.cjs.map +1 -1
  30. package/dist/react/index.js +123 -15
  31. package/dist/react/index.js.map +1 -1
  32. package/dist/server/index.cjs +343 -40
  33. package/dist/server/index.cjs.map +1 -1
  34. package/dist/server/index.js +343 -40
  35. package/dist/server/index.js.map +1 -1
  36. package/dist/server/mcp-server.d.ts.map +1 -1
  37. package/dist/utils/http-client.d.ts +4 -1
  38. package/dist/utils/http-client.d.ts.map +1 -1
  39. package/dist/utils/prediction-engine.d.ts +90 -0
  40. package/dist/utils/prediction-engine.d.ts.map +1 -0
  41. package/dist/vue/composables/useMemoryIntelligence.d.ts +59 -0
  42. package/dist/vue/composables/useMemoryIntelligence.d.ts.map +1 -1
  43. package/dist/vue/index.cjs.map +1 -1
  44. package/dist/vue/index.js.map +1 -1
  45. package/package.json +9 -3
@@ -160,23 +160,48 @@ var HttpClient = class {
160
160
  processingMode;
161
161
  cache;
162
162
  constructor(config) {
163
- if (!config.apiKey) {
164
- throw new ConfigurationError("API key is required");
165
- }
166
- if (!config.apiKey.startsWith("lano_")) {
163
+ this.apiUrl = config.apiUrl.replace(/\/$/, "");
164
+ let authType;
165
+ if (config.authType) {
166
+ authType = config.authType;
167
+ } else if (config.apiKey) {
168
+ authType = "apiKey";
169
+ } else if (config.authToken) {
170
+ authType = "bearer";
171
+ } else if (config.allowMissingAuth) {
172
+ authType = "apiKey";
173
+ } else {
167
174
  throw new ConfigurationError(
168
- "Invalid API key format. API key should start with 'lano_'"
175
+ "Authentication required: provide apiKey, authToken, or set allowMissingAuth to true"
169
176
  );
170
177
  }
171
- this.apiUrl = config.apiUrl.replace(/\/$/, "");
178
+ const allowMissingAuth = Boolean(config.allowMissingAuth);
179
+ if (authType === "apiKey") {
180
+ if (!config.apiKey && !allowMissingAuth) {
181
+ throw new ConfigurationError("API key is required when authType is 'apiKey'");
182
+ }
183
+ if (config.apiKey && !config.apiKey.startsWith("lano_")) {
184
+ throw new ConfigurationError(
185
+ "Invalid API key format. API key should start with 'lano_'"
186
+ );
187
+ }
188
+ } else if (!config.authToken && !allowMissingAuth) {
189
+ throw new ConfigurationError("Bearer token is required when authType is 'bearer'");
190
+ }
172
191
  this.apiKey = config.apiKey;
173
192
  this.timeout = config.timeout || 3e4;
174
193
  this.processingMode = config.processingMode || "api";
175
- this.headers = {
194
+ const baseHeaders = {
176
195
  "Content-Type": "application/json",
177
- "X-API-Key": this.apiKey,
178
196
  ...config.headers
179
197
  };
198
+ if (authType === "apiKey" && this.apiKey && !("X-API-Key" in baseHeaders)) {
199
+ baseHeaders["X-API-Key"] = this.apiKey;
200
+ }
201
+ if (authType === "bearer" && config.authToken && !("Authorization" in baseHeaders)) {
202
+ baseHeaders["Authorization"] = `Bearer ${config.authToken}`;
203
+ }
204
+ this.headers = baseHeaders;
180
205
  if (config.enableCache !== false && this.processingMode === "offline-fallback") {
181
206
  this.cache = new ResponseCache(config.cacheTTL || 3e5);
182
207
  } else {
@@ -336,15 +361,14 @@ var MemoryIntelligenceClient = class {
336
361
  defaultResponseFormat;
337
362
  processingMode;
338
363
  constructor(config) {
339
- if (!config.apiKey) {
340
- throw new ConfigurationError(
341
- "Missing required configuration: apiKey is required (format: lano_xxxxxxxxxx)"
342
- );
343
- }
344
364
  this.processingMode = config.processingMode || "api";
365
+ const authType = config.authType || (config.apiKey ? "apiKey" : "bearer");
345
366
  this.httpClient = new HttpClient({
346
367
  apiUrl: config.apiUrl || DEFAULT_API_URL,
347
368
  apiKey: config.apiKey,
369
+ authToken: config.authToken,
370
+ authType,
371
+ allowMissingAuth: config.allowMissingAuth,
348
372
  timeout: config.timeout,
349
373
  headers: config.headers,
350
374
  processingMode: this.processingMode,
@@ -524,6 +548,75 @@ var MemoryIntelligenceClient = class {
524
548
  fromCache: response.fromCache
525
549
  };
526
550
  }
551
+ /**
552
+ * Predictive Memory Recall - AI that anticipates what you need
553
+ *
554
+ * Uses a weighted scoring algorithm:
555
+ * - Semantic similarity to current context (40%)
556
+ * - Temporal relevance (recency decay curve) (30%)
557
+ * - Usage frequency (20%)
558
+ * - Serendipity factor (adjacent discoveries) (10%)
559
+ *
560
+ * @example
561
+ * ```typescript
562
+ * const result = await client.predictiveRecall({
563
+ * userId: "user-123",
564
+ * context: {
565
+ * currentProject: "Building dashboard components",
566
+ * recentTopics: ["React", "performance", "hooks"],
567
+ * contextText: "Optimizing render performance for data tables"
568
+ * },
569
+ * limit: 5,
570
+ * minConfidence: 50
571
+ * });
572
+ *
573
+ * for (const prediction of result.data.predictions) {
574
+ * console.log(`[${prediction.confidence}%] ${prediction.title}`);
575
+ * console.log(` Reason: ${prediction.reason}`);
576
+ * console.log(` Action: ${prediction.suggestedAction}`);
577
+ * }
578
+ * ```
579
+ */
580
+ async predictiveRecall(params) {
581
+ const response = await this.httpClient.postEnhanced(
582
+ "/intelligence/predictive-recall",
583
+ {
584
+ userId: params.userId,
585
+ context: params.context,
586
+ limit: params.limit || 5,
587
+ minConfidence: params.minConfidence || 40,
588
+ includeSerendipity: params.includeSerendipity !== false,
589
+ memoryTypes: params.memoryTypes,
590
+ timeWindowDays: params.timeWindowDays || 90,
591
+ responseFormat: params.responseFormat || this.defaultResponseFormat
592
+ }
593
+ );
594
+ if (response.error) {
595
+ throw new DatabaseError(`Failed to get predictions: ${response.error.message}`);
596
+ }
597
+ return {
598
+ data: response.data,
599
+ usage: response.usage,
600
+ tier_info: response.tier_info,
601
+ fromCache: response.fromCache
602
+ };
603
+ }
604
+ /**
605
+ * Record feedback on a prediction (for improving accuracy over time)
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * await client.recordPredictionFeedback({
610
+ * memoryId: "mem-123",
611
+ * userId: "user-123",
612
+ * useful: true,
613
+ * action: "clicked"
614
+ * });
615
+ * ```
616
+ */
617
+ async recordPredictionFeedback(params) {
618
+ await this.httpClient.post("/intelligence/prediction-feedback", params);
619
+ }
527
620
  };
528
621
  var ResponseFormat = {
529
622
  JSON: "json",
@@ -828,22 +921,27 @@ function createMCPServer(config) {
828
921
  let md = `# Duplicate Detection
829
922
 
830
923
  `;
831
- md += `**Memories Analyzed:** ${data.total_memories_analyzed}
924
+ md += `**Memories Analyzed:** ${data.memories_analyzed}
925
+ `;
926
+ md += `**Duplicate Groups Found:** ${data.total_groups}
832
927
  `;
833
- md += `**Duplicate Pairs Found:** ${data.duplicate_pairs_found}
928
+ md += `**Total Duplicates:** ${data.total_duplicates}
834
929
  `;
835
- md += `**Storage Savings:** ${data.estimated_storage_savings}
930
+ md += `**Storage Savings:** ${data.potential_storage_savings}
836
931
 
837
932
  `;
838
- for (const pair of data.duplicate_pairs) {
839
- md += `### Similarity: ${(pair.similarity_score * 100).toFixed(1)}%
933
+ for (const group of data.duplicate_groups) {
934
+ md += `### ${group.primary_title}
840
935
  `;
841
- md += `**Memory 1:** ${pair.memory_1.title}
936
+ md += `**Similarity Score:** ${(group.similarity_score * 100).toFixed(1)}%
842
937
  `;
843
- md += `**Memory 2:** ${pair.memory_2.title}
938
+ md += `**Duplicates:**
844
939
  `;
845
- md += `**Recommendation:** ${pair.recommendation}
846
-
940
+ for (const dup of group.duplicates) {
941
+ md += `- ${dup.title} (${(dup.similarity * 100).toFixed(1)}% similar)
942
+ `;
943
+ }
944
+ md += `
847
945
  `;
848
946
  }
849
947
  return md;
@@ -902,7 +1000,7 @@ function createMCPServer(config) {
902
1000
  let md = `# Memory Insights
903
1001
 
904
1002
  `;
905
- md += `**Memories Analyzed:** ${data.total_memories_analyzed}
1003
+ md += `**Memories Analyzed:** ${data.memories_analyzed}
906
1004
  `;
907
1005
  if (data.topic_filter) {
908
1006
  md += `**Topic:** ${data.topic_filter}
@@ -910,24 +1008,24 @@ function createMCPServer(config) {
910
1008
  }
911
1009
  md += `
912
1010
  ## Summary
913
- ${data.summary}
1011
+ ${data.overall_summary}
914
1012
 
915
1013
  `;
916
1014
  md += `## Insights
917
1015
  `;
918
- const categoryIcons = {
919
- pattern: "\u{1F504}",
920
- learning: "\u{1F4A1}",
921
- opportunity: "\u{1F680}",
922
- risk: "\u26A0\uFE0F",
923
- action_item: "\u2705"
1016
+ const typeIcons = {
1017
+ themes: "\u{1F3AF}",
1018
+ connections: "\u{1F517}",
1019
+ gaps: "\u26A0\uFE0F",
1020
+ actions: "\u2705",
1021
+ summary: "\u{1F4CB}"
924
1022
  };
925
1023
  for (const insight of data.insights) {
926
- const icon = categoryIcons[insight.category] || "\u{1F4CC}";
1024
+ const icon = typeIcons[insight.type] || "\u{1F4CC}";
927
1025
  md += `
928
- ### ${icon} ${insight.title}
1026
+ ### ${icon} ${insight.type.charAt(0).toUpperCase() + insight.type.slice(1)}
929
1027
  `;
930
- md += `${insight.description}
1028
+ md += `${insight.content}
931
1029
  `;
932
1030
  md += `**Confidence:** ${(insight.confidence * 100).toFixed(0)}%
933
1031
  `;
@@ -982,25 +1080,43 @@ ${data.summary}
982
1080
  let md = `# Memory Health Check
983
1081
 
984
1082
  `;
985
- md += `**Health Score:** ${data.health_score}/100
1083
+ md += `**Health Score:** ${data.health_score.overall}/100
1084
+ `;
1085
+ md += `**Status:** ${data.status}
1086
+
1087
+ `;
1088
+ md += `## Score Breakdown
1089
+ `;
1090
+ md += `- **Organization:** ${data.health_score.breakdown.organization}
1091
+ `;
1092
+ md += `- **Tagging:** ${data.health_score.breakdown.tagging}
1093
+ `;
1094
+ md += `- **Recency:** ${data.health_score.breakdown.recency}
1095
+ `;
1096
+ md += `- **Completeness:** ${data.health_score.breakdown.completeness}
1097
+ `;
1098
+ md += `- **Diversity:** ${data.health_score.breakdown.diversity}
986
1099
 
987
1100
  `;
988
- md += `## Metrics
1101
+ md += `## Statistics
1102
+ `;
1103
+ md += `- **Total Memories:** ${data.statistics.total_memories}
989
1104
  `;
990
- md += `- **Total Memories:** ${data.metrics.total_memories}
1105
+ md += `- **Active Memories:** ${data.statistics.active_memories}
991
1106
  `;
992
- md += `- **Embedding Coverage:** ${data.metrics.embedding_coverage_percentage}%
1107
+ md += `- **Memories with Tags:** ${data.statistics.memories_with_tags}
993
1108
  `;
994
- md += `- **Tagging Rate:** ${data.metrics.tagging_percentage}%
1109
+ md += `- **Unique Tags:** ${data.statistics.unique_tags}
995
1110
  `;
996
- md += `- **Avg Tags/Memory:** ${data.metrics.average_tags_per_memory}
1111
+ md += `- **Recent (30d):** ${data.statistics.recent_memories_30d}
997
1112
 
998
1113
  `;
999
1114
  if (data.issues.length > 0) {
1000
1115
  md += `## Issues
1001
1116
  `;
1002
1117
  for (const issue of data.issues) {
1003
- md += `- ${issue}
1118
+ const icon = issue.severity === "high" ? "\u{1F534}" : issue.severity === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
1119
+ md += `- ${icon} **${issue.category}:** ${issue.description}
1004
1120
  `;
1005
1121
  }
1006
1122
  md += `
@@ -1031,6 +1147,193 @@ ${data.summary}
1031
1147
  }
1032
1148
  }
1033
1149
  );
1150
+ server.registerTool(
1151
+ "memory_predictive_recall",
1152
+ {
1153
+ title: "Predictive Memory Recall",
1154
+ description: `AI-powered prediction of memories you'll need based on your current context. Uses semantic similarity, temporal relevance, usage patterns, and serendipity scoring to anticipate what you need before you realize it.`,
1155
+ inputSchema: zod.z.object({
1156
+ user_id: zod.z.string().uuid(),
1157
+ context: zod.z.object({
1158
+ current_project: zod.z.string().optional().describe("Current project or task description"),
1159
+ recent_topics: zod.z.array(zod.z.string()).optional().describe("Recent topics you've been working on"),
1160
+ active_files: zod.z.array(zod.z.string()).optional().describe("Files currently being worked on"),
1161
+ context_text: zod.z.string().optional().describe("Free-form context (current task, meeting notes, etc.)"),
1162
+ team_context: zod.z.string().optional().describe("Team discussion topics for team-aware predictions")
1163
+ }).describe("Your current work context for generating predictions"),
1164
+ limit: zod.z.number().int().min(1).max(20).default(5).describe("Maximum predictions to return"),
1165
+ min_confidence: zod.z.number().min(0).max(100).default(40).describe("Minimum confidence threshold (0-100)"),
1166
+ include_serendipity: zod.z.boolean().default(true).describe("Include surprising adjacent discoveries"),
1167
+ memory_types: zod.z.array(MemoryType).optional().describe("Filter by memory types"),
1168
+ time_window_days: zod.z.number().int().min(1).max(365).default(90).describe("Time window for recency scoring"),
1169
+ response_format: zod.z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
1170
+ }).strict(),
1171
+ annotations: {
1172
+ readOnlyHint: true,
1173
+ destructiveHint: false,
1174
+ idempotentHint: false,
1175
+ openWorldHint: true
1176
+ }
1177
+ },
1178
+ async (rawParams) => {
1179
+ try {
1180
+ const params = {
1181
+ userId: rawParams.user_id,
1182
+ context: {
1183
+ currentProject: rawParams.context?.current_project,
1184
+ recentTopics: rawParams.context?.recent_topics,
1185
+ activeFiles: rawParams.context?.active_files,
1186
+ contextText: rawParams.context?.context_text,
1187
+ teamContext: rawParams.context?.team_context
1188
+ },
1189
+ limit: rawParams.limit,
1190
+ minConfidence: rawParams.min_confidence,
1191
+ includeSerendipity: rawParams.include_serendipity,
1192
+ memoryTypes: rawParams.memory_types,
1193
+ timeWindowDays: rawParams.time_window_days,
1194
+ responseFormat: rawParams.response_format
1195
+ };
1196
+ const response = await client.predictiveRecall(params);
1197
+ const result = response.data;
1198
+ const responseText = formatResponse(
1199
+ result,
1200
+ params.responseFormat || "markdown",
1201
+ (data) => {
1202
+ let md = `# Predicted Memories for You
1203
+
1204
+ `;
1205
+ md += `**Memories Analyzed:** ${data.memoriesAnalyzed}
1206
+ `;
1207
+ md += `**Predictions Found:** ${data.totalPredictions}
1208
+
1209
+ `;
1210
+ if (data.predictions.length === 0) {
1211
+ md += `_No predictions above the confidence threshold. Try providing more context or lowering the threshold._
1212
+ `;
1213
+ return md;
1214
+ }
1215
+ md += `## Your Predictions
1216
+
1217
+ `;
1218
+ for (const pred of data.predictions) {
1219
+ const confidenceIcon = pred.confidence >= 80 ? "\u{1F3AF}" : pred.confidence >= 60 ? "\u2728" : pred.confidence >= 40 ? "\u{1F4A1}" : "\u{1F50D}";
1220
+ const actionIcon = pred.suggestedAction === "apply" ? "\u26A1" : pred.suggestedAction === "reference" ? "\u{1F4DA}" : pred.suggestedAction === "explore" ? "\u{1F52D}" : "\u{1F440}";
1221
+ md += `### ${confidenceIcon} ${pred.title}
1222
+ `;
1223
+ md += `**Confidence:** ${pred.confidence}% | **Type:** ${pred.type}
1224
+ `;
1225
+ md += `**Why:** ${pred.reason}
1226
+ `;
1227
+ md += `**Suggested Action:** ${actionIcon} ${pred.suggestedAction}
1228
+ `;
1229
+ if (pred.tags.length > 0) {
1230
+ md += `**Tags:** ${pred.tags.slice(0, 5).join(", ")}
1231
+ `;
1232
+ }
1233
+ md += `
1234
+ > ${pred.contentPreview}
1235
+
1236
+ `;
1237
+ md += `<details>
1238
+ <summary>Score Breakdown</summary>
1239
+
1240
+ `;
1241
+ md += `- Semantic: ${pred.scoreBreakdown.semanticScore}%
1242
+ `;
1243
+ md += `- Temporal: ${pred.scoreBreakdown.temporalScore}%
1244
+ `;
1245
+ md += `- Frequency: ${pred.scoreBreakdown.frequencyScore}%
1246
+ `;
1247
+ md += `- Serendipity: ${pred.scoreBreakdown.serendipityScore}%
1248
+ `;
1249
+ md += `- **Combined:** ${pred.scoreBreakdown.combinedScore}%
1250
+ `;
1251
+ md += `</details>
1252
+
1253
+ `;
1254
+ md += `---
1255
+
1256
+ `;
1257
+ }
1258
+ md += `## Algorithm Info
1259
+ `;
1260
+ md += `- **Version:** ${data.algorithmInfo.version}
1261
+ `;
1262
+ md += `- **Embedding Model:** ${data.algorithmInfo.embeddingModel}
1263
+ `;
1264
+ md += `- **Time Window:** ${data.algorithmInfo.timeWindowDays} days
1265
+ `;
1266
+ md += `- **Weights:** Semantic ${data.scoringWeights.semantic * 100}%, `;
1267
+ md += `Temporal ${data.scoringWeights.temporal * 100}%, `;
1268
+ md += `Frequency ${data.scoringWeights.frequency * 100}%, `;
1269
+ md += `Serendipity ${data.scoringWeights.serendipity * 100}%
1270
+ `;
1271
+ return md;
1272
+ }
1273
+ );
1274
+ return {
1275
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
1276
+ };
1277
+ } catch (error) {
1278
+ return {
1279
+ isError: true,
1280
+ content: [
1281
+ {
1282
+ type: "text",
1283
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
1284
+ }
1285
+ ]
1286
+ };
1287
+ }
1288
+ }
1289
+ );
1290
+ server.registerTool(
1291
+ "memory_prediction_feedback",
1292
+ {
1293
+ title: "Record Prediction Feedback",
1294
+ description: `Record whether a prediction was useful. This helps improve future predictions.`,
1295
+ inputSchema: zod.z.object({
1296
+ memory_id: zod.z.string().uuid(),
1297
+ user_id: zod.z.string().uuid(),
1298
+ useful: zod.z.boolean().describe("Was this prediction useful?"),
1299
+ action: zod.z.enum(["clicked", "saved", "dismissed", "ignored"]).describe("What action was taken"),
1300
+ dismiss_reason: zod.z.enum(["not_relevant", "already_know", "not_now", "other"]).optional().describe("Reason for dismissal")
1301
+ }).strict(),
1302
+ annotations: {
1303
+ readOnlyHint: false,
1304
+ destructiveHint: false,
1305
+ idempotentHint: true,
1306
+ openWorldHint: false
1307
+ }
1308
+ },
1309
+ async (rawParams) => {
1310
+ try {
1311
+ await client.recordPredictionFeedback({
1312
+ memoryId: rawParams.memory_id,
1313
+ userId: rawParams.user_id,
1314
+ useful: rawParams.useful,
1315
+ action: rawParams.action,
1316
+ dismissReason: rawParams.dismiss_reason
1317
+ });
1318
+ return {
1319
+ content: [{
1320
+ type: "text",
1321
+ text: `Feedback recorded. Thank you for helping improve predictions!`
1322
+ }]
1323
+ };
1324
+ } catch (error) {
1325
+ return {
1326
+ isError: true,
1327
+ content: [
1328
+ {
1329
+ type: "text",
1330
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
1331
+ }
1332
+ ]
1333
+ };
1334
+ }
1335
+ }
1336
+ );
1034
1337
  return server;
1035
1338
  }
1036
1339