Rewritten from a coding-rules-only playbook into the full mode: minimal
solutions AND compressed speech, triggered per conversation by tag.
Two rules lead the prompt because a small local model drops whatever is buried
in the middle. Rule 1: anything destructive gets a full-sentence warning BEFORE
the command, naming what is lost and what to back up - brevity never applies
there. Rule 2: an abstraction asked for with a single use gets a one-line
"not needed" and the small version instead. Rule 1 is repeated at the very end,
which is what made it hold in testing.
Tags carry the trigger words. A reference playbook is injected only when one of
its tag words appears in the message (_route_playbooks), so a playbook with no
matching tag never routes in at all.
Known limits, measured against llama3.1:8b: as a reference playbook only the
voice holds reliably. The build ladder and the warning-before-command ordering
need the playbook promoted to first position, because the chat endpoint appends
memory facts, conversation snippets and documents AFTER the reference block - a
reference playbook cannot own the end of the prompt, so a rule needing recency
weighting cannot get it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ported from downstream development. Four independent defects.
1. The memory dump was unrestorable. iterdump() serializes sqlite_vec virtual
tables as a raw INSERT INTO sqlite_master(...) followed by inserts into a
table the replaying connection cannot see, so replaying memory.db.sql died
on "no such table: vec_messages" and left ZERO tables behind. dump_db() now
loads the vec0 extension and filters the derived vec tables out of the
iterdump stream, matched on each statement's target table rather than as a
substring - a chat message whose text mentions vec_messages is an
INSERT INTO "messages" and has to survive.
compare() reported an unreadable dump as "diverged", which read like a real
verdict and made both guards refuse backup AND restore, locking the machine
out of syncing in either direction. Unreadable is now its own verdict.
_extra() compared updated_at against a "" default, but the column is REAL,
so the comparison raises TypeError on the first conversation the other side
lacks - exactly the case it counts. It tests membership first now. The
direction test declared updated_at TEXT, which is why this survived: the
test compared str to str while the field compared str to float.
2. The memory curator invented facts. It attributed the ASSISTANT's words to
the user, wrote absence claims read off the existing-memory block, and added
judgements ("favorite") the user never used. The prompt now scopes the USER
line as the only source, and two deterministic guards drop absence claims
and facts whose distinctive tokens appear nowhere in the user's message -
prompt wording alone did not hold on a 7B curator.
3. _best_vulkan_device scored Mesa's llvmpipe above an integrated GPU, pinning
Ollama to a software rasterizer advertising 31 GiB of "VRAM" - CPU inference
with Vulkan overhead on top. Software rasterizers are dropped.
4. Models.jsx compared catalog names to installed names literally, but Ollama
resolves a bare name to ":latest", so an untagged entry (nomic-embed-text)
read as missing forever and the Required gate never opened. Chatbot.jsx
fetched the model list once on mount although App keeps the page mounted
behind display:none, so a newly pulled model never appeared in the picker
until a full browser reload.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
New Modules entry in Flagship features + Architecture describes the
modules/ plugin auto-discovery. Chat/vision/voice, action tools,
Layout, and Configuration reworded from prose/tables into bullets for
scannability.
Bugs go through this repo's Issues tab with an ncp doctor ask; feature
requests stay pointed at NexusOS-requests so the bug tracker doesn't
mix with the planning backlog.
core.fileMode=false (repo-local or a machine-wide /etc/gitconfig) can
silently drop the +x bit on every tracked script during checkout, which
then surfaces later as a confusing "Permission denied" on whatever
script happens to run next rather than as an obvious failure up front.
ensure_exec_bits() re-applies +x from `git ls-files -s` (mode 100755)
right after every pull, so a restore is self-healing regardless of cause.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
requirements-amd.txt/requirements-nvidia.txt were pulling a multi-GB
torch wheel by default even though nothing in synapse/ imports torch,
transformers, accelerate, bitsandbytes, or PySide6 - dead weight that
made the pip batch fragile (one failed download could take unrelated
base deps down with it on a slow connection). Split the unused ML/GUI
stack out of requirements-base.txt into a new opt-in requirements-ml.txt,
and dropped the torch lines from the AMD/NVIDIA overlays and generator.
Also: recreate the venv if it exists but pip is missing, instead of
silently reusing a half-built one (ensurepip can fail during venv
creation and leave an interpreter with no pip).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Newer distros drop the python3-venv transitional package once it no longer
resolves to a real pythonX.Y-venv candidate, which crashed sync.py's venv
creation with a raw traceback. Prep now resolves the exact versioned
package via apt-cache, and skips xfce4-genmon-plugin/plank/blueman on
boxes with no xfconf-query so a non-XFCE box doesn't get noisy "unable to
locate package" failures for a panel it'll never run. venv_python() also
fails with an actionable message instead of an uncaught CalledProcessError.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Distilled from the private repo's playbook set with names and personal
specifics genericized. Reuses the same IDs as their private counterparts,
matching the existing main.yaml.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ported from the private repo (bin/publish.sh's README-only path): adds a
Flagship features section, reorders Quick start (Linux first), splits out
a Promethean section, corrects the ncp cross-platform parity note, and
replaces the stale in-README Roadmap with a pointer to NexusOS-requests.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ported from the private repo via bin/publish.sh, plus a manual catch-up
on files that had drifted out of sync before today:
- launch_nexus.ps1: health-check based restart decisions instead of a
bare port-listen check (a wedged leftover process squatting a port
used to look "already running" and block the real service from
starting), a script-path quoting fix for Start-Process, hidden
console via a wscript.exe wrapper (bin/launch_nexus_hidden.vbs), and
a taskbar/window icon for the native app window.
- Sidebar: slim icon+text nav rows instead of bulky bordered buttons,
tighter spacing throughout.
- Settings: full-width layout, a Vite dev-server Start/Stop toggle
(synapse/frontend_manager.py + /frontend/* endpoints), and the
Linux-only Icon Branding section now gated on the new /status
`platform` field instead of always rendering.
- Chatbot: a Think toggle next to the model picker, so extended
thinking can be flipped without leaving the chat page.
- management/ncp.py: faster start/stop polling (0.25s steps instead of
1s), Vite no longer blocks `ncp start` on Linux and is skipped
outright on Windows.
Note: the private repo also has a Mail (IMAP/SMTP) feature; it's
intentionally not included here, so the Mail-only pieces of main.py,
App.jsx, and requirements-windows.txt were left out of this port.
Models page redesign: tabs (Required/Recommended/Installed) with a
multi-column card grid, required models (memory curator + embeddings)
surfaced first and gating the rest until both are installed. Adds a
qwen2.5:14b tier to the hardware-fit catalog for high-VRAM machines.
Installer and restore messaging updated to match. Also declares pytest
in requirements-base.txt so bin/check.sh's test suite is reproducible
on a fresh venv.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Models.jsx clipped the whole card with overflow:hidden while only the
"Available Models" section (never visible when the hardware-recommended
list alone filled the card) had its own scroll — the installed-models
list was unreachable with no scrollbar. The whole card now scrolls as
one region instead.
install-windows.ps1's original (non-elevated) window printed "Requesting
administrator privileges..." and exited immediately, so all real
progress and the "installed!" banner only ever appeared in the separate
elevated window — making the original window look like it silently
quit. It now waits (-Wait -PassThru) and reports success/failure itself.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Opt-in repair pass: reinstall Python deps on import failure, npm install when
node_modules missing, npm run build when dist missing, fetch Ollama binary.
Plain doctor stays read-only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Debian apt ships EOL Node 18 which crashes Vite 8. Prep stage installs Node 20
from NodeSource when node is missing or <20; package.json declares engines.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Settings "Auto model routing" picks which installed model fires for chat vs
coding intent when no model is pinned (auto_chat_model / auto_code_model).
_auto_select_model honors the remap; _MODEL_PREFERENCE["code"] prefers real
coder models first.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Windows installer no longer auto-downloads models; points to the Models tab.
synapse/hardware.py detects RAM + best-effort VRAM and a curated catalog;
GET /models/recommended annotates each model with fit (gpu/ram/no); the Models
page shows detected RAM/VRAM with fit badges and per-row Pull buttons.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3-way action_tool_policy (off/ask/allow). In "ask", the chat stream stays
open and the tool loop awaits approval: emits event:tool_request, the UI
shows Approve/Deny, POST /chat/approve resumes the same stream. Declined
actions return a denied result; a timeout denies.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Conversations bind to a project on creation; RAG scopes to the
conversation's project, not the global setting.
- Action tools (web_search/fetch_url/remember) are withheld unless
allow_action_tools is enabled (off by default). Settings toggle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Projects/workspaces: documents grouped into projects; chat RAG scopes to the
active project. Switcher in the Documents page.
- Agentic action tools: web_search, fetch_url, and remember (first write tool),
allowlist-gated per playbook.
- Local Whisper STT (faster-whisper, no torch): on-device dictation replacing
the browser Web Speech API. POST /stt + GET /stt/status; browser fallback.
- Vector index extended to conversation recall (message_vectors), with the
brute-force cosine scan kept as the fallback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Chunker: char overlap across boundaries + hard-split of oversized paragraphs.
- Retrieval knobs: rag_top_k / rag_min_score in settings + Settings UI.
- Vector index: sqlite-vec ANN over document embeddings, dual-written and
backfilled, with brute-force cosine as the guaranteed fallback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Upload endpoint (base64 JSON, no multipart dep): extracts text from
pdf/docx/txt/md via pypdf + python-docx, then runs the existing
chunk/embed pipeline. Documents page uploads files straight through.
- Citations: the chat stream emits an SSE `sources` event listing the
documents that fed the answer; the UI shows them as chips under the reply.
- Deps: pypdf, python-docx (both pure-Python, Windows-safe).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Process scope for the current window, LocalMachine RemoteSigned so it persists
and ncp works from later shells without -ExecutionPolicy Bypass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>