mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
Normalize session_id into ws_id as sole persistent identity (#29)
* Normalize session_id into ws_id as sole persistent identity Eliminate the separate session_id concept. The workstream ID (ws_id) is now the single identity used for both real-time routing and conversation persistence, removing a layer of indirection that was 1:1 in practice and buggy on resume (stale pointers, orphaned rows). Schema changes (migration 006): - Drop sessions table; add alias/title columns to workstreams - Rename conversations.session_id → ws_id - Rename session_config table → workstream_config (ws_id column) - Data migration remaps existing conversations to ws_id Storage/API renames: - register_session → register_workstream (already existed, merged) - save_message/load_messages now keyed by ws_id - resolve_session → resolve_workstream - ChatSession.session_id property → ws_id - ChatSession.resume_session() → resume() - resume_session field → resume_ws - SessionResumedEvent → WorkstreamResumedEvent - /api/sessions → /api/workstreams/saved - /sessions slash command → /workstreams - --session-retention-days → --retention-days Channel eviction recovery simplified: reuses old ws_id directly instead of get_session_id_by_ws() reverse lookup. * Fix Copilot review feedback: stale session wording in docs, regenerate OpenAPI spec - docs/channels.md: "resumes the session" → "resumes the workstream", "Session resumed:" → "Resumed:", "old session was pruned" → "old workstream was pruned" - docs/api-reference.md: "Each session object" → "Each saved workstream object", field descriptions updated, removed stale node_id field - sdk/typescript/openapi-server.json: fully regenerated from Python models — removes all stale session_id properties from WorkstreamInfo, DashboardWorkstream, CreateWorkstreamResponse schemas
This commit is contained in:
+11
-14
@@ -515,8 +515,8 @@ Returns a list of all active workstreams.
|
||||
```json
|
||||
{
|
||||
"workstreams": [
|
||||
{"id": "abc123", "name": "default", "state": "idle", "session_id": "a1b2c3d4e5f6"},
|
||||
{"id": "def456", "name": "hacker-news", "state": "thinking", "session_id": "c5d6e7f8a9b0"}
|
||||
{"id": "abc123", "name": "default", "state": "idle"},
|
||||
{"id": "def456", "name": "hacker-news", "state": "thinking"}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -528,22 +528,21 @@ Each workstream object:
|
||||
| `id` | string | Unique workstream routing identifier |
|
||||
| `name` | string | Display name (alias if set, otherwise `ws-xxxx`) |
|
||||
| `state` | string | Current state (see state values above) |
|
||||
| `session_id` | string/null | Session ID of the workstream's `ChatSession`, used for deduplication against `/v1/api/sessions` |
|
||||
|
||||
---
|
||||
|
||||
### `GET /v1/api/sessions`
|
||||
### `GET /v1/api/workstreams/saved`
|
||||
|
||||
Returns a list of saved sessions from the database, ordered by most recently
|
||||
Returns a list of saved workstreams from the database, ordered by most recently
|
||||
updated.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"sessions": [
|
||||
"workstreams": [
|
||||
{
|
||||
"session_id": "a1b2c3d4e5f6",
|
||||
"ws_id": "a1b2c3d4e5f6",
|
||||
"alias": "refactor",
|
||||
"title": "JWT Authentication Refactor",
|
||||
"created": "2026-03-01 10:00:00",
|
||||
@@ -554,18 +553,16 @@ updated.
|
||||
}
|
||||
```
|
||||
|
||||
Each session object:
|
||||
Each saved workstream object:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-----------------|-------------|--------------------------------------------|
|
||||
| `session_id` | string | Unique 32-char hex UUID session identifier |
|
||||
| `ws_id` | string | Unique workstream identifier |
|
||||
| `alias` | string/null | User-assigned short name |
|
||||
| `title` | string/null | LLM-generated title |
|
||||
| `created` | string | ISO timestamp of session creation |
|
||||
| `created` | string | ISO timestamp of workstream 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 |
|
||||
| `message_count` | int | Number of messages in the workstream |
|
||||
|
||||
---
|
||||
|
||||
@@ -721,7 +718,7 @@ All fields are optional. The body can be empty or an empty JSON object.
|
||||
| `name` | string | auto | Workstream display name |
|
||||
| `model` | string | default | Model alias from the registry (`[models.*]`) |
|
||||
| `auto_approve` | bool | false | Auto-approve all tool calls for this workstream |
|
||||
| `resume_session` | string | "" | Session ID to resume atomically during creation (empty = fresh)|
|
||||
| `resume_ws` | string | "" | Workstream ID to resume atomically during creation (empty = fresh)|
|
||||
|
||||
**Response (success):**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user