vesper-memory 0.4.0 → 0.5.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 (63) hide show
  1. package/CHANGELOG.md +57 -3
  2. package/LICENSE +59 -0
  3. package/README.md +420 -23
  4. package/config/migrations/001_add_skill_summary.sql +75 -0
  5. package/config/migrations/001_rollback_skill_summary.sql +60 -0
  6. package/config/sqlite-schema.sql +68 -4
  7. package/dist/benchmark/types.d.ts +4 -4
  8. package/dist/cli.js +0 -0
  9. package/dist/consolidation/pipeline.d.ts +6 -1
  10. package/dist/consolidation/pipeline.d.ts.map +1 -1
  11. package/dist/consolidation/pipeline.js +53 -35
  12. package/dist/consolidation/pipeline.js.map +1 -1
  13. package/dist/memory-layers/semantic-memory.d.ts +9 -19
  14. package/dist/memory-layers/semantic-memory.d.ts.map +1 -1
  15. package/dist/memory-layers/semantic-memory.js +31 -54
  16. package/dist/memory-layers/semantic-memory.js.map +1 -1
  17. package/dist/memory-layers/skill-lazy-loading.d.ts +160 -0
  18. package/dist/memory-layers/skill-lazy-loading.d.ts.map +1 -0
  19. package/dist/memory-layers/skill-lazy-loading.js +247 -0
  20. package/dist/memory-layers/skill-lazy-loading.js.map +1 -0
  21. package/dist/memory-layers/skill-library.d.ts +133 -4
  22. package/dist/memory-layers/skill-library.d.ts.map +1 -1
  23. package/dist/memory-layers/skill-library.js +427 -8
  24. package/dist/memory-layers/skill-library.js.map +1 -1
  25. package/dist/memory-layers/working-memory.d.ts +35 -14
  26. package/dist/memory-layers/working-memory.d.ts.map +1 -1
  27. package/dist/memory-layers/working-memory.js +114 -36
  28. package/dist/memory-layers/working-memory.js.map +1 -1
  29. package/dist/retrieval/hybrid-search.d.ts +2 -2
  30. package/dist/retrieval/hybrid-search.d.ts.map +1 -1
  31. package/dist/retrieval/hybrid-search.js +4 -3
  32. package/dist/retrieval/hybrid-search.js.map +1 -1
  33. package/dist/router/smart-router.d.ts +25 -0
  34. package/dist/router/smart-router.d.ts.map +1 -1
  35. package/dist/router/smart-router.js +90 -10
  36. package/dist/router/smart-router.js.map +1 -1
  37. package/dist/scheduler/consolidation-scheduler.d.ts +129 -0
  38. package/dist/scheduler/consolidation-scheduler.d.ts.map +1 -0
  39. package/dist/scheduler/consolidation-scheduler.js +179 -0
  40. package/dist/scheduler/consolidation-scheduler.js.map +1 -0
  41. package/dist/scheduler/index.d.ts +7 -0
  42. package/dist/scheduler/index.d.ts.map +1 -0
  43. package/dist/scheduler/index.js +7 -0
  44. package/dist/scheduler/index.js.map +1 -0
  45. package/dist/server-wrapper.js +0 -0
  46. package/dist/server.js +879 -28
  47. package/dist/server.js.map +1 -1
  48. package/dist/synthesis/conflict-detector.d.ts +4 -6
  49. package/dist/synthesis/conflict-detector.d.ts.map +1 -1
  50. package/dist/synthesis/conflict-detector.js +19 -21
  51. package/dist/synthesis/conflict-detector.js.map +1 -1
  52. package/dist/utils/validation.d.ts +123 -1
  53. package/dist/utils/validation.d.ts.map +1 -1
  54. package/dist/utils/validation.js +146 -7
  55. package/dist/utils/validation.js.map +1 -1
  56. package/docker-compose.yml +6 -6
  57. package/embedding-service/README.md +8 -0
  58. package/package.json +4 -2
  59. package/scripts/FRESH_INSTALL.md +1 -1
  60. package/scripts/ensure-infrastructure.sh +86 -26
  61. package/scripts/health-check.sh +2 -1
  62. package/scripts/stop-infrastructure.sh +23 -0
  63. package/scripts/test-mcp-server.sh +2 -1
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Lazy Loading for Skill Library
3
+ *
4
+ * Token-efficient skill loading system that reduces skill-related token usage by 80-90%.
5
+ *
6
+ * Strategy:
7
+ * 1. Inject lightweight skill summaries (~50 tokens each) in MCP context
8
+ * 2. Load full implementations only when explicitly invoked
9
+ * 3. Cache loaded skills in working memory (Redis) for session
10
+ *
11
+ * Performance targets:
12
+ * - Summary retrieval: <10ms
13
+ * - Full load: <20ms
14
+ * - Cache hit: <5ms
15
+ * - Token reduction: 80-90%
16
+ */
17
+ /**
18
+ * Lazy Loading Skill Library
19
+ *
20
+ * Extends the base SkillLibrary with lazy loading capabilities.
21
+ */
22
+ export class LazyLoadingSkillLibrary {
23
+ db;
24
+ cacheKeyPrefix = 'skill:cache:';
25
+ constructor(db) {
26
+ this.db = db;
27
+ }
28
+ /**
29
+ * Get skill summaries for context injection
30
+ *
31
+ * Returns lightweight summaries of all non-archived skills,
32
+ * sorted by quality score (satisfaction × success rate).
33
+ *
34
+ * @param limit - Maximum number of summaries to return (default: 20)
35
+ * @param category - Optional category filter
36
+ * @returns Array of SkillSummary objects
37
+ */
38
+ getSummaries(limit = 20, category, namespace = 'default') {
39
+ let query = `
40
+ SELECT
41
+ id,
42
+ name,
43
+ summary,
44
+ category,
45
+ triggers,
46
+ success_count,
47
+ failure_count,
48
+ avg_user_satisfaction,
49
+ last_used
50
+ FROM skills
51
+ WHERE is_archived = 0 AND namespace = ?
52
+ `;
53
+ const params = [namespace];
54
+ if (category) {
55
+ query += ' AND category = ?';
56
+ params.push(category);
57
+ }
58
+ // Calculate quality score as: avg_satisfaction × success_rate
59
+ // Where success_rate = success_count / (success_count + failure_count)
60
+ query += `
61
+ ORDER BY
62
+ (avg_user_satisfaction * (CAST(success_count AS REAL) / NULLIF(success_count + failure_count, 0))) DESC,
63
+ avg_user_satisfaction DESC,
64
+ success_count DESC
65
+ LIMIT ?
66
+ `;
67
+ params.push(limit);
68
+ const stmt = this.db.prepare(query);
69
+ const rows = stmt.all(...params);
70
+ return rows.map(row => ({
71
+ id: row.id,
72
+ name: row.name,
73
+ summary: row.summary || this.generateSummary(row.name, row.description),
74
+ category: row.category,
75
+ triggers: JSON.parse(row.triggers || '[]'),
76
+ quality_score: this.calculateQualityScore(row.avg_user_satisfaction, row.success_count, row.failure_count),
77
+ last_used: row.last_used ? new Date(row.last_used) : undefined,
78
+ }));
79
+ }
80
+ /**
81
+ * Load full skill implementation
82
+ *
83
+ * Retrieves complete skill details for execution.
84
+ * Results should be cached in working memory.
85
+ *
86
+ * @param skillId - The skill ID to load
87
+ * @returns FullSkill object or null if not found
88
+ */
89
+ loadFull(skillId) {
90
+ const stmt = this.db.prepare(`
91
+ SELECT * FROM skills WHERE id = ? AND is_archived = 0
92
+ `);
93
+ const row = stmt.get(skillId);
94
+ if (!row) {
95
+ return null;
96
+ }
97
+ return {
98
+ id: row.id,
99
+ name: row.name,
100
+ summary: row.summary || this.generateSummary(row.name, row.description),
101
+ description: row.description,
102
+ category: row.category,
103
+ triggers: JSON.parse(row.triggers || '[]'),
104
+ code: row.code,
105
+ code_type: row.code_type,
106
+ prerequisites: row.prerequisites ? JSON.parse(row.prerequisites) : undefined,
107
+ quality_score: this.calculateQualityScore(row.avg_user_satisfaction, row.success_count, row.failure_count),
108
+ success_count: row.success_count,
109
+ failure_count: row.failure_count,
110
+ avg_user_satisfaction: row.avg_user_satisfaction,
111
+ uses_skills: row.uses_skills ? JSON.parse(row.uses_skills) : undefined,
112
+ used_by_skills: row.used_by_skills ? JSON.parse(row.used_by_skills) : undefined,
113
+ created_from: row.created_from,
114
+ created_at: new Date(row.created_at),
115
+ last_modified: new Date(row.last_modified),
116
+ last_used: row.last_used ? new Date(row.last_used) : undefined,
117
+ version: row.version,
118
+ notes: row.notes,
119
+ };
120
+ }
121
+ /**
122
+ * Detect if a query is attempting to invoke a specific skill
123
+ *
124
+ * Uses pattern matching to identify skill invocations:
125
+ * - Explicit: "use skill X", "invoke X", "run X"
126
+ * - Implicit: "analyze this like before", "same as last time"
127
+ * - By ID: References a skill ID directly
128
+ *
129
+ * @param query - The user query
130
+ * @param summaries - Available skill summaries for matching
131
+ * @returns InvocationDetection result
132
+ */
133
+ detectInvocation(query, summaries) {
134
+ const normalizedQuery = query.toLowerCase().trim();
135
+ // Pattern 1: Explicit invocation by name
136
+ // "use skill Data Analysis", "invoke Code Review"
137
+ const explicitPattern = /\b(use|invoke|run|execute)\s+(skill\s+)?(.+)/i;
138
+ const explicitMatch = normalizedQuery.match(explicitPattern);
139
+ if (explicitMatch) {
140
+ const skillName = explicitMatch[3].trim();
141
+ const matchingSkill = summaries.find(s => s.name.toLowerCase() === skillName);
142
+ if (matchingSkill) {
143
+ return {
144
+ is_invocation: true,
145
+ skill_id: matchingSkill.id,
146
+ confidence: 0.95,
147
+ matched_pattern: 'explicit_name',
148
+ };
149
+ }
150
+ }
151
+ // Pattern 2: Implicit invocation by trigger
152
+ // "analyze this dataset", "review this code"
153
+ for (const skill of summaries) {
154
+ for (const trigger of skill.triggers) {
155
+ if (normalizedQuery.includes(trigger.toLowerCase())) {
156
+ return {
157
+ is_invocation: true,
158
+ skill_id: skill.id,
159
+ confidence: 0.75,
160
+ matched_pattern: `trigger:${trigger}`,
161
+ };
162
+ }
163
+ }
164
+ }
165
+ // Pattern 3: Reference to previous skill
166
+ // "like before", "same as last time", "same way"
167
+ const referencePattern = /\b(like before|same as|same way|as before|previously)\b/i;
168
+ if (referencePattern.test(normalizedQuery)) {
169
+ // Return most recently used skill
170
+ const recentSkill = summaries
171
+ .filter(s => s.last_used)
172
+ .sort((a, b) => (b.last_used?.getTime() || 0) - (a.last_used?.getTime() || 0))[0];
173
+ if (recentSkill) {
174
+ return {
175
+ is_invocation: true,
176
+ skill_id: recentSkill.id,
177
+ confidence: 0.8,
178
+ matched_pattern: 'reference_previous',
179
+ };
180
+ }
181
+ }
182
+ // Pattern 4: Skill ID reference
183
+ // "skill_12345", direct ID in query
184
+ const idPattern = /skill_[a-z0-9]+/i;
185
+ const idMatch = normalizedQuery.match(idPattern);
186
+ if (idMatch) {
187
+ const skillId = idMatch[0];
188
+ const matchingSkill = summaries.find(s => s.id === skillId);
189
+ if (matchingSkill) {
190
+ return {
191
+ is_invocation: true,
192
+ skill_id: skillId,
193
+ confidence: 1.0,
194
+ matched_pattern: 'skill_id',
195
+ };
196
+ }
197
+ }
198
+ // No invocation detected
199
+ return {
200
+ is_invocation: false,
201
+ confidence: 0.0,
202
+ };
203
+ }
204
+ /**
205
+ * Calculate quality score for a skill
206
+ *
207
+ * Formula: avg_satisfaction × success_rate
208
+ * Where success_rate = success_count / (success_count + failure_count)
209
+ *
210
+ * @param avgSatisfaction - Average user satisfaction (0-1)
211
+ * @param successCount - Number of successful executions
212
+ * @param failureCount - Number of failed executions
213
+ * @returns Quality score (0-1)
214
+ */
215
+ calculateQualityScore(avgSatisfaction, successCount, failureCount) {
216
+ const totalExecutions = successCount + failureCount;
217
+ if (totalExecutions === 0) {
218
+ // No executions yet, return base satisfaction
219
+ return avgSatisfaction * 0.5; // Penalize untested skills
220
+ }
221
+ const successRate = successCount / totalExecutions;
222
+ return avgSatisfaction * successRate;
223
+ }
224
+ /**
225
+ * Generate a one-line summary from name and description
226
+ *
227
+ * Used when summary field is not populated.
228
+ * Truncates description to ~20 words.
229
+ *
230
+ * @param name - Skill name
231
+ * @param description - Full description
232
+ * @returns One-line summary
233
+ */
234
+ generateSummary(name, description) {
235
+ if (!description) {
236
+ return name;
237
+ }
238
+ // Take first sentence or first 20 words, whichever is shorter
239
+ const firstSentence = description.split(/[.!?]/)[0].trim();
240
+ const words = firstSentence.split(/\s+/);
241
+ if (words.length <= 20) {
242
+ return firstSentence;
243
+ }
244
+ return words.slice(0, 20).join(' ') + '...';
245
+ }
246
+ }
247
+ //# sourceMappingURL=skill-lazy-loading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-lazy-loading.js","sourceRoot":"","sources":["../../src/memory-layers/skill-lazy-loading.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,12 @@
2
2
  * Skill Library - v3.0 Voyager-Style Implementation
