documentation update

This commit is contained in:
Storme-bit
2026-04-18 23:37:32 -07:00
parent 1fc6e8a66d
commit e1375e7d1b
5 changed files with 145 additions and 98 deletions

View File

@@ -32,8 +32,7 @@ here for reference and direct debugging use.
```
`model` and `temperature` are optional. Inference parameters (temperature,
topP, topK, repeatPenalty) are read from `settings.json` on every request —
the request body values are not used for these; they are controlled via
`PATCH /settings`.
controlled via `PATCH /settings`.
**POST /chat — response:**
```json
@@ -91,7 +90,7 @@ Returns `{ sessionId, episodes: [...] }`. Episodes ordered newest first.
|---|---|---|
| GET | /projects | Get all projects |
| POST | /projects | Create a new project |
| PATCH | /projects/:id | Update a project |
| PATCH | /projects/:id | Update a project (partial — any subset of fields) |
| DELETE | /projects/:id | Delete a project (nulls session assignments) |
**POST /projects — body:**
@@ -101,13 +100,27 @@ Returns `{ sessionId, episodes: [...] }`. Episodes ordered newest first.
"description": "Optional description",
"colour": "#3d3a79",
"icon": null,
"isolated": 0
"isolated": 1
}
```
`name` is required. All other fields optional. `isolated` is `0` or `1`.
Returns `201` with the created project object.
`name` is required. All other fields optional. `isolated` is always `1`
all projects use isolated memory. Returns `201` with the created project object.
**PATCH /projects/:id — body:** same fields as POST, all optional.
**PATCH /projects/:id — body:** any subset of fields, all optional.
| Field | Type | Description |
|---|---|---|
| `name` | string | Project name |
| `description` | string | Project description |
| `colour` | string | Hex colour for UI accent |
| `icon` | string | Icon identifier |
| `isolated` | integer | Memory isolation flag (always 1) |
| `notes` | string | User-authored project notes |
Only provided fields are updated — omitted fields are not touched. This
enables safe partial updates (e.g. saving just `notes` without affecting
`name` or `colour`). Both orchestration and memory service implement dynamic
field patching.
### Models
@@ -127,8 +140,9 @@ with `models.json` in the same folder for label and description metadata.
```json
{ "contextWindow": 64000, "modelAlias": "gemma-4-26B-A4B-Claude-Distill-APEX-I-Mini.gguf" }
```
Fetches directly from llama-server `/props`. Returns `503` if llama-server
is unreachable.
Fetches directly from llama-server `/props`. `n_ctx` is at
`data.default_generation_settings.n_ctx` in the llama-server response.
Returns `503` if llama-server is unreachable.
### Settings
@@ -218,8 +232,7 @@ orchestration.
```json
{ "name": "Session Name", "projectId": 3 }
```
Both fields are optional. Only provided fields are updated — other fields
are not touched.
Both fields are optional. Only provided fields are updated.
### Episodes
@@ -251,7 +264,7 @@ are not touched.
| POST | /projects | Create a new project |
| GET | /projects | Get all projects |
| GET | /projects/:id | Get project by ID |
| PATCH | /projects/:id | Update a project |
| PATCH | /projects/:id | Update a project (dynamic — any subset of fields) |
| DELETE | /projects/:id | Delete project + null session assignments |
Same request/response shape as orchestration `/projects` above.

View File

@@ -1,15 +1,16 @@
# Memory Isolation
NexusAI implements project-scoped memory — sessions belonging to the same
project can share semantic context, and isolated projects can be restricted
from drawing on memory outside the project. This document describes how the
system works end-to-end.
project share semantic context within that project's boundary. All projects
are isolated by default.
## Concepts
**Session** — a single conversation thread. Identified by `external_id`.
**Project** — a named grouping of sessions. Has an `isolated` flag (0 or 1).
**Project** — a named grouping of sessions. `isolated` is always `1`
the toggle has been removed from the UI and `isolated: 1` is hardcoded on
project creation.
**Semantic search** — at inference time, the user's message is embedded and
compared against past episodes in Qdrant to surface relevant context. The
@@ -20,11 +21,10 @@ scope of this search is controlled by the project context.
| Session state | Semantic search scope |
|---|---|
| No project | Own session's episodes only |
| Assigned to a non-isolated project | All episodes across all sessions in the project |
| Assigned to an isolated project | All episodes within the project only |
| Assigned to a project | All episodes across all sessions in that project |
| Removed from a project | Own session's episodes only (from that point) |
Sessions with no project assigned behave the same as they always have —
Sessions with no project assigned behave as they always have —
only their own past episodes are searched.
## How It Works
@@ -44,16 +44,9 @@ if (session.project_id) {
}
```
If the session belongs to any project (isolated or not), `projectSessionIds`
is populated with the internal integer IDs of all sessions in that project.
For **non-isolated projects**, this expands the search to all project sessions.
For **isolated projects**, the same set is used but the intent is restriction
— since `projectSessionIds` only contains project sessions, no external
episodes can appear.
Both cases use the same code path — the `isolated` flag does not change the
query logic, only the conceptual meaning.
If the session belongs to any project, `projectSessionIds` is populated with
the internal integer IDs of all sessions in that project — creating a shared
memory pool across all conversations in the project.
### Step 2 — Qdrant filter construction
@@ -96,26 +89,11 @@ message, `getProjectSessions` will not include that session's ID, so its
episodes disappear from the semantic search scope.
**New sessions created from ProjectView are assigned after the first message.**
The `useChat` hook writes the `project_id` assignment via `updateSession` after
`onDone` fires. There is a brief window during the first message where the
session has no project assigned. The project is correctly applied from the
second message onward.
## Isolated vs Non-Isolated
The `isolated` flag is stored on the project but does not currently change the
query logic — both isolated and non-isolated projects result in a
`projectSessionIds` filter. The distinction is semantic and enforced by
the project's membership:
- **Non-isolated** — intentionally draws from all sessions in the project,
creating a shared memory pool for related conversations
- **Isolated** — by design contains only sessions explicitly added to it,
so the same filter naturally restricts context to project-only episodes
If cross-project contamination became a concern (e.g. a session accidentally
added to the wrong project), removing it from the project immediately restores
isolation.
`handleNewProjectChat` in `App.jsx` calls `sendMessage` with the project ID,
which is passed to `useChat`. After `onDone` fires, `useChat` calls
`updateSession` to write the project assignment to the backend. There is a
brief window during the first message where the session has no project assigned.
The project is correctly applied from the second message onward.
## Qdrant Payload Structure