prism-mcp-server 16.1.1 โ 17.0.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.
- package/README.md +149 -0
- package/dist/server.js +15 -0
- package/dist/storage/synalux.js +16 -0
- package/dist/tools/index.js +3 -0
- package/dist/tools/sessionDriftHandler.js +62 -0
- package/dist/tools/sessionMemoryDefinitions.js +86 -0
- package/dist/utils/ddLogger.js +33 -15
- package/dist/utils/llm/adapters/gemini.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -157,6 +157,18 @@ Categories: abstention, adversarial traps, cascade, disambiguation, edge cases,
|
|
|
157
157
|
### ๐ L3 Grounding Verifier
|
|
158
158
|
When `prism_infer` receives an `evidence` payload, the grounding verifier automatically checks the model's response against the provided evidence before returning to the caller. Unverified or hallucinated claims are flagged. This is the third layer (L3) of the cascade โ after tool routing (L1) and confidence gating (L2).
|
|
159
159
|
|
|
160
|
+
### ๐ง HRR Semantic Drift Detection (v17.0)
|
|
161
|
+
Detects when long AI agent sessions drift from their original goal โ using Holographic Reduced Representations for temporal trajectory encoding and anomaly detection.
|
|
162
|
+
|
|
163
|
+
**Three domains, one detector:**
|
|
164
|
+
| Domain | Signals | Safety |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| **BCBA/Clinical** | Client specificity decay, function-intervention alignment (4 functions), contraindication detection (epilepsy/pica/dysphagia/diabetes) | PHI-safe, deterministic |
|
|
167
|
+
| **Coding** | File scope entropy, summary vagueness, test coverage ratio, trajectory HRR divergence | Adaptive threshold for refactors |
|
|
168
|
+
| **AAC** | Prediction accuracy, vocabulary stagnation, topic divergence | Emergency phrases always โฅ 0.95 |
|
|
169
|
+
|
|
170
|
+
**Research-backed:** trajectory association (Frady et al. 2018), HDAD anomaly detection (Wang et al. 2021), unit-modulus projection (Ganesan et al. NeurIPS 2021). 306 tests across 8 files, zero failures. Use `session_detect_drift` with optional `domain` parameter.
|
|
171
|
+
|
|
160
172
|
### โก Zero-search retrieval *(new in v15.8)*
|
|
161
173
|
Holographic Reduced Representations (HRR) via Rust WASM for instant memory retrieval without a database query.
|
|
162
174
|
|
|
@@ -229,6 +241,51 @@ That's it. Open Claude / Cursor and your AI now has memory.
|
|
|
229
241
|
|
|
230
242
|
More setup details in [`docs/SETUP_GEMINI.md`](docs/SETUP_GEMINI.md).
|
|
231
243
|
|
|
244
|
+
### Monitoring & Observability *(new in v16.2)*
|
|
245
|
+
|
|
246
|
+
Built-in Datadog integration โ every tool call is logged with tool name, project, and latency. Zero config for self-hosted users (logs to stdout); set `DD_API_KEY` to send structured logs to Datadog HTTP intake.
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Enable Datadog logging (optional)
|
|
250
|
+
export DD_API_KEY=your_datadog_api_key
|
|
251
|
+
|
|
252
|
+
# Enable OpenTelemetry tracing (optional โ works with Jaeger, Zipkin, Datadog, Grafana Tempo)
|
|
253
|
+
export PRISM_OTEL_ENABLED=true
|
|
254
|
+
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**What's tracked automatically:**
|
|
258
|
+
- `mcp.tool.success` โ tool name, project, duration (ms) on every successful call
|
|
259
|
+
- `mcp.tool.error` โ tool name, error message, stack trace on failures
|
|
260
|
+
- OpenTelemetry spans with `tool.name` and `project` attributes on all 50 tool handlers
|
|
261
|
+
|
|
262
|
+
| Dashboard | What it tracks |
|
|
263
|
+
|-----------|---------------|
|
|
264
|
+
| [Prism MCP โ Server Analytics](https://app.datadoghq.com/dashboard/tdm-92f-myh/prism-mcp--server-analytics) | Tool call volume, latency per tool (avg/p95), errors by tool, project activity, knowledge search/ingest, session memory ops |
|
|
265
|
+
|
|
266
|
+
### In-app analytics for paid users *(new in v16.2)*
|
|
267
|
+
|
|
268
|
+
Paid Synalux subscribers get a built-in analytics dashboard at `/app/memory-analytics`:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
272
|
+
โ Analytics [standard] plan โ
|
|
273
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
274
|
+
โ ๐ Sessions: 147 ๐ Handoffs: 23 ๐ Knowledge: 89 โ
|
|
275
|
+
โ ๐ Projects: 5 ๐พ Memory: 42 KB โ
|
|
276
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
277
|
+
โ Today's Usage ๐ง 47/200 ๐ 12/50 ๐ฌ 85/200 โ
|
|
278
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
279
|
+
โ 30-Day Trend โโโ
โโโโโ
โโโโโ
โโโโ
โโโ
โโโโโโ
โโโ
โ โ
|
|
280
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
281
|
+
โ Top Projects prism-mcp (45) ยท portal (32) ยท ... โ
|
|
282
|
+
โ Compaction 3 entries > 5KB โ run compact_ledger โ
|
|
283
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
- **Free tier**: paywall with upgrade CTA
|
|
287
|
+
- **Standard+**: session counts, handoffs, knowledge entries, daily quotas with tier limits, 30-day activity trend, project breakdown, compaction candidates
|
|
288
|
+
|
|
232
289
|
---
|
|
233
290
|
|
|
234
291
|
## How AI agents use it
|
|
@@ -319,6 +376,98 @@ python3 tests/benchmarks/cascade-14b-32b-opus/cascade_eval.py
|
|
|
319
376
|
|---|---|---|
|
|
320
377
|
| Per-model BFCL | [`tests/benchmarks/prism-routing-100/`](tests/benchmarks/prism-routing-100/) | Solo accuracy per model, 12 categories |
|
|
321
378
|
| Cascade vs Opus | [`tests/benchmarks/cascade-14b-32b-opus/`](tests/benchmarks/cascade-14b-32b-opus/) | Tier distribution, Opus engagement rate, cascade accuracy |
|
|
379
|
+
| LoCoMo-Plus (Cognitive) | [`dcostenco/Locomo-Plus`](https://github.com/dcostenco/Locomo-Plus) | Long-context dialogue coherence and historical memory retention |
|
|
380
|
+
|
|
381
|
+
### Cognitive Dialogue Memory (LoCoMo-Plus Benchmark)
|
|
382
|
+
|
|
383
|
+
LoCoMo-Plus is a long-context, multi-day dialogue benchmark designed to test an AI agent's memory retention, context awareness, and ability to coherently reference historical dialogue evidence.
|
|
384
|
+
|
|
385
|
+
The **Cognitive** subset (401 multi-day dialogue scenarios) was evaluated head-to-head comparing raw baseline models against the **Prism-MCP** framework (using local SQLite semantic memory). Graded by a neutral `gemini-2.5-flash` model acting as judge (scoring on coherence, continuity, and fact accuracy):
|
|
386
|
+
|
|
387
|
+
| Configuration | Samples | Total Score | Average Score | Absolute Delta | Relative Error Reduction |
|
|
388
|
+
| :--- | :---: | :---: | :---: | :---: | :---: |
|
|
389
|
+
| **Gemini-2.5-flash (Baseline)** | 401 | 278.0 / 401 | **69.33%** | โ | โ |
|
|
390
|
+
| **Prism-MCP (Gemini-2.5-flash + Memory)** | 401 | 361.0 / 401 | **90.02%** | **+20.69pp** | **67.5%** |
|
|
391
|
+
| **Gemini-3.1-pro-preview (Baseline)** | 401 | 272.0 / 401 | **67.83%** | โ | โ |
|
|
392
|
+
| **Prism-MCP (Gemini-3.1-pro + Memory)** | 401 | 382.0 / 401 | **95.26%** | **+27.43pp** | **85.3%** |
|
|
393
|
+
| **Gemini-3.5-flash (Baseline)** | 401 | 237.0 / 401 | **59.10%** | โ | โ |
|
|
394
|
+
| **Prism-MCP (Gemini-3.5-flash + Memory)** | 401 | 388.0 / 401 | **96.76%** | **+37.66pp** | **92.1%** |
|
|
395
|
+
| **Claude Sonnet 4.6 (Baseline)** | 401 | 290.0 / 401 | **72.32%** | โ | โ |
|
|
396
|
+
| **Prism-MCP (Claude Sonnet 4.6 + Memory)** | 401 | 357.0 / 401 | **89.03%** | **+16.71pp** | **60.4%** |
|
|
397
|
+
|
|
398
|
+
**Key Takeaways**:
|
|
399
|
+
* **Pure attention limits**: Even the strongest frontier model tested โ Claude Sonnet 4.6 at **72.32%** โ misses over a quarter of cognitive memory cues without external memory. Gemini 3.5 Flash baseline sits at **59.10%**. Both suffer from attention dilution when parsing massive multi-day transcripts directly in active context.
|
|
400
|
+
* **Prism lifts every model**: Prism-MCP yields large gains regardless of base model โ from +16.71pp (Claude) to +37.66pp (Gemini 3.5 Flash). Even Claude's stronger native recall benefits from structured retrieval, jumping from 72.32% to **89.03%**.
|
|
401
|
+
* **Best overall**: Prism-MCP + Gemini 3.5 Flash achieves the highest score (**96.76%**), eliminating 92.1% of baseline errors. This makes the cheapest model + Prism more accurate than the most expensive model alone.
|
|
402
|
+
* **Claude vs Gemini (raw)**: Claude Sonnet 4.6 outperforms all Gemini baselines by a wide margin (+13.22pp over Flash 3.5, +4.49pp over Pro 3.1), confirming stronger native long-context recall.
|
|
403
|
+
|
|
404
|
+
<details>
|
|
405
|
+
<summary>๐ View Test Case Schema & Sample</summary>
|
|
406
|
+
|
|
407
|
+
A representative test sample from the `unified_cognitive_only.json` ([GitHub source](https://github.com/dcostenco/Locomo-Plus/blob/main/data/unified_cognitive_only.json)) dataset contains a multi-turn chat history with a memory "needle" placed days prior, followed by a cued dialogue prompt:
|
|
408
|
+
|
|
409
|
+
```json
|
|
410
|
+
{
|
|
411
|
+
"category": "Cognitive",
|
|
412
|
+
"input_prompt": "Caroline said, \"...\"\nMelanie said, \"...\"",
|
|
413
|
+
"trigger": "Melanie said, \"Hey, Caroline! Nice to hear from you! Love the necklace, any special meaning to it?\"",
|
|
414
|
+
"evidence": "Swedish grandmother's necklace was gifted to Caroline",
|
|
415
|
+
"answer": "Yes, this necklace was a gift from my grandmother in my home country, Sweden."
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
When evaluated:
|
|
420
|
+
* **Baseline models** without memory frequently output a generic guess (e.g., "Thanks, it was a gift from a friend") or fail to reference the Sweden/grandmother relationship.
|
|
421
|
+
* **Prism-MCP** automatically embeds the prior turns, stores them in SQLite, and when cued, retrieves the precise "Swedish grandmother" evidence turn via semantic vectors to inject it into active context.
|
|
422
|
+
</details>
|
|
423
|
+
|
|
424
|
+
<details>
|
|
425
|
+
<summary>๐ป View How to Reproduce Publicly (Test Source & Guide)</summary>
|
|
426
|
+
|
|
427
|
+
To run and review the evaluation suite on your local setup using the benchmark runner scripts (`evaluate_qa.py` and `llm_as_judge.py`):
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# 1. Clone the LoCoMo-Plus evaluation codebase
|
|
431
|
+
git clone https://github.com/dcostenco/Locomo-Plus /tmp/Locomo-Plus
|
|
432
|
+
cd /tmp/Locomo-Plus
|
|
433
|
+
|
|
434
|
+
# 2. Run Baseline Gemini 3.1 Pro Evaluation (concurrency 5)
|
|
435
|
+
export GOOGLE_API_KEY="your-api-key"
|
|
436
|
+
PYTHONPATH=/tmp/Locomo-Plus python3 evaluation_framework/task_eval/evaluate_qa.py \
|
|
437
|
+
--data-file data/unified_cognitive_only.json \
|
|
438
|
+
--out-file output/gemini_3.1_pro_pred.json \
|
|
439
|
+
--model gemini-3.1-pro-preview \
|
|
440
|
+
--backend call_gemini \
|
|
441
|
+
--concurrency 5
|
|
442
|
+
|
|
443
|
+
# 3. Run Prism-MCP powered by Gemini 3.1 Pro Evaluation (concurrency 1 to guard SQLite locks)
|
|
444
|
+
export PRISM_TEXT_MODEL=gemini-3.1-pro-preview
|
|
445
|
+
PYTHONPATH=/tmp/Locomo-Plus python3 evaluation_framework/task_eval/evaluate_qa.py \
|
|
446
|
+
--data-file data/unified_cognitive_only.json \
|
|
447
|
+
--out-file output/prism_gemini_3.1_pro_pred.json \
|
|
448
|
+
--model gemini-3.1-pro-preview \
|
|
449
|
+
--backend call_prism \
|
|
450
|
+
--concurrency 1
|
|
451
|
+
|
|
452
|
+
# 4. Run Claude Sonnet 4.6 Baseline Evaluation (concurrency 3, rate-limit safe)
|
|
453
|
+
export ANTHROPIC_API_KEY="your-api-key"
|
|
454
|
+
PYTHONPATH=/tmp/Locomo-Plus python3 evaluation_framework/task_eval/evaluate_qa.py \
|
|
455
|
+
--data-file data/unified_cognitive_only.json \
|
|
456
|
+
--out-file output/claude_sonnet46_pred.json \
|
|
457
|
+
--model claude-sonnet-4-6 \
|
|
458
|
+
--backend call_claude \
|
|
459
|
+
--concurrency 3
|
|
460
|
+
|
|
461
|
+
# 5. Grade results using the LLM-as-a-Judge script
|
|
462
|
+
PYTHONPATH=/tmp/Locomo-Plus python3 evaluation_framework/task_eval/llm_as_judge.py \
|
|
463
|
+
--input-file output/prism_gemini_3.1_pro_pred.json \
|
|
464
|
+
--out-file output/prism_gemini_3.1_pro_judged.json \
|
|
465
|
+
--model gemini-2.5-flash \
|
|
466
|
+
--backend call_gemini \
|
|
467
|
+
--concurrency 5 \
|
|
468
|
+
--summary-file output/prism_gemini_3.1_pro_summary.json
|
|
469
|
+
```
|
|
470
|
+
</details>
|
|
322
471
|
|
|
323
472
|
### Models on HuggingFace
|
|
324
473
|
|
package/dist/server.js
CHANGED
|
@@ -77,6 +77,7 @@ import { getSettingSync, initConfigStorage } from "./storage/configStorage.js";
|
|
|
77
77
|
import { sanitizeMcpOutput } from "./utils/sanitizer.js";
|
|
78
78
|
import { getTracer, initTelemetry } from "./utils/telemetry.js";
|
|
79
79
|
import { context as otelContext, trace, SpanStatusCode } from "@opentelemetry/api";
|
|
80
|
+
import { ddInfo, ddError as ddLogError } from "./utils/ddLogger.js";
|
|
80
81
|
// โโโ Import Tool Definitions (schemas) and Handlers (implementations) โโโโโ
|
|
81
82
|
import { WEB_SEARCH_TOOL, BRAVE_WEB_SEARCH_CODE_MODE_TOOL, LOCAL_SEARCH_TOOL, BRAVE_LOCAL_SEARCH_CODE_MODE_TOOL, CODE_MODE_TRANSFORM_TOOL, BRAVE_ANSWERS_TOOL, RESEARCH_PAPER_ANALYSIS_TOOL, webSearchHandler, braveWebSearchCodeModeHandler, localSearchHandler, braveLocalSearchCodeModeHandler, codeModeTransformHandler, braveAnswersHandler, researchPaperAnalysisHandler, } from "./tools/index.js";
|
|
82
83
|
// Session memory tools โ only used if Supabase is configured
|
|
@@ -103,6 +104,8 @@ SESSION_SAVE_EXPERIENCE_TOOL, KNOWLEDGE_UPVOTE_TOOL, KNOWLEDGE_DOWNVOTE_TOOL,
|
|
|
103
104
|
SESSION_BACKFILL_LINKS_TOOL, SESSION_SYNTHESIZE_EDGES_TOOL, SESSION_COGNITIVE_ROUTE_TOOL,
|
|
104
105
|
// v7.1: Task Router
|
|
105
106
|
SESSION_TASK_ROUTE_TOOL,
|
|
107
|
+
// Session Drift Detection
|
|
108
|
+
SESSION_DETECT_DRIFT_TOOL,
|
|
106
109
|
// v12: Developer Onboarding & Enterprise Observability
|
|
107
110
|
ONBOARDING_WIZARD_TOOL, EXTRACT_ENTITIES_TOOL, API_ANALYTICS_TOOL, BACKUP_DATABASE_TOOL, CONFIGURE_NOTIFICATIONS_TOOL, QUERY_MEMORY_NATURAL_TOOL,
|
|
108
111
|
// v15.5: Knowledge Ingestion
|
|
@@ -133,6 +136,8 @@ MAINTENANCE_VACUUM_TOOL, maintenanceVacuumHandler,
|
|
|
133
136
|
AGENT_REGISTRY_TOOLS, agentRegisterHandler, agentHeartbeatHandler, agentListTeamHandler,
|
|
134
137
|
// v7.1: Task Router
|
|
135
138
|
sessionTaskRouteHandler,
|
|
139
|
+
// Session Drift Detection
|
|
140
|
+
sessionDetectDriftHandler,
|
|
136
141
|
// v7.3: Dark Factory Pipeline tools
|
|
137
142
|
SESSION_START_PIPELINE_TOOL, SESSION_CHECK_PIPELINE_STATUS_TOOL, SESSION_ABORT_PIPELINE_TOOL, sessionStartPipelineHandler, sessionCheckPipelineStatusHandler, sessionAbortPipelineHandler,
|
|
138
143
|
// v12: Handler implementations
|
|
@@ -224,6 +229,7 @@ function buildSessionMemoryTools(autoloadList) {
|
|
|
224
229
|
SESSION_BACKFILL_LINKS_TOOL, // session_backfill_links โ retroactive graph edge creation
|
|
225
230
|
SESSION_SYNTHESIZE_EDGES_TOOL, // session_synthesize_edges โ inferred semantic graph enrichment
|
|
226
231
|
SESSION_COGNITIVE_ROUTE_TOOL, // session_cognitive_route โ HDC policy-gated concept routing (v6.5)
|
|
232
|
+
SESSION_DETECT_DRIFT_TOOL, // session_detect_drift โ semantic goal drift detection (synalux)
|
|
227
233
|
// โโโ v6.1: Storage Hygiene tool โโโ
|
|
228
234
|
MAINTENANCE_VACUUM_TOOL, // maintenance_vacuum โ reclaim SQLite disk space post-purge
|
|
229
235
|
// โโโ v12.1: Developer Onboarding & Framework Bridge โโโ
|
|
@@ -672,6 +678,7 @@ export function createServer() {
|
|
|
672
678
|
// through await chains โ including fire-and-forget workers launched
|
|
673
679
|
// within the handler body (e.g. imageCaptioner, embeddings backfill).
|
|
674
680
|
return otelContext.with(trace.setSpan(otelContext.active(), rootSpan), async () => {
|
|
681
|
+
const _ddStart = Date.now();
|
|
675
682
|
try {
|
|
676
683
|
if (!args) {
|
|
677
684
|
throw new Error("No arguments provided");
|
|
@@ -879,6 +886,12 @@ export function createServer() {
|
|
|
879
886
|
throw new Error("Task router not enabled. Enable it in the dashboard or set PRISM_TASK_ROUTER_ENABLED=true.");
|
|
880
887
|
result = await sessionTaskRouteHandler(args);
|
|
881
888
|
break;
|
|
889
|
+
// โโโ Session Drift Detection โโโ
|
|
890
|
+
case "session_detect_drift":
|
|
891
|
+
if (!SESSION_MEMORY_ENABLED)
|
|
892
|
+
throw new Error("Session memory not configured. Set SUPABASE_URL and SUPABASE_KEY.");
|
|
893
|
+
result = await sessionDetectDriftHandler(args);
|
|
894
|
+
break;
|
|
882
895
|
// โโโ v7.3: Dark Factory Pipeline Tools โโโ
|
|
883
896
|
case "session_start_pipeline":
|
|
884
897
|
if (!SESSION_MEMORY_ENABLED)
|
|
@@ -945,6 +958,7 @@ export function createServer() {
|
|
|
945
958
|
};
|
|
946
959
|
}
|
|
947
960
|
rootSpan.setStatus({ code: SpanStatusCode.OK });
|
|
961
|
+
ddInfo("mcp.tool.success", { tool: name, project: args?.project, durationMs: Date.now() - _ddStart });
|
|
948
962
|
// โโโ v5.3: Hivemind Watchdog Alert Injection (Telepathy) โโโ
|
|
949
963
|
// CRITICAL: Append alerts DIRECTLY to tool response content
|
|
950
964
|
// so the LLM actually reads them. sendLoggingMessage goes to
|
|
@@ -985,6 +999,7 @@ export function createServer() {
|
|
|
985
999
|
}
|
|
986
1000
|
catch (error) {
|
|
987
1001
|
console.error(`Error in tool handler: ${error instanceof Error ? error.message : String(error)}`);
|
|
1002
|
+
ddLogError("mcp.tool.error", error instanceof Error ? error : undefined, { tool: name, project: args?.project, durationMs: Date.now() - _ddStart });
|
|
988
1003
|
rootSpan.recordException(error instanceof Error ? error : new Error(String(error)));
|
|
989
1004
|
rootSpan.setStatus({
|
|
990
1005
|
code: SpanStatusCode.ERROR,
|
package/dist/storage/synalux.js
CHANGED
|
@@ -346,6 +346,22 @@ export class SynaluxStorage extends SupabaseStorage {
|
|
|
346
346
|
};
|
|
347
347
|
}
|
|
348
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Detect semantic drift between the session goal and recent ledger entries.
|
|
351
|
+
* Delegates embedding + detection to the Synalux portal (source of truth for
|
|
352
|
+
* the HRR/GloVe/cosine stack). Prism-mcp never does NLP directly.
|
|
353
|
+
*/
|
|
354
|
+
async detectDrift(project, goal, windowHours, minDirectionalRatio, extraParams) {
|
|
355
|
+
const body = { action: "detect_drift", project, goal };
|
|
356
|
+
if (typeof windowHours === "number")
|
|
357
|
+
body.window_hours = windowHours;
|
|
358
|
+
if (typeof minDirectionalRatio === "number")
|
|
359
|
+
body.min_directional_ratio = minDirectionalRatio;
|
|
360
|
+
if (extraParams)
|
|
361
|
+
Object.assign(body, extraParams);
|
|
362
|
+
const result = await this.portalPost("/api/v1/prism/memory", body);
|
|
363
|
+
return result;
|
|
364
|
+
}
|
|
349
365
|
/**
|
|
350
366
|
* Fetch skill content from Synalux portal (paid-tier single source of truth).
|
|
351
367
|
* Returns a map of { skillName โ SKILL.md content } for all names that exist.
|
package/dist/tools/index.js
CHANGED
|
@@ -54,6 +54,9 @@ export { SESSION_START_PIPELINE_TOOL, SESSION_CHECK_PIPELINE_STATUS_TOOL, SESSIO
|
|
|
54
54
|
export { sessionStartPipelineHandler, sessionCheckPipelineStatusHandler, sessionAbortPipelineHandler, } from "./pipelineHandlers.js";
|
|
55
55
|
// โโ v12 Tool Handlers (Developer Onboarding & Enterprise Observability) โโ
|
|
56
56
|
export { onboardingWizardHandler, extractEntitiesHandler, apiAnalyticsHandler, backupDatabaseHandler, configureNotificationsHandler, queryMemoryNaturalHandler, } from "./v12Handlers.js";
|
|
57
|
+
// โโ Session Drift Detection โโ
|
|
58
|
+
export { SESSION_DETECT_DRIFT_TOOL, isSessionDetectDriftArgs } from "./sessionMemoryDefinitions.js";
|
|
59
|
+
export { sessionDetectDriftHandler } from "./sessionDriftHandler.js";
|
|
57
60
|
// โโ Knowledge Ingestion (v15.5 โ Open Interface) โโ
|
|
58
61
|
// Chunks source code, generates Q&A via Claude Haiku, stores in knowledge graph.
|
|
59
62
|
// Three entry points: MCP tool, REST API, GitHub webhook.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session_detect_drift โ MCP Tool Handler
|
|
3
|
+
*
|
|
4
|
+
* Thin-client dispatcher: validates args, delegates to the Synalux portal
|
|
5
|
+
* (POST /api/v1/prism/memory action=detect_drift) which owns the embedding
|
|
6
|
+
* + detection logic, and returns the structured result.
|
|
7
|
+
*
|
|
8
|
+
* Prism-mcp never does NLP or embedding here โ that lives in synalux-private.
|
|
9
|
+
*/
|
|
10
|
+
import { isSessionDetectDriftArgs } from "./sessionMemoryDefinitions.js";
|
|
11
|
+
import { getStorage } from "../storage/index.js";
|
|
12
|
+
import { debugLog } from "../utils/logger.js";
|
|
13
|
+
export async function sessionDetectDriftHandler(args) {
|
|
14
|
+
if (!isSessionDetectDriftArgs(args)) {
|
|
15
|
+
return {
|
|
16
|
+
content: [{ type: "text", text: "Invalid arguments for session_detect_drift. Required: project (string), goal (string). Optional: window_hours (number), min_directional_ratio (number)." }],
|
|
17
|
+
isError: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const storage = await getStorage();
|
|
22
|
+
// SynaluxStorage exposes detectDrift(); SqliteStorage falls through to
|
|
23
|
+
// an error because it has no embedding stack. Free-tier users without
|
|
24
|
+
// portal access receive a clear upgrade message.
|
|
25
|
+
if (typeof storage.detectDrift !== "function") {
|
|
26
|
+
return {
|
|
27
|
+
content: [{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: JSON.stringify({
|
|
30
|
+
status: "error",
|
|
31
|
+
error: "session_detect_drift requires cloud memory (Standard plan or higher). Set SUPABASE_URL and SUPABASE_KEY to enable.",
|
|
32
|
+
upgrade_url: "/pricing",
|
|
33
|
+
}),
|
|
34
|
+
}],
|
|
35
|
+
isError: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Build extra params for domain-specific signals
|
|
39
|
+
const extra = {};
|
|
40
|
+
if (args.domain)
|
|
41
|
+
extra.domain = args.domain;
|
|
42
|
+
if (args.behavior_functions)
|
|
43
|
+
extra.behavior_functions = args.behavior_functions;
|
|
44
|
+
if (args.contraindications)
|
|
45
|
+
extra.contraindications = args.contraindications;
|
|
46
|
+
if (args.client_descriptors)
|
|
47
|
+
extra.client_descriptors = args.client_descriptors;
|
|
48
|
+
if (args.assessment_type)
|
|
49
|
+
extra.assessment_type = args.assessment_type;
|
|
50
|
+
const result = await storage.detectDrift(args.project, args.goal, args.window_hours, args.min_directional_ratio, Object.keys(extra).length > 0 ? extra : undefined);
|
|
51
|
+
return {
|
|
52
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
debugLog(`[session_detect_drift] Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
57
|
+
return {
|
|
58
|
+
content: [{ type: "text", text: `Error running drift detection: ${err instanceof Error ? err.message : String(err)}` }],
|
|
59
|
+
isError: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1664,3 +1664,89 @@ export function isQueryMemoryNaturalArgs(args) {
|
|
|
1664
1664
|
return false;
|
|
1665
1665
|
return true;
|
|
1666
1666
|
}
|
|
1667
|
+
// โโโ Session Detect Drift โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
1668
|
+
export const SESSION_DETECT_DRIFT_TOOL = {
|
|
1669
|
+
name: "session_detect_drift",
|
|
1670
|
+
description: "Detect whether the current agent session has semantically drifted from its " +
|
|
1671
|
+
"original goal. Scores recent ledger entries against the goal using synalux's " +
|
|
1672
|
+
"HRR embedding stack (GloVe โ Gemini/Voyage โ cosine similarity), then runs " +
|
|
1673
|
+
"the rolling-window drift detector algorithm.\n\n" +
|
|
1674
|
+
"**Triggers:**\n" +
|
|
1675
|
+
"- `goal-drift` โ cumulative alignment loss is high and monotonic (not random tangents)\n" +
|
|
1676
|
+
"- `context-collapse` โ average output quality has dropped below floor\n\n" +
|
|
1677
|
+
"**Pre-warning:**\n" +
|
|
1678
|
+
"- `quality-degrading` โ quality slope steeply negative before collapse\n\n" +
|
|
1679
|
+
"**Returns:** drifted, reason, warning, drift_score (0..1), goal_alignment, " +
|
|
1680
|
+
"quality_avg, sample_count, adaptive_threshold, recommendation.\n\n" +
|
|
1681
|
+
"Use alongside GATE 5 (60-minute drift check): call this tool instead of " +
|
|
1682
|
+
"session_cognitive_route for goal-alignment drift detection.",
|
|
1683
|
+
inputSchema: {
|
|
1684
|
+
type: "object",
|
|
1685
|
+
properties: {
|
|
1686
|
+
project: {
|
|
1687
|
+
type: "string",
|
|
1688
|
+
description: "Project identifier. Must match the project used in session_save_ledger.",
|
|
1689
|
+
},
|
|
1690
|
+
goal: {
|
|
1691
|
+
type: "string",
|
|
1692
|
+
description: "The original session goal โ the task you started this session to accomplish. " +
|
|
1693
|
+
"Used as the semantic reference vector. Be specific: 'implement drift detection for prism-mcp' " +
|
|
1694
|
+
"is better than 'work on prism'.",
|
|
1695
|
+
},
|
|
1696
|
+
window_hours: {
|
|
1697
|
+
type: "number",
|
|
1698
|
+
description: "How many hours of ledger history to evaluate. Default 1. Range 0.083โ24 (5 min to 24 h).",
|
|
1699
|
+
},
|
|
1700
|
+
min_directional_ratio: {
|
|
1701
|
+
type: "number",
|
|
1702
|
+
description: "Directional ratio floor for the tremor filter (0..1). " +
|
|
1703
|
+
"Random topic tangents that return to the goal are suppressed below this threshold. " +
|
|
1704
|
+
"Default 0.2. Set to 0 to disable filter.",
|
|
1705
|
+
},
|
|
1706
|
+
domain: {
|
|
1707
|
+
type: "string",
|
|
1708
|
+
enum: ["coder", "bcba", "aac"],
|
|
1709
|
+
description: "Optional domain for domain-specific drift signals. " +
|
|
1710
|
+
"'coder' adds file_entropy, summary_vagueness, test_coverage_ratio, trajectory_divergence. " +
|
|
1711
|
+
"'bcba' adds clinical_specificity, function_aligned, contraindication_safe (requires behavior_functions, contraindications, client_descriptors params). " +
|
|
1712
|
+
"'aac' is reserved for future AAC prediction drift (use the AAC-specific endpoint instead).",
|
|
1713
|
+
},
|
|
1714
|
+
behavior_functions: {
|
|
1715
|
+
type: "array",
|
|
1716
|
+
items: { type: "string" },
|
|
1717
|
+
description: "BCBA domain only: identified behavior functions for this client (e.g. ['escape-maintained', 'attention-maintained']).",
|
|
1718
|
+
},
|
|
1719
|
+
contraindications: {
|
|
1720
|
+
type: "array",
|
|
1721
|
+
items: { type: "string" },
|
|
1722
|
+
description: "BCBA domain only: known medical conditions (e.g. ['epilepsy', 'pica']).",
|
|
1723
|
+
},
|
|
1724
|
+
client_descriptors: {
|
|
1725
|
+
type: "array",
|
|
1726
|
+
items: { type: "string" },
|
|
1727
|
+
description: "BCBA domain only: client-specific terms to check for specificity (e.g. ['7-year-old', 'aggression at transitions']).",
|
|
1728
|
+
},
|
|
1729
|
+
assessment_type: {
|
|
1730
|
+
type: "string",
|
|
1731
|
+
description: "BCBA domain only: assessment instrument name (e.g. 'vb-mapp', 'vineland', 'ablls-r').",
|
|
1732
|
+
},
|
|
1733
|
+
},
|
|
1734
|
+
required: ["project", "goal"],
|
|
1735
|
+
},
|
|
1736
|
+
};
|
|
1737
|
+
export function isSessionDetectDriftArgs(args) {
|
|
1738
|
+
if (typeof args !== "object" || args === null)
|
|
1739
|
+
return false;
|
|
1740
|
+
const a = args;
|
|
1741
|
+
if (typeof a.project !== "string" || !a.project.trim())
|
|
1742
|
+
return false;
|
|
1743
|
+
if (typeof a.goal !== "string" || !a.goal.trim())
|
|
1744
|
+
return false;
|
|
1745
|
+
if (a.window_hours !== undefined && typeof a.window_hours !== "number")
|
|
1746
|
+
return false;
|
|
1747
|
+
if (a.min_directional_ratio !== undefined && typeof a.min_directional_ratio !== "number")
|
|
1748
|
+
return false;
|
|
1749
|
+
if (a.domain !== undefined && !["coder", "bcba", "aac"].includes(a.domain))
|
|
1750
|
+
return false;
|
|
1751
|
+
return true;
|
|
1752
|
+
}
|
package/dist/utils/ddLogger.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Telemetry Logger โ Prism MCP Server
|
|
3
3
|
*
|
|
4
|
-
* Sends structured
|
|
5
|
-
*
|
|
4
|
+
* Sends structured events to Synalux portal (/api/v1/telemetry)
|
|
5
|
+
* which stores in Supabase with 15-day retention.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Falls back to Datadog HTTP Logs if DD_API_KEY is set.
|
|
8
|
+
* Env: PRISM_SYNALUX_BASE_URL (default https://synalux.ai)
|
|
8
9
|
*/
|
|
10
|
+
const SYNALUX_BASE = process.env.PRISM_SYNALUX_BASE_URL || "https://synalux.ai";
|
|
9
11
|
const DD_API_KEY = process.env.DD_API_KEY || "";
|
|
10
12
|
const DD_SITE = process.env.DD_SITE || "datadoghq.com";
|
|
11
13
|
const SERVICE = "prism-mcp";
|
|
12
|
-
const INTAKE_URL = `https://http-intake.logs.${DD_SITE}/api/v2/logs`;
|
|
13
14
|
const queue = [];
|
|
14
15
|
let flushTimer = null;
|
|
15
16
|
const FLUSH_INTERVAL_MS = 5_000;
|
|
@@ -21,29 +22,46 @@ function scheduleFlush() {
|
|
|
21
22
|
}
|
|
22
23
|
async function flush() {
|
|
23
24
|
flushTimer = null;
|
|
24
|
-
if (queue.length === 0
|
|
25
|
+
if (queue.length === 0)
|
|
25
26
|
return;
|
|
26
27
|
const batch = queue.splice(0, MAX_BATCH);
|
|
28
|
+
// Primary: Synalux portal โ Supabase (always available)
|
|
27
29
|
try {
|
|
28
|
-
await fetch(
|
|
30
|
+
await fetch(`${SYNALUX_BASE}/api/v1/telemetry`, {
|
|
29
31
|
method: "POST",
|
|
30
|
-
headers: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
headers: { "Content-Type": "application/json" },
|
|
33
|
+
body: JSON.stringify(batch.map(e => ({
|
|
34
|
+
service: SERVICE,
|
|
35
|
+
event_type: e.status === "error" ? "error" : "action",
|
|
36
|
+
message: e.message,
|
|
37
|
+
context: { ...e, service: undefined, message: undefined },
|
|
38
|
+
user_id: e.user_id,
|
|
39
|
+
user_plan: e.user_plan,
|
|
40
|
+
}))),
|
|
35
41
|
signal: AbortSignal.timeout(5_000),
|
|
36
42
|
});
|
|
37
43
|
}
|
|
38
44
|
catch {
|
|
39
|
-
// Silent โ don't crash the
|
|
45
|
+
// Silent โ don't crash the MCP server
|
|
46
|
+
}
|
|
47
|
+
// Secondary: Datadog Logs (if API key is set AND Logs product is enabled)
|
|
48
|
+
if (DD_API_KEY) {
|
|
49
|
+
try {
|
|
50
|
+
await fetch(`https://http-intake.logs.${DD_SITE}/api/v2/logs`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: { "Content-Type": "application/json", "DD-API-KEY": DD_API_KEY },
|
|
53
|
+
body: JSON.stringify(batch),
|
|
54
|
+
signal: AbortSignal.timeout(5_000),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Silent
|
|
59
|
+
}
|
|
40
60
|
}
|
|
41
61
|
if (queue.length > 0)
|
|
42
62
|
scheduleFlush();
|
|
43
63
|
}
|
|
44
64
|
export function ddLog(level, message, context) {
|
|
45
|
-
if (!DD_API_KEY)
|
|
46
|
-
return;
|
|
47
65
|
queue.push({
|
|
48
66
|
ddsource: "nodejs",
|
|
49
67
|
ddtags: `env:${process.env.NODE_ENV || "development"},service:${SERVICE}`,
|
|
@@ -37,7 +37,7 @@ import { debugLog } from "../../logger.js";
|
|
|
37
37
|
// โโโ Model Constants โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
38
38
|
// Defined as constants (not hardcoded strings) so external reviewers can see
|
|
39
39
|
// all model choices at a glance, and future changes only need one edit.
|
|
40
|
-
const TEXT_MODEL = "gemini-2.5-flash"; // chat/instruction-following model
|
|
40
|
+
const TEXT_MODEL = process.env.PRISM_TEXT_MODEL || "gemini-2.5-flash"; // chat/instruction-following model
|
|
41
41
|
const EMBEDDING_MODEL = "gemini-embedding-001"; // vector embedding model (MRL-enabled)
|
|
42
42
|
const EMBEDDING_DIMS = 768; // fixed output dims โ must match DB schema
|
|
43
43
|
// โโโ Embedding Truncation Constants โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prism-mcp-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "17.0.0",
|
|
4
4
|
"mcpName": "io.github.dcostenco/prism-coder",
|
|
5
|
-
"description": "Prism Coder โ Cognitive memory + tool-calling intelligence for AI agents. Mind Palace persistent memory (BFCL Gold Certified, 100% Tool-Call Accuracy, 54 Agent Skills, Zero-Search HDC/HRR retrieval, HIPAA-hardened local-first storage, SLERP-optimized GRPO alignment) plus the prism-coder:7b / 14b open-weights LLM fleet.",
|
|
5
|
+
"description": "Prism Coder โ Cognitive memory + tool-calling intelligence for AI agents. Mind Palace persistent memory (BFCL Gold Certified, 100% Tool-Call Accuracy, 54 Agent Skills, Zero-Search HDC/HRR retrieval, HRR Semantic Drift Detection across BCBA/Coding/AAC domains, HIPAA-hardened local-first storage, SLERP-optimized GRPO alignment) plus the prism-coder:7b / 14b open-weights LLM fleet.",
|
|
6
6
|
"module": "index.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/server.js",
|