3
3
  *
4
4
  * Procedural memory: reusable patterns learned from conversations.
5
+ * Includes RelationalSkillLibrary for geometric embeddings and analogical reasoning.
6
+ * Enhanced with lazy loading support for token efficiency.
5
7
  */
6
8
  import Database from 'better-sqlite3';
9
+ import { EmbeddingClient } from '../embeddings/client.js';
10
+ import { SkillSummary, FullSkill, InvocationDetection } from './skill-lazy-loading.js';
7
11
  export interface Skill {
8
12
  id: string;
9
13
  name: string;
@@ -13,13 +17,138 @@ export interface Skill {
13
17
  successCount: number;
14
18
  failureCount: number;
15
19
  avgSatisfaction: number;
20
+ embedding?: number[];
21
+ similarity?: number;
16
22
  }
23
+ export interface SkillRelationship {
24
+ id: string;
25
+ skillId1: string;
26
+ skillId2: string;
27
+ relationshipType: string;
28
+ coOccurrenceCount: number;
29
+ relationalVector?: number[];
30
+ createdAt: Date;
31
+ lastUpdated: Date;
32
+ }
33
+ export interface SkillWithScore extends Skill {
34
+ fusedScore?: number;
35
+ analogyScore?: number;
36
+ }
37
+ export type { SkillSummary, FullSkill, InvocationDetection };
17
38
  export declare class SkillLibrary {
18
39
  private db;
40
+ private lazyLoader;
19
41
  constructor(db: Database.Database);
20
- addSkill(skill: Omit<Skill, 'id' | 'successCount' | 'failureCount' | 'avgSatisfaction'>): string;
21
- search(query: string, limit?: number): Skill[];
22
- recordSuccess(skillId: string, satisfaction: number): void;
23
- recordFailure(skillId: string): void;
42
+ addSkill(skill: Omit<Skill, 'id' | 'successCount' | 'failureCount' | 'avgSatisfaction'>, namespace?: string): string;
43
+ search(query: string, limit?: number, namespace?: string): Skill[];
44
+ recordSuccess(skillId: string, satisfaction: number, _namespace?: string): void;
45
+ recordFailure(skillId: string, _namespace?: string): void;
46
+ /**
47
+ * Get database instance for subclasses
48
+ */
49
+ protected getDb(): Database.Database;
50
+ /**
51
+ * Get skill summaries for lazy loading context injection
52
+ *
53
+ * Returns lightweight summaries (~50 tokens each) instead of full skills.
54
+ * This reduces token usage by 80-90% for skill-related context.
55
+ *
56
+ * @param limit - Maximum number of summaries (default: 20)
57
+ * @param category - Optional category filter
58
+ * @returns Array of SkillSummary objects
59
+ */
60
+ getSummaries(limit?: number, category?: string, namespace?: string): SkillSummary[];
61
+ /**
62
+ * Load full skill implementation on-demand
63
+ *
64
+ * Used when a skill is explicitly invoked and full details are needed.
65
+ * Results should be cached in working memory to avoid repeated loads.
66
+ *
67
+ * @param skillId - The skill ID to load
68
+ * @returns FullSkill object or null if not found
69
+ */
70
+ loadFull(skillId: string, _namespace?: string): FullSkill | null;
71
+ /**
72
+ * Detect if a query is attempting to invoke a specific skill
73
+ *
74
+ * Uses pattern matching to identify skill invocations.
75
+ *
76
+ * @param query - The user query
77
+ * @returns InvocationDetection result with skill ID if detected
78
+ */
79
+ detectInvocation(query: string, namespace?: string): InvocationDetection;
80
+ /**
81
+ * Update last_used timestamp for a skill
82
+ *
83
+ * Called when a skill is successfully executed.
84
+ *
85
+ * @param skillId - The skill ID
86
+ */
87
+ updateLastUsed(skillId: string): void;
88
+ }
89
+ /**
90
+ * RelationalSkillLibrary - Extended skill library with geometric embeddings
91
+ * and analogical reasoning capabilities.
92
+ *
93
+ * Features:
94
+ * - Skill embeddings for semantic similarity search
95
+ * - Co-occurrence tracking between skills
96
+ * - Relational vectors for analogical reasoning
97
+ * - Hybrid search combining trigger-based and embedding-based results
98
+ */
99
+ export declare class RelationalSkillLibrary extends SkillLibrary {
100
+ private embeddingClient?;
101
+ constructor(db: Database.Database, embeddingClient?: EmbeddingClient);
102
+ /**
103
+ * Construct pattern text from skill properties for embedding generation.
104
+ * Combines name, description, category, and triggers into a single text
105
+ * that captures the skill's semantic meaning.
106
+ */
107
+ constructPatternText(skill: Omit<Skill, 'id' | 'successCount' | 'failureCount' | 'avgSatisfaction'>): string;
108
+ /**
109
+ * Add a skill with automatic embedding generation.
110
+ * Falls back to adding without embedding if embedding service unavailable.
111
+ */
112
+ addSkillWithEmbedding(skill: Omit<Skill, 'id' | 'successCount' | 'failureCount' | 'avgSatisfaction'>): Promise<string>;
113
+ /**
114
+ * Generate embeddings for all skills that don't have one.
115
+ * Useful for migrating existing skills or after embedding service comes back online.
116
+ */
117
+ generateMissingEmbeddings(): Promise<number>;
118
+ /**
119
+ * Calculate cosine similarity between two embedding vectors.
120
+ * Returns value between -1 and 1, where 1 is identical.
121
+ */
122
+ cosineSimilarity(a: number[], b: number[]): number;
123
+ /**
124
+ * Search skills by embedding similarity (geometric search).
125
+ * Uses cosine similarity to find semantically similar skills.
126
+ */
127
+ searchByEmbedding(query: string, limit?: number): Promise<Skill[]>;
128
+ /**
129
+ * Hybrid search combining trigger-based and embedding-based search.
130
+ * Uses Reciprocal Rank Fusion (RRF) with k=60 to combine results.
131
+ */
132
+ hybridSearch(query: string, limit?: number): Promise<SkillWithScore[]>;
133
+ /**
134
+ * Record co-occurrence between two skills.
135
+ * Used to track which skills are often used together.
136
+ * Normalizes skill pair order for consistency.
137
+ */
138
+ recordCoOccurrence(skillId1: string, skillId2: string): Promise<void>;
139
+ /**
140
+ * Compute relational vectors for skill relationships that meet the threshold.
141
+ * Relational vector = embedding(skill2) - embedding(skill1)
142
+ * Used for analogical reasoning.
143
+ */
144
+ computeRelationalVectors(minCoOccurrenceCount?: number): Promise<number>;
145
+ /**
146
+ * Find analogous skills using relational vectors.
147
+ * Query: "What is to sourceB as targetA is to sourceA?"
148
+ *
149
+ * Uses the relationship between sourceA and targetA to find
150
+ * a similar relationship starting from sourceB.
151
+ */
152
+ analogicalSearch(sourceA: string, targetA: string, sourceB: string, limit?: number): Promise<SkillWithScore[]>;
24
153
  }
25
154
  //# sourceMappingURL=skill-library.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-library.d.ts","sourceRoot":"","sources":["../../src/memory-layers/skill-library.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAoB;gBAElB,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAIjC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,CAAC,GAAG,MAAM;IAiBhG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,KAAK,EAAE;IAkCjD,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAY1D,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAGrC"}
1
+ {"version":3,"file":"skill-library.d.ts","sourceRoot":"","sources":["../../src/memory-layers/skill-library.ts"],"names":[],"mappings":"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"}