prism-mcp-server 8.0.3 → 9.0.5
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 +51 -75
- package/dist/cli.js +0 -0
- package/dist/config.js +0 -14
- package/dist/darkfactory/runner.js +0 -7
- package/dist/darkfactory/safetyController.js +2 -10
- package/dist/dashboard/authUtils.js +30 -2
- package/dist/dashboard/server.js +14 -13
- package/dist/dashboard/ui.js +6 -72
- package/dist/memory/cognitiveBudget.js +224 -0
- package/dist/memory/spreadingActivation.js +107 -0
- package/dist/memory/surprisalGate.js +119 -0
- package/dist/memory/synapseEngine.js +15 -0
- package/dist/memory/valenceEngine.js +234 -0
- package/dist/observability/graphMetrics.js +0 -44
- package/dist/sdm/sdmEngine.js +3 -27
- package/dist/server.js +0 -0
- package/dist/storage/sqlite.js +20 -130
- package/dist/storage/supabase.js +10 -164
- package/dist/tools/graphHandlers.js +137 -18
- package/dist/tools/hygieneHandlers.js +33 -61
- package/dist/utils/actrActivation.js +0 -2
- package/dist/utils/executor.js +0 -1
- package/dist/utils/llm/adapters/traced.js +0 -35
- package/dist/utils/llm/adapters/voyage.js +41 -67
- package/dist/utils/llm/factory.js +14 -38
- package/dist/utils/llm/provider.js +0 -2
- package/dist/utils/universalImporter.js +0 -0
- package/package.json +2 -1
- package/dist/dashboard/ui.tmp.js +0 -3475
- package/dist/test-cli.js +0 -18
- package/dist/tools/sessionMemoryHandlers.js +0 -2633
- package/dist/utils/embeddingApi.js +0 -104
- package/dist/utils/googleAi.js +0 -88
- package/dist/utils/testUniversalImporter.js +0 -10
- package/dist/verification/renameDetector.js +0 -170
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
**Your AI agent forgets everything between sessions. Prism fixes that — then teaches it to think.**
|
|
14
14
|
|
|
15
|
-
Prism
|
|
15
|
+
Prism v7.8 is a true **Cognitive Architecture** inspired by human brain mechanics. Beyond flat vector search, your agent now forms principles from experience, follows causal trains of thought, and possesses the self-awareness to know when it lacks information. **Your agents don't just remember; they learn.**
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npx -y prism-mcp-server
|
|
@@ -20,7 +20,7 @@ npx -y prism-mcp-server
|
|
|
20
20
|
|
|
21
21
|
Works with **Claude Desktop · Claude Code · Cursor · Windsurf · Cline · Gemini · Antigravity** — **any MCP client.**
|
|
22
22
|
|
|
23
|
-
## Table of Contents
|
|
23
|
+
## 📖 Table of Contents
|
|
24
24
|
|
|
25
25
|
- [Why Prism?](#why-prism)
|
|
26
26
|
- [Quick Start](#quick-start)
|
|
@@ -28,8 +28,7 @@ Works with **Claude Desktop · Claude Code · Cursor · Windsurf · Cline · Gem
|
|
|
28
28
|
- [Setup Guides](#setup-guides)
|
|
29
29
|
- [Universal Import: Bring Your History](#universal-import-bring-your-history)
|
|
30
30
|
- [What Makes Prism Different](#what-makes-prism-different)
|
|
31
|
-
- [
|
|
32
|
-
- [Cognitive Architecture (v7.8)](#cognitive-architecture-v78)
|
|
31
|
+
- [Cognitive Architecture (v7.8)](#-cognitive-architecture-v78)
|
|
33
32
|
- [Data Privacy & Egress](#data-privacy--egress)
|
|
34
33
|
- [Use Cases](#use-cases)
|
|
35
34
|
- [What's New](#whats-new)
|
|
@@ -53,15 +52,15 @@ Every time you start a new conversation with an AI coding assistant, it starts f
|
|
|
53
52
|
|
|
54
53
|
Prism has three pillars:
|
|
55
54
|
|
|
56
|
-
1. **🧠 Cognitive Memory** — Memories are ranked like a human brain: recently and frequently accessed context surfaces first, while stale context fades naturally via ACT-R activation decay. Raw experience consolidates into semantic principles through Hebbian learning. The result is retrieval quality that no flat vector search can match. *(See [Cognitive Architecture](
|
|
55
|
+
1. **🧠 Cognitive Memory** — Memories are ranked like a human brain: recently and frequently accessed context surfaces first, while stale context fades naturally via ACT-R activation decay. Raw experience consolidates into semantic principles through Hebbian learning. The result is retrieval quality that no flat vector search can match. *(See [Cognitive Architecture](#-cognitive-architecture-v78) and [Scientific Foundation](#-scientific-foundation).)*
|
|
57
56
|
|
|
58
|
-
2.
|
|
57
|
+
2. **🔗 Multi-Hop Reasoning** — When your agent searches for "Error X", Prism doesn't just find logs mentioning "Error X". Spreading activation traverses the causal graph and brings back "Workaround Y", which is connected to "Architecture Decision Z" — a literal train of thought. *(See [Cognitive Architecture](#-cognitive-architecture-v78).)*
|
|
59
58
|
|
|
60
|
-
3. **🏭 Autonomous Execution (Dark Factory)** — When you're ready, Prism can run coding tasks end-to-end with a fail-closed pipeline where an adversarial evaluator catches bugs the generator missed — before you ever see the PR. *(See [Dark Factory](
|
|
59
|
+
3. **🏭 Autonomous Execution (Dark Factory)** — When you're ready, Prism can run coding tasks end-to-end with a fail-closed pipeline where an adversarial evaluator catches bugs the generator missed — before you ever see the PR. *(See [Dark Factory](#-dark-factory--adversarial-autonomous-pipelines).)*
|
|
61
60
|
|
|
62
61
|
---
|
|
63
62
|
|
|
64
|
-
## Quick Start
|
|
63
|
+
## 🚀 Quick Start
|
|
65
64
|
|
|
66
65
|
### Prerequisites
|
|
67
66
|
|
|
@@ -135,7 +134,7 @@ Then open `http://localhost:3001` instead.
|
|
|
135
134
|
|
|
136
135
|
---
|
|
137
136
|
|
|
138
|
-
## The Magic Moment
|
|
137
|
+
## ✨ The Magic Moment
|
|
139
138
|
|
|
140
139
|
> **Session 1** (Monday evening):
|
|
141
140
|
> ```
|
|
@@ -156,7 +155,7 @@ Then open `http://localhost:3001` instead.
|
|
|
156
155
|
|
|
157
156
|
---
|
|
158
157
|
|
|
159
|
-
## Setup Guides
|
|
158
|
+
## 📖 Setup Guides
|
|
160
159
|
|
|
161
160
|
<details>
|
|
162
161
|
<summary><strong>Claude Desktop</strong></summary>
|
|
@@ -379,7 +378,7 @@ Prism can be deployed natively to cloud platforms like [Render](https://render.c
|
|
|
379
378
|
|
|
380
379
|
---
|
|
381
380
|
|
|
382
|
-
## Universal Import: Bring Your History
|
|
381
|
+
## 📥 Universal Import: Bring Your History
|
|
383
382
|
|
|
384
383
|
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.
|
|
385
384
|
|
|
@@ -412,7 +411,7 @@ npx -y prism-mcp-server universal-import --format gemini --path ./gemini_history
|
|
|
412
411
|
|
|
413
412
|
---
|
|
414
413
|
|
|
415
|
-
## What Makes Prism Different
|
|
414
|
+
## ✨ What Makes Prism Different
|
|
416
415
|
|
|
417
416
|
|
|
418
417
|
### 🧠 Your Agent Learns From Mistakes
|
|
@@ -455,59 +454,46 @@ OpenTelemetry spans for every MCP tool call, LLM hop, and background worker. Rou
|
|
|
455
454
|
### 🌐 Autonomous Web Scholar
|
|
456
455
|
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).
|
|
457
456
|
|
|
458
|
-
### Dark Factory — Adversarial Autonomous Pipelines
|
|
457
|
+
### 🏭 Dark Factory — Adversarial Autonomous Pipelines
|
|
459
458
|
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)
|
|
460
459
|
|
|
461
460
|
---
|
|
462
461
|
|
|
463
|
-
##
|
|
462
|
+
## 🤖 Autonomous Cognitive OS (v9.0)
|
|
464
463
|
|
|
465
|
-
> *
|
|
464
|
+
> *Memory isn't just about storing data; it's about economics and emotion. Prism v9.0 transforms passive memory into a living Cognitive Operating System that forces agents to learn compression and develop intuition.*
|
|
466
465
|
|
|
467
|
-
|
|
466
|
+
Most AI agents have an infinite memory budget. They dump massive, repetitive logs into vector databases until they bankrupt your API budget and choke their own context windows. Prism v9.0 fixes this by introducing **Token-Economic Reinforcement Learning** and **Affect-Tagged Memory**.
|
|
468
467
|
|
|
469
|
-
###
|
|
468
|
+
### 💰 Memory-as-an-Economy (The Surprisal Gate)
|
|
469
|
+
Prism assigns every project a strict **Cognitive Budget** (e.g., 2,000 tokens) that persists across sessions. Every time the agent saves a memory, it costs tokens.
|
|
470
470
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
| **Agent output** | Summarizes the design doc | Summarizes the design doc **and warns about the unresolved auth issue** |
|
|
476
|
-
| **Discovery tag** | — | `[🌐 Synapse]` marks the auth bug node, proving the engine found context the user didn't ask for |
|
|
471
|
+
But not all memories are priced equally. Prism intercepts the save and runs a **Vector-Based Surprisal** calculation against recent memories:
|
|
472
|
+
* **High Surprisal (Novel thought):** Costs 0.5× tokens. The agent is rewarded for new insights.
|
|
473
|
+
* **Low Surprisal (Boilerplate):** Costs 2.0× tokens. The agent is penalized for repeating itself.
|
|
474
|
+
* **Universal Basic Income (UBI):** The budget recovers passively over time (+100 tokens/hour).
|
|
477
475
|
|
|
478
|
-
|
|
476
|
+
If an agent is too verbose, it goes into **Cognitive Debt**. You don't need to prompt the agent to "be concise." The physics of the system force the LLM to learn data compression to avoid bankruptcy.
|
|
479
477
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
│
|
|
483
|
-
┌───────────┼───────────────┐
|
|
484
|
-
▼ ▼ ▼
|
|
485
|
-
[Design [Sprint [Deployment
|
|
486
|
-
Doc] Retro] Log]
|
|
487
|
-
│ 1.0 │ 0.8 │ 0.6 ← semantic anchors
|
|
488
|
-
│ │ │
|
|
489
|
-
▼ ▼ ▼
|
|
490
|
-
[Dev [Auth Bug [Perf ← Synapse discovered
|
|
491
|
-
Profile Thread 🌐] Regression 🌐] (multi-hop)
|
|
492
|
-
0.42] 0.38] 0.31]
|
|
493
|
-
```
|
|
478
|
+
### 🎭 Affect-Tagged Memory (Giving AI a "Gut Feeling")
|
|
479
|
+
Vector math measures *semantic similarity*, not *sentiment*. If an agent searches for "Authentication Architecture," standard RAG will return two past approaches—it doesn't know that Approach A caused a 3-day production outage, while Approach B worked perfectly.
|
|
494
480
|
|
|
495
|
-
**
|
|
481
|
+
* **Affective Salience:** Prism automatically tags experience events with a `valence` score (-1.0 for failure, +1.0 for success).
|
|
482
|
+
* **Emotional Retrieval:** At retrieval time, the absolute magnitude (`|valence|`) significantly boosts the memory's ranking score. Extreme failures and extreme successes surface to the top.
|
|
483
|
+
* **UX Warnings:** If an agent retrieves memories that are historically negative, Prism intercepts the prompt injection: `⚠️ Caution: This topic is strongly correlated with historical failures. Review past decisions before proceeding.` Your AI now has a "gut feeling" about bad code.
|
|
496
484
|
|
|
497
|
-
|
|
498
|
-
|---|---|
|
|
499
|
-
| **Dampened Fan Effect** (`1/ln(degree+e)`) | Prevents hub nodes from flooding results |
|
|
500
|
-
| **Asymmetric Propagation** (fwd 100%, back 50%) | Preserves causal directionality |
|
|
501
|
-
| **Cyclic Loop Prevention** (`visitedEdges` set) | Prevents infinite energy amplification |
|
|
502
|
-
| **Sigmoid Normalization** | Structural scores can't overwhelm semantic base |
|
|
503
|
-
| **Lateral Inhibition** | Caps output to top-K most energized nodes |
|
|
504
|
-
| **Hybrid Scoring** (70% semantic / 30% structural) | Base relevance always matters |
|
|
485
|
+
### The Paradigm Shift
|
|
505
486
|
|
|
506
|
-
|
|
487
|
+
| Feature | Standard RAG / Agents | Prism v9.0 |
|
|
488
|
+
| :--- | :--- | :--- |
|
|
489
|
+
| **Storage Limit** | Infinite (bloats context) | Bounded Token Economy |
|
|
490
|
+
| **Data Quality** | Saves repetitive boilerplate | Surprisal Gate penalizes redundancy |
|
|
491
|
+
| **Sentiment** | Treats all data as neutral facts | Affect-Tagged (Warns agent of past trauma) |
|
|
492
|
+
| **Recovery** | Manual deletion | Universal Basic Income (UBI) over time |
|
|
507
493
|
|
|
508
494
|
---
|
|
509
495
|
|
|
510
|
-
## Cognitive Architecture (v7.8)
|
|
496
|
+
## 🧠 Cognitive Architecture (v7.8)
|
|
511
497
|
|
|
512
498
|
> *Prism v7.8 is our biggest leap forward yet. We have moved beyond flat vector search and implemented a true Cognitive Architecture inspired by human brain mechanics. With the new ACT-R Spreading Activation Engine, Episodic-to-Semantic memory consolidation, and Uncertainty-Aware Rejection Gates, Prism doesn't just store logs anymore — it forms principles, follows causal trains of thought, and possesses the self-awareness to know when it lacks information.*
|
|
513
499
|
|
|
@@ -572,7 +558,7 @@ Standard RAG (Retrieval-Augmented Generation) is now a commodity. Everyone has v
|
|
|
572
558
|
|
|
573
559
|
---
|
|
574
560
|
|
|
575
|
-
## Data Privacy & Egress
|
|
561
|
+
## 🔒 Data Privacy & Egress
|
|
576
562
|
|
|
577
563
|
**Where is my data stored?**
|
|
578
564
|
|
|
@@ -603,7 +589,7 @@ Prism will recreate the directory with empty databases on next startup.
|
|
|
603
589
|
|
|
604
590
|
---
|
|
605
591
|
|
|
606
|
-
## Use Cases
|
|
592
|
+
## 🎯 Use Cases
|
|
607
593
|
|
|
608
594
|
- **Long-running feature work** — Save state at end of day, restore full context next morning. No re-explaining.
|
|
609
595
|
- **Multi-agent collaboration** — Dev, QA, and PM agents share real-time context without stepping on each other's memory.
|
|
@@ -632,7 +618,7 @@ Then continue a specific thread with a follow-up message to the selected agent,
|
|
|
632
618
|
|
|
633
619
|
---
|
|
634
620
|
|
|
635
|
-
## Adversarial Evaluation in Action
|
|
621
|
+
## ⚔️ Adversarial Evaluation in Action
|
|
636
622
|
|
|
637
623
|
> **Split-Brain Anti-Sycophancy** — the signature feature of v7.4.0.
|
|
638
624
|
|
|
@@ -737,12 +723,11 @@ The Generator strips the `console.log`, resubmits, and the next `EVALUATE` retur
|
|
|
737
723
|
|
|
738
724
|
---
|
|
739
725
|
|
|
740
|
-
## What's New
|
|
726
|
+
## 🆕 What's New
|
|
741
727
|
|
|
742
|
-
> **Current release:
|
|
728
|
+
> **Current release: v7.8.2 — Cognitive Architecture**
|
|
743
729
|
|
|
744
|
-
-
|
|
745
|
-
- 🧠 **v7.8.x — Cognitive Architecture:** Episodic-to-Semantic consolidation (Hebbian learning), ACT-R Spreading Activation with multi-hop causal reasoning, Uncertainty-Aware Rejection Gate, and Dynamic Fast Weight Decay. Validated by **LoCoMo-Plus benchmark**. → [Cognitive Architecture](#cognitive-architecture-v78)
|
|
730
|
+
- 🧠 **v7.8.0 — Cognitive Architecture:** The biggest leap forward yet. Moved beyond flat vector search into a true cognitive architecture inspired by human brain mechanics. Episodic-to-Semantic memory consolidation (Hebbian learning), ACT-R Spreading Activation with multi-hop causal reasoning, Uncertainty-Aware Rejection Gate (your agent can say "I don't know"), and Dynamic Fast Weight Decay (semantic memories outlive episodic chatter by 2×). **Your agents don't just remember; they learn.** → [Cognitive Architecture](#-cognitive-architecture-v78)
|
|
746
731
|
- 🌐 **v7.7.0 — Cloud-Native SSE Transport:** Full unauthenticated and authenticated Server-Sent Events MCP support for seamless network deployments.
|
|
747
732
|
- 🩺 **v7.5.0 — Intent Health Dashboard + Security Hardening:** Real-time 0–100 project health scoring (staleness × TODO load × decisions). 10 XSS injection vectors patched. Algorithm hardened with NaN guards and score ceiling.
|
|
748
733
|
- ⚔️ **v7.4.0 — Adversarial Evaluation:** Split-brain anti-sycophancy pipeline. Generator and evaluator in isolated roles with evidence-bound findings.
|
|
@@ -752,7 +737,7 @@ The Generator strips the `console.log`, resubmits, and the next `EVALUATE` retur
|
|
|
752
737
|
|
|
753
738
|
---
|
|
754
739
|
|
|
755
|
-
## How Prism Compares
|
|
740
|
+
## ⚔️ How Prism Compares
|
|
756
741
|
|
|
757
742
|
Standard memory servers (like Mem0, Zep, or the baseline Anthropic MCP) act as passive filing cabinets — they wait for the LLM to search them. **Prism is an active cognitive architecture.** Designed specifically for the **Model Context Protocol (MCP)**, Prism doesn't just store vectors — it consolidates experience into principles, traverses causal graphs for multi-hop reasoning, and rejects queries it can't confidently answer.
|
|
758
743
|
|
|
@@ -804,7 +789,7 @@ Every other AI coding pipeline has a fatal flaw: it asks the same model that wro
|
|
|
804
789
|
|
|
805
790
|
---
|
|
806
791
|
|
|
807
|
-
## Tool Reference
|
|
792
|
+
## 🔧 Tool Reference
|
|
808
793
|
|
|
809
794
|
Prism ships 30+ tools, but **90% of your workflow uses just three:**
|
|
810
795
|
|
|
@@ -986,11 +971,6 @@ Requires `PRISM_DARK_FACTORY_ENABLED=true`.
|
|
|
986
971
|
| `PRISM_ACTR_WEIGHT_ACTIVATION` | No | Composite score ACT-R activation weight (default: `0.3`) |
|
|
987
972
|
| `PRISM_ACTR_ACCESS_LOG_RETENTION_DAYS` | No | Days before access logs are pruned by background scheduler (default: `90`) |
|
|
988
973
|
| `PRISM_DARK_FACTORY_ENABLED` | No | `"true"` to enable Dark Factory autonomous pipeline tools (`session_start_pipeline`, `session_check_pipeline_status`, `session_abort_pipeline`) |
|
|
989
|
-
| `PRISM_SYNAPSE_ENABLED` | No | `"true"` (default) to enable Synapse Engine graph propagation in search results |
|
|
990
|
-
| `PRISM_SYNAPSE_ITERATIONS` | No | Propagation iterations (default: `3`). Higher = deeper graph traversal |
|
|
991
|
-
| `PRISM_SYNAPSE_SPREAD_FACTOR` | No | Energy decay multiplier per hop (default: `0.8`). Range: 0.0–1.0 |
|
|
992
|
-
| `PRISM_SYNAPSE_LATERAL_INHIBITION` | No | Max nodes returned by Synapse (default: `7`, min: `1`) |
|
|
993
|
-
| `PRISM_SYNAPSE_SOFT_CAP` | No | Max candidate pool size during propagation (default: `20`, min: `1`) |
|
|
994
974
|
|
|
995
975
|
</details>
|
|
996
976
|
|
|
@@ -1018,11 +998,10 @@ Prism is a **stdio-based MCP server** that manages persistent agent memory. Here
|
|
|
1018
998
|
│ └──────┬───────┘ └──────────────┘ └────────────────┘ │
|
|
1019
999
|
│ ↕ │
|
|
1020
1000
|
│ ┌────────────────────────────────────────────────────┐ │
|
|
1021
|
-
│ │ Cognitive Engine (
|
|
1022
|
-
│ │ •
|
|
1001
|
+
│ │ Cognitive Engine (v7.8) │ │
|
|
1002
|
+
│ │ • ACT-R Spreading Activation (multi-hop) │ │
|
|
1023
1003
|
│ │ • Episodic → Semantic Consolidation (Hebbian) │ │
|
|
1024
1004
|
│ │ • Uncertainty-Aware Rejection Gate │ │
|
|
1025
|
-
│ │ • LoCoMo-Plus Benchmark Validation │ │
|
|
1026
1005
|
│ │ • Dynamic Fast Weight Decay (dual-rate) │ │
|
|
1027
1006
|
│ │ • HDC Cognitive Routing (XOR binding) │ │
|
|
1028
1007
|
│ └──────┬─────────────────────────────────────────────┘ │
|
|
@@ -1066,7 +1045,7 @@ Prism is a **stdio-based MCP server** that manages persistent agent memory. Here
|
|
|
1066
1045
|
|
|
1067
1046
|
### Auto-Load Architecture
|
|
1068
1047
|
|
|
1069
|
-
Each MCP client has its own mechanism for ensuring Prism context loads on session start. See the platform-specific [Setup Guides](
|
|
1048
|
+
Each MCP client has its own mechanism for ensuring Prism context loads on session start. See the platform-specific [Setup Guides](#-setup-guides) above for detailed instructions:
|
|
1070
1049
|
|
|
1071
1050
|
- **Claude Code** — Lifecycle hooks (`SessionStart` / `Stop`)
|
|
1072
1051
|
- **Gemini / Antigravity** — Three-layer architecture (User Rules + AGENTS.md + Startup Skill)
|
|
@@ -1077,7 +1056,7 @@ All platforms benefit from the **server-side fallback** (v5.2.1): if `session_lo
|
|
|
1077
1056
|
|
|
1078
1057
|
---
|
|
1079
1058
|
|
|
1080
|
-
## Scientific Foundation
|
|
1059
|
+
## 🧬 Scientific Foundation
|
|
1081
1060
|
|
|
1082
1061
|
Prism has evolved from smart session logging into a **cognitive memory architecture** — grounded in real research, not marketing. Every retrieval decision is backed by peer-reviewed models from cognitive psychology, neuroscience, and distributed computing.
|
|
1083
1062
|
|
|
@@ -1111,22 +1090,19 @@ Prism has evolved from smart session logging into a **cognitive memory architect
|
|
|
1111
1090
|
| **v7.8** | Multi-Hop Causal Reasoning — spreading activation traverses `caused_by`/`led_to` edges with damped fan effect (`1/ln(fan+e)`) and lateral inhibition | ACT-R spreading activation (Anderson), Collins & Loftus (1975) | ✅ Shipped |
|
|
1112
1091
|
| **v7.8** | Uncertainty-Aware Rejection Gate — dual-signal (similarity floor + gap distance) safety layer prevents hallucination from low-confidence retrievals | Metacognition research, uncertainty quantification | ✅ Shipped |
|
|
1113
1092
|
| **v7.8** | Dynamic Fast Weight Decay — `is_rollup` semantic nodes decay 50% slower (`ageModifier = 0.5`) than episodic entries, creating Long-Term Context anchors | ACT-R base-level activation with differential decay rates | ✅ Shipped |
|
|
1114
|
-
| **v7.8** | LoCoMo Benchmark Harness — deterministic integration suite (`tests/benchmarks/locomo.ts`, 20 assertions) benchmarking multi-hop compaction structures via `MockLLM` | Long-Context Memory evaluation (cognitive benchmarking) | ✅ Shipped |
|
|
1115
|
-
| **v7.8** | LoCoMo-Plus Benchmark — 16-assertion suite (`tests/benchmarks/locomo-plus.ts`) adapted from arXiv 2602.10715 validating cue–trigger semantic disconnect bridging via graph traversal and Hebbian consolidation; reports Precision@1/3/5/10 and MRR | LoCoMo-Plus (Li et al., ARR 2026), cue–trigger disconnect research | ✅ Shipped |
|
|
1116
1093
|
| **v7.x** | Affect-Tagged Memory — sentiment shapes what gets recalled | Affect-modulated retrieval (neuroscience) | 🔭 Horizon |
|
|
1117
1094
|
| **v8+** | Zero-Search Retrieval — no index, no ANN, just ask the vector | Holographic Reduced Representations | 🔭 Horizon |
|
|
1118
1095
|
|
|
1119
|
-
> Informed by Anderson's ACT-R (Adaptive Control of Thought—Rational), Collins & Loftus spreading activation networks (1975), Kanerva's SDM (1988), Hebb's learning rule,
|
|
1096
|
+
> Informed by Anderson's ACT-R (Adaptive Control of Thought—Rational), Collins & Loftus spreading activation networks (1975), Kanerva's SDM (1988), Hebb's learning rule, and LeCun's "Why AI Systems Don't Learn" (Dupoux, LeCun, Malik).
|
|
1120
1097
|
|
|
1121
1098
|
---
|
|
1122
1099
|
|
|
1123
|
-
## Milestones & Roadmap
|
|
1100
|
+
## 📦 Milestones & Roadmap
|
|
1124
1101
|
|
|
1125
|
-
> **Current:
|
|
1102
|
+
> **Current: v7.8.2** — Cognitive Architecture ([CHANGELOG](CHANGELOG.md))
|
|
1126
1103
|
|
|
1127
1104
|
| Release | Headline |
|
|
1128
1105
|
|---------|----------|
|
|
1129
|
-
| **v8.0** | ⚡ Synapse Engine — Pure multi-hop GraphRAG propagation, storage-agnostic, NaN-hardened, `[🌐 Synapse]` discovery tags |
|
|
1130
1106
|
| **v7.8** | 🧠 Cognitive Architecture — Hebbian consolidation, multi-hop reasoning, rejection gate, dynamic decay |
|
|
1131
1107
|
| **v7.7** | 🌐 Cloud-Native SSE Transport |
|
|
1132
1108
|
| **v7.5** | 🩺 Intent Health Dashboard + Security Hardening |
|
|
@@ -1145,7 +1121,7 @@ Prism has evolved from smart session logging into a **cognitive memory architect
|
|
|
1145
1121
|
👉 **[Full ROADMAP.md →](ROADMAP.md)**
|
|
1146
1122
|
|
|
1147
1123
|
|
|
1148
|
-
## Troubleshooting FAQ
|
|
1124
|
+
## ❓ Troubleshooting FAQ
|
|
1149
1125
|
|
|
1150
1126
|
**Q: Why is the dashboard project selector stuck on "Loading projects..."?**
|
|
1151
1127
|
A: Fixed in v7.3.3. The root cause was a multi-layer quote-escaping trap in the `abortPipeline` onclick handler that generated a `SyntaxError` in the browser, silently killing the entire dashboard IIFE. Update to v7.3.3+ (`npx -y prism-mcp-server`). If still stuck, check that Supabase env values are properly set (unresolved placeholders like `${SUPABASE_URL}` cause `/api/projects` to return empty). Prism auto-falls back to local SQLite when Supabase is misconfigured.
|
package/dist/cli.js
CHANGED
|
File without changes
|
package/dist/config.js
CHANGED
|
@@ -268,17 +268,3 @@ export const PRISM_DARK_FACTORY_ENABLED = process.env.PRISM_DARK_FACTORY_ENABLED
|
|
|
268
268
|
export const PRISM_DARK_FACTORY_POLL_MS = parseInt(process.env.PRISM_DARK_FACTORY_POLL_MS || "30000", 10);
|
|
269
269
|
/** Default max wall-clock time per pipeline (ms). Default: 15 minutes. */
|
|
270
270
|
export const PRISM_DARK_FACTORY_MAX_RUNTIME_MS = parseInt(process.env.PRISM_DARK_FACTORY_MAX_RUNTIME_MS || "900000", 10);
|
|
271
|
-
// ─── v8.0: Synapse — Spreading Activation Engine ──────────────
|
|
272
|
-
// Multi-hop energy propagation through memory_links graph.
|
|
273
|
-
// Enabled by default. Set PRISM_SYNAPSE_ENABLED=false to fall back
|
|
274
|
-
// to 1-hop candidateScopedSpreadingActivation (v7.0 behavior).
|
|
275
|
-
/** Master switch for the Synapse engine. Enabled by default (opt-out). */
|
|
276
|
-
export const PRISM_SYNAPSE_ENABLED = (process.env.PRISM_SYNAPSE_ENABLED ?? "true") !== "false";
|
|
277
|
-
/** Number of propagation iterations (depth). Higher = deeper traversal, more latency. (Default: 3) */
|
|
278
|
-
export const PRISM_SYNAPSE_ITERATIONS = parseInt(process.env.PRISM_SYNAPSE_ITERATIONS || "3", 10);
|
|
279
|
-
/** Energy attenuation per hop. Must be < 1.0 for convergence. (Default: 0.8) */
|
|
280
|
-
export const PRISM_SYNAPSE_SPREAD_FACTOR = parseFloat(process.env.PRISM_SYNAPSE_SPREAD_FACTOR || "0.8");
|
|
281
|
-
/** Hard cap on final output nodes (lateral inhibition). (Default: 7) */
|
|
282
|
-
export const PRISM_SYNAPSE_LATERAL_INHIBITION = parseInt(process.env.PRISM_SYNAPSE_LATERAL_INHIBITION || "7", 10);
|
|
283
|
-
/** Soft cap on active nodes per iteration (prevents explosion). (Default: 20) */
|
|
284
|
-
export const PRISM_SYNAPSE_SOFT_CAP = parseInt(process.env.PRISM_SYNAPSE_SOFT_CAP || "20", 10);
|
|
@@ -599,13 +599,6 @@ async function runnerTick() {
|
|
|
599
599
|
const harnessPath = path.join(path.resolve(spec.workingDirectory), 'verification_harness.json');
|
|
600
600
|
if (fs.existsSync(harnessPath)) {
|
|
601
601
|
try {
|
|
602
|
-
// MED-5 FIX: Guard against LLM-generated files that are malformed or
|
|
603
|
-
// excessively large. Cap at 1MB to prevent heap exhaustion.
|
|
604
|
-
const MAX_HARNESS_SIZE = 1_000_000;
|
|
605
|
-
const stat = fs.statSync(harnessPath);
|
|
606
|
-
if (stat.size > MAX_HARNESS_SIZE) {
|
|
607
|
-
throw new Error(`Verification harness too large (${stat.size} bytes, max ${MAX_HARNESS_SIZE}). Possible corrupt LLM output.`);
|
|
608
|
-
}
|
|
609
602
|
const rawHarness = fs.readFileSync(harnessPath, 'utf8');
|
|
610
603
|
const harnessData = JSON.parse(rawHarness);
|
|
611
604
|
// GAP-5 fix: Persist the harness so CLI drift detection works for DarkFactory runs
|
|
@@ -45,16 +45,8 @@ export class SafetyController {
|
|
|
45
45
|
if (!spec.workingDirectory)
|
|
46
46
|
return true;
|
|
47
47
|
// Resolve symlinks and protect against ../ escapes.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// EDGE-2 FIX: macOS (HFS+/APFS) and Windows (NTFS) use case-insensitive
|
|
51
|
-
// filesystems by default. Without case normalization, "/App/Workspace"
|
|
52
|
-
// and "/app/workspace" are treated as different paths — allowing a scope
|
|
53
|
-
// escape via case mismatch.
|
|
54
|
-
if (process.platform === 'darwin' || process.platform === 'win32') {
|
|
55
|
-
resolvedTarget = resolvedTarget.toLowerCase();
|
|
56
|
-
resolvedWorkspace = resolvedWorkspace.toLowerCase();
|
|
57
|
-
}
|
|
48
|
+
const resolvedTarget = path.resolve(targetPath);
|
|
49
|
+
const resolvedWorkspace = path.resolve(spec.workingDirectory);
|
|
58
50
|
// Path Traversal Guard: A naive startsWith() check is vulnerable to
|
|
59
51
|
// prefix collisions — e.g. /app/workspace-hacked passes startsWith('/app/workspace').
|
|
60
52
|
// We require EITHER exact match OR the target starts with workspace + path separator.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Dashboard authentication helpers extracted from server.ts for direct unit testing.
|
|
3
3
|
*/
|
|
4
4
|
import { randomBytes } from "crypto";
|
|
5
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
5
6
|
// ─────────────────────────────────────────────────────────────────
|
|
6
7
|
// TIMING-SAFE COMPARISON
|
|
7
8
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -34,6 +35,18 @@ export function generateToken() {
|
|
|
34
35
|
return randomBytes(32).toString("hex");
|
|
35
36
|
}
|
|
36
37
|
// ─────────────────────────────────────────────────────────────────
|
|
38
|
+
// JWKS SETUP
|
|
39
|
+
// ─────────────────────────────────────────────────────────────────
|
|
40
|
+
let jwksCache = null;
|
|
41
|
+
export function initJWKS(uri) {
|
|
42
|
+
try {
|
|
43
|
+
jwksCache = createRemoteJWKSet(new URL(uri));
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(`Failed to initialize JWKS from ${uri}:`, err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// ─────────────────────────────────────────────────────────────────
|
|
37
50
|
// AUTHENTICATION CHECK
|
|
38
51
|
// ─────────────────────────────────────────────────────────────────
|
|
39
52
|
/**
|
|
@@ -47,9 +60,25 @@ export function generateToken() {
|
|
|
47
60
|
* Side effect: expired session tokens are lazily cleaned up when
|
|
48
61
|
* encountered, preventing unbounded memory growth.
|
|
49
62
|
*/
|
|
50
|
-
export function isAuthenticated(req, config) {
|
|
63
|
+
export async function isAuthenticated(req, config) {
|
|
51
64
|
if (!config.authEnabled)
|
|
52
65
|
return true;
|
|
66
|
+
// Check Bearer Token (JWKS)
|
|
67
|
+
const authHeader = req.headers.authorization || "";
|
|
68
|
+
if (authHeader.startsWith("Bearer ") && jwksCache) {
|
|
69
|
+
try {
|
|
70
|
+
const token = authHeader.slice(7);
|
|
71
|
+
const { payload } = await jwtVerify(token, jwksCache);
|
|
72
|
+
// Attach agent_id to the request for traceability if needed downstream
|
|
73
|
+
req.agent_id = payload.agent_id || payload.sub;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
// Verification failed — let it fall through or return false
|
|
78
|
+
// console.error("JWT verification failed:", err);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
53
82
|
// Check session cookie first
|
|
54
83
|
const cookies = req.headers.cookie || "";
|
|
55
84
|
const match = cookies.match(/prism_session=([a-f0-9]{64})/);
|
|
@@ -63,7 +92,6 @@ export function isAuthenticated(req, config) {
|
|
|
63
92
|
config.activeSessions.delete(token);
|
|
64
93
|
}
|
|
65
94
|
// Check Basic Auth header
|
|
66
|
-
const authHeader = req.headers.authorization || "";
|
|
67
95
|
if (authHeader.startsWith("Basic ")) {
|
|
68
96
|
try {
|
|
69
97
|
const decoded = Buffer.from(authHeader.slice(6), "base64").toString("utf-8");
|
package/dist/dashboard/server.js
CHANGED
|
@@ -32,7 +32,7 @@ import { getLLMProvider } from "../utils/llm/factory.js";
|
|
|
32
32
|
import { buildVaultDirectory } from "../utils/vaultExporter.js";
|
|
33
33
|
import { redactSettings } from "../tools/commonHelpers.js";
|
|
34
34
|
import { handleGraphRoutes } from "./graphRouter.js";
|
|
35
|
-
import { safeCompare, generateToken, isAuthenticated, createRateLimiter, } from "./authUtils.js";
|
|
35
|
+
import { safeCompare, generateToken, isAuthenticated, createRateLimiter, initJWKS, } from "./authUtils.js";
|
|
36
36
|
const PORT = parseInt(process.env.PRISM_DASHBOARD_PORT || "3000", 10);
|
|
37
37
|
/** Read HTTP request body as string (Buffer-based to avoid GC thrash on large imports) */
|
|
38
38
|
function readBody(req) {
|
|
@@ -76,7 +76,12 @@ export async function startDashboardServer() {
|
|
|
76
76
|
*/
|
|
77
77
|
const AUTH_USER = process.env.PRISM_DASHBOARD_USER || "";
|
|
78
78
|
const AUTH_PASS = process.env.PRISM_DASHBOARD_PASS || "";
|
|
79
|
-
const
|
|
79
|
+
const AUTH_JWKS_URI = process.env.PRISM_JWKS_URI || process.env.AUTH_JWKS_URI || "";
|
|
80
|
+
// Auth is enabled if basic auth is configured OR if JWKS is configured
|
|
81
|
+
const AUTH_ENABLED = (AUTH_USER.length > 0 && AUTH_PASS.length > 0) || AUTH_JWKS_URI.length > 0;
|
|
82
|
+
if (AUTH_JWKS_URI) {
|
|
83
|
+
initJWKS(AUTH_JWKS_URI);
|
|
84
|
+
}
|
|
80
85
|
const SESSION_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
81
86
|
const activeSessions = new Map(); // token → expiry timestamp
|
|
82
87
|
// Auth config object — injectable for testing via authUtils.ts
|
|
@@ -301,10 +306,11 @@ return false;}
|
|
|
301
306
|
return res.end(JSON.stringify({ error: err.message || "Failed to generate server card" }));
|
|
302
307
|
}
|
|
303
308
|
}
|
|
304
|
-
// ───
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
309
|
+
// ─── AUTHENTICATION GATE ───
|
|
310
|
+
// Basic Auth & Session & JWKS
|
|
311
|
+
if (AUTH_ENABLED && !(await isAuthenticated(req, authConfig))) {
|
|
312
|
+
// If it's an API request, return 401 JSON
|
|
313
|
+
if (reqUrl.pathname.startsWith('/api/') || reqUrl.pathname === "/sse" || reqUrl.pathname === "/messages") {
|
|
308
314
|
res.writeHead(401, { "Content-Type": "application/json" });
|
|
309
315
|
return res.end(JSON.stringify({ error: "Authentication required" }));
|
|
310
316
|
}
|
|
@@ -445,7 +451,6 @@ return false;}
|
|
|
445
451
|
let cursorId = undefined;
|
|
446
452
|
let iterations = 0;
|
|
447
453
|
const MAX_ITERATIONS = 100; // safety cap: 100 × 50 = 5000 entries max
|
|
448
|
-
let lastBackfillError = undefined;
|
|
449
454
|
while (hasMore && iterations < MAX_ITERATIONS) {
|
|
450
455
|
iterations++;
|
|
451
456
|
const result = await backfillEmbeddingsHandler({ dry_run: false, limit: 50, _cursor_id: cursorId });
|
|
@@ -453,8 +458,6 @@ return false;}
|
|
|
453
458
|
if (bStats) {
|
|
454
459
|
repairedCount += bStats.repaired;
|
|
455
460
|
failedCount += bStats.failed;
|
|
456
|
-
if (bStats.error)
|
|
457
|
-
lastBackfillError = bStats.error;
|
|
458
461
|
if (bStats.last_id)
|
|
459
462
|
cursorId = bStats.last_id;
|
|
460
463
|
else
|
|
@@ -467,10 +470,8 @@ return false;}
|
|
|
467
470
|
}
|
|
468
471
|
}
|
|
469
472
|
cleanupMessages.push(`Repaired ${repairedCount} embeddings`);
|
|
470
|
-
if (failedCount > 0)
|
|
471
|
-
|
|
472
|
-
cleanupMessages.push(`Failed to repair ${failedCount} embeddings${errMsg}`);
|
|
473
|
-
}
|
|
473
|
+
if (failedCount > 0)
|
|
474
|
+
cleanupMessages.push(`Failed to repair ${failedCount} embeddings`);
|
|
474
475
|
}
|
|
475
476
|
catch (err) {
|
|
476
477
|
console.error("[Dashboard] Failed to backfill embeddings:", err);
|
package/dist/dashboard/ui.js
CHANGED
|
@@ -1253,9 +1253,7 @@ Example:\n## Dev Rules\n- Always write tests first\n- Use TypeScript strict mode
|
|
|
1253
1253
|
onchange="onEmbeddingProviderChange(this.value)">
|
|
1254
1254
|
<option value="auto">🔄 Auto (same as Text Provider)</option>
|
|
1255
1255
|
<option value="gemini">🔵 Gemini</option>
|
|
1256
|
-
<option value="openai">🟢 OpenAI</option>
|
|
1257
|
-
<option value="voyage">🔮 Voyage AI</option>
|
|
1258
|
-
<option value="ollama">🟠 Ollama (Local)</option>
|
|
1256
|
+
<option value="openai">🟢 OpenAI / Ollama</option>
|
|
1259
1257
|
</select>
|
|
1260
1258
|
</div>
|
|
1261
1259
|
|
|
@@ -1263,7 +1261,7 @@ Example:\n## Dev Rules\n- Always write tests first\n- Use TypeScript strict mode
|
|
|
1263
1261
|
<div id="anthropic-embed-warning" style="display:none;margin-top:0.5rem;padding:0.5rem 0.75rem;background:rgba(251,146,60,0.1);border:1px solid rgba(251,146,60,0.3);border-radius:6px;font-size:0.78rem;color:#fb923c;line-height:1.5">
|
|
1264
1262
|
⚠️ <strong>Anthropic has no native embedding API.</strong>
|
|
1265
1263
|
Auto mode will route embeddings to <strong>Gemini</strong>.
|
|
1266
|
-
Set Embedding Provider to <strong>Ollama
|
|
1264
|
+
Set Embedding Provider to <strong>OpenAI / Ollama</strong> to use a local model (e.g. <code>nomic-embed-text</code>).
|
|
1267
1265
|
</div>
|
|
1268
1266
|
|
|
1269
1267
|
<!-- OpenAI embedding model field (shown when embedding_provider = openai) -->
|
|
@@ -1271,7 +1269,7 @@ Example:\n## Dev Rules\n- Always write tests first\n- Use TypeScript strict mode
|
|
|
1271
1269
|
<div class="setting-row">
|
|
1272
1270
|
<div>
|
|
1273
1271
|
<div class="setting-label">Embedding Model</div>
|
|
1274
|
-
<div class="setting-desc">Must output 768 dims.
|
|
1272
|
+
<div class="setting-desc">Must output 768 dims. Ollama: nomic-embed-text · OpenAI: text-embedding-3-small</div>
|
|
1275
1273
|
</div>
|
|
1276
1274
|
<input type="text" id="input-openai-embedding-model"
|
|
1277
1275
|
placeholder="text-embedding-3-small"
|
|
@@ -1281,61 +1279,9 @@ Example:\n## Dev Rules\n- Always write tests first\n- Use TypeScript strict mode
|
|
|
1281
1279
|
</div>
|
|
1282
1280
|
</div>
|
|
1283
1281
|
|
|
1284
|
-
<!-- Voyage AI embedding fields (shown when embedding_provider = voyage) -->
|
|
1285
|
-
<div id="embed-fields-voyage" style="display:none">
|
|
1286
|
-
<div class="setting-row">
|
|
1287
|
-
<div>
|
|
1288
|
-
<div class="setting-label">Voyage API Key</div>
|
|
1289
|
-
<div class="setting-desc">Get one free at <a href="https://dash.voyageai.com" target="_blank" style="color:var(--accent)">dash.voyageai.com</a></div>
|
|
1290
|
-
</div>
|
|
1291
|
-
<input type="password" id="input-voyage-api-key"
|
|
1292
|
-
placeholder="pa-…"
|
|
1293
|
-
style="padding: 0.2rem 0.5rem; background: var(--bg-hover); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.85rem; font-family: var(--font-mono); width: 180px;"
|
|
1294
|
-
onchange="saveBootSetting('VOYAGE_API_KEY', this.value)"
|
|
1295
|
-
oninput="clearTimeout(this._pv); var self=this; this._pv=setTimeout(function(){saveBootSetting('VOYAGE_API_KEY',self.value)},800)" />
|
|
1296
|
-
</div>
|
|
1297
|
-
<div class="setting-row">
|
|
1298
|
-
<div>
|
|
1299
|
-
<div class="setting-label">Voyage Model</div>
|
|
1300
|
-
<div class="setting-desc">voyage-code-3 (code) · voyage-3 (general). Both MRL → 768 dims.</div>
|
|
1301
|
-
</div>
|
|
1302
|
-
<input type="text" id="input-voyage-model"
|
|
1303
|
-
placeholder="voyage-code-3"
|
|
1304
|
-
style="padding: 0.2rem 0.5rem; background: var(--bg-hover); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.85rem; font-family: var(--font-mono); width: 160px;"
|
|
1305
|
-
onchange="saveBootSetting('voyage_model', this.value)"
|
|
1306
|
-
oninput="clearTimeout(this._pvm); var self=this; this._pvm=setTimeout(function(){saveBootSetting('voyage_model',self.value)},800)" />
|
|
1307
|
-
</div>
|
|
1308
|
-
</div>
|
|
1309
|
-
|
|
1310
|
-
<!-- Ollama embedding fields (shown when embedding_provider = ollama) -->
|
|
1311
|
-
<div id="embed-fields-ollama" style="display:none">
|
|
1312
|
-
<div class="setting-row">
|
|
1313
|
-
<div>
|
|
1314
|
-
<div class="setting-label">Ollama Base URL</div>
|
|
1315
|
-
<div class="setting-desc">Where Ollama is running locally</div>
|
|
1316
|
-
</div>
|
|
1317
|
-
<input type="text" id="input-ollama-base-url"
|
|
1318
|
-
placeholder="http://localhost:11434"
|
|
1319
|
-
style="padding: 0.2rem 0.5rem; background: var(--bg-hover); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.85rem; font-family: var(--font-mono); width: 220px;"
|
|
1320
|
-
onchange="saveBootSetting('ollama_base_url', this.value)"
|
|
1321
|
-
oninput="clearTimeout(this._pou); var self=this; this._pou=setTimeout(function(){saveBootSetting('ollama_base_url',self.value)},800)" />
|
|
1322
|
-
</div>
|
|
1323
|
-
<div class="setting-row">
|
|
1324
|
-
<div>
|
|
1325
|
-
<div class="setting-label">Embedding Model</div>
|
|
1326
|
-
<div class="setting-desc">Must output 768 dims. <code>nomic-embed-text</code> recommended.</div>
|
|
1327
|
-
</div>
|
|
1328
|
-
<input type="text" id="input-ollama-model"
|
|
1329
|
-
placeholder="nomic-embed-text"
|
|
1330
|
-
style="padding: 0.2rem 0.5rem; background: var(--bg-hover); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.85rem; font-family: var(--font-mono); width: 180px;"
|
|
1331
|
-
onchange="saveBootSetting('ollama_model', this.value)"
|
|
1332
|
-
oninput="clearTimeout(this._pom); var self=this; this._pom=setTimeout(function(){saveBootSetting('ollama_model',self.value)},800)" />
|
|
1333
|
-
</div>
|
|
1334
|
-
</div>
|
|
1335
|
-
|
|
1336
1282
|
<div style="margin-top:1rem;padding:0.6rem 0.8rem;background:rgba(139,92,246,0.08);border:1px solid rgba(139,92,246,0.2);border-radius:6px;font-size:0.78rem;color:var(--text-secondary);line-height:1.5">
|
|
1337
|
-
💡 <strong>
|
|
1338
|
-
Use Claude for reasoning & <code>nomic-embed-text</code> (free, local
|
|
1283
|
+
💡 <strong>Cost-optimized setup:</strong> Text Provider → <code>Anthropic</code>, Embedding Provider → <code>OpenAI / Ollama</code>.<br>
|
|
1284
|
+
Use Claude 3.5 Sonnet for reasoning & <code>nomic-embed-text</code> (free, local) for embeddings.
|
|
1339
1285
|
</div>
|
|
1340
1286
|
|
|
1341
1287
|
<span class="setting-saved" id="savedToastProviders">Saved ✓</span>
|
|
@@ -3189,10 +3135,8 @@ function onTextProviderChange(value) {
|
|
|
3189
3135
|
// Called when the EMBEDDING provider dropdown changes.
|
|
3190
3136
|
function onEmbeddingProviderChange(value) {
|
|
3191
3137
|
var textVal = document.getElementById('select-text-provider').value;
|
|
3192
|
-
// Show
|
|
3138
|
+
// Show the OpenAI embedding model field only when embedding=openai
|
|
3193
3139
|
document.getElementById('embed-fields-openai').style.display = value === 'openai' ? '' : 'none';
|
|
3194
|
-
document.getElementById('embed-fields-voyage').style.display = value === 'voyage' ? '' : 'none';
|
|
3195
|
-
document.getElementById('embed-fields-ollama').style.display = value === 'ollama' ? '' : 'none';
|
|
3196
3140
|
refreshAnthropicWarning(textVal, value);
|
|
3197
3141
|
saveBootSetting('embedding_provider', value);
|
|
3198
3142
|
}
|
|
@@ -3230,17 +3174,7 @@ function loadAiProviderSettings() {
|
|
|
3230
3174
|
if (embedSel)
|
|
3231
3175
|
embedSel.value = embedProvider;
|
|
3232
3176
|
document.getElementById('embed-fields-openai').style.display = embedProvider === 'openai' ? '' : 'none';
|
|
3233
|
-
document.getElementById('embed-fields-voyage').style.display = embedProvider === 'voyage' ? '' : 'none';
|
|
3234
|
-
document.getElementById('embed-fields-ollama').style.display = embedProvider === 'ollama' ? '' : 'none';
|
|
3235
3177
|
refreshAnthropicWarning(textProvider, embedProvider);
|
|
3236
|
-
var vKey = document.getElementById('input-voyage-api-key');
|
|
3237
|
-
if (vKey) vKey.placeholder = s.VOYAGE_API_KEY ? '(key saved — paste to update)' : 'pa-…';
|
|
3238
|
-
var vMod = document.getElementById('input-voyage-model');
|
|
3239
|
-
if (vMod && s.voyage_model) vMod.value = s.voyage_model;
|
|
3240
|
-
var olUrl = document.getElementById('input-ollama-base-url');
|
|
3241
|
-
if (olUrl && s.ollama_base_url) olUrl.value = s.ollama_base_url;
|
|
3242
|
-
var olMod = document.getElementById('input-ollama-model');
|
|
3243
|
-
if (olMod && s.ollama_model) olMod.value = s.ollama_model;
|
|
3244
3178
|
gKey = document.getElementById('input-google-api-key');
|
|
3245
3179
|
if (gKey)
|
|
3246
3180
|
gKey.placeholder = s.GOOGLE_API_KEY ? '(key saved — paste to update)' : 'AIza…';
|