@jungjaehoon/mama-core 1.1.2 → 1.1.3

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 (67) hide show
  1. package/dist/config-loader.d.ts +61 -0
  2. package/dist/config-loader.js +187 -0
  3. package/dist/db-adapter/base-adapter.d.ts +76 -0
  4. package/dist/db-adapter/base-adapter.js +11 -0
  5. package/dist/db-adapter/index.d.ts +24 -0
  6. package/dist/db-adapter/index.js +29 -0
  7. package/dist/db-adapter/sqlite-adapter.d.ts +73 -0
  8. package/dist/db-adapter/sqlite-adapter.js +330 -0
  9. package/dist/db-adapter/statement.d.ts +119 -0
  10. package/dist/db-adapter/statement.js +113 -0
  11. package/dist/db-manager.d.ts +252 -0
  12. package/dist/db-manager.js +622 -0
  13. package/dist/debug-logger.d.ts +32 -0
  14. package/dist/debug-logger.js +83 -0
  15. package/dist/decision-formatter.d.ts +172 -0
  16. package/dist/decision-formatter.js +894 -0
  17. package/dist/decision-tracker.d.ts +218 -0
  18. package/dist/decision-tracker.js +531 -0
  19. package/dist/embedding-cache.d.ts +83 -0
  20. package/dist/embedding-cache.js +182 -0
  21. package/dist/embedding-client.d.ts +43 -0
  22. package/dist/embedding-client.js +132 -0
  23. package/dist/embedding-server/index.d.ts +65 -0
  24. package/dist/embedding-server/index.js +397 -0
  25. package/dist/embedding-server/mobile/auth.d.ts +53 -0
  26. package/dist/embedding-server/mobile/auth.js +140 -0
  27. package/dist/embedding-server/mobile/daemon.d.ts +128 -0
  28. package/dist/embedding-server/mobile/daemon.js +303 -0
  29. package/dist/embedding-server/mobile/output-parser.d.ts +115 -0
  30. package/dist/embedding-server/mobile/output-parser.js +241 -0
  31. package/dist/embedding-server/mobile/session-api.d.ts +57 -0
  32. package/dist/embedding-server/mobile/session-api.js +261 -0
  33. package/dist/embedding-server/mobile/session-manager.d.ts +135 -0
  34. package/dist/embedding-server/mobile/session-manager.js +333 -0
  35. package/dist/embedding-server/mobile/websocket-handler.d.ts +127 -0
  36. package/dist/embedding-server/mobile/websocket-handler.js +435 -0
  37. package/dist/embeddings.d.ts +75 -0
  38. package/dist/embeddings.js +262 -0
  39. package/dist/errors.d.ts +131 -0
  40. package/dist/errors.js +225 -0
  41. package/dist/index.d.ts +32 -0
  42. package/dist/index.js +193 -0
  43. package/dist/mama-api.d.ts +954 -0
  44. package/dist/mama-api.js +2210 -0
  45. package/dist/memory-inject.d.ts +24 -0
  46. package/dist/memory-inject.js +116 -0
  47. package/dist/memory-store.d.ts +103 -0
  48. package/dist/memory-store.js +129 -0
  49. package/dist/notification-manager.d.ts +7 -0
  50. package/dist/notification-manager.js +12 -0
  51. package/dist/ollama-client.d.ts +51 -0
  52. package/dist/ollama-client.js +308 -0
  53. package/dist/outcome-tracker.d.ts +165 -0
  54. package/dist/outcome-tracker.js +315 -0
  55. package/dist/progress-indicator.d.ts +48 -0
  56. package/dist/progress-indicator.js +82 -0
  57. package/dist/query-intent.d.ts +27 -0
  58. package/dist/query-intent.js +144 -0
  59. package/dist/relevance-scorer.d.ts +124 -0
  60. package/dist/relevance-scorer.js +243 -0
  61. package/dist/test-utils.d.ts +66 -0
  62. package/dist/test-utils.js +166 -0
  63. package/dist/tier-validator.d.ts +55 -0
  64. package/dist/tier-validator.js +216 -0
  65. package/dist/time-formatter.d.ts +25 -0
  66. package/dist/time-formatter.js +93 -0
  67. package/package.json +3 -2
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ /**
3
+ * MAMA (Memory-Augmented MCP Architecture) - Embedding Cache
4
+ *
5
+ * LRU cache for embedding vectors to avoid re-computation
6
+ *
7
+ * Task 2: Implement Embedding Cache
8
+ * AC #3: Cache embeddings to avoid re-computation
9
+ * Target: > 80% cache hit ratio
10
+ *
11
+ * @module embedding-cache
12
+ */
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.embeddingCache = exports.EmbeddingCache = exports.MAX_CACHE_SIZE = void 0;
18
+ const crypto_1 = __importDefault(require("crypto"));
19
+ // Cache configuration
20
+ exports.MAX_CACHE_SIZE = 1000; // Max 1000 entries (story req 2.2)
21
+ const CLEANUP_THRESHOLD = 1100; // Trigger cleanup at 110%
22
+ /**
23
+ * LRU Cache for embeddings
24
+ *
25
+ * Key: SHA-256 hash of decision text
26
+ * Value: {embedding: Float32Array, timestamp: number, hits: number}
27
+ *
28
+ * Eviction: Least Recently Used when size > MAX_CACHE_SIZE
29
+ */
30
+ class EmbeddingCache {
31
+ cache;
32
+ stats;
33
+ constructor() {
34
+ this.cache = new Map();
35
+ this.stats = {
36
+ hits: 0,
37
+ misses: 0,
38
+ evictions: 0,
39
+ totalSize: 0,
40
+ };
41
+ }
42
+ /**
43
+ * Generate cache key from text
44
+ *
45
+ * Task 2.3: Key = decision text hash (SHA-256)
46
+ */
47
+ generateKey(text) {
48
+ if (!text || typeof text !== 'string') {
49
+ throw new Error('Text must be a non-empty string');
50
+ }
51
+ return crypto_1.default.createHash('sha256').update(text).digest('hex');
52
+ }
53
+ /**
54
+ * Get embedding from cache
55
+ *
56
+ * Task 2.2: Cache hit updates LRU position
57
+ */
58
+ get(text) {
59
+ const key = this.generateKey(text);
60
+ const entry = this.cache.get(key);
61
+ if (entry) {
62
+ // Cache hit - update LRU position
63
+ this.stats.hits++;
64
+ entry.hits++;
65
+ entry.lastAccessed = Date.now();
66
+ // Move to end (most recently used)
67
+ this.cache.delete(key);
68
+ this.cache.set(key, entry);
69
+ return entry.embedding;
70
+ }
71
+ // Cache miss
72
+ this.stats.misses++;
73
+ return null;
74
+ }
75
+ /**
76
+ * Store embedding in cache
77
+ *
78
+ * Task 2.2: Add to cache with LRU tracking
79
+ * Task 2.5: Implement cache eviction (LRU)
80
+ */
81
+ set(text, embedding) {
82
+ const key = this.generateKey(text);
83
+ // Check if already exists (update case)
84
+ if (this.cache.has(key)) {
85
+ const entry = this.cache.get(key);
86
+ entry.embedding = embedding;
87
+ entry.lastAccessed = Date.now();
88
+ // Move to end (most recently used)
89
+ this.cache.delete(key);
90
+ this.cache.set(key, entry);
91
+ return;
92
+ }
93
+ // New entry
94
+ const entry = {
95
+ embedding,
96
+ timestamp: Date.now(),
97
+ lastAccessed: Date.now(),
98
+ hits: 0,
99
+ };
100
+ this.cache.set(key, entry);
101
+ this.stats.totalSize++;
102
+ // Trigger cleanup if threshold exceeded
103
+ if (this.cache.size > CLEANUP_THRESHOLD) {
104
+ this.evictLRU();
105
+ }
106
+ }
107
+ /**
108
+ * Evict least recently used entries
109
+ *
110
+ * Task 2.5: Implement cache eviction (LRU)
111
+ * Strategy: Remove entries until size <= MAX_CACHE_SIZE
112
+ *
113
+ * Eviction order:
114
+ * 1. Oldest lastAccessed (LRU)
115
+ * 2. If tied, lowest hits
116
+ */
117
+ evictLRU() {
118
+ const targetEvictions = this.cache.size - exports.MAX_CACHE_SIZE;
119
+ if (targetEvictions <= 0) {
120
+ return;
121
+ }
122
+ // Convert to array for sorting
123
+ const entries = Array.from(this.cache.entries());
124
+ // Sort by LRU (oldest first), then by hits (lowest first)
125
+ entries.sort((a, b) => {
126
+ const [, entryA] = a;
127
+ const [, entryB] = b;
128
+ // Primary: lastAccessed (ascending - oldest first)
129
+ if (entryA.lastAccessed !== entryB.lastAccessed) {
130
+ return entryA.lastAccessed - entryB.lastAccessed;
131
+ }
132
+ // Secondary: hits (ascending - lowest first)
133
+ return entryA.hits - entryB.hits;
134
+ });
135
+ // Evict oldest entries
136
+ for (let i = 0; i < targetEvictions; i++) {
137
+ const [key] = entries[i];
138
+ this.cache.delete(key);
139
+ this.stats.evictions++;
140
+ this.stats.totalSize--;
141
+ }
142
+ }
143
+ /**
144
+ * Get cache hit ratio
145
+ *
146
+ * Task 2.4: Cache hit ratio target: > 80%
147
+ */
148
+ getHitRatio() {
149
+ const total = this.stats.hits + this.stats.misses;
150
+ if (total === 0) {
151
+ return 0;
152
+ }
153
+ return this.stats.hits / total;
154
+ }
155
+ /**
156
+ * Get cache statistics
157
+ */
158
+ getStats() {
159
+ return {
160
+ ...this.stats,
161
+ hitRatio: this.getHitRatio(),
162
+ size: this.cache.size,
163
+ maxSize: exports.MAX_CACHE_SIZE,
164
+ };
165
+ }
166
+ /**
167
+ * Clear cache
168
+ */
169
+ clear() {
170
+ this.cache.clear();
171
+ this.stats = {
172
+ hits: 0,
173
+ misses: 0,
174
+ evictions: 0,
175
+ totalSize: 0,
176
+ };
177
+ }
178
+ }
179
+ exports.EmbeddingCache = EmbeddingCache;
180
+ // Singleton instance
181
+ exports.embeddingCache = new EmbeddingCache();
182
+ //# sourceMappingURL=embedding-cache.js.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * MAMA Embedding Client
3
+ *
4
+ * HTTP client for the embedding server running in MCP server.
5
+ * Used by hooks for fast embedding generation.
6
+ *
7
+ * Features:
8
+ * - Auto-discovery via port file
9
+ * - Timeout handling
10
+ * - Fallback to local embedding when server unavailable
11
+ *
12
+ * @module embedding-client
13
+ */
14
+ export declare const DEFAULT_PORT: number;
15
+ export declare const HOST = "127.0.0.1";
16
+ export declare const TIMEOUT_MS = 500;
17
+ export declare const PORT_FILE: string;
18
+ export interface ServerStatus {
19
+ status: string;
20
+ model?: string;
21
+ dimension?: number;
22
+ uptime?: number;
23
+ }
24
+ /**
25
+ * Get server port from port file or default
26
+ */
27
+ export declare function getServerPort(): number;
28
+ /**
29
+ * Check if embedding server is running
30
+ */
31
+ export declare function isServerRunning(): Promise<boolean>;
32
+ /**
33
+ * Generate embedding via HTTP server
34
+ *
35
+ * @param text - Text to embed
36
+ * @returns Embedding or null if failed
37
+ */
38
+ export declare function getEmbeddingFromServer(text: string): Promise<Float32Array | null>;
39
+ /**
40
+ * Get server status
41
+ */
42
+ export declare function getServerStatus(): Promise<ServerStatus | null>;
43
+ //# sourceMappingURL=embedding-client.d.ts.map
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * MAMA Embedding Client
4
+ *
5
+ * HTTP client for the embedding server running in MCP server.
6
+ * Used by hooks for fast embedding generation.
7
+ *
8
+ * Features:
9
+ * - Auto-discovery via port file
10
+ * - Timeout handling
11
+ * - Fallback to local embedding when server unavailable
12
+ *
13
+ * @module embedding-client
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.PORT_FILE = exports.TIMEOUT_MS = exports.HOST = exports.DEFAULT_PORT = void 0;
20
+ exports.getServerPort = getServerPort;
21
+ exports.isServerRunning = isServerRunning;
22
+ exports.getEmbeddingFromServer = getEmbeddingFromServer;
23
+ exports.getServerStatus = getServerStatus;
24
+ const fs_1 = __importDefault(require("fs"));
25
+ const path_1 = __importDefault(require("path"));
26
+ const debug_logger_js_1 = require("./debug-logger.js");
27
+ function resolveConfiguredPort() {
28
+ const rawPort = process.env.MAMA_EMBEDDING_PORT || process.env.MAMA_HTTP_PORT || '';
29
+ const parsedPort = parseInt(rawPort, 10);
30
+ if (Number.isInteger(parsedPort) && parsedPort > 0 && parsedPort < 65536) {
31
+ return parsedPort;
32
+ }
33
+ return 3849;
34
+ }
35
+ // Configuration
36
+ exports.DEFAULT_PORT = resolveConfiguredPort();
37
+ exports.HOST = '127.0.0.1';
38
+ exports.TIMEOUT_MS = 500; // 500ms timeout for fast response
39
+ exports.PORT_FILE = path_1.default.join(process.env.HOME || '/tmp', '.mama-embedding-port');
40
+ /**
41
+ * Get server port from port file or default
42
+ */
43
+ function getServerPort() {
44
+ try {
45
+ if (fs_1.default.existsSync(exports.PORT_FILE)) {
46
+ const port = parseInt(fs_1.default.readFileSync(exports.PORT_FILE, 'utf8').trim(), 10);
47
+ if (port > 0 && port < 65536) {
48
+ return port;
49
+ }
50
+ }
51
+ }
52
+ catch {
53
+ // Ignore errors, use default
54
+ }
55
+ return exports.DEFAULT_PORT;
56
+ }
57
+ /**
58
+ * Check if embedding server is running
59
+ */
60
+ async function isServerRunning() {
61
+ const port = getServerPort();
62
+ try {
63
+ const controller = new AbortController();
64
+ const timeout = setTimeout(() => controller.abort(), 200);
65
+ const response = await fetch(`http://${exports.HOST}:${port}/health`, {
66
+ signal: controller.signal,
67
+ });
68
+ clearTimeout(timeout);
69
+ return response.ok;
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ }
75
+ /**
76
+ * Generate embedding via HTTP server
77
+ *
78
+ * @param text - Text to embed
79
+ * @returns Embedding or null if failed
80
+ */
81
+ async function getEmbeddingFromServer(text) {
82
+ const port = getServerPort();
83
+ try {
84
+ const controller = new AbortController();
85
+ const timeout = setTimeout(() => controller.abort(), exports.TIMEOUT_MS);
86
+ const response = await fetch(`http://${exports.HOST}:${port}/embed`, {
87
+ method: 'POST',
88
+ headers: { 'Content-Type': 'application/json' },
89
+ body: JSON.stringify({ text }),
90
+ signal: controller.signal,
91
+ });
92
+ clearTimeout(timeout);
93
+ if (!response.ok) {
94
+ const error = (await response.json());
95
+ throw new Error(error.error || 'Server error');
96
+ }
97
+ const result = (await response.json());
98
+ (0, debug_logger_js_1.info)(`[EmbeddingClient] Got embedding in ${result.latency}ms from server`);
99
+ return new Float32Array(result.embedding);
100
+ }
101
+ catch (error) {
102
+ if (error instanceof Error && error.name === 'AbortError') {
103
+ (0, debug_logger_js_1.warn)('[EmbeddingClient] Server timeout, will use fallback');
104
+ return null;
105
+ }
106
+ const message = error instanceof Error ? error.message : String(error);
107
+ (0, debug_logger_js_1.warn)(`[EmbeddingClient] Server error: ${message}`);
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * Get server status
113
+ */
114
+ async function getServerStatus() {
115
+ const port = getServerPort();
116
+ try {
117
+ const controller = new AbortController();
118
+ const timeout = setTimeout(() => controller.abort(), 200);
119
+ const response = await fetch(`http://${exports.HOST}:${port}/health`, {
120
+ signal: controller.signal,
121
+ });
122
+ clearTimeout(timeout);
123
+ if (response.ok) {
124
+ return (await response.json());
125
+ }
126
+ return null;
127
+ }
128
+ catch {
129
+ return null;
130
+ }
131
+ }
132
+ //# sourceMappingURL=embedding-client.js.map
@@ -0,0 +1,65 @@
1
+ /**
2
+ * MAMA Embedding HTTP Server
3
+ *
4
+ * HTTP API for embedding generation, integrated with MCP server.
5
+ * Provides fast embedding access for Claude Code hooks.
6
+ *
7
+ * Features:
8
+ * - Model stays loaded in memory (singleton)
9
+ * - HTTP API at localhost:${MAMA_EMBEDDING_PORT || MAMA_HTTP_PORT || 3849}
10
+ * - Health check endpoint
11
+ * - Shared model with MCP server
12
+ *
13
+ * @module embedding-http-server
14
+ */
15
+ import type { IncomingMessage, ServerResponse, Server as HTTPServer } from 'http';
16
+ export declare const SHUTDOWN_TOKEN: string;
17
+ export declare const DEFAULT_PORT: number;
18
+ export declare const HOST = "127.0.0.1";
19
+ export declare const PORT_FILE: string;
20
+ /**
21
+ * Request handler type
22
+ */
23
+ type RequestHandler = (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
24
+ /**
25
+ * MessageRouter interface
26
+ */
27
+ interface MessageRouter {
28
+ process(message: unknown): Promise<unknown>;
29
+ }
30
+ /**
31
+ * SessionStore interface
32
+ */
33
+ interface SessionStore {
34
+ getHistory?(sessionId: string): unknown[];
35
+ getHistoryByChannel?(source: string, channelId: string): unknown[];
36
+ }
37
+ /**
38
+ * Server options
39
+ */
40
+ export interface ServerOptions {
41
+ messageRouter?: MessageRouter;
42
+ sessionStore?: SessionStore;
43
+ graphHandler?: RequestHandler;
44
+ }
45
+ /**
46
+ * Clean up port file on exit
47
+ */
48
+ export declare function cleanupPortFile(): void;
49
+ /**
50
+ * Start the HTTP embedding server
51
+ *
52
+ * @param port - Port to listen on (default: DEFAULT_PORT)
53
+ * @returns HTTP server instance
54
+ */
55
+ export declare function startEmbeddingServer(port?: number, options?: ServerOptions): Promise<HTTPServer | null>;
56
+ /**
57
+ * Pre-warm the embedding model
58
+ */
59
+ export declare function warmModel(): Promise<{
60
+ success: boolean;
61
+ latency?: number;
62
+ error?: string;
63
+ }>;
64
+ export {};
65
+ //# sourceMappingURL=index.d.ts.map