updated documentation to reflect additions of new project, settings, and UI restructure

This commit is contained in:
Storme-bit
2026-04-13 17:26:20 -07:00
parent 699592071f
commit 0b9fedcd6e
3 changed files with 175 additions and 35 deletions

View File

@@ -66,6 +66,7 @@ export default defineConfig({
'/models': 'http://192.168.0.205:4000', '/models': 'http://192.168.0.205:4000',
'/sessions': 'http://192.168.0.205:4000', '/sessions': 'http://192.168.0.205:4000',
'/chat': 'http://192.168.0.205:4000', '/chat': 'http://192.168.0.205:4000',
'/projects': 'http://192.168.0.205:4000',
} }
} }
}); });
@@ -78,44 +79,63 @@ If new routes are added to the orchestration service, add them here too.
``` ```
src/ src/
├── api/ ├── api/
│ └── orchestration.js # All fetch calls to the orchestration service │ └── orchestration.js # All fetch calls to the orchestration service
├── config/ ├── config/
│ └── constants.js # FALLBACK_MODELS, DEFAULT_MODEL, API_DEFAULTS │ └── constants.js # FALLBACK_MODELS, DEFAULT_MODEL, API_DEFAULTS
├── hooks/ ├── hooks/
│ ├── useSession.js # Session list, history loading, active session state │ ├── useSession.js # Session list, history loading, active session state
│ ├── useChat.js # Message sending, SSE streaming, message state │ ├── useChat.js # Message sending, SSE streaming, message state
│ ├── useModels.js # Dynamic model list fetched from /models endpoint │ ├── useModels.js # Dynamic model list fetched from /models endpoint
── useContextMenu.js # Right-click context menu position and visibility ── useProjects.js # Project list fetched from /projects endpoint
│ └── useContextMenu.js # Right-click context menu position and visibility
├── components/ ├── components/
│ ├── App.jsx # Root component — layout and shared state │ ├── App.jsx # Root component — layout, shared state, view routing
│ ├── SessionList.jsx # Left sidebar — session list, rename, delete │ ├── Sidebar.jsx # Left sidebar — projects, recent chats, navigation
│ ├── ChatWindow.jsx # Centre panel — message thread and input bar │ ├── ChatWindow.jsx # Centre panel — message thread and input bar
│ ├── MessageBubble.jsx # Individual message bubble (user or assistant) │ ├── MessageBubble.jsx # Individual message bubble (user or assistant)
│ ├── InfoPanel.jsx # Right panel — model selector and session metadata │ ├── InfoPanel.jsx # Right panel — model selector and session metadata
── SessionModal.jsx # Modal dialog for session settings and delete confirmation ── SessionModal.jsx # Modal for session rename and delete confirmation
│ ├── ProjectModal.jsx # Modal for project create, edit, and delete confirmation
│ ├── AllChatsView.jsx # Full paginated session list with multi-select bulk delete
│ ├── AllProjectsView.jsx # Project tile grid with create/edit/delete
│ └── SettingsView.jsx # Settings placeholder (sections: Appearance, Memory, Models, About)
├── index.css # Global reset, CSS variables, utility classes ├── index.css # Global reset, CSS variables, utility classes
└── main.jsx # React entry point └── main.jsx # React entry point
``` ```
> `SessionList.jsx` is superseded by `Sidebar.jsx` and kept only as a reference.
## Layout ## Layout
Three-panel layout with collapsible sidebars: The app uses a view-based layout. `App.jsx` manages a `view` state
(`'chat' | 'all-chats' | 'all-projects' | 'settings'`) that controls which
main panel is rendered. The left sidebar and right info panel are always present.
``` ```
┌─────────────────┬──────────────────────────┬─────────────┐ ┌─────────────────┬──────────────────────────────┐
Session List Chat Window │ Info Panel Sidebar Main Area (view-dependent)
│ (collapsible) │ │ (collapsible) │ (collapsible)
│ │ [message thread] │ chat → ChatWindow
│ + New Chat │ │ Model │ + New Chat all-chats → AllChatsView
│ │ Session ID ⊞ New Project │ all-projects → AllProjectsView
Session 1 │ Token count │ settings → SettingsView
Session 2 PROJECTS ▾ │ │
│ [input bar] │ [tile] [tile] │
└─────────────────┴──────────────────────────┴─────────────┘ │ All Projects → │ │
│ │ │
│ RECENT CHATS ▾ │ │
│ Session 1 │ │
│ Session 2 │ │
│ All Chats → │ │
│ │ │
│ ⚙ Settings │ │
└──────────────────┴──────────────────────────────┘
``` ```
Sidebars collapse to a 56px icon rail. The centre chat window always The sidebar collapses to a 48px icon rail. The right info panel (`InfoPanel`)
fills the remaining space. slides in from the right over the main area using `transform: translateX()`
it is hidden by default (`rightOpen` starts `false`) and toggled via a button
in the `ChatWindow` header.
## CSS Architecture ## CSS Architecture
@@ -148,7 +168,7 @@ rules, inline styles for dynamic prop-driven values.
| Class | Description | | Class | Description |
|---|---| |---|---|
| `.panel-header` | Shared header row — used in all three panels | | `.panel-header` | Shared header row — used across all panels |
| `.btn-reset` | Resets button styles (no border, bg, cursor pointer) | | `.btn-reset` | Resets button styles (no border, bg, cursor pointer) |
| `.btn-icon` | Icon button with hover state | | `.btn-icon` | Icon button with hover state |
| `.btn-primary` | Accent-coloured action button with `:hover` and `:disabled` states | | `.btn-primary` | Accent-coloured action button with `:hover` and `:disabled` states |
@@ -174,6 +194,10 @@ All orchestration calls are centralised in `src/api/orchestration.js`:
| `fetchModels` | GET | /models | Load available models from manifest | | `fetchModels` | GET | /models | Load available models from manifest |
| `renameSession` | PATCH | /sessions/:id | Rename a session | | `renameSession` | PATCH | /sessions/:id | Rename a session |
| `deleteSession` | DELETE | /sessions/:id | Delete a session | | `deleteSession` | DELETE | /sessions/:id | Delete a session |
| `fetchProjects` | GET | /projects | Load project list |
| `createProject` | POST | /projects | Create a new project |
| `updateProject` | PATCH | /projects/:id | Update a project |
| `deleteProject` | DELETE | /projects/:id | Delete a project |
`streamMessage` returns an abort function — call it to cancel a stream mid-flight. `streamMessage` returns an abort function — call it to cancel a stream mid-flight.
Uses a buffer pattern to handle SSE chunks that may span multiple network packets. Uses a buffer pattern to handle SSE chunks that may span multiple network packets.
@@ -215,7 +239,7 @@ response to surface newly created sessions.
### Session Name Display ### Session Name Display
The chat header and session list both display `session.name` if set, falling back The chat header and session rows both display `session.name` if set, falling back
to `session.external_id` if no name has been assigned: to `session.external_id` if no name has been assigned:
```js ```js
@@ -224,9 +248,9 @@ activeSession.name || activeSession.external_id
### Session Actions ### Session Actions
The session list supports rename and delete via two entry points: Session rows in the sidebar support rename and delete via two entry points:
- **Hover** — reveals ✎ (rename) and ✕ (delete) icon buttons alongside the session row - **Hover** — reveals ✎ (rename) and ✕ (delete) icon buttons alongside the row
- **Right-click** — opens a context menu with the same actions - **Right-click** — opens a context menu with the same actions
Both trigger `SessionModal` — a shared modal component with two modes: Both trigger `SessionModal` — a shared modal component with two modes:
@@ -234,10 +258,7 @@ Both trigger `SessionModal` — a shared modal component with two modes:
| Mode | Trigger | Behaviour | | Mode | Trigger | Behaviour |
|---|---|---| |---|---|---|
| `settings` | Rename button / context menu rename | Shows name input, saves on Enter or Save button | | `settings` | Rename button / context menu rename | Shows name input, saves on Enter or Save button |
| `confirm-delete` | Delete button / context menu delete | Shows confirmation dialog with session name, requires explicit Delete button click | | `confirm-delete` | Delete button / context menu delete | Shows confirmation dialog, requires explicit Delete click |
The modal is intentionally titled "Session Settings" and structured to expand
into a full settings panel in future iterations.
Actions are disabled on unsaved (new) sessions that haven't had a first message sent yet. Actions are disabled on unsaved (new) sessions that haven't had a first message sent yet.
@@ -268,3 +289,40 @@ Session row action icons (✎ ✕) are rendered as siblings of the session
`<button>`, not children — HTML does not allow `<button>` inside `<button>`. `<button>`, not children — HTML does not allow `<button>` inside `<button>`.
The outer `<div>` owns hover state and context menu; the inner `<button>` handles The outer `<div>` owns hover state and context menu; the inner `<button>` handles
session selection; action icon buttons sit alongside it in the same flex row. session selection; action icon buttons sit alongside it in the same flex row.
## Project Management
Projects are a first-class concept in the UI. The `useProjects` hook fetches
the project list from `GET /projects` on mount and exposes a `refreshProjects`
callback for keeping the sidebar in sync after mutations.
### Project Actions
Projects are managed from `AllProjectsView` via `ProjectModal`:
| Mode | Behaviour |
|---|---|
| `create` | Name (required), description (optional), colour picker |
| `edit` | Same fields as create, pre-populated |
| `confirm-delete` | Confirmation dialog — sessions in the project are not deleted |
The sidebar Projects section shows up to 6 project tiles as coloured badge buttons.
Clicking any tile navigates to `AllProjectsView`. The "All Projects →" link is
always shown below the tiles.
After any create, edit, or delete in `AllProjectsView`, `onProjectsChange` is called
to trigger `refreshProjects` in `App.jsx`, keeping the sidebar tiles in sync.
## View Routing
`App.jsx` manages a `view` state string that controls which main panel renders:
| View | Component | Trigger |
|---|---|---|
| `'chat'` | `ChatWindow` | Default; selecting a session from sidebar or AllChatsView |
| `'all-chats'` | `AllChatsView` | "All Chats →" link or ☰ icon in collapsed rail |
| `'all-projects'` | `AllProjectsView` | "All Projects →" link, ⊞ icon, or New Project button |
| `'settings'` | `SettingsView` | Settings button or ⚙ icon in collapsed rail |
`AllChatsView` navigates back to `'chat'` on session row click, passing the selected
session to `selectSession` so history loads immediately.

View File

@@ -35,7 +35,8 @@ service to generate and store a vector in Qdrant.
src/ src/
├── db/ ├── db/
│ ├── index.js # SQLite connection + initialization + migrations │ ├── index.js # SQLite connection + initialization + migrations
── schema.js # Table definitions, indexes, FTS5, triggers ── schema.js # Table definitions, indexes, FTS5, triggers
│ └── projects.js # Project CRUD functions
├── episodic/ ├── episodic/
│ └── index.js # Session + episode CRUD, FTS search, embedding write path │ └── index.js # Session + episode CRUD, FTS search, embedding write path
├── semantic/ ├── semantic/
@@ -47,13 +48,14 @@ src/
## SQLite Schema ## SQLite Schema
Five core tables: Six core tables:
- **sessions** — top-level conversation containers, identified by an `external_id` and optional `name` - **sessions** — top-level conversation containers, identified by an `external_id`, optional `name`, and optional `project_id`
- **episodes** — individual exchanges (user message + AI response) tied to a session - **episodes** — individual exchanges (user message + AI response) tied to a session
- **entities** — named things the system learns about (people, places, concepts) - **entities** — named things the system learns about (people, places, concepts)
- **relationships** — directional labeled links between entities - **relationships** — directional labeled links between entities
- **summaries** — condensed episode groups for efficient context retrieval - **summaries** — condensed episode groups for efficient context retrieval
- **projects** — named groupings of sessions with optional description, colour, and icon
### Migrations ### Migrations
@@ -64,13 +66,25 @@ already-applied changes:
```js ```js
try { try {
db.exec(`ALTER TABLE sessions ADD COLUMN name TEXT`); db.exec(`ALTER TABLE sessions ADD COLUMN name TEXT`);
} catch { } catch {}
// Column already exists — safe to ignore on subsequent startups
} try {
db.exec(`ALTER TABLE sessions ADD COLUMN project_id INTEGER REFERENCES projects(id)`);
} catch {}
try {
db.exec(`CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id)`);
} catch {}
``` ```
This pattern is idempotent — safe to run on every startup. New migrations should
always be appended here rather than modifying the schema file, since `ALTER TABLE`
and index creation on existing tables cannot use `IF NOT EXISTS` guards in SQLite.
Current migrations: Current migrations:
- `ALTER TABLE sessions ADD COLUMN name TEXT` — adds display name to sessions - `ALTER TABLE sessions ADD COLUMN name TEXT` — adds display name to sessions
- `ALTER TABLE sessions ADD COLUMN project_id INTEGER` — links sessions to projects
- `CREATE INDEX idx_sessions_project` — index on the new project_id column
### FTS5 Full-Text Search ### FTS5 Full-Text Search
@@ -216,6 +230,37 @@ and summaries via SQLite `ON DELETE CASCADE`.
> Note: `/episodes/search` must be defined before `/episodes/:id` in Express to prevent > Note: `/episodes/search` must be defined before `/episodes/:id` in Express to prevent
> the word `search` being captured as an ID parameter. > the word `search` being captured as an ID parameter.
### Projects
| Method | Path | Description |
|---|---|---|
| POST | /projects | Create a new project |
| GET | /projects | Get all projects |
| GET | /projects/:id | Get project by ID |
| PATCH | /projects/:id | Update a project |
| DELETE | /projects/:id | Delete a project |
**POST /projects body:**
```json
{
"name": "My Project",
"description": "Optional description",
"colour": "#3d3a79",
"icon": null
}
```
`name` is required. `description`, `colour`, and `icon` are optional.
Returns `201` with the created project object on success.
**PATCH /projects/:id body:** same fields as POST, all optional.
**DELETE /projects/:id**
Returns `204 No Content`. Sessions assigned to the project are not deleted —
their `project_id` foreign key is left as-is (nullable, no cascade).
### Entities ### Entities
| Method | Path | Description | | Method | Path | Description |

View File

@@ -32,6 +32,7 @@ or inference services — all traffic flows through orchestration.
| MODELS_MANIFEST_PATH | Yes | — | Path to `models.json` manifest file | | MODELS_MANIFEST_PATH | Yes | — | Path to `models.json` manifest file |
## Internal Structure ## Internal Structure
``` ```
src/ src/
├── services/ ├── services/
@@ -44,6 +45,7 @@ src/
├── routes/ ├── routes/
│ ├── chat.js # POST /chat and POST /chat/stream route handlers │ ├── chat.js # POST /chat and POST /chat/stream route handlers
│ ├── sessions.js # Session list, history, rename, and delete routes │ ├── sessions.js # Session list, history, rename, and delete routes
│ ├── projects.js # Project CRUD routes — proxies to memory service
│ └── models.js # GET /models — reads models.json manifest from disk │ └── models.js # GET /models — reads models.json manifest from disk
└── index.js # Express app entry point └── index.js # Express app entry point
``` ```
@@ -87,6 +89,7 @@ the client.
count to the client. count to the client.
## Prompt Structure ## Prompt Structure
``` ```
[System prompt] [System prompt]
@@ -174,6 +177,17 @@ are added or removed.
| PATCH | /sessions/:sessionId | Rename a session | | PATCH | /sessions/:sessionId | Rename a session |
| DELETE | /sessions/:sessionId | Delete a session and all its episodes | | DELETE | /sessions/:sessionId | Delete a session and all its episodes |
### Projects
Projects are proxied directly from the memory service with no transformation.
| Method | Path | Description |
|---|---|---|
| GET | /projects | Get all projects |
| POST | /projects | Create a new project |
| PATCH | /projects/:id | Update a project |
| DELETE | /projects/:id | Delete a project |
### Models ### Models
| Method | Path | Description | | Method | Path | Description |
@@ -280,3 +294,26 @@ Returns the parsed contents of `models.json`:
``` ```
Returns `500` if the manifest file cannot be read or parsed. Returns `500` if the manifest file cannot be read or parsed.
## Caddy Configuration
The Caddy reverse proxy on Mini PC 2 must have a handle block for each route
prefix the client needs to reach. Current required blocks:
```
handle /chat* {
reverse_proxy localhost:4000
}
handle /sessions* {
reverse_proxy localhost:4000
}
handle /models* {
reverse_proxy localhost:4000
}
handle /projects* {
reverse_proxy localhost:4000
}
```
When adding new top-level routes to the orchestration service, add a matching
block here and reload Caddy: `caddy reload --config /path/to/Caddyfile`