prism-mcp-server 7.5.0 → 7.6.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 +60 -28
- package/dist/config.js +11 -0
- package/dist/utils/llm/adapters/anthropic.js +5 -2
- package/dist/utils/llm/adapters/voyage.js +129 -0
- package/dist/utils/llm/factory.js +12 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
[](CONTRIBUTING.md)
|
|
10
10
|
|
|
11
|
-

|
|
12
12
|
|
|
13
13
|
**Your AI agent forgets everything between sessions. Prism fixes that.**
|
|
14
14
|
|
|
@@ -23,21 +23,21 @@ Works with **Claude Desktop · Claude Code · Cursor · Windsurf · Cline · Gem
|
|
|
23
23
|
## 📖 Table of Contents
|
|
24
24
|
|
|
25
25
|
- [Why Prism?](#why-prism)
|
|
26
|
-
- [Quick Start](
|
|
27
|
-
- [The Magic Moment](
|
|
28
|
-
- [Setup Guides](
|
|
29
|
-
- [Universal Import](
|
|
30
|
-
- [What Makes Prism Different](
|
|
31
|
-
- [Data Privacy & Egress](
|
|
32
|
-
- [Use Cases](
|
|
33
|
-
- [What's New](
|
|
34
|
-
- [How Prism Compares](
|
|
35
|
-
- [Tool Reference](
|
|
26
|
+
- [Quick Start](#quick-start)
|
|
27
|
+
- [The Magic Moment](#the-magic-moment)
|
|
28
|
+
- [Setup Guides](#setup-guides)
|
|
29
|
+
- [Universal Import: Bring Your History](#universal-import-bring-your-history)
|
|
30
|
+
- [What Makes Prism Different](#what-makes-prism-different)
|
|
31
|
+
- [Data Privacy & Egress](#data-privacy--egress)
|
|
32
|
+
- [Use Cases](#use-cases)
|
|
33
|
+
- [What's New](#whats-new)
|
|
34
|
+
- [How Prism Compares](#how-prism-compares)
|
|
35
|
+
- [Tool Reference](#tool-reference)
|
|
36
36
|
- [Environment Variables](#environment-variables)
|
|
37
37
|
- [Architecture](#architecture)
|
|
38
|
-
- [Scientific Foundation](
|
|
39
|
-
- [Milestones & Roadmap](
|
|
40
|
-
- [Troubleshooting FAQ](
|
|
38
|
+
- [Scientific Foundation](#scientific-foundation)
|
|
39
|
+
- [Milestones & Roadmap](#milestones--roadmap)
|
|
40
|
+
- [Troubleshooting FAQ](#troubleshooting-faq)
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
@@ -84,6 +84,8 @@ Add to your MCP client config (`claude_desktop_config.json`, `.cursor/mcp.json`,
|
|
|
84
84
|
|
|
85
85
|
**That's it.** Restart your client. All tools are available. The **Mind Palace Dashboard** (the visual UI for your agent's brain) starts automatically at `http://localhost:3000`. You don't need to keep a tab open — the dashboard runs in the background and the MCP tools work with or without it.
|
|
86
86
|
|
|
87
|
+
> 🔮 **Pro Tip:** Once installed, open **`http://localhost:3000`** in your browser to view the Mind Palace Dashboard — a beautiful, real-time UI of your agent's brain. Explore the Knowledge Graph, Intent Health gauges, and Session Ledger.
|
|
88
|
+
|
|
87
89
|
> 🔄 **Updating Prism:** `npx -y` caches the package locally. To force an update to the latest version, restart your MCP client — `npx -y` will fetch the newest release automatically. If you're stuck on a stale version, run `npx clear-npx-cache` (or `npm cache clean --force`) before restarting.
|
|
88
90
|
|
|
89
91
|
<details>
|
|
@@ -318,6 +320,32 @@ Then add to your MCP config:
|
|
|
318
320
|
|
|
319
321
|
</details>
|
|
320
322
|
|
|
323
|
+
<details>
|
|
324
|
+
<summary><strong>Cloud Deployment (Render)</strong></summary>
|
|
325
|
+
|
|
326
|
+
Prism can be deployed natively to cloud platforms like [Render](https://render.com) so your agent's memory is always online and accessible across different machines or teams.
|
|
327
|
+
|
|
328
|
+
1. Fork this repository.
|
|
329
|
+
2. In the Render Dashboard, create a new **Web Service** pointing to your repository.
|
|
330
|
+
3. In the setup wizard, select **Docker** as the Runtime.
|
|
331
|
+
4. Set the Dockerfile path to `Dockerfile.smithery`.
|
|
332
|
+
5. Connect your local MCP client to your new cloud endpoint using the `sse` transport:
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"mcpServers": {
|
|
337
|
+
"prism-mcp-cloud": {
|
|
338
|
+
"command": "npx",
|
|
339
|
+
"args": ["-y", "supergateway", "--url", "https://your-prism-app.onrender.com/sse"]
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
> **Note:** The `Dockerfile.smithery` uses an optimized multi-stage build that compiles Typescript safely in a development environment before booting the server in a stripped-down production image. No NPM publishing required!
|
|
346
|
+
|
|
347
|
+
</details>
|
|
348
|
+
|
|
321
349
|
### Common Installation Pitfalls
|
|
322
350
|
|
|
323
351
|
> **❌ Don't use `npm install -g`:**
|
|
@@ -343,11 +371,11 @@ Then add to your MCP config:
|
|
|
343
371
|
> ```
|
|
344
372
|
> At the start of every conversation, call session_load_context with project "my-project" before doing any work.
|
|
345
373
|
> ```
|
|
346
|
-
> Claude Code users can use the `.clauderules` auto-load hook shown in the [Setup Guides](
|
|
374
|
+
> Claude Code users can use the `.clauderules` auto-load hook shown in the [Setup Guides](#setup-guides). Prism also has a **server-side fallback** (v5.2.1+) that auto-pushes context after 10 seconds if no load is detected.
|
|
347
375
|
|
|
348
376
|
---
|
|
349
377
|
|
|
350
|
-
## 📥 Universal Import
|
|
378
|
+
## 📥 Universal Import: Bring Your History
|
|
351
379
|
|
|
352
380
|
Switching to Prism? Don't leave months of AI session history behind. Prism can **ingest historical sessions from Claude Code, Gemini, and OpenAI** and give your Mind Palace an instant head start — no manual re-entry required.
|
|
353
381
|
|
|
@@ -373,7 +401,7 @@ npx -y prism-mcp-server universal-import --format gemini --path ./gemini_history
|
|
|
373
401
|
**Option 2 — Dashboard:** Open `localhost:3000`, navigate to the **Import** tab, select the format and file, and click Import. Supports dry-run preview.
|
|
374
402
|
|
|
375
403
|
### Why It's Safe to Re-Run
|
|
376
|
-
* **
|
|
404
|
+
* **Memory-Safe Streaming:** Processes massive log files line-by-line using `stream-json` to prevent Out-of-Memory (OOM) crashes.
|
|
377
405
|
* **Idempotent Dedup:** Content-hash prevents duplicate imports on re-run (`skipCount` reported).
|
|
378
406
|
* **Chronological Integrity:** Uses timestamp fallbacks and `requestId` sorting to preserve your memory timeline.
|
|
379
407
|
* **Smart Context Mapping:** Extracts `cwd`, `gitBranch`, and tool usage patterns into searchable metadata.
|
|
@@ -403,7 +431,7 @@ A gorgeous glassmorphism UI at `localhost:3000` that lets you see exactly what y
|
|
|
403
431
|
- **Morning Briefing** — AI-synthesized action plan after 4+ hours away
|
|
404
432
|
- **Brain Health** — memory integrity scan with one-click auto-repair
|
|
405
433
|
|
|
406
|
-
|
|
434
|
+
|
|
407
435
|
|
|
408
436
|
### 🧬 10× Memory Compression
|
|
409
437
|
Powered by a pure TypeScript port of Google's TurboQuant (inspired by Google's ICLR research), Prism compresses 768-dim embeddings from **3,072 bytes → ~400 bytes** — enabling decades of session history on a standard laptop. No native modules. No vector database required.
|
|
@@ -423,7 +451,12 @@ OpenTelemetry spans for every MCP tool call, LLM hop, and background worker. Rou
|
|
|
423
451
|
### 🌐 Autonomous Web Scholar
|
|
424
452
|
Prism researches while you sleep. A background pipeline searches the web, scrapes articles, synthesizes findings via LLM, and injects results directly into your semantic memory — fully searchable on your next session. Brave Search → Firecrawl scrape → LLM synthesis → Prism ledger. Task-aware, Hivemind-integrated, and zero-config when API keys are missing (falls back to Yahoo + Readability).
|
|
425
453
|
|
|
426
|
-
###
|
|
454
|
+
### 🏭 Dark Factory — Adversarial Autonomous Pipelines
|
|
455
|
+
When you trigger a Dark Factory pipeline, Prism doesn't just run your task — it fights itself to produce high-quality output. A `PLAN_CONTRACT` step locks a machine-parseable rubric before any code is written. After execution, an **Adversarial Evaluator** (in a fully isolated context) scores the output against the rubric. It cannot pass the Generator without providing exact file and line evidence for every failing criterion. Failed evaluations inject the critique directly into the Generator's retry prompt so it's never flying blind. The result: security issues, regressions, and lazy debug logs caught autonomously — before you ever see the PR. → [See it in action](examples/adversarial-eval-demo/README.md)
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## 🔒 Data Privacy & Egress
|
|
427
460
|
|
|
428
461
|
**Where is my data stored?**
|
|
429
462
|
|
|
@@ -446,14 +479,12 @@ Prism will recreate the directory with empty databases on next startup.
|
|
|
446
479
|
**What leaves your machine?**
|
|
447
480
|
- **Local mode (default):** Nothing. Zero network calls. All data is on-disk SQLite.
|
|
448
481
|
- **With `GOOGLE_API_KEY`:** Text snippets are sent to Gemini for embedding generation, summaries, and Morning Briefings. No session data is stored on Google's servers beyond the API call.
|
|
482
|
+
- **With `VOYAGE_API_KEY` / `OPENAI_API_KEY`:** Text snippets are sent to providers if selected as your embedding endpoints.
|
|
449
483
|
- **With `BRAVE_API_KEY` / `FIRECRAWL_API_KEY`:** Web Scholar queries are sent to Brave/Firecrawl for search and scraping.
|
|
450
484
|
- **With Supabase:** Session data syncs to your own Supabase instance (you control the Postgres database).
|
|
451
485
|
|
|
452
486
|
**GDPR compliance:** Soft/hard delete (Art. 17), full export in JSON, Markdown, or Obsidian vault `.zip` (Art. 20), API key redaction in exports, per-project TTL retention policies, and immutable audit trail. Enterprise-ready out of the box.
|
|
453
487
|
|
|
454
|
-
### 🏭 Dark Factory — Adversarial Autonomous Pipelines
|
|
455
|
-
When you trigger a Dark Factory pipeline, Prism doesn't just run your task — it fights itself to produce high-quality output. A `PLAN_CONTRACT` step locks a machine-parseable rubric before any code is written. After execution, an **Adversarial Evaluator** (in a fully isolated context) scores the output against the rubric. It cannot pass the Generator without providing exact file and line evidence for every failing criterion. Failed evaluations inject the critique directly into the Generator's retry prompt so it's never flying blind. The result: security issues, regressions, and lazy debug logs caught autonomously — before you ever see the PR. → [See it in action](examples/adversarial-eval-demo/README.md)
|
|
456
|
-
|
|
457
488
|
---
|
|
458
489
|
|
|
459
490
|
## 🎯 Use Cases
|
|
@@ -461,8 +492,8 @@ When you trigger a Dark Factory pipeline, Prism doesn't just run your task — i
|
|
|
461
492
|
- **Long-running feature work** — Save state at end of day, restore full context next morning. No re-explaining.
|
|
462
493
|
- **Multi-agent collaboration** — Dev, QA, and PM agents share real-time context without stepping on each other's memory.
|
|
463
494
|
- **Consulting / multi-project** — Switch between client projects with progressive loading: `quick` (~50 tokens), `standard` (~200), or `deep` (~1000+).
|
|
464
|
-
|
|
465
|
-
|
|
495
|
+
- **Autonomous execution (v7.4)** — Dark Factory pipeline: `plan → plan_contract → execute → evaluate → verify → finalize`. Generator and evaluator run in isolated roles — the evaluator cannot approve without evidence-bound findings scored against a pre-committed rubric.
|
|
496
|
+
- **Project health monitoring (v7.5)** — Intent Health Dashboard scores each project 0–100 based on staleness, TODO load, and decision quality — turning silent drift into an actionable signal.
|
|
466
497
|
- **Team onboarding** — New team member's agent loads the full project history instantly.
|
|
467
498
|
- **Behavior enforcement** — Agent corrections auto-graduate into permanent `.cursorrules` / `.clauderules` rules.
|
|
468
499
|
- **Offline / air-gapped** — Full SQLite local mode + Ollama LLM adapter. Zero internet dependency.
|
|
@@ -485,8 +516,6 @@ Then continue a specific thread with a follow-up message to the selected agent,
|
|
|
485
516
|
|
|
486
517
|
---
|
|
487
518
|
|
|
488
|
-
---
|
|
489
|
-
|
|
490
519
|
## ⚔️ Adversarial Evaluation in Action
|
|
491
520
|
|
|
492
521
|
> **Split-Brain Anti-Sycophancy** — the signature feature of v7.4.0.
|
|
@@ -811,6 +840,8 @@ Requires `PRISM_DARK_FACTORY_ENABLED=true`.
|
|
|
811
840
|
| `PRISM_ENABLE_HIVEMIND` | No | `"true"` to enable multi-agent tools — restart required |
|
|
812
841
|
| `PRISM_INSTANCE` | No | Instance name for multi-server PID isolation |
|
|
813
842
|
| `GOOGLE_API_KEY` | No | Gemini — enables semantic search, Briefings, compaction |
|
|
843
|
+
| `VOYAGE_API_KEY` | No | Voyage AI — optional premium embedding provider |
|
|
844
|
+
| `OPENAI_API_KEY` | No | OpenAI — optional proxy model and embedding provider |
|
|
814
845
|
| `BRAVE_ANSWERS_API_KEY` | No | Separate Brave Answers key |
|
|
815
846
|
| `SUPABASE_URL` | If cloud | Supabase project URL |
|
|
816
847
|
| `SUPABASE_KEY` | If cloud | Supabase anon/service key |
|
|
@@ -982,18 +1013,19 @@ A: Use `session_forget_memory` for targeted soft/hard deletion. For manual clean
|
|
|
982
1013
|
**Q: How do I verify the install quickly?**
|
|
983
1014
|
A: Run `npm run build && npm test`, then open the Mind Palace dashboard (`localhost:3000`) and confirm projects load plus Graph Health renders.
|
|
984
1015
|
|
|
1016
|
+
|
|
985
1017
|
---
|
|
986
1018
|
|
|
987
1019
|
### 💡 Known Limitations & Quirks
|
|
988
1020
|
|
|
989
1021
|
- **LLM-dependent features require an API key.** Semantic search, Morning Briefings, auto-compaction, and VLM captioning need a `GOOGLE_API_KEY` (your Gemini API key) or equivalent provider key. Without one, Prism falls back to keyword-only search (FTS5).
|
|
990
|
-
- **Auto-load is model- and client-dependent.** Session auto-loading relies on both the LLM following system prompt instructions *and* the MCP client completing tool registration before the model's first turn. Prism provides platform-specific [Setup Guides](
|
|
1022
|
+
- **Auto-load is model- and client-dependent.** Session auto-loading relies on both the LLM following system prompt instructions *and* the MCP client completing tool registration before the model's first turn. Prism provides platform-specific [Setup Guides](#setup-guides) and a server-side fallback (v5.2.1) that auto-pushes context after 10 seconds.
|
|
991
1023
|
- **MCP client race conditions.** Some MCP clients may not finish tool enumeration before the model generates its first response, causing transient `unknown_tool` errors. This is a client-side timing issue — Prism's server completes the MCP handshake in ~60ms. Workaround: the server-side auto-push fallback and the startup skill's retry logic.
|
|
992
1024
|
- **No real-time sync without Supabase.** Local SQLite mode is single-machine only. Multi-device or team sync requires a Supabase backend.
|
|
993
1025
|
- **Embedding quality varies by provider.** Gemini `text-embedding-004` and OpenAI `text-embedding-3-small` produce high-quality 768-dim vectors. Prism passes `dimensions: 768` via the Matryoshka API for OpenAI models (native output is 1536-dim; this truncation is lossless and outperforms ada-002 at full 1536 dims). Ollama embeddings (e.g., `nomic-embed-text`) are usable but may reduce retrieval accuracy.
|
|
994
1026
|
- **Dashboard is HTTP-only.** The Mind Palace dashboard at `localhost:3000` does not support HTTPS. For remote access, use a reverse proxy (nginx/Caddy) or SSH tunnel. Basic auth is available via `PRISM_DASHBOARD_USER` / `PRISM_DASHBOARD_PASS`.
|
|
995
1027
|
- **Long-lived clients can accumulate zombie processes.** MCP clients that run for extended periods (e.g., Claude CLI) may leave orphaned Prism server processes. The lifecycle manager detects true orphans (PPID=1) but allows coexistence for active parent processes. Use `PRISM_INSTANCE` to isolate instances across clients.
|
|
996
|
-
- **Migration is one-way.** Universal
|
|
1028
|
+
- **Migration is one-way.** Universal Import ingests sessions *into* Prism but does not export back to Claude/Gemini/OpenAI formats. Use `session_export_memory` for portable JSON/Markdown export, or the `vault` format for Obsidian/Logseq-compatible `.zip` archives.
|
|
997
1029
|
- **Export ceiling at 10,000 ledger entries.** The `session_export_memory` tool and the dashboard export button cap vault/JSON exports at 10,000 entries per project as an OOM guard. Projects exceeding this limit should use per-project exports and time-based filtering to stay within the ceiling. This limit does not affect search or context loading.
|
|
998
1030
|
- **No Windows CI testing.** Prism is developed and tested on macOS/Linux. It should work on Windows via Node.js, but edge cases (file paths, PID locks) may surface.
|
|
999
1031
|
|
package/dist/config.js
CHANGED
|
@@ -15,6 +15,9 @@ import { fileURLToPath } from "node:url";
|
|
|
15
15
|
* SUPABASE_KEY — (optional) Your Supabase anon/service key. Enables session memory tools.
|
|
16
16
|
* PRISM_USER_ID — (optional) Unique tenant ID for multi-user Supabase instances.
|
|
17
17
|
* Defaults to "default". Set per-user in Claude Desktop config.
|
|
18
|
+
* VOYAGE_API_KEY — (optional) API key for Voyage AI embeddings. Enables embedding_provider=voyage.
|
|
19
|
+
* Voyage AI is the embedding provider recommended by Anthropic for use with
|
|
20
|
+
* Claude. Get a free key at https://dash.voyageai.com.
|
|
18
21
|
*
|
|
19
22
|
* If a required key is missing, the process exits immediately.
|
|
20
23
|
* If an optional key is missing, a warning is logged but the server continues
|
|
@@ -60,6 +63,14 @@ export const BRAVE_ANSWERS_API_KEY = process.env.BRAVE_ANSWERS_API_KEY;
|
|
|
60
63
|
if (!BRAVE_ANSWERS_API_KEY) {
|
|
61
64
|
console.error("Warning: BRAVE_ANSWERS_API_KEY environment variable is missing. Brave Answers tool will be unavailable.");
|
|
62
65
|
}
|
|
66
|
+
// ─── Optional: Voyage AI API Key ──────────────────────────────
|
|
67
|
+
// Used when embedding_provider = "voyage" in the dashboard.
|
|
68
|
+
// Voyage AI is the embedding provider recommended by Anthropic for use
|
|
69
|
+
// alongside Claude. voyage-3 supports 768-dim output via MRL truncation,
|
|
70
|
+
// matching Prism's storage schema for zero-migration drop-in replacement.
|
|
71
|
+
// Without this, VoyageAdapter construction will throw at server start if
|
|
72
|
+
// embedding_provider=voyage is selected.
|
|
73
|
+
export const VOYAGE_API_KEY = process.env.VOYAGE_API_KEY;
|
|
63
74
|
// ─── v2.0: Storage Backend Selection ─────────────────────────
|
|
64
75
|
// REVIEWER NOTE: Step 1 of v2.0 introduces a storage abstraction.
|
|
65
76
|
// Currently only "supabase" is implemented. "local" (SQLite) is
|
|
@@ -85,8 +85,11 @@ export class AnthropicAdapter {
|
|
|
85
85
|
// silent zero-vector or crash.
|
|
86
86
|
throw new Error("AnthropicAdapter does not support text embeddings. " +
|
|
87
87
|
"Anthropic has no native embedding API. " +
|
|
88
|
-
"
|
|
89
|
-
"
|
|
88
|
+
"Their official recommendation is Voyage AI (voyage-3, voyage-3-lite). " +
|
|
89
|
+
"In the Mind Palace dashboard, set 'Embedding Provider' to: " +
|
|
90
|
+
"'voyage' (Anthropic-recommended, set VOYAGE_API_KEY), " +
|
|
91
|
+
"'openai' (OpenAI cloud or local Ollama with nomic-embed-text), " +
|
|
92
|
+
"or 'gemini' (Google AI, set GOOGLE_API_KEY).");
|
|
90
93
|
}
|
|
91
94
|
// ─── Image Description (VLM) ─────────────────────────────────────────────
|
|
92
95
|
/**
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voyage AI Adapter (v1.0)
|
|
3
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
* PURPOSE:
|
|
5
|
+
* Implements LLMProvider using Voyage AI's REST API for text embeddings.
|
|
6
|
+
* Voyage AI is the embedding provider officially recommended by Anthropic
|
|
7
|
+
* for use alongside Claude — it fills the gap left by Anthropic's lack
|
|
8
|
+
* of a native embedding API.
|
|
9
|
+
*
|
|
10
|
+
* TEXT GENERATION:
|
|
11
|
+
* Voyage AI is an embeddings-only service. generateText() throws an explicit
|
|
12
|
+
* error, the same pattern used by AnthropicAdapter.generateEmbedding().
|
|
13
|
+
* Set text_provider separately (anthropic, openai, or gemini).
|
|
14
|
+
*
|
|
15
|
+
* EMBEDDING DIMENSION PARITY (768 dims):
|
|
16
|
+
* Prism's SQLite (sqlite-vec) and Supabase (pgvector) schemas define
|
|
17
|
+
* embedding columns as EXACTLY 768 dimensions.
|
|
18
|
+
*
|
|
19
|
+
* Voyage solution: voyage-3 and voyage-3-lite output 1024 dims by default,
|
|
20
|
+
* but both support the `output_dimension` parameter (Matryoshka Representation
|
|
21
|
+
* Learning), enabling truncation to 768 while preserving quality.
|
|
22
|
+
* voyage-3-lite at 768 dims is the fastest and most cost-efficient option.
|
|
23
|
+
*
|
|
24
|
+
* MODELS:
|
|
25
|
+
* voyage-3 — Highest quality, 1024 dims natively (MRL → 768)
|
|
26
|
+
* voyage-3-lite — Fast & cheap, 512 dims natively (MRL → 768 NOT supported)
|
|
27
|
+
* voyage-3-large — Best quality, use for offline indexing
|
|
28
|
+
* voyage-code-3 — Optimised for code (recommended for dev sessions)
|
|
29
|
+
*
|
|
30
|
+
* NOTE: voyage-3-lite natively outputs 512 dims; it does NOT support
|
|
31
|
+
* output_dimension truncation to 768. Use voyage-3 for dimension parity.
|
|
32
|
+
* Default is voyage-3 for this reason.
|
|
33
|
+
*
|
|
34
|
+
* CONFIG KEYS (Prism dashboard "AI Providers" tab OR environment variables):
|
|
35
|
+
* voyage_api_key — Required. Voyage AI API key (pa-...)
|
|
36
|
+
* voyage_model — Embedding model (default: voyage-3)
|
|
37
|
+
*
|
|
38
|
+
* USAGE WITH ANTHROPIC TEXT PROVIDER:
|
|
39
|
+
* Set text_provider=anthropic, embedding_provider=voyage in the dashboard.
|
|
40
|
+
* This pairs Claude for reasoning with Voyage for semantic memory — the
|
|
41
|
+
* combination Anthropic recommends in their documentation.
|
|
42
|
+
*
|
|
43
|
+
* API REFERENCE:
|
|
44
|
+
* https://docs.voyageai.com/reference/embeddings-api
|
|
45
|
+
*/
|
|
46
|
+
import { getSettingSync } from "../../../storage/configStorage.js";
|
|
47
|
+
import { debugLog } from "../../logger.js";
|
|
48
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
49
|
+
// Must match Prism's DB schema (sqlite-vec and pgvector column sizes).
|
|
50
|
+
const EMBEDDING_DIMS = 768;
|
|
51
|
+
// voyage-3 supports up to 32,000 tokens. Character-based cap (consistent
|
|
52
|
+
// with OpenAI and Gemini adapters) avoids tokenizer dependency.
|
|
53
|
+
// 8000 chars ≈ 1500-2000 tokens for typical session summaries.
|
|
54
|
+
const MAX_EMBEDDING_CHARS = 8000;
|
|
55
|
+
// Default model: voyage-3 (supports output_dimension=768 via MRL)
|
|
56
|
+
// voyage-3-lite is NOT recommended as its native 512 dims < 768.
|
|
57
|
+
const DEFAULT_MODEL = "voyage-3";
|
|
58
|
+
const VOYAGE_API_BASE = "https://api.voyageai.com/v1";
|
|
59
|
+
// ─── Adapter ─────────────────────────────────────────────────────────────────
|
|
60
|
+
export class VoyageAdapter {
|
|
61
|
+
apiKey;
|
|
62
|
+
constructor() {
|
|
63
|
+
const apiKey = getSettingSync("voyage_api_key", process.env.VOYAGE_API_KEY ?? "");
|
|
64
|
+
if (!apiKey) {
|
|
65
|
+
throw new Error("VoyageAdapter requires a Voyage AI API key. " +
|
|
66
|
+
"Get one free at https://dash.voyageai.com — then set VOYAGE_API_KEY " +
|
|
67
|
+
"or configure it in the Mind Palace dashboard under 'AI Providers'.");
|
|
68
|
+
}
|
|
69
|
+
this.apiKey = apiKey;
|
|
70
|
+
debugLog("[VoyageAdapter] Initialized");
|
|
71
|
+
}
|
|
72
|
+
// ─── Text Generation (Not Supported) ────────────────────────────────────
|
|
73
|
+
async generateText(_prompt, _systemInstruction) {
|
|
74
|
+
// Voyage AI is an embeddings-only service.
|
|
75
|
+
// Use text_provider=anthropic, openai, or gemini for text generation.
|
|
76
|
+
throw new Error("VoyageAdapter does not support text generation. " +
|
|
77
|
+
"Voyage AI is an embeddings-only service. " +
|
|
78
|
+
"Set text_provider to 'anthropic', 'openai', or 'gemini' in the dashboard.");
|
|
79
|
+
}
|
|
80
|
+
// ─── Embedding Generation ────────────────────────────────────────────────
|
|
81
|
+
async generateEmbedding(text) {
|
|
82
|
+
if (!text || !text.trim()) {
|
|
83
|
+
throw new Error("[VoyageAdapter] generateEmbedding called with empty text");
|
|
84
|
+
}
|
|
85
|
+
// Truncate to character limit (consistent with other adapters)
|
|
86
|
+
const truncated = text.length > MAX_EMBEDDING_CHARS
|
|
87
|
+
? text.slice(0, MAX_EMBEDDING_CHARS).replace(/\s+\S*$/, "")
|
|
88
|
+
: text;
|
|
89
|
+
const model = getSettingSync("voyage_model", DEFAULT_MODEL);
|
|
90
|
+
debugLog(`[VoyageAdapter] generateEmbedding — model=${model}, chars=${truncated.length}`);
|
|
91
|
+
const requestBody = {
|
|
92
|
+
input: [truncated],
|
|
93
|
+
model,
|
|
94
|
+
// Request exactly 768 dims via Matryoshka truncation.
|
|
95
|
+
// Supported by voyage-3, voyage-3-large, voyage-code-3.
|
|
96
|
+
// voyage-3-lite (native 512 dims) will ignore this and return 512,
|
|
97
|
+
// which will be caught by the dimension guard below.
|
|
98
|
+
output_dimension: EMBEDDING_DIMS,
|
|
99
|
+
};
|
|
100
|
+
const response = await fetch(`${VOYAGE_API_BASE}/embeddings`, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: {
|
|
103
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
104
|
+
"Content-Type": "application/json",
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify(requestBody),
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
const errorText = await response.text().catch(() => "unknown error");
|
|
110
|
+
throw new Error(`[VoyageAdapter] API request failed — status=${response.status}: ${errorText}`);
|
|
111
|
+
}
|
|
112
|
+
const data = (await response.json());
|
|
113
|
+
const embedding = data?.data?.[0]?.embedding;
|
|
114
|
+
if (!Array.isArray(embedding)) {
|
|
115
|
+
throw new Error("[VoyageAdapter] Unexpected response format — no embedding array found");
|
|
116
|
+
}
|
|
117
|
+
// Dimension guard: Prism's DB schema requires exactly 768 dims.
|
|
118
|
+
// This catches voyage-3-lite (512) or future API changes silently early.
|
|
119
|
+
if (embedding.length !== EMBEDDING_DIMS) {
|
|
120
|
+
throw new Error(`[VoyageAdapter] Embedding dimension mismatch: expected ${EMBEDDING_DIMS}, ` +
|
|
121
|
+
`got ${embedding.length}. ` +
|
|
122
|
+
`Use voyage-3 (not voyage-3-lite) to get 768-dim output via MRL truncation. ` +
|
|
123
|
+
`Change voyage_model in the Mind Palace dashboard.`);
|
|
124
|
+
}
|
|
125
|
+
debugLog(`[VoyageAdapter] Embedding generated — dims=${embedding.length}, ` +
|
|
126
|
+
`tokens_used=${data.usage?.total_tokens ?? "unknown"}`);
|
|
127
|
+
return embedding;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LLM Provider Factory (v4.
|
|
2
|
+
* LLM Provider Factory (v4.5 — Voyage AI Embedding Support)
|
|
3
3
|
* ─────────────────────────────────────────────────────────────────────────────
|
|
4
4
|
* PURPOSE:
|
|
5
5
|
* Single point of resolution for the active LLMProvider.
|
|
@@ -11,19 +11,21 @@
|
|
|
11
11
|
* Two independent settings control text and embedding routing:
|
|
12
12
|
*
|
|
13
13
|
* text_provider — "gemini" (default) | "openai" | "anthropic"
|
|
14
|
-
* embedding_provider — "auto" (default) | "gemini" | "openai"
|
|
14
|
+
* embedding_provider — "auto" (default) | "gemini" | "openai" | "voyage"
|
|
15
15
|
*
|
|
16
16
|
* When embedding_provider = "auto":
|
|
17
17
|
* * If text_provider is gemini or openai → use same provider for embeddings
|
|
18
18
|
* * If text_provider is anthropic → auto-fallback to gemini for embeddings
|
|
19
|
-
* (Anthropic has no native embedding API
|
|
19
|
+
* (Anthropic has no native embedding API; consider setting
|
|
20
|
+
* embedding_provider=voyage for the Anthropic-recommended pairing)
|
|
20
21
|
*
|
|
21
22
|
* EXAMPLE CONFIGURATIONS:
|
|
22
23
|
* text_provider=gemini, embedding_provider=auto → Gemini+Gemini (default)
|
|
23
24
|
* text_provider=openai, embedding_provider=auto → OpenAI+OpenAI
|
|
24
25
|
* text_provider=anthropic, embedding_provider=auto → Claude+Gemini (auto-bridge)
|
|
26
|
+
* text_provider=anthropic, embedding_provider=voyage → Claude+Voyage (Anthropic-recommended)
|
|
25
27
|
* text_provider=anthropic, embedding_provider=openai → Claude+Ollama (cost-optimized)
|
|
26
|
-
* text_provider=gemini, embedding_provider=
|
|
28
|
+
* text_provider=gemini, embedding_provider=voyage → Gemini+Voyage (mixed)
|
|
27
29
|
*
|
|
28
30
|
* SINGLETON + GRACEFUL DEGRADATION:
|
|
29
31
|
* Same as before — instance cached per process, errors fall back to Gemini.
|
|
@@ -41,6 +43,7 @@ import { getSettingSync } from "../../storage/configStorage.js";
|
|
|
41
43
|
import { GeminiAdapter } from "./adapters/gemini.js";
|
|
42
44
|
import { OpenAIAdapter } from "./adapters/openai.js";
|
|
43
45
|
import { AnthropicAdapter } from "./adapters/anthropic.js";
|
|
46
|
+
import { VoyageAdapter } from "./adapters/voyage.js";
|
|
44
47
|
import { TracingLLMProvider } from "./adapters/traced.js";
|
|
45
48
|
// Module-level singleton — one composed provider per MCP server process.
|
|
46
49
|
let providerInstance = null;
|
|
@@ -59,8 +62,10 @@ function buildEmbeddingAdapter(type) {
|
|
|
59
62
|
// Note: "anthropic" is intentionally absent from this switch.
|
|
60
63
|
// Anthropic has no embedding API, so it can never be an embedding provider.
|
|
61
64
|
// The factory resolves "auto" away from "anthropic" before calling this.
|
|
65
|
+
// For Anthropic text users, "voyage" is the Anthropic-recommended pairing.
|
|
62
66
|
switch (type) {
|
|
63
67
|
case "openai": return new OpenAIAdapter();
|
|
68
|
+
case "voyage": return new VoyageAdapter();
|
|
64
69
|
case "gemini":
|
|
65
70
|
default: return new GeminiAdapter();
|
|
66
71
|
}
|
|
@@ -90,7 +95,9 @@ export function getLLMProvider() {
|
|
|
90
95
|
if (textType === "anthropic") {
|
|
91
96
|
console.info("[LLMFactory] text_provider=anthropic with embedding_provider=auto: " +
|
|
92
97
|
"routing embeddings to GeminiAdapter (Anthropic has no native embedding API). " +
|
|
93
|
-
"
|
|
98
|
+
"For the Anthropic-recommended pairing, set embedding_provider=voyage in the dashboard " +
|
|
99
|
+
"(voyage-3 supports 768-dim output via MRL). " +
|
|
100
|
+
"Alternatively, set embedding_provider=openai to use Ollama/OpenAI.");
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prism-mcp-server",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.0",
|
|
4
4
|
"mcpName": "io.github.dcostenco/prism-mcp",
|
|
5
5
|
"description": "The Mind Palace for AI Agents — adversarial evaluation (PLAN_CONTRACT→EVALUATE anti-sycophancy), fail-closed Dark Factory autonomous pipelines (3-gate parse→type→scope), persistent memory (SQLite/Supabase), ACT-R cognitive retrieval, behavioral learning & IDE rules sync, multi-agent Hivemind, time travel, visual dashboard. Zero-config local mode.",
|
|
6
6
|
"module": "index.ts",
|