@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.
- package/.env.example +11 -1
- package/CHANGELOG.md +233 -6
- package/README.md +3 -3
- package/USER_DOCS/00_START_HERE.md +9 -1
- package/USER_DOCS/01_HOSTED_REMOTE_MCP.md +1 -1
- package/USER_DOCS/04_CLIENT_CONFIGS.md +3 -3
- package/USER_DOCS/06_DESKTOP_GUI_WIZARD.md +5 -5
- package/config.example.json +1 -1
- package/config.secure-example.json +1 -1
- package/dist/config/env.d.ts +18 -0
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +14 -2
- package/dist/config/env.js.map +1 -1
- package/dist/config/mcp-client-injection.js +3 -3
- package/dist/config/paths.d.ts +9 -1
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +15 -1
- package/dist/config/paths.js.map +1 -1
- package/dist/config/wizard.d.ts.map +1 -1
- package/dist/config/wizard.js +3 -1
- package/dist/config/wizard.js.map +1 -1
- package/dist/core/constants.d.ts +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/logger.js +1 -1
- package/dist/memory/async-processor.d.ts +107 -0
- package/dist/memory/async-processor.d.ts.map +1 -0
- package/dist/memory/async-processor.js +204 -0
- package/dist/memory/async-processor.js.map +1 -0
- package/dist/memory/auto-record.d.ts +47 -0
- package/dist/memory/auto-record.d.ts.map +1 -0
- package/dist/memory/auto-record.js +133 -0
- package/dist/memory/auto-record.js.map +1 -0
- package/dist/memory/database.d.ts +103 -0
- package/dist/memory/database.d.ts.map +1 -0
- package/dist/memory/database.js +337 -0
- package/dist/memory/database.js.map +1 -0
- package/dist/memory/hermes-bridge.d.ts +70 -0
- package/dist/memory/hermes-bridge.d.ts.map +1 -0
- package/dist/memory/hermes-bridge.js +155 -0
- package/dist/memory/hermes-bridge.js.map +1 -0
- package/dist/memory/index.d.ts +23 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +22 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/memory-store.d.ts +76 -0
- package/dist/memory/memory-store.d.ts.map +1 -0
- package/dist/memory/memory-store.js +231 -0
- package/dist/memory/memory-store.js.map +1 -0
- package/dist/memory/stream-buffer-store.d.ts +69 -0
- package/dist/memory/stream-buffer-store.d.ts.map +1 -0
- package/dist/memory/stream-buffer-store.js +182 -0
- package/dist/memory/stream-buffer-store.js.map +1 -0
- package/dist/memory/tool-call-store.d.ts +68 -0
- package/dist/memory/tool-call-store.d.ts.map +1 -0
- package/dist/memory/tool-call-store.js +189 -0
- package/dist/memory/tool-call-store.js.map +1 -0
- package/dist/memory/types.d.ts +197 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +15 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/utils.d.ts +30 -0
- package/dist/memory/utils.d.ts.map +1 -0
- package/dist/memory/utils.js +47 -0
- package/dist/memory/utils.js.map +1 -0
- package/dist/payments/hosted-tool-eligibility.d.ts.map +1 -1
- package/dist/payments/hosted-tool-eligibility.js +4 -6
- package/dist/payments/hosted-tool-eligibility.js.map +1 -1
- package/dist/payments/monetization-gate.d.ts +39 -0
- package/dist/payments/monetization-gate.d.ts.map +1 -1
- package/dist/payments/monetization-gate.js +165 -11
- package/dist/payments/monetization-gate.js.map +1 -1
- package/dist/payments/pricing.d.ts.map +1 -1
- package/dist/payments/pricing.js +69 -0
- package/dist/payments/pricing.js.map +1 -1
- package/dist/payments/x402-paid-call.js +1 -1
- package/dist/premium/builtin-plugins.d.ts +42 -0
- package/dist/premium/builtin-plugins.d.ts.map +1 -1
- package/dist/premium/builtin-plugins.js +91 -10
- package/dist/premium/builtin-plugins.js.map +1 -1
- package/dist/premium/manifest-builder.d.ts.map +1 -1
- package/dist/premium/manifest-builder.js +43 -7
- package/dist/premium/manifest-builder.js.map +1 -1
- package/dist/premium/meme-radar-capabilities.js +9 -9
- package/dist/premium/meme-radar-capabilities.js.map +1 -1
- package/dist/premium/plugin-validator.d.ts.map +1 -1
- package/dist/premium/plugin-validator.js +62 -1
- package/dist/premium/plugin-validator.js.map +1 -1
- package/dist/premium/provider-bridge.d.ts +25 -1
- package/dist/premium/provider-bridge.d.ts.map +1 -1
- package/dist/premium/provider-bridge.js +130 -20
- package/dist/premium/provider-bridge.js.map +1 -1
- package/dist/premium/session-manager.d.ts.map +1 -1
- package/dist/premium/session-manager.js +12 -3
- package/dist/premium/session-manager.js.map +1 -1
- package/dist/premium/tech-fundamentals-capabilities.js +5 -5
- package/dist/premium/tech-fundamentals-capabilities.js.map +1 -1
- package/dist/premium/trading-capabilities.js +5 -5
- package/dist/premium/trading-capabilities.js.map +1 -1
- package/dist/premium/webhook-engine.d.ts.map +1 -1
- package/dist/premium/webhook-engine.js +7 -1
- package/dist/premium/webhook-engine.js.map +1 -1
- package/dist/prompts/context/sap-agent-context.prompt.js +1 -1
- package/dist/prompts/payments/explain-x402-settlement.prompt.js +1 -1
- package/dist/remote/premium-routes.d.ts.map +1 -1
- package/dist/remote/premium-routes.js +3 -2
- package/dist/remote/premium-routes.js.map +1 -1
- package/dist/remote/public-home/sections.d.ts.map +1 -1
- package/dist/remote/public-home/sections.js +2 -3
- package/dist/remote/public-home/sections.js.map +1 -1
- package/dist/remote/public-home/styles.d.ts +1 -1
- package/dist/remote/public-home/styles.js +2 -2
- package/dist/remote/server.d.ts.map +1 -1
- package/dist/remote/server.js +19 -4
- package/dist/remote/server.js.map +1 -1
- package/dist/server/server-metadata.js +1 -1
- package/dist/strategies/strategy-store.d.ts +82 -0
- package/dist/strategies/strategy-store.d.ts.map +1 -0
- package/dist/strategies/strategy-store.js +165 -0
- package/dist/strategies/strategy-store.js.map +1 -0
- package/dist/tools/agent-start-tool.d.ts.map +1 -1
- package/dist/tools/agent-start-tool.js +97 -10
- package/dist/tools/agent-start-tool.js.map +1 -1
- package/dist/tools/client-sdk-tools.d.ts.map +1 -1
- package/dist/tools/client-sdk-tools.js +152 -9
- package/dist/tools/client-sdk-tools.js.map +1 -1
- package/dist/tools/estimate-tool-cost.js +1 -1
- package/dist/tools/estimate-tool-cost.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/magicblock-tools.js +5 -5
- package/dist/tools/magicblock-tools.js.map +1 -1
- package/dist/tools/memory-tools.d.ts +26 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +533 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/perp-tools.d.ts +7 -9
- package/dist/tools/perp-tools.d.ts.map +1 -1
- package/dist/tools/perp-tools.js +386 -367
- package/dist/tools/perp-tools.js.map +1 -1
- package/dist/tools/premium-tools.d.ts.map +1 -1
- package/dist/tools/premium-tools.js +8 -2
- package/dist/tools/premium-tools.js.map +1 -1
- package/dist/tools/profile-tools.d.ts.map +1 -1
- package/dist/tools/profile-tools.js +18 -1
- package/dist/tools/profile-tools.js.map +1 -1
- package/dist/tools/quick-context-tool.d.ts.map +1 -1
- package/dist/tools/quick-context-tool.js +100 -9
- package/dist/tools/quick-context-tool.js.map +1 -1
- package/dist/tools/register-tools.d.ts.map +1 -1
- package/dist/tools/register-tools.js +3 -0
- package/dist/tools/register-tools.js.map +1 -1
- package/dist/tools/sap-sdk-tools.js +3 -3
- package/dist/tools/sap-sdk-tools.js.map +1 -1
- package/dist/tools/session-context-packet.d.ts +19 -0
- package/dist/tools/session-context-packet.d.ts.map +1 -0
- package/dist/tools/session-context-packet.js +256 -0
- package/dist/tools/session-context-packet.js.map +1 -0
- package/dist/tools/skills-tools.d.ts +10 -0
- package/dist/tools/skills-tools.d.ts.map +1 -1
- package/dist/tools/skills-tools.js +19 -0
- package/dist/tools/skills-tools.js.map +1 -1
- package/dist/tools/transaction-tools.d.ts +1 -0
- package/dist/tools/transaction-tools.d.ts.map +1 -1
- package/dist/tools/transaction-tools.js +248 -9
- package/dist/tools/transaction-tools.js.map +1 -1
- package/dist/tools/x402-paid-call-tool.d.ts.map +1 -1
- package/dist/tools/x402-paid-call-tool.js +55 -21
- package/dist/tools/x402-paid-call-tool.js.map +1 -1
- package/dist/wizard-core/desktop-flow.d.ts.map +1 -1
- package/dist/wizard-core/desktop-flow.js +4 -2
- package/dist/wizard-core/desktop-flow.js.map +1 -1
- package/docs/06_PAYMENTS_X402_AND_PAYSH.md +14 -5
- package/docs/07_ENDPOINTS_AND_CLIENTS.md +1 -1
- package/docs/09_TOOLS_SKILLS_AND_AGENT_GUIDE.md +13 -5
- package/docs/13_BOUNTY_PROGRAM_PROPOSAL.md +1 -1
- package/docs/14_DESKTOP_WIZARD_RELEASE.md +3 -3
- package/docs/15_DASHBOARD_SCREENSHARE_SCRIPT.md +1 -1
- package/docs/BRANCH_AND_CI.md +2 -2
- package/docs/README.md +1 -1
- package/package.json +3 -1
- package/server.json +3 -3
- package/skills/README.md +1 -1
- package/skills/sap-agentkit/SKILL.md +1 -2
- package/skills/sap-defi/SKILL.md +31 -2
- package/skills/sap-mcp/SKILL.md +24 -13
- package/skills/sap-mcp/TOOL_REFERENCE.md +2 -4
- package/skills/sap-payments-x402/SKILL.md +15 -3
- package/assets/logos/drift.svg +0 -12
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module memory/async-processor
|
|
3
|
+
* @description Async background processor for memory maintenance tasks.
|
|
4
|
+
*
|
|
5
|
+
* Runs periodic maintenance on the memory database without blocking the main
|
|
6
|
+
* event loop:
|
|
7
|
+
* - Relevance decay application (every 1 hour)
|
|
8
|
+
* - Stream buffer eviction (every 5 minutes)
|
|
9
|
+
* - Tool call archiving (every 1 hour)
|
|
10
|
+
* - Memory pruning (every 6 hours)
|
|
11
|
+
* - WAL checkpoint (every 10 minutes)
|
|
12
|
+
*
|
|
13
|
+
* Uses setImmediate + setTimeout for non-blocking scheduling. The processor
|
|
14
|
+
* is a singleton that starts when the MCP server boots and stops on shutdown.
|
|
15
|
+
*/
|
|
16
|
+
import { memoryDatabase } from './database.js';
|
|
17
|
+
import { toolCallStore } from './tool-call-store.js';
|
|
18
|
+
import { memoryStore } from './memory-store.js';
|
|
19
|
+
import { streamBufferStore } from './stream-buffer-store.js';
|
|
20
|
+
import { logger } from '../core/logger.js';
|
|
21
|
+
const DEFAULT_SCHEDULE = {
|
|
22
|
+
decayIntervalMs: 60 * 60 * 1000, // 1 hour
|
|
23
|
+
evictIntervalMs: 5 * 60 * 1000, // 5 minutes
|
|
24
|
+
archiveIntervalMs: 60 * 60 * 1000, // 1 hour
|
|
25
|
+
pruneIntervalMs: 6 * 60 * 60 * 1000, // 6 hours
|
|
26
|
+
checkpointIntervalMs: 10 * 60 * 1000, // 10 minutes
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* @name AsyncMemoryProcessor
|
|
30
|
+
* @description Background processor for memory maintenance.
|
|
31
|
+
*
|
|
32
|
+
* Runs non-blocking periodic tasks using setTimeout chains (not setInterval,
|
|
33
|
+
* to avoid overlapping executions). Each task catches its own errors and logs
|
|
34
|
+
* them — a failure in one task doesn't stop the others.
|
|
35
|
+
*/
|
|
36
|
+
export class AsyncMemoryProcessor {
|
|
37
|
+
timers = new Set();
|
|
38
|
+
running = false;
|
|
39
|
+
schedule;
|
|
40
|
+
constructor(schedule = {}) {
|
|
41
|
+
this.schedule = { ...DEFAULT_SCHEDULE, ...schedule };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @name start
|
|
45
|
+
* @description Starts all background maintenance tasks.
|
|
46
|
+
*/
|
|
47
|
+
start() {
|
|
48
|
+
if (this.running)
|
|
49
|
+
return;
|
|
50
|
+
this.running = true;
|
|
51
|
+
this.scheduleTask('decay', this.schedule.decayIntervalMs, () => this.runDecay());
|
|
52
|
+
this.scheduleTask('evict', this.schedule.evictIntervalMs, () => this.runEvict());
|
|
53
|
+
this.scheduleTask('archive', this.schedule.archiveIntervalMs, () => this.runArchive());
|
|
54
|
+
this.scheduleTask('prune', this.schedule.pruneIntervalMs, () => this.runPrune());
|
|
55
|
+
this.scheduleTask('checkpoint', this.schedule.checkpointIntervalMs, () => this.runCheckpoint());
|
|
56
|
+
logger.info('Memory async processor started', {
|
|
57
|
+
tasks: ['decay', 'evict', 'archive', 'prune', 'checkpoint'],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @name stop
|
|
62
|
+
* @description Stops all background tasks and clears timers.
|
|
63
|
+
*/
|
|
64
|
+
stop() {
|
|
65
|
+
this.running = false;
|
|
66
|
+
for (const timer of this.timers) {
|
|
67
|
+
clearTimeout(timer);
|
|
68
|
+
}
|
|
69
|
+
this.timers.clear();
|
|
70
|
+
logger.info('Memory async processor stopped');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @name isRunning
|
|
74
|
+
* @description Returns whether the processor is running.
|
|
75
|
+
*/
|
|
76
|
+
isRunning() {
|
|
77
|
+
return this.running;
|
|
78
|
+
}
|
|
79
|
+
// ── Task Scheduling ────────────────────────────────────────────────────────
|
|
80
|
+
/**
|
|
81
|
+
* @name scheduleTask
|
|
82
|
+
* @description Schedules a recurring task using setTimeout chains.
|
|
83
|
+
* Uses setImmediate for the first run to avoid blocking server startup.
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
scheduleTask(name, intervalMs, task) {
|
|
87
|
+
const run = () => {
|
|
88
|
+
if (!this.running)
|
|
89
|
+
return;
|
|
90
|
+
// Execute the task — errors are caught and logged, never propagated.
|
|
91
|
+
try {
|
|
92
|
+
task();
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger.warn(`Memory maintenance task "${name}" failed`, {
|
|
96
|
+
error: error instanceof Error ? error.message : String(error),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// Schedule the next run.
|
|
100
|
+
if (this.running) {
|
|
101
|
+
const timer = setTimeout(run, intervalMs);
|
|
102
|
+
this.timers.add(timer);
|
|
103
|
+
// Auto-clean the timer reference when it fires.
|
|
104
|
+
timer.unref?.();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
// First run after a short delay (don't block startup).
|
|
108
|
+
const timer = setTimeout(run, 5000);
|
|
109
|
+
this.timers.add(timer);
|
|
110
|
+
timer.unref?.();
|
|
111
|
+
}
|
|
112
|
+
// ── Maintenance Tasks ──────────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* @name runDecay
|
|
115
|
+
* @description Applies relevance decay to all agent memories.
|
|
116
|
+
* The decay is computed in JS (better-sqlite3 is synchronous) and applied
|
|
117
|
+
* as a batch UPDATE.
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
runDecay() {
|
|
121
|
+
if (memoryDatabase.isDegraded())
|
|
122
|
+
return;
|
|
123
|
+
memoryDatabase.init();
|
|
124
|
+
const db = memoryDatabase.getDb();
|
|
125
|
+
const rows = db.prepare('SELECT id, relevance_score, created_at FROM agent_memory WHERE expires_at IS NULL OR expires_at > datetime(\'now\')').all();
|
|
126
|
+
let updated = 0;
|
|
127
|
+
const updateStmt = db.prepare('UPDATE agent_memory SET relevance_score = ? WHERE id = ?');
|
|
128
|
+
const now = Date.now();
|
|
129
|
+
for (const row of rows) {
|
|
130
|
+
const created = new Date(row.created_at).getTime();
|
|
131
|
+
const daysSince = (now - created) / (1000 * 60 * 60 * 24);
|
|
132
|
+
const decayed = row.relevance_score * Math.pow(0.99, daysSince);
|
|
133
|
+
const clamped = Math.max(0, Math.min(1, decayed));
|
|
134
|
+
if (Math.abs(clamped - row.relevance_score) > 0.001) {
|
|
135
|
+
updateStmt.run(clamped, row.id);
|
|
136
|
+
updated++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (updated > 0) {
|
|
140
|
+
logger.debug('Memory decay applied', { updated, total: rows.length });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* @name runEvict
|
|
145
|
+
* @description Evicts old consumed stream events to keep the buffer bounded.
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
runEvict() {
|
|
149
|
+
if (memoryDatabase.isDegraded())
|
|
150
|
+
return;
|
|
151
|
+
const evicted = streamBufferStore.evict(10_000);
|
|
152
|
+
if (evicted > 0) {
|
|
153
|
+
logger.debug('Stream buffer evicted', { evicted });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @name runArchive
|
|
158
|
+
* @description Archives tool call records older than the retention period.
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
runArchive() {
|
|
162
|
+
if (memoryDatabase.isDegraded())
|
|
163
|
+
return;
|
|
164
|
+
const archived = toolCallStore.archive(90);
|
|
165
|
+
if (archived > 0) {
|
|
166
|
+
logger.debug('Tool calls archived', { archived });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* @name runPrune
|
|
171
|
+
* @description Prunes expired and low-relevance memories.
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
runPrune() {
|
|
175
|
+
if (memoryDatabase.isDegraded())
|
|
176
|
+
return;
|
|
177
|
+
const pruned = memoryStore.prune(0.05);
|
|
178
|
+
if (pruned > 0) {
|
|
179
|
+
logger.debug('Memories pruned', { pruned });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* @name runCheckpoint
|
|
184
|
+
* @description Forces a WAL checkpoint to prevent the WAL file from growing
|
|
185
|
+
* unbounded. Uses PASSIVE mode to avoid blocking readers.
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
188
|
+
runCheckpoint() {
|
|
189
|
+
if (memoryDatabase.isDegraded())
|
|
190
|
+
return;
|
|
191
|
+
try {
|
|
192
|
+
memoryDatabase.getDb().pragma('wal_checkpoint(PASSIVE)');
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Best-effort checkpoint.
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* @name asyncMemoryProcessor
|
|
201
|
+
* @description Singleton instance of the async memory processor.
|
|
202
|
+
*/
|
|
203
|
+
export const asyncMemoryProcessor = new AsyncMemoryProcessor();
|
|
204
|
+
//# sourceMappingURL=async-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-processor.js","sourceRoot":"","sources":["../../src/memory/async-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module memory/auto-record
|
|
3
|
+
* @description Automatic tool call recording hook.
|
|
4
|
+
*
|
|
5
|
+
* Wraps the MCP tool handler to automatically record every tool call in the
|
|
6
|
+
* local memory database — no agent action required. The hook measures
|
|
7
|
+
* latency, captures the outcome, and stores truncated input/output.
|
|
8
|
+
*
|
|
9
|
+
* The hook is designed to be non-blocking: if the memory DB is degraded or
|
|
10
|
+
* the recording fails, the tool call proceeds normally. Recording errors
|
|
11
|
+
* are logged but never propagated to the caller.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @name AutoRecordResult
|
|
15
|
+
* @description Result of a tool call with metadata for recording.
|
|
16
|
+
*/
|
|
17
|
+
export interface AutoRecordResult {
|
|
18
|
+
/** The original tool result text. */
|
|
19
|
+
result: string;
|
|
20
|
+
/** Whether the result indicates an error. */
|
|
21
|
+
isError: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @name recordToolCall
|
|
25
|
+
* @description Records a tool call execution in the memory database.
|
|
26
|
+
*
|
|
27
|
+
* This function is called after every tool handler executes. It captures:
|
|
28
|
+
* - toolName: the MCP tool name
|
|
29
|
+
* - input: JSON-serialized input (truncated to 8KB)
|
|
30
|
+
* - output: JSON-serialized output (truncated to 8KB)
|
|
31
|
+
* - outcome: 'success' | 'error' | 'partial'
|
|
32
|
+
* - latencyMs: wall-clock time from start to finish
|
|
33
|
+
* - costUsd: estimated from the pricing tier (if available)
|
|
34
|
+
* - txSignature: extracted from the output if present
|
|
35
|
+
*
|
|
36
|
+
* The function never throws — recording failures are logged and swallowed.
|
|
37
|
+
*
|
|
38
|
+
* @param toolName - The MCP tool name.
|
|
39
|
+
* @param input - The raw input object passed to the tool.
|
|
40
|
+
* @param output - The tool result text.
|
|
41
|
+
* @param isError - Whether the tool returned an error.
|
|
42
|
+
* @param latencyMs - Execution latency in milliseconds.
|
|
43
|
+
* @param sessionId - Optional session identifier.
|
|
44
|
+
* @param callerProfile - Optional signer profile.
|
|
45
|
+
*/
|
|
46
|
+
export declare function recordToolCall(toolName: string, input: unknown, output: string, isError: boolean, latencyMs: number, sessionId?: string, callerProfile?: string): void;
|
|
47
|
+
//# sourceMappingURL=auto-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-record.d.ts","sourceRoot":"","sources":["../../src/memory/auto-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CAuCN"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module memory/auto-record
|
|
3
|
+
* @description Automatic tool call recording hook.
|
|
4
|
+
*
|
|
5
|
+
* Wraps the MCP tool handler to automatically record every tool call in the
|
|
6
|
+
* local memory database — no agent action required. The hook measures
|
|
7
|
+
* latency, captures the outcome, and stores truncated input/output.
|
|
8
|
+
*
|
|
9
|
+
* The hook is designed to be non-blocking: if the memory DB is degraded or
|
|
10
|
+
* the recording fails, the tool call proceeds normally. Recording errors
|
|
11
|
+
* are logged but never propagated to the caller.
|
|
12
|
+
*/
|
|
13
|
+
import { toolCallStore } from './tool-call-store.js';
|
|
14
|
+
import { memoryDatabase } from './database.js';
|
|
15
|
+
import { logger } from '../core/logger.js';
|
|
16
|
+
/**
|
|
17
|
+
* @name recordToolCall
|
|
18
|
+
* @description Records a tool call execution in the memory database.
|
|
19
|
+
*
|
|
20
|
+
* This function is called after every tool handler executes. It captures:
|
|
21
|
+
* - toolName: the MCP tool name
|
|
22
|
+
* - input: JSON-serialized input (truncated to 8KB)
|
|
23
|
+
* - output: JSON-serialized output (truncated to 8KB)
|
|
24
|
+
* - outcome: 'success' | 'error' | 'partial'
|
|
25
|
+
* - latencyMs: wall-clock time from start to finish
|
|
26
|
+
* - costUsd: estimated from the pricing tier (if available)
|
|
27
|
+
* - txSignature: extracted from the output if present
|
|
28
|
+
*
|
|
29
|
+
* The function never throws — recording failures are logged and swallowed.
|
|
30
|
+
*
|
|
31
|
+
* @param toolName - The MCP tool name.
|
|
32
|
+
* @param input - The raw input object passed to the tool.
|
|
33
|
+
* @param output - The tool result text.
|
|
34
|
+
* @param isError - Whether the tool returned an error.
|
|
35
|
+
* @param latencyMs - Execution latency in milliseconds.
|
|
36
|
+
* @param sessionId - Optional session identifier.
|
|
37
|
+
* @param callerProfile - Optional signer profile.
|
|
38
|
+
*/
|
|
39
|
+
export function recordToolCall(toolName, input, output, isError, latencyMs, sessionId, callerProfile) {
|
|
40
|
+
// Skip recording for memory tools themselves — avoid infinite recursion.
|
|
41
|
+
if (toolName.startsWith('sap_memory_') || toolName.startsWith('sap_audit_') || toolName.startsWith('sap_strategy_') || toolName.startsWith('sap_stream_')) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Skip if the memory database is degraded.
|
|
45
|
+
if (memoryDatabase.isDegraded())
|
|
46
|
+
return;
|
|
47
|
+
try {
|
|
48
|
+
// Serialize input/output with truncation.
|
|
49
|
+
const inputJson = safeStringify(input, 8192);
|
|
50
|
+
const outputJson = safeStringify(output, 8192);
|
|
51
|
+
// Determine outcome.
|
|
52
|
+
const outcome = isError ? 'error' : determineOutcome(output);
|
|
53
|
+
// Extract transaction signature from output if present.
|
|
54
|
+
const txSignature = extractTxSignature(output);
|
|
55
|
+
// Record in the database.
|
|
56
|
+
toolCallStore.record({
|
|
57
|
+
toolName,
|
|
58
|
+
sessionId: sessionId ?? null,
|
|
59
|
+
callerProfile: callerProfile ?? null,
|
|
60
|
+
input: inputJson,
|
|
61
|
+
output: outputJson,
|
|
62
|
+
outcome,
|
|
63
|
+
costUsd: null, // Cost is tracked by the x402 gate, not here.
|
|
64
|
+
txSignature,
|
|
65
|
+
latencyMs,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// Never propagate recording errors — the tool call already succeeded.
|
|
70
|
+
logger.debug('Auto-record failed', {
|
|
71
|
+
toolName,
|
|
72
|
+
error: error instanceof Error ? error.message : String(error),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @name determineOutcome
|
|
78
|
+
* @description Classifies the tool call outcome from the output text.
|
|
79
|
+
* Checks for partial success indicators (e.g. "partial", "some failed", "retry").
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
function determineOutcome(output) {
|
|
83
|
+
const lower = output.toLowerCase();
|
|
84
|
+
if (lower.includes('"partial"') || lower.includes('"some failed"') || lower.includes('"retry-safe": false')) {
|
|
85
|
+
return 'partial';
|
|
86
|
+
}
|
|
87
|
+
return 'success';
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* @name extractTxSignature
|
|
91
|
+
* @description Extracts a Solana transaction signature from the tool output.
|
|
92
|
+
* Looks for common patterns like "signature": "..." or "txSignature": "...".
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
function extractTxSignature(output) {
|
|
96
|
+
// Try JSON parsing first.
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse(output);
|
|
99
|
+
if (typeof parsed['signature'] === 'string')
|
|
100
|
+
return parsed['signature'];
|
|
101
|
+
if (typeof parsed['txSignature'] === 'string')
|
|
102
|
+
return parsed['txSignature'];
|
|
103
|
+
if (typeof parsed['transactionSignature'] === 'string')
|
|
104
|
+
return parsed['transactionSignature'];
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Not JSON — try regex.
|
|
108
|
+
}
|
|
109
|
+
// Regex fallback for base58 signatures (64-88 chars).
|
|
110
|
+
const match = output.match(/\b[1-9A-HJ-NP-Za-km-z]{64,88}\b/);
|
|
111
|
+
return match ? match[0] : null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* @name safeStringify
|
|
115
|
+
* @description Safely serializes a value to JSON with truncation.
|
|
116
|
+
* Handles circular references and large objects.
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
119
|
+
function safeStringify(value, maxBytes) {
|
|
120
|
+
try {
|
|
121
|
+
const json = JSON.stringify(value);
|
|
122
|
+
if (!json)
|
|
123
|
+
return '';
|
|
124
|
+
const buf = Buffer.from(json, 'utf-8');
|
|
125
|
+
if (buf.length <= maxBytes)
|
|
126
|
+
return json;
|
|
127
|
+
return buf.subarray(0, maxBytes).toString('utf-8') + '...[truncated]';
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return String(value).slice(0, maxBytes);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=auto-record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-record.js","sourceRoot":"","sources":["../../src/memory/auto-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
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 type { Database as DatabaseType, Statement } from 'better-sqlite3';
|
|
17
|
+
import type { MemoryConfig } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* @name DEFAULT_CONFIG
|
|
20
|
+
* @description Default memory configuration. The DB is stored in
|
|
21
|
+
* ~/.config/mcp-sap/memory/ which is the standard SAP MCP config directory.
|
|
22
|
+
*/
|
|
23
|
+
export declare const DEFAULT_CONFIG: MemoryConfig;
|
|
24
|
+
/**
|
|
25
|
+
* @name MemoryDatabase
|
|
26
|
+
* @description Thread-safe singleton managing the SQLite connection for agent memory.
|
|
27
|
+
*
|
|
28
|
+
* The class lazily initializes the database on first access and caches prepared
|
|
29
|
+
* statements for performance. All methods are synchronous (better-sqlite3 is
|
|
30
|
+
* synchronous by design). The database runs in WAL mode for concurrent reads.
|
|
31
|
+
*
|
|
32
|
+
* If the database cannot be opened (e.g. disk full, permissions), the instance
|
|
33
|
+
* enters a degraded mode where all queries return empty results instead of
|
|
34
|
+
* crashing the MCP server.
|
|
35
|
+
*/
|
|
36
|
+
export declare class MemoryDatabase {
|
|
37
|
+
private db;
|
|
38
|
+
private readonly config;
|
|
39
|
+
private degraded;
|
|
40
|
+
private initialized;
|
|
41
|
+
private statements;
|
|
42
|
+
constructor(config?: Partial<MemoryConfig>);
|
|
43
|
+
/**
|
|
44
|
+
* @name init
|
|
45
|
+
* @description Initializes the database connection, creates the schema, and
|
|
46
|
+
* enables WAL mode. Called lazily on first query.
|
|
47
|
+
*/
|
|
48
|
+
init(): void;
|
|
49
|
+
/**
|
|
50
|
+
* @name getDb
|
|
51
|
+
* @description Returns the underlying Database instance. Throws if degraded.
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
getDb(): DatabaseType;
|
|
55
|
+
/**
|
|
56
|
+
* @name isDegraded
|
|
57
|
+
* @description Returns true if the database is in degraded mode (init failed).
|
|
58
|
+
*/
|
|
59
|
+
isDegraded(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* @name getStatement
|
|
62
|
+
* @description Returns a cached prepared statement by key.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
getStatement(key: string): Statement | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* @name close
|
|
68
|
+
* @description Closes the database connection gracefully.
|
|
69
|
+
*/
|
|
70
|
+
close(): void;
|
|
71
|
+
/**
|
|
72
|
+
* @name getDbSize
|
|
73
|
+
* @description Returns the database file size in bytes.
|
|
74
|
+
*/
|
|
75
|
+
getDbSize(): number;
|
|
76
|
+
/**
|
|
77
|
+
* @name runMigrations
|
|
78
|
+
* @description Runs idempotent schema migrations. Each migration checks if
|
|
79
|
+
* the current schema version is below the target and applies changes.
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
private runMigrations;
|
|
83
|
+
/**
|
|
84
|
+
* @name migrateToV1
|
|
85
|
+
* @description Creates the initial schema: tool_calls, agent_memory,
|
|
86
|
+
* stream_buffers, and their FTS5 indexes.
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
private migrateToV1;
|
|
90
|
+
/**
|
|
91
|
+
* @name prepareStatements
|
|
92
|
+
* @description Pre-compiles and caches frequently used SQL statements.
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
private prepareStatements;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @name memoryDatabase
|
|
99
|
+
* @description Singleton instance of the memory database.
|
|
100
|
+
* Lazily initialized on first access. Shared across all memory tools.
|
|
101
|
+
*/
|
|
102
|
+
export declare const memoryDatabase: MemoryDatabase;
|
|
103
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/memory/database.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,YAQ5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAA6B;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAqC;gBAE3C,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAI9C;;;;OAIG;IACI,IAAI,IAAI,IAAI;IA0CnB;;;;OAIG;IACI,KAAK,IAAI,YAAY;IAO5B;;;OAGG;IACI,UAAU,IAAI,OAAO;IAI5B;;;;OAIG;IACI,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIvD;;;OAGG;IACI,KAAK,IAAI,IAAI;IAapB;;;OAGG;IACI,SAAS,IAAI,MAAM;IAU1B;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IA4BrB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAkHnB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAyD1B;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
|