mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
Update docs and diagrams for cluster-scale schema changes
- StorageBackend protocol: document 5 new workstream methods (26 total) - Session ID: 12-char hex → 32-char full UUID in API reference - /health endpoint: add node_id field to response docs - sessions table: document node_id and ws_id columns - Bridge node_id: document server-owned identity with /health retrieval - Regenerate storage architecture PNG from updated PlantUML
This commit is contained in:
@@ -394,12 +394,14 @@ Each session object:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-----------------|-------------|--------------------------------------------|
|
||||
| `session_id` | string | Unique 12-char hex session identifier |
|
||||
| `session_id` | string | Unique 32-char hex UUID session identifier |
|
||||
| `alias` | string/null | User-assigned short name |
|
||||
| `title` | string/null | LLM-generated title |
|
||||
| `created` | string | ISO timestamp of session creation |
|
||||
| `updated` | string | ISO timestamp of last message |
|
||||
| `message_count` | int | Number of messages in the session |
|
||||
| `node_id` | string/null | Server node that created the session |
|
||||
| `ws_id` | string/null | Workstream the session belongs to |
|
||||
|
||||
---
|
||||
|
||||
@@ -692,7 +694,8 @@ liveness probes.
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.5",
|
||||
"node_id": "worker-01_a3f2",
|
||||
"uptime_seconds": 3614.72,
|
||||
"model": "llama-3.1-70b-instruct",
|
||||
"workstreams": {
|
||||
@@ -714,6 +717,7 @@ liveness probes.
|
||||
|-------|------|-------------|
|
||||
| `status` | string | `"ok"` or `"degraded"` (degraded when backend unreachable) |
|
||||
| `version` | string | turnstone server version |
|
||||
| `node_id` | string | Server-generated node identity (`{hostname}_{4hex}`) |
|
||||
| `uptime_seconds` | number | Seconds since the server process started |
|
||||
| `model` | string | Model name detected or configured at startup |
|
||||
| `workstreams.total` | integer | Total active workstreams |
|
||||
|
||||
+15
-5
@@ -713,7 +713,7 @@ and are the single source of truth for both backends and Alembic migrations.
|
||||
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `register_session(session_id, title)` | Create a sessions row (no-op if exists) |
|
||||
| `register_session(session_id, title, node_id, ws_id)` | Create a sessions row (no-op if exists) |
|
||||
| `save_message(session_id, role, content, ...)` | Log a message to conversations |
|
||||
| `load_session_messages(session_id)` | Reconstruct OpenAI message format from DB rows |
|
||||
| `list_sessions(limit)` | List sessions with >=1 message, ordered by updated DESC |
|
||||
@@ -725,6 +725,11 @@ and are the single source of truth for both backends and Alembic migrations.
|
||||
| `set_session_alias(session_id, alias)` | Set user-friendly alias (returns False if taken) |
|
||||
| `get_session_name(session_id)` | Return alias if set, else title, else None |
|
||||
| `update_session_title(session_id, title)` | Set/update LLM-generated title |
|
||||
| `register_workstream(ws_id, node_id, name, state)` | Create a workstreams row (no-op if exists) |
|
||||
| `update_workstream_state(ws_id, state)` | Update workstream state and bump timestamp |
|
||||
| `update_workstream_name(ws_id, name)` | Update workstream display name |
|
||||
| `delete_workstream(ws_id)` | Delete a workstream row |
|
||||
| `list_workstreams(node_id, limit)` | List workstreams, optionally by node |
|
||||
| `kv_get(key)` / `kv_set(key, value)` / `kv_delete(key)` | Generic key-value store (backs memories table) |
|
||||
| `kv_list()` / `kv_search(query)` | List or search key-value pairs |
|
||||
| `search_history(query, limit)` | Full-text search (FTS5 on SQLite, tsvector on PostgreSQL) |
|
||||
@@ -745,9 +750,11 @@ Environment variables: `TURNSTONE_DB_BACKEND`, `TURNSTONE_DB_URL`, `TURNSTONE_DB
|
||||
|
||||
### Session Persistence and Resume
|
||||
|
||||
Each `ChatSession` generates a 12-char hex `_session_id` on creation and
|
||||
registers it in the `sessions` table. Messages are saved to `conversations`
|
||||
as they happen via `save_message()`.
|
||||
Each `ChatSession` generates a full 32-char hex UUID `_session_id` on creation
|
||||
and registers it in the `sessions` table with the server's `node_id` and the
|
||||
owning `ws_id`. Messages are saved to `conversations` as they happen via
|
||||
`save_message()`. Workstreams are persisted to the `workstreams` table on
|
||||
creation, with state changes tracked via `update_workstream_state()`.
|
||||
|
||||
**Auto-titling:** After the first complete exchange (user message + assistant
|
||||
response), a background thread calls the LLM with a title-generation prompt
|
||||
@@ -1037,7 +1044,10 @@ a response or the approval timeout (default 3600s / 1 hour) expires.
|
||||
`ws_id` for active sends. When the global SSE reports `ws_state → idle` for a tracked
|
||||
workstream, the bridge emits a synthetic `TurnCompleteEvent` with the correlation ID.
|
||||
|
||||
**Multi-node routing:** Each bridge has a `node_id` (defaults to hostname) and BLPOPs
|
||||
**Multi-node routing:** Each bridge retrieves its `node_id` from the server's
|
||||
`/health` endpoint on startup (with exponential backoff retry). The server
|
||||
generates the `node_id` (`{hostname}_{4hex}`) and is the sole authority for
|
||||
node identity. The bridge BLPOPs
|
||||
from both `turnstone:inbound:{node_id}` (directed, priority) and `turnstone:inbound` (shared).
|
||||
Messages with `target_node` set are pushed to the target's per-node queue. Messages
|
||||
for existing workstreams are auto-routed via `turnstone:ws:{ws_id}` ownership keys in Redis.
|
||||
|
||||
@@ -13,7 +13,7 @@ skinparam class {
|
||||
|
||||
' -- Protocol --
|
||||
interface "StorageBackend" as SB <<protocol>> {
|
||||
+register_session(session_id, title)
|
||||
+register_session(session_id, title, node_id, ws_id)
|
||||
+save_message(session_id, role, content, ...)
|
||||
+load_session_messages(session_id) → list[dict]
|
||||
+list_sessions(limit) → list
|
||||
@@ -25,6 +25,11 @@ interface "StorageBackend" as SB <<protocol>> {
|
||||
+set_session_alias(session_id, alias) → bool
|
||||
+get_session_name(session_id) → str | None
|
||||
+update_session_title(session_id, title)
|
||||
+register_workstream(ws_id, node_id, name, state)
|
||||
+update_workstream_state(ws_id, state)
|
||||
+update_workstream_name(ws_id, name)
|
||||
+delete_workstream(ws_id) → bool
|
||||
+list_workstreams(node_id, limit) → list
|
||||
+kv_get(key) → str | None
|
||||
+kv_set(key, value) → str | None
|
||||
+kv_delete(key) → bool
|
||||
@@ -58,7 +63,8 @@ class "_schema.py" as Schema <<schema>> {
|
||||
+metadata: MetaData
|
||||
+memories: Table
|
||||
+conversations: Table
|
||||
+sessions: Table
|
||||
+sessions: Table (node_id, ws_id)
|
||||
+workstreams: Table (node_id, state)
|
||||
+session_config: Table
|
||||
--
|
||||
SQLAlchemy Core
|
||||
@@ -94,9 +100,11 @@ class "memory.py" as Facade <<facade>> {
|
||||
+register_session()
|
||||
+save_message()
|
||||
+load_session_messages()
|
||||
+register_workstream()
|
||||
+update_workstream_state()
|
||||
+save_memory() / delete_memory()
|
||||
+search_memories()
|
||||
+... (all 18 functions)
|
||||
+... (all 22 functions)
|
||||
--
|
||||
Thin delegation to
|
||||
get_storage()
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0c615984373b4893b6cc5755604f137541e9d391862122746a4fcbae63543563
|
||||
size 201041
|
||||
oid sha256:bd776a34b50d3fe194e2a34d3b4d04ec71af31e1154b5fc98223636b1844e6b8
|
||||
size 226686
|
||||
|
||||
Reference in New Issue
Block a user