@oobe-protocol-labs/sap-mcp-server 0.9.21 → 0.9.35

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 (190) hide show
  1. package/.env.example +11 -1
  2. package/CHANGELOG.md +233 -6
  3. package/README.md +3 -3
  4. package/USER_DOCS/00_START_HERE.md +9 -1
  5. package/USER_DOCS/01_HOSTED_REMOTE_MCP.md +1 -1
  6. package/USER_DOCS/04_CLIENT_CONFIGS.md +3 -3
  7. package/USER_DOCS/06_DESKTOP_GUI_WIZARD.md +5 -5
  8. package/config.example.json +1 -1
  9. package/config.secure-example.json +1 -1
  10. package/dist/config/env.d.ts +18 -0
  11. package/dist/config/env.d.ts.map +1 -1
  12. package/dist/config/env.js +14 -2
  13. package/dist/config/env.js.map +1 -1
  14. package/dist/config/mcp-client-injection.js +3 -3
  15. package/dist/config/paths.d.ts +9 -1
  16. package/dist/config/paths.d.ts.map +1 -1
  17. package/dist/config/paths.js +15 -1
  18. package/dist/config/paths.js.map +1 -1
  19. package/dist/config/wizard.d.ts.map +1 -1
  20. package/dist/config/wizard.js +3 -1
  21. package/dist/config/wizard.js.map +1 -1
  22. package/dist/core/constants.d.ts +1 -1
  23. package/dist/core/constants.js +1 -1
  24. package/dist/core/logger.js +1 -1
  25. package/dist/memory/async-processor.d.ts +107 -0
  26. package/dist/memory/async-processor.d.ts.map +1 -0
  27. package/dist/memory/async-processor.js +204 -0
  28. package/dist/memory/async-processor.js.map +1 -0
  29. package/dist/memory/auto-record.d.ts +47 -0
  30. package/dist/memory/auto-record.d.ts.map +1 -0
  31. package/dist/memory/auto-record.js +133 -0
  32. package/dist/memory/auto-record.js.map +1 -0
  33. package/dist/memory/database.d.ts +103 -0
  34. package/dist/memory/database.d.ts.map +1 -0
  35. package/dist/memory/database.js +337 -0
  36. package/dist/memory/database.js.map +1 -0
  37. package/dist/memory/hermes-bridge.d.ts +70 -0
  38. package/dist/memory/hermes-bridge.d.ts.map +1 -0
  39. package/dist/memory/hermes-bridge.js +155 -0
  40. package/dist/memory/hermes-bridge.js.map +1 -0
  41. package/dist/memory/index.d.ts +23 -0
  42. package/dist/memory/index.d.ts.map +1 -0
  43. package/dist/memory/index.js +22 -0
  44. package/dist/memory/index.js.map +1 -0
  45. package/dist/memory/memory-store.d.ts +76 -0
  46. package/dist/memory/memory-store.d.ts.map +1 -0
  47. package/dist/memory/memory-store.js +231 -0
  48. package/dist/memory/memory-store.js.map +1 -0
  49. package/dist/memory/stream-buffer-store.d.ts +69 -0
  50. package/dist/memory/stream-buffer-store.d.ts.map +1 -0
  51. package/dist/memory/stream-buffer-store.js +182 -0
  52. package/dist/memory/stream-buffer-store.js.map +1 -0
  53. package/dist/memory/tool-call-store.d.ts +68 -0
  54. package/dist/memory/tool-call-store.d.ts.map +1 -0
  55. package/dist/memory/tool-call-store.js +189 -0
  56. package/dist/memory/tool-call-store.js.map +1 -0
  57. package/dist/memory/types.d.ts +197 -0
  58. package/dist/memory/types.d.ts.map +1 -0
  59. package/dist/memory/types.js +15 -0
  60. package/dist/memory/types.js.map +1 -0
  61. package/dist/memory/utils.d.ts +30 -0
  62. package/dist/memory/utils.d.ts.map +1 -0
  63. package/dist/memory/utils.js +47 -0
  64. package/dist/memory/utils.js.map +1 -0
  65. package/dist/payments/hosted-tool-eligibility.d.ts.map +1 -1
  66. package/dist/payments/hosted-tool-eligibility.js +4 -6
  67. package/dist/payments/hosted-tool-eligibility.js.map +1 -1
  68. package/dist/payments/monetization-gate.d.ts +39 -0
  69. package/dist/payments/monetization-gate.d.ts.map +1 -1
  70. package/dist/payments/monetization-gate.js +165 -11
  71. package/dist/payments/monetization-gate.js.map +1 -1
  72. package/dist/payments/pricing.d.ts.map +1 -1
  73. package/dist/payments/pricing.js +69 -0
  74. package/dist/payments/pricing.js.map +1 -1
  75. package/dist/payments/x402-paid-call.js +1 -1
  76. package/dist/premium/builtin-plugins.d.ts +42 -0
  77. package/dist/premium/builtin-plugins.d.ts.map +1 -1
  78. package/dist/premium/builtin-plugins.js +91 -10
  79. package/dist/premium/builtin-plugins.js.map +1 -1
  80. package/dist/premium/manifest-builder.d.ts.map +1 -1
  81. package/dist/premium/manifest-builder.js +43 -7
  82. package/dist/premium/manifest-builder.js.map +1 -1
  83. package/dist/premium/meme-radar-capabilities.js +9 -9
  84. package/dist/premium/meme-radar-capabilities.js.map +1 -1
  85. package/dist/premium/plugin-validator.d.ts.map +1 -1
  86. package/dist/premium/plugin-validator.js +62 -1
  87. package/dist/premium/plugin-validator.js.map +1 -1
  88. package/dist/premium/provider-bridge.d.ts +25 -1
  89. package/dist/premium/provider-bridge.d.ts.map +1 -1
  90. package/dist/premium/provider-bridge.js +130 -20
  91. package/dist/premium/provider-bridge.js.map +1 -1
  92. package/dist/premium/session-manager.d.ts.map +1 -1
  93. package/dist/premium/session-manager.js +12 -3
  94. package/dist/premium/session-manager.js.map +1 -1
  95. package/dist/premium/tech-fundamentals-capabilities.js +5 -5
  96. package/dist/premium/tech-fundamentals-capabilities.js.map +1 -1
  97. package/dist/premium/trading-capabilities.js +5 -5
  98. package/dist/premium/trading-capabilities.js.map +1 -1
  99. package/dist/premium/webhook-engine.d.ts.map +1 -1
  100. package/dist/premium/webhook-engine.js +7 -1
  101. package/dist/premium/webhook-engine.js.map +1 -1
  102. package/dist/prompts/context/sap-agent-context.prompt.js +1 -1
  103. package/dist/prompts/payments/explain-x402-settlement.prompt.js +1 -1
  104. package/dist/remote/premium-routes.d.ts.map +1 -1
  105. package/dist/remote/premium-routes.js +3 -2
  106. package/dist/remote/premium-routes.js.map +1 -1
  107. package/dist/remote/public-home/sections.d.ts.map +1 -1
  108. package/dist/remote/public-home/sections.js +2 -3
  109. package/dist/remote/public-home/sections.js.map +1 -1
  110. package/dist/remote/public-home/styles.d.ts +1 -1
  111. package/dist/remote/public-home/styles.js +2 -2
  112. package/dist/remote/server.d.ts.map +1 -1
  113. package/dist/remote/server.js +19 -4
  114. package/dist/remote/server.js.map +1 -1
  115. package/dist/server/server-metadata.js +1 -1
  116. package/dist/strategies/strategy-store.d.ts +82 -0
  117. package/dist/strategies/strategy-store.d.ts.map +1 -0
  118. package/dist/strategies/strategy-store.js +165 -0
  119. package/dist/strategies/strategy-store.js.map +1 -0
  120. package/dist/tools/agent-start-tool.d.ts.map +1 -1
  121. package/dist/tools/agent-start-tool.js +97 -10
  122. package/dist/tools/agent-start-tool.js.map +1 -1
  123. package/dist/tools/client-sdk-tools.d.ts.map +1 -1
  124. package/dist/tools/client-sdk-tools.js +152 -9
  125. package/dist/tools/client-sdk-tools.js.map +1 -1
  126. package/dist/tools/estimate-tool-cost.js +1 -1
  127. package/dist/tools/estimate-tool-cost.js.map +1 -1
  128. package/dist/tools/index.d.ts +1 -0
  129. package/dist/tools/index.d.ts.map +1 -1
  130. package/dist/tools/index.js +2 -0
  131. package/dist/tools/index.js.map +1 -1
  132. package/dist/tools/magicblock-tools.js +5 -5
  133. package/dist/tools/magicblock-tools.js.map +1 -1
  134. package/dist/tools/memory-tools.d.ts +26 -0
  135. package/dist/tools/memory-tools.d.ts.map +1 -0
  136. package/dist/tools/memory-tools.js +533 -0
  137. package/dist/tools/memory-tools.js.map +1 -0
  138. package/dist/tools/perp-tools.d.ts +7 -9
  139. package/dist/tools/perp-tools.d.ts.map +1 -1
  140. package/dist/tools/perp-tools.js +386 -367
  141. package/dist/tools/perp-tools.js.map +1 -1
  142. package/dist/tools/premium-tools.d.ts.map +1 -1
  143. package/dist/tools/premium-tools.js +8 -2
  144. package/dist/tools/premium-tools.js.map +1 -1
  145. package/dist/tools/profile-tools.d.ts.map +1 -1
  146. package/dist/tools/profile-tools.js +18 -1
  147. package/dist/tools/profile-tools.js.map +1 -1
  148. package/dist/tools/quick-context-tool.d.ts.map +1 -1
  149. package/dist/tools/quick-context-tool.js +100 -9
  150. package/dist/tools/quick-context-tool.js.map +1 -1
  151. package/dist/tools/register-tools.d.ts.map +1 -1
  152. package/dist/tools/register-tools.js +3 -0
  153. package/dist/tools/register-tools.js.map +1 -1
  154. package/dist/tools/sap-sdk-tools.js +3 -3
  155. package/dist/tools/sap-sdk-tools.js.map +1 -1
  156. package/dist/tools/session-context-packet.d.ts +19 -0
  157. package/dist/tools/session-context-packet.d.ts.map +1 -0
  158. package/dist/tools/session-context-packet.js +256 -0
  159. package/dist/tools/session-context-packet.js.map +1 -0
  160. package/dist/tools/skills-tools.d.ts +10 -0
  161. package/dist/tools/skills-tools.d.ts.map +1 -1
  162. package/dist/tools/skills-tools.js +19 -0
  163. package/dist/tools/skills-tools.js.map +1 -1
  164. package/dist/tools/transaction-tools.d.ts +1 -0
  165. package/dist/tools/transaction-tools.d.ts.map +1 -1
  166. package/dist/tools/transaction-tools.js +248 -9
  167. package/dist/tools/transaction-tools.js.map +1 -1
  168. package/dist/tools/x402-paid-call-tool.d.ts.map +1 -1
  169. package/dist/tools/x402-paid-call-tool.js +55 -21
  170. package/dist/tools/x402-paid-call-tool.js.map +1 -1
  171. package/dist/wizard-core/desktop-flow.d.ts.map +1 -1
  172. package/dist/wizard-core/desktop-flow.js +4 -2
  173. package/dist/wizard-core/desktop-flow.js.map +1 -1
  174. package/docs/06_PAYMENTS_X402_AND_PAYSH.md +14 -5
  175. package/docs/07_ENDPOINTS_AND_CLIENTS.md +1 -1
  176. package/docs/09_TOOLS_SKILLS_AND_AGENT_GUIDE.md +13 -5
  177. package/docs/13_BOUNTY_PROGRAM_PROPOSAL.md +1 -1
  178. package/docs/14_DESKTOP_WIZARD_RELEASE.md +3 -3
  179. package/docs/15_DASHBOARD_SCREENSHARE_SCRIPT.md +1 -1
  180. package/docs/BRANCH_AND_CI.md +2 -2
  181. package/docs/README.md +1 -1
  182. package/package.json +3 -1
  183. package/server.json +3 -3
  184. package/skills/README.md +1 -1
  185. package/skills/sap-agentkit/SKILL.md +1 -2
  186. package/skills/sap-defi/SKILL.md +31 -2
  187. package/skills/sap-mcp/SKILL.md +24 -13
  188. package/skills/sap-mcp/TOOL_REFERENCE.md +2 -4
  189. package/skills/sap-payments-x402/SKILL.md +15 -3
  190. package/assets/logos/drift.svg +0 -12
@@ -0,0 +1,337 @@
1
+ /**
2
+ * @module memory/database
3
+ * @description Thread-safe SQLite database manager for the SAP MCP agent memory subsystem.
4
+ *
5
+ * Uses better-sqlite3 (synchronous, native, FTS5-enabled) with WAL mode for
6
+ * concurrent read access. The database is a singleton — one connection per process.
7
+ *
8
+ * Design principles:
9
+ * - Synchronous I/O: better-sqlite3 is synchronous, no async overhead, no callback hell.
10
+ * - WAL mode: readers don't block writers, crash-safe via WAL journal.
11
+ * - Prepared statements: cached for performance, reused across calls.
12
+ * - FTS5: inverted full-text index for relevance-ranked retrieval.
13
+ * - Schema versioning: idempotent migrations on init.
14
+ * - Graceful degradation: if the DB can't be opened, tools return empty results.
15
+ */
16
+ import Database from 'better-sqlite3';
17
+ import { mkdirSync, statSync } from 'fs';
18
+ import { dirname, join } from 'path';
19
+ import { logger } from '../core/logger.js';
20
+ import { getMemoryDir } from '../config/paths.js';
21
+ /**
22
+ * @name SCHEMA_VERSION
23
+ * @description Current schema version. Increment when the schema changes.
24
+ * The database tracks this in the `_meta` table and runs migrations as needed.
25
+ */
26
+ const SCHEMA_VERSION = 1;
27
+ /**
28
+ * @name DEFAULT_CONFIG
29
+ * @description Default memory configuration. The DB is stored in
30
+ * ~/.config/mcp-sap/memory/ which is the standard SAP MCP config directory.
31
+ */
32
+ export const DEFAULT_CONFIG = {
33
+ dbPath: join(getMemoryDir(), 'agent-memory.db'),
34
+ enableWal: true,
35
+ maxPayloadBytes: 8192,
36
+ relevanceDecayPerDay: 0.01,
37
+ minRelevanceThreshold: 0.05,
38
+ toolCallRetentionDays: 90,
39
+ maxStreamBufferSize: 10_000,
40
+ };
41
+ /**
42
+ * @name MemoryDatabase
43
+ * @description Thread-safe singleton managing the SQLite connection for agent memory.
44
+ *
45
+ * The class lazily initializes the database on first access and caches prepared
46
+ * statements for performance. All methods are synchronous (better-sqlite3 is
47
+ * synchronous by design). The database runs in WAL mode for concurrent reads.
48
+ *
49
+ * If the database cannot be opened (e.g. disk full, permissions), the instance
50
+ * enters a degraded mode where all queries return empty results instead of
51
+ * crashing the MCP server.
52
+ */
53
+ export class MemoryDatabase {
54
+ db = null;
55
+ config;
56
+ degraded = false;
57
+ initialized = false;
58
+ statements = new Map();
59
+ constructor(config = {}) {
60
+ this.config = { ...DEFAULT_CONFIG, ...config };
61
+ }
62
+ /**
63
+ * @name init
64
+ * @description Initializes the database connection, creates the schema, and
65
+ * enables WAL mode. Called lazily on first query.
66
+ */
67
+ init() {
68
+ if (this.initialized)
69
+ return;
70
+ this.initialized = true;
71
+ try {
72
+ // Ensure the directory exists.
73
+ const dir = dirname(this.config.dbPath);
74
+ mkdirSync(dir, { recursive: true });
75
+ // Open the database with better-sqlite3.
76
+ this.db = new Database(this.config.dbPath);
77
+ // Enable WAL mode for concurrent read access and crash safety.
78
+ if (this.config.enableWal) {
79
+ this.db.pragma('journal_mode = WAL');
80
+ this.db.pragma('synchronous = NORMAL');
81
+ this.db.pragma('wal_autocheckpoint = 1000');
82
+ }
83
+ // Set busy timeout to 5 seconds for concurrent access.
84
+ this.db.pragma('busy_timeout = 5000');
85
+ // Run schema migrations.
86
+ this.runMigrations();
87
+ // Prepare cached statements.
88
+ this.prepareStatements();
89
+ logger.info('Memory database initialized', {
90
+ path: this.config.dbPath,
91
+ wal: this.config.enableWal,
92
+ schemaVersion: SCHEMA_VERSION,
93
+ });
94
+ }
95
+ catch (error) {
96
+ logger.error('Memory database initialization failed — entering degraded mode', {
97
+ error: error instanceof Error ? error.message : String(error),
98
+ path: this.config.dbPath,
99
+ });
100
+ this.degraded = true;
101
+ }
102
+ }
103
+ /**
104
+ * @name getDb
105
+ * @description Returns the underlying Database instance. Throws if degraded.
106
+ * @internal
107
+ */
108
+ getDb() {
109
+ if (this.degraded || !this.db) {
110
+ throw new Error('Memory database is in degraded mode — queries return empty results.');
111
+ }
112
+ return this.db;
113
+ }
114
+ /**
115
+ * @name isDegraded
116
+ * @description Returns true if the database is in degraded mode (init failed).
117
+ */
118
+ isDegraded() {
119
+ return this.degraded;
120
+ }
121
+ /**
122
+ * @name getStatement
123
+ * @description Returns a cached prepared statement by key.
124
+ * @internal
125
+ */
126
+ getStatement(key) {
127
+ return this.statements.get(key);
128
+ }
129
+ /**
130
+ * @name close
131
+ * @description Closes the database connection gracefully.
132
+ */
133
+ close() {
134
+ if (this.db) {
135
+ try {
136
+ this.db.close();
137
+ }
138
+ catch {
139
+ // Best-effort close.
140
+ }
141
+ this.db = null;
142
+ }
143
+ this.statements.clear();
144
+ this.initialized = false;
145
+ }
146
+ /**
147
+ * @name getDbSize
148
+ * @description Returns the database file size in bytes.
149
+ */
150
+ getDbSize() {
151
+ try {
152
+ return statSync(this.config.dbPath).size;
153
+ }
154
+ catch {
155
+ return 0;
156
+ }
157
+ }
158
+ // ── Schema Migrations ──────────────────────────────────────────────────────
159
+ /**
160
+ * @name runMigrations
161
+ * @description Runs idempotent schema migrations. Each migration checks if
162
+ * the current schema version is below the target and applies changes.
163
+ * @internal
164
+ */
165
+ runMigrations() {
166
+ if (!this.db)
167
+ return;
168
+ // Create _meta table if it doesn't exist.
169
+ this.db.exec(`
170
+ CREATE TABLE IF NOT EXISTS _meta (
171
+ key TEXT PRIMARY KEY,
172
+ value TEXT NOT NULL
173
+ );
174
+ `);
175
+ // Get current schema version.
176
+ const versionRow = this.db.prepare('SELECT value FROM _meta WHERE key = ?').get('schema_version');
177
+ const currentVersion = versionRow ? parseInt(versionRow.value, 10) : 0;
178
+ if (currentVersion < 1) {
179
+ this.migrateToV1();
180
+ }
181
+ // Update schema version.
182
+ this.db.prepare('INSERT OR REPLACE INTO _meta (key, value) VALUES (?, ?)').run('schema_version', SCHEMA_VERSION.toString());
183
+ }
184
+ /**
185
+ * @name migrateToV1
186
+ * @description Creates the initial schema: tool_calls, agent_memory,
187
+ * stream_buffers, and their FTS5 indexes.
188
+ * @internal
189
+ */
190
+ migrateToV1() {
191
+ if (!this.db)
192
+ return;
193
+ this.db.exec(`
194
+ -- Tool call history
195
+ CREATE TABLE IF NOT EXISTS tool_calls (
196
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
197
+ tool_name TEXT NOT NULL,
198
+ session_id TEXT,
199
+ caller_profile TEXT,
200
+ input TEXT,
201
+ output TEXT,
202
+ outcome TEXT NOT NULL DEFAULT 'success',
203
+ cost_usd REAL DEFAULT 0,
204
+ tx_signature TEXT,
205
+ latency_ms INTEGER,
206
+ created_at TEXT DEFAULT (datetime('now')),
207
+ updated_at TEXT DEFAULT (datetime('now'))
208
+ );
209
+
210
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_tool ON tool_calls(tool_name);
211
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_session ON tool_calls(session_id);
212
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_outcome ON tool_calls(outcome);
213
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_created ON tool_calls(created_at);
214
+
215
+ -- FTS5 inverted index for tool call search
216
+ CREATE VIRTUAL TABLE IF NOT EXISTS tool_calls_fts USING fts5(
217
+ tool_name,
218
+ input,
219
+ output,
220
+ content='tool_calls',
221
+ content_rowid='id'
222
+ );
223
+
224
+ -- Triggers to keep FTS index in sync with tool_calls
225
+ CREATE TRIGGER IF NOT EXISTS tool_calls_ai AFTER INSERT ON tool_calls BEGIN
226
+ INSERT INTO tool_calls_fts(rowid, tool_name, input, output)
227
+ VALUES (new.id, new.tool_name, new.input, new.output);
228
+ END;
229
+
230
+ CREATE TRIGGER IF NOT EXISTS tool_calls_ad AFTER DELETE ON tool_calls BEGIN
231
+ INSERT INTO tool_calls_fts(tool_calls_fts, rowid, tool_name, input, output)
232
+ VALUES ('delete', old.id, old.tool_name, old.input, old.output);
233
+ END;
234
+
235
+ CREATE TRIGGER IF NOT EXISTS tool_calls_au AFTER UPDATE ON tool_calls BEGIN
236
+ INSERT INTO tool_calls_fts(tool_calls_fts, rowid, tool_name, input, output)
237
+ VALUES ('delete', old.id, old.tool_name, old.input, old.output);
238
+ INSERT INTO tool_calls_fts(rowid, tool_name, input, output)
239
+ VALUES (new.id, new.tool_name, new.input, new.output);
240
+ END;
241
+
242
+ -- Agent memory — LLM-generated summaries
243
+ CREATE TABLE IF NOT EXISTS agent_memory (
244
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
245
+ memory_type TEXT NOT NULL,
246
+ category TEXT NOT NULL,
247
+ summary TEXT NOT NULL,
248
+ source_tool_calls TEXT,
249
+ relevance_score REAL DEFAULT 0.5,
250
+ created_at TEXT DEFAULT (datetime('now')),
251
+ expires_at TEXT,
252
+ last_accessed_at TEXT DEFAULT (datetime('now'))
253
+ );
254
+
255
+ CREATE INDEX IF NOT EXISTS idx_agent_memory_category ON agent_memory(category);
256
+ CREATE INDEX IF NOT EXISTS idx_agent_memory_relevance ON agent_memory(relevance_score);
257
+ CREATE INDEX IF NOT EXISTS idx_agent_memory_type ON agent_memory(memory_type);
258
+
259
+ -- FTS5 inverted index for agent memory search
260
+ CREATE VIRTUAL TABLE IF NOT EXISTS agent_memory_fts USING fts5(
261
+ memory_type,
262
+ category,
263
+ summary,
264
+ content='agent_memory',
265
+ content_rowid='id'
266
+ );
267
+
268
+ -- Triggers to keep FTS index in sync with agent_memory
269
+ CREATE TRIGGER IF NOT EXISTS agent_memory_ai AFTER INSERT ON agent_memory BEGIN
270
+ INSERT INTO agent_memory_fts(rowid, memory_type, category, summary)
271
+ VALUES (new.id, new.memory_type, new.category, new.summary);
272
+ END;
273
+
274
+ CREATE TRIGGER IF NOT EXISTS agent_memory_ad AFTER DELETE ON agent_memory BEGIN
275
+ INSERT INTO agent_memory_fts(agent_memory_fts, rowid, memory_type, category, summary)
276
+ VALUES ('delete', old.id, old.memory_type, old.category, old.summary);
277
+ END;
278
+
279
+ CREATE TRIGGER IF NOT EXISTS agent_memory_au AFTER UPDATE ON agent_memory BEGIN
280
+ INSERT INTO agent_memory_fts(agent_memory_fts, rowid, memory_type, category, summary)
281
+ VALUES ('delete', old.id, old.memory_type, old.category, old.summary);
282
+ INSERT INTO agent_memory_fts(rowid, memory_type, category, summary)
283
+ VALUES (new.id, new.memory_type, new.category, new.summary);
284
+ END;
285
+
286
+ -- Stream buffer events
287
+ CREATE TABLE IF NOT EXISTS stream_buffers (
288
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
289
+ stream_type TEXT NOT NULL,
290
+ event_id TEXT NOT NULL,
291
+ event_type TEXT NOT NULL,
292
+ payload TEXT NOT NULL,
293
+ consumed INTEGER DEFAULT 0,
294
+ created_at TEXT DEFAULT (datetime('now'))
295
+ );
296
+
297
+ CREATE INDEX IF NOT EXISTS idx_stream_buffers_type ON stream_buffers(stream_type);
298
+ CREATE INDEX IF NOT EXISTS idx_stream_buffers_consumed ON stream_buffers(consumed);
299
+ CREATE INDEX IF NOT EXISTS idx_stream_buffers_created ON stream_buffers(created_at);
300
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_stream_buffers_event ON stream_buffers(stream_type, event_id);
301
+ `);
302
+ }
303
+ /**
304
+ * @name prepareStatements
305
+ * @description Pre-compiles and caches frequently used SQL statements.
306
+ * @internal
307
+ */
308
+ prepareStatements() {
309
+ if (!this.db)
310
+ return;
311
+ // Tool calls
312
+ this.statements.set('insert_tool_call', this.db.prepare(`INSERT INTO tool_calls (tool_name, session_id, caller_profile, input, output, outcome, cost_usd, tx_signature, latency_ms)
313
+ VALUES (@toolName, @sessionId, @callerProfile, @input, @output, @outcome, @costUsd, @txSignature, @latencyMs)`));
314
+ this.statements.set('count_tool_calls', this.db.prepare('SELECT COUNT(*) as count FROM tool_calls'));
315
+ this.statements.set('count_tool_calls_by_outcome', this.db.prepare('SELECT outcome, COUNT(*) as count FROM tool_calls GROUP BY outcome'));
316
+ this.statements.set('last_tool_call_at', this.db.prepare('SELECT created_at FROM tool_calls ORDER BY id DESC LIMIT 1'));
317
+ // Agent memory
318
+ this.statements.set('insert_memory', this.db.prepare(`INSERT INTO agent_memory (memory_type, category, summary, source_tool_calls, relevance_score, expires_at)
319
+ VALUES (@memoryType, @category, @summary, @sourceToolCalls, @relevanceScore, @expiresAt)`));
320
+ this.statements.set('count_memory', this.db.prepare('SELECT COUNT(*) as count FROM agent_memory'));
321
+ this.statements.set('count_memory_by_type', this.db.prepare('SELECT memory_type, COUNT(*) as count FROM agent_memory GROUP BY memory_type'));
322
+ this.statements.set('last_memory_at', this.db.prepare('SELECT created_at FROM agent_memory ORDER BY id DESC LIMIT 1'));
323
+ this.statements.set('update_memory_access', this.db.prepare('UPDATE agent_memory SET last_accessed_at = datetime(\'now\') WHERE id = ?'));
324
+ // Stream buffers
325
+ this.statements.set('count_pending_streams', this.db.prepare('SELECT COUNT(*) as count FROM stream_buffers WHERE consumed = 0'));
326
+ this.statements.set('insert_stream_event', this.db.prepare(`INSERT OR IGNORE INTO stream_buffers (stream_type, event_id, event_type, payload, consumed)
327
+ VALUES (@streamType, @eventId, @eventType, @payload, 0)`));
328
+ this.statements.set('consume_stream_events', this.db.prepare('UPDATE stream_buffers SET consumed = 1 WHERE stream_type = ? AND id <= ?'));
329
+ }
330
+ }
331
+ /**
332
+ * @name memoryDatabase
333
+ * @description Singleton instance of the memory database.
334
+ * Lazily initialized on first access. Shared across all memory tools.
335
+ */
336
+ export const memoryDatabase = new MemoryDatabase();
337
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/memory/database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @module memory/hermes-bridge
3
+ * @description Cross-session integration with Hermes Agent session database.
4
+ *
5
+ * If the user has Hermes Agent installed (detected via ~/.hermes/ directory),
6
+ * the memory subsystem can query Hermes session history for cross-session
7
+ * context. This enables the agent to recall relevant conversations from
8
+ * previous Hermes sessions while keeping the data local.
9
+ *
10
+ * If Hermes is not installed, all bridge functions return empty results —
11
+ * the memory subsystem operates standalone.
12
+ */
13
+ /**
14
+ * @name HermesBridge
15
+ * @description Bridges the SAP MCP memory subsystem with Hermes Agent session data.
16
+ *
17
+ * Detection: checks for ~/.hermes/ directory. If present, the bridge can query
18
+ * the Hermes SQLite session database for relevant past conversations.
19
+ */
20
+ export declare class HermesBridge {
21
+ private readonly hermesDir;
22
+ private readonly hermesDbPath;
23
+ private available;
24
+ constructor();
25
+ /**
26
+ * @name isAvailable
27
+ * @description Checks whether Hermes Agent is installed on this machine.
28
+ * Caches the result to avoid repeated filesystem checks.
29
+ */
30
+ isAvailable(): boolean;
31
+ /**
32
+ * @name getHermesDir
33
+ * @description Returns the Hermes installation directory.
34
+ */
35
+ getHermesDir(): string;
36
+ /**
37
+ * @name searchSessions
38
+ * @description Searches Hermes session history for relevant past conversations.
39
+ *
40
+ * This is a lightweight bridge — it reads the Hermes session database using
41
+ * the same better-sqlite3 driver (opening a read-only connection). The query
42
+ * uses FTS5 if the Hermes DB has it, otherwise falls back to LIKE search.
43
+ *
44
+ * @param query - Search query (natural language).
45
+ * @param limit - Max results. Default 5.
46
+ * @returns Array of session snippets with timestamps.
47
+ */
48
+ searchSessions(query: string, limit?: number): Array<{
49
+ sessionId: string;
50
+ title: string;
51
+ snippet: string;
52
+ timestamp: string;
53
+ }>;
54
+ /**
55
+ * @name getRecentSessions
56
+ * @description Returns recent Hermes sessions for context injection.
57
+ * @param limit - Max sessions. Default 3.
58
+ */
59
+ getRecentSessions(limit?: number): Array<{
60
+ sessionId: string;
61
+ title: string;
62
+ timestamp: string;
63
+ }>;
64
+ }
65
+ /**
66
+ * @name hermesBridge
67
+ * @description Singleton instance of the Hermes bridge.
68
+ */
69
+ export declare const hermesBridge: HermesBridge;
70
+ //# sourceMappingURL=hermes-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes-bridge.d.ts","sourceRoot":"","sources":["../../src/memory/hermes-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,SAAS,CAAwB;;IAOzC;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAWtB;;;OAGG;IACH,YAAY,IAAI,MAAM;IAItB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAsDzH;;;;OAIG;IACH,iBAAiB,CAAC,KAAK,SAAI,GAAG,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CA0B7F;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * @module memory/hermes-bridge
3
+ * @description Cross-session integration with Hermes Agent session database.
4
+ *
5
+ * If the user has Hermes Agent installed (detected via ~/.hermes/ directory),
6
+ * the memory subsystem can query Hermes session history for cross-session
7
+ * context. This enables the agent to recall relevant conversations from
8
+ * previous Hermes sessions while keeping the data local.
9
+ *
10
+ * If Hermes is not installed, all bridge functions return empty results —
11
+ * the memory subsystem operates standalone.
12
+ */
13
+ import { existsSync } from 'fs';
14
+ import { join } from 'path';
15
+ import { homedir } from 'os';
16
+ import { createRequire } from 'module';
17
+ import { logger } from '../core/logger.js';
18
+ const require = createRequire(import.meta.url);
19
+ /**
20
+ * @name HermesBridge
21
+ * @description Bridges the SAP MCP memory subsystem with Hermes Agent session data.
22
+ *
23
+ * Detection: checks for ~/.hermes/ directory. If present, the bridge can query
24
+ * the Hermes SQLite session database for relevant past conversations.
25
+ */
26
+ export class HermesBridge {
27
+ hermesDir;
28
+ hermesDbPath;
29
+ available = null;
30
+ constructor() {
31
+ this.hermesDir = join(homedir(), '.hermes');
32
+ this.hermesDbPath = join(this.hermesDir, 'sessions.db');
33
+ }
34
+ /**
35
+ * @name isAvailable
36
+ * @description Checks whether Hermes Agent is installed on this machine.
37
+ * Caches the result to avoid repeated filesystem checks.
38
+ */
39
+ isAvailable() {
40
+ if (this.available !== null)
41
+ return this.available;
42
+ this.available = existsSync(this.hermesDir);
43
+ if (this.available) {
44
+ logger.info('Hermes Agent detected — cross-session bridge enabled', {
45
+ hermesDir: this.hermesDir,
46
+ });
47
+ }
48
+ return this.available;
49
+ }
50
+ /**
51
+ * @name getHermesDir
52
+ * @description Returns the Hermes installation directory.
53
+ */
54
+ getHermesDir() {
55
+ return this.hermesDir;
56
+ }
57
+ /**
58
+ * @name searchSessions
59
+ * @description Searches Hermes session history for relevant past conversations.
60
+ *
61
+ * This is a lightweight bridge — it reads the Hermes session database using
62
+ * the same better-sqlite3 driver (opening a read-only connection). The query
63
+ * uses FTS5 if the Hermes DB has it, otherwise falls back to LIKE search.
64
+ *
65
+ * @param query - Search query (natural language).
66
+ * @param limit - Max results. Default 5.
67
+ * @returns Array of session snippets with timestamps.
68
+ */
69
+ searchSessions(query, limit = 5) {
70
+ if (!this.isAvailable())
71
+ return [];
72
+ if (!existsSync(this.hermesDbPath))
73
+ return [];
74
+ try {
75
+ // Use dynamic import to avoid loading better-sqlite3 if Hermes is not present.
76
+ const Database = require('better-sqlite3');
77
+ const db = new Database(this.hermesDbPath, { readonly: true });
78
+ try {
79
+ // Try FTS5 search first (if Hermes has it).
80
+ const ftsResults = db.prepare(`SELECT s.id, s.title, substr(m.content, 1, 200) as snippet, s.created_at
81
+ FROM messages m
82
+ JOIN sessions s ON s.id = m.session_id
83
+ WHERE m.content MATCH ?
84
+ ORDER BY s.created_at DESC
85
+ LIMIT ?`).all(query, limit);
86
+ return ftsResults.map(r => ({
87
+ sessionId: r.id,
88
+ title: r.title ?? 'Untitled',
89
+ snippet: r.snippet,
90
+ timestamp: r.created_at,
91
+ }));
92
+ }
93
+ catch {
94
+ // FTS not available — try LIKE search.
95
+ const likeResults = db.prepare(`SELECT s.id, s.title, substr(m.content, 1, 200) as snippet, s.created_at
96
+ FROM messages m
97
+ JOIN sessions s ON s.id = m.session_id
98
+ WHERE m.content LIKE ?
99
+ ORDER BY s.created_at DESC
100
+ LIMIT ?`).all(`%${query}%`, limit);
101
+ return likeResults.map(r => ({
102
+ sessionId: r.id,
103
+ title: r.title ?? 'Untitled',
104
+ snippet: r.snippet,
105
+ timestamp: r.created_at,
106
+ }));
107
+ }
108
+ finally {
109
+ db.close();
110
+ }
111
+ }
112
+ catch (error) {
113
+ logger.debug('Hermes bridge query failed', {
114
+ error: error instanceof Error ? error.message : String(error),
115
+ });
116
+ return [];
117
+ }
118
+ }
119
+ /**
120
+ * @name getRecentSessions
121
+ * @description Returns recent Hermes sessions for context injection.
122
+ * @param limit - Max sessions. Default 3.
123
+ */
124
+ getRecentSessions(limit = 3) {
125
+ if (!this.isAvailable())
126
+ return [];
127
+ if (!existsSync(this.hermesDbPath))
128
+ return [];
129
+ try {
130
+ const Database = require('better-sqlite3');
131
+ const db = new Database(this.hermesDbPath, { readonly: true });
132
+ try {
133
+ const results = db.prepare(`SELECT id, title, created_at FROM sessions
134
+ ORDER BY created_at DESC LIMIT ?`).all(limit);
135
+ return results.map(r => ({
136
+ sessionId: r.id,
137
+ title: r.title ?? 'Untitled',
138
+ timestamp: r.created_at,
139
+ }));
140
+ }
141
+ finally {
142
+ db.close();
143
+ }
144
+ }
145
+ catch {
146
+ return [];
147
+ }
148
+ }
149
+ }
150
+ /**
151
+ * @name hermesBridge
152
+ * @description Singleton instance of the Hermes bridge.
153
+ */
154
+ export const hermesBridge = new HermesBridge();
155
+ //# sourceMappingURL=hermes-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes-bridge.js","sourceRoot":"","sources":["../../src/memory/hermes-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module memory
3
+ * @description SAP MCP local agent memory subsystem — SQLite FTS5 backed.
4
+ *
5
+ * Exports all stores and types for use by the MCP tool registration layer.
6
+ *
7
+ * Architecture:
8
+ * - database.ts: Thread-safe singleton SQLite connection with WAL mode + FTS5.
9
+ * - tool-call-store.ts: Records and searches tool call history.
10
+ * - memory-store.ts: Manages LLM-generated agent memories with relevance decay.
11
+ * - stream-buffer-store.ts: Buffers premium stream events for offline consumption.
12
+ * - types.ts: Type definitions.
13
+ * - utils.ts: Utility functions (truncate, decay, expiry).
14
+ */
15
+ export { MemoryDatabase, memoryDatabase, DEFAULT_CONFIG } from './database.js';
16
+ export { ToolCallStore, toolCallStore } from './tool-call-store.js';
17
+ export { MemoryStore, memoryStore } from './memory-store.js';
18
+ export { StreamBufferStore, streamBufferStore } from './stream-buffer-store.js';
19
+ export { AsyncMemoryProcessor, asyncMemoryProcessor } from './async-processor.js';
20
+ export { recordToolCall } from './auto-record.js';
21
+ export { HermesBridge, hermesBridge } from './hermes-bridge.js';
22
+ export type { ToolCallRecord, ToolCallOutcome, AgentMemoryRecord, MemoryType, StreamBufferRecord, MemorySearchResult, MemoryQueryOptions, MemoryStats, MemoryPruneResult, MemoryConfig, } from './types.js';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module memory
3
+ * @description SAP MCP local agent memory subsystem — SQLite FTS5 backed.
4
+ *
5
+ * Exports all stores and types for use by the MCP tool registration layer.
6
+ *
7
+ * Architecture:
8
+ * - database.ts: Thread-safe singleton SQLite connection with WAL mode + FTS5.
9
+ * - tool-call-store.ts: Records and searches tool call history.
10
+ * - memory-store.ts: Manages LLM-generated agent memories with relevance decay.
11
+ * - stream-buffer-store.ts: Buffers premium stream events for offline consumption.
12
+ * - types.ts: Type definitions.
13
+ * - utils.ts: Utility functions (truncate, decay, expiry).
14
+ */
15
+ export { MemoryDatabase, memoryDatabase, DEFAULT_CONFIG } from './database.js';
16
+ export { ToolCallStore, toolCallStore } from './tool-call-store.js';
17
+ export { MemoryStore, memoryStore } from './memory-store.js';
18
+ export { StreamBufferStore, streamBufferStore } from './stream-buffer-store.js';
19
+ export { AsyncMemoryProcessor, asyncMemoryProcessor } from './async-processor.js';
20
+ export { recordToolCall } from './auto-record.js';
21
+ export { HermesBridge, hermesBridge } from './hermes-bridge.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}