prism-mcp-server 16.2.0 → 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 +36 -9
- package/dist/server.js +11 -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/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
|
|
|
@@ -364,7 +376,7 @@ python3 tests/benchmarks/cascade-14b-32b-opus/cascade_eval.py
|
|
|
364
376
|
|---|---|---|
|
|
365
377
|
| Per-model BFCL | [`tests/benchmarks/prism-routing-100/`](tests/benchmarks/prism-routing-100/) | Solo accuracy per model, 12 categories |
|
|
366
378
|
| Cascade vs Opus | [`tests/benchmarks/cascade-14b-32b-opus/`](tests/benchmarks/cascade-14b-32b-opus/) | Tier distribution, Opus engagement rate, cascade accuracy |
|
|
367
|
-
| LoCoMo-Plus (Cognitive) |
|
|
379
|
+
| LoCoMo-Plus (Cognitive) | [`dcostenco/Locomo-Plus`](https://github.com/dcostenco/Locomo-Plus) | Long-context dialogue coherence and historical memory retention |
|
|
368
380
|
|
|
369
381
|
### Cognitive Dialogue Memory (LoCoMo-Plus Benchmark)
|
|
370
382
|
|
|
@@ -372,21 +384,27 @@ LoCoMo-Plus is a long-context, multi-day dialogue benchmark designed to test an
|
|
|
372
384
|
|
|
373
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):
|
|
374
386
|
|
|
375
|
-
| Configuration |
|
|
387
|
+
| Configuration | Samples | Total Score | Average Score | Absolute Delta | Relative Error Reduction |
|
|
376
388
|
| :--- | :---: | :---: | :---: | :---: | :---: |
|
|
377
389
|
| **Gemini-2.5-flash (Baseline)** | 401 | 278.0 / 401 | **69.33%** | — | — |
|
|
378
|
-
| **Prism-MCP (Gemini-2.5-flash + Memory)** | 401 | 361.0 / 401 | **90.02%** | **+20.
|
|
390
|
+
| **Prism-MCP (Gemini-2.5-flash + Memory)** | 401 | 361.0 / 401 | **90.02%** | **+20.69pp** | **67.5%** |
|
|
379
391
|
| **Gemini-3.1-pro-preview (Baseline)** | 401 | 272.0 / 401 | **67.83%** | — | — |
|
|
380
|
-
| **Prism-MCP (Gemini-3.1-pro + Memory)** | 401 | 382.0 / 401 | **95.26%** | **+27.
|
|
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%** |
|
|
381
397
|
|
|
382
398
|
**Key Takeaways**:
|
|
383
|
-
* **Pure attention limits**:
|
|
384
|
-
* **
|
|
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.
|
|
385
403
|
|
|
386
404
|
<details>
|
|
387
405
|
<summary>🔍 View Test Case Schema & Sample</summary>
|
|
388
406
|
|
|
389
|
-
A representative test sample from the
|
|
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:
|
|
390
408
|
|
|
391
409
|
```json
|
|
392
410
|
{
|
|
@@ -406,7 +424,7 @@ When evaluated:
|
|
|
406
424
|
<details>
|
|
407
425
|
<summary>💻 View How to Reproduce Publicly (Test Source & Guide)</summary>
|
|
408
426
|
|
|
409
|
-
To run and review the evaluation suite on your local setup using the benchmark runner scripts (
|
|
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`):
|
|
410
428
|
|
|
411
429
|
```bash
|
|
412
430
|
# 1. Clone the LoCoMo-Plus evaluation codebase
|
|
@@ -431,7 +449,16 @@ PYTHONPATH=/tmp/Locomo-Plus python3 evaluation_framework/task_eval/evaluate_qa.p
|
|
|
431
449
|
--backend call_prism \
|
|
432
450
|
--concurrency 1
|
|
433
451
|
|
|
434
|
-
# 4.
|
|
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
|
|
435
462
|
PYTHONPATH=/tmp/Locomo-Plus python3 evaluation_framework/task_eval/llm_as_judge.py \
|
|
436
463
|
--input-file output/prism_gemini_3.1_pro_pred.json \
|
|
437
464
|
--out-file output/prism_gemini_3.1_pro_judged.json \
|
package/dist/server.js
CHANGED
|
@@ -104,6 +104,8 @@ SESSION_SAVE_EXPERIENCE_TOOL, KNOWLEDGE_UPVOTE_TOOL, KNOWLEDGE_DOWNVOTE_TOOL,
|
|
|
104
104
|
SESSION_BACKFILL_LINKS_TOOL, SESSION_SYNTHESIZE_EDGES_TOOL, SESSION_COGNITIVE_ROUTE_TOOL,
|
|
105
105
|
// v7.1: Task Router
|
|
106
106
|
SESSION_TASK_ROUTE_TOOL,
|
|
107
|
+
// Session Drift Detection
|
|
108
|
+
SESSION_DETECT_DRIFT_TOOL,
|
|
107
109
|
// v12: Developer Onboarding & Enterprise Observability
|
|
108
110
|
ONBOARDING_WIZARD_TOOL, EXTRACT_ENTITIES_TOOL, API_ANALYTICS_TOOL, BACKUP_DATABASE_TOOL, CONFIGURE_NOTIFICATIONS_TOOL, QUERY_MEMORY_NATURAL_TOOL,
|
|
109
111
|
// v15.5: Knowledge Ingestion
|
|
@@ -134,6 +136,8 @@ MAINTENANCE_VACUUM_TOOL, maintenanceVacuumHandler,
|
|
|
134
136
|
AGENT_REGISTRY_TOOLS, agentRegisterHandler, agentHeartbeatHandler, agentListTeamHandler,
|
|
135
137
|
// v7.1: Task Router
|
|
136
138
|
sessionTaskRouteHandler,
|
|
139
|
+
// Session Drift Detection
|
|
140
|
+
sessionDetectDriftHandler,
|
|
137
141
|
// v7.3: Dark Factory Pipeline tools
|
|
138
142
|
SESSION_START_PIPELINE_TOOL, SESSION_CHECK_PIPELINE_STATUS_TOOL, SESSION_ABORT_PIPELINE_TOOL, sessionStartPipelineHandler, sessionCheckPipelineStatusHandler, sessionAbortPipelineHandler,
|
|
139
143
|
// v12: Handler implementations
|
|
@@ -225,6 +229,7 @@ function buildSessionMemoryTools(autoloadList) {
|
|
|
225
229
|
SESSION_BACKFILL_LINKS_TOOL, // session_backfill_links — retroactive graph edge creation
|
|
226
230
|
SESSION_SYNTHESIZE_EDGES_TOOL, // session_synthesize_edges — inferred semantic graph enrichment
|
|
227
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)
|
|
228
233
|
// ─── v6.1: Storage Hygiene tool ───
|
|
229
234
|
MAINTENANCE_VACUUM_TOOL, // maintenance_vacuum — reclaim SQLite disk space post-purge
|
|
230
235
|
// ─── v12.1: Developer Onboarding & Framework Bridge ───
|
|
@@ -881,6 +886,12 @@ export function createServer() {
|
|
|
881
886
|
throw new Error("Task router not enabled. Enable it in the dashboard or set PRISM_TASK_ROUTER_ENABLED=true.");
|
|
882
887
|
result = await sessionTaskRouteHandler(args);
|
|
883
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;
|
|
884
895
|
// ─── v7.3: Dark Factory Pipeline Tools ───
|
|
885
896
|
case "session_start_pipeline":
|
|
886
897
|
if (!SESSION_MEMORY_ENABLED)
|
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}`,
|
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",
|