From 03974ba0e6d0443e793781f764aa139f66265a92 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 4 Jun 2026 14:49:05 -0400 Subject: [PATCH] fix(core): harden v2 session context epochs --- .../migration.sql | 7 - .../snapshot.json | 2026 ---------------- .../migration.sql | 10 - .../migration.sql | 1 - .../snapshot.json | 2123 ---------------- .../migration.sql | 1 - .../snapshot.json | 2133 ----------------- .../migration.sql | 17 + .../snapshot.json | 32 +- packages/core/src/database/migration.gen.ts | 5 +- ...0260604180746_add_session_context_epoch.ts | 19 - ...4181706_add_session_context_replacement.ts | 11 - ...dd_session_context_replacement_sequence.ts | 11 - ...260604184448_add_session_context_epoch.ts} | 17 +- packages/core/src/session/context-epoch.ts | 44 +- packages/core/src/session/context.ts | 16 +- packages/core/src/session/runner/llm.ts | 18 +- .../core/src/session/runner/to-llm-message.ts | 3 +- packages/core/src/session/sql.ts | 6 +- packages/core/src/session/store.ts | 5 +- packages/core/src/system-context.ts | 12 +- packages/core/test/database-migration.test.ts | 5 +- .../core/test/session-runner-message.test.ts | 17 +- packages/core/test/session-runner.test.ts | 173 +- packages/core/test/system-context.test.ts | 27 +- .../llm/src/protocols/anthropic-messages.ts | 2 +- .../llm/src/protocols/bedrock-converse.ts | 2 +- packages/llm/src/protocols/gemini.ts | 2 +- packages/llm/src/protocols/openai-chat.ts | 2 +- .../llm/src/protocols/openai-responses.ts | 2 +- packages/llm/src/protocols/shared.ts | 16 +- packages/llm/test/schema.test.ts | 26 +- specs/v2/schema-changelog.md | 10 +- 33 files changed, 340 insertions(+), 6461 deletions(-) delete mode 100644 packages/core/migration/20260604180746_add_session_context_epoch/migration.sql delete mode 100644 packages/core/migration/20260604180746_add_session_context_epoch/snapshot.json delete mode 100644 packages/core/migration/20260604181329_add_session_context_updates/migration.sql delete mode 100644 packages/core/migration/20260604181706_add_session_context_replacement/migration.sql delete mode 100644 packages/core/migration/20260604181706_add_session_context_replacement/snapshot.json delete mode 100644 packages/core/migration/20260604181807_add_session_context_replacement_sequence/migration.sql delete mode 100644 packages/core/migration/20260604181807_add_session_context_replacement_sequence/snapshot.json create mode 100644 packages/core/migration/20260604184448_add_session_context_epoch/migration.sql rename packages/core/migration/{20260604181329_add_session_context_updates => 20260604184448_add_session_context_epoch}/snapshot.json (98%) delete mode 100644 packages/core/src/database/migration/20260604180746_add_session_context_epoch.ts delete mode 100644 packages/core/src/database/migration/20260604181706_add_session_context_replacement.ts delete mode 100644 packages/core/src/database/migration/20260604181807_add_session_context_replacement_sequence.ts rename packages/core/src/database/migration/{20260604181329_add_session_context_updates.ts => 20260604184448_add_session_context_epoch.ts} (54%) diff --git a/packages/core/migration/20260604180746_add_session_context_epoch/migration.sql b/packages/core/migration/20260604180746_add_session_context_epoch/migration.sql deleted file mode 100644 index 7aaf9ecb79c..00000000000 --- a/packages/core/migration/20260604180746_add_session_context_epoch/migration.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE `session_context_epoch` ( - `session_id` text PRIMARY KEY, - `baseline` text NOT NULL, - `checkpoint` text NOT NULL, - `baseline_seq` integer NOT NULL, - CONSTRAINT `fk_session_context_epoch_session_id_session_id_fk` FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE -); diff --git a/packages/core/migration/20260604180746_add_session_context_epoch/snapshot.json b/packages/core/migration/20260604180746_add_session_context_epoch/snapshot.json deleted file mode 100644 index 7ff48041b3f..00000000000 --- a/packages/core/migration/20260604180746_add_session_context_epoch/snapshot.json +++ /dev/null @@ -1,2026 +0,0 @@ -{ - "version": "7", - "dialect": "sqlite", - "id": "f08074bb-2b27-4365-924c-5a4eae9a5194", - "prevIds": [ - "fc92fa34-8074-44c3-88f0-a5417f7fd92d" - ], - "ddl": [ - { - "name": "workspace", - "entityType": "tables" - }, - { - "name": "data_migration", - "entityType": "tables" - }, - { - "name": "account_state", - "entityType": "tables" - }, - { - "name": "account", - "entityType": "tables" - }, - { - "name": "control_account", - "entityType": "tables" - }, - { - "name": "event_sequence", - "entityType": "tables" - }, - { - "name": "event", - "entityType": "tables" - }, - { - "name": "permission", - "entityType": "tables" - }, - { - "name": "project_directory", - "entityType": "tables" - }, - { - "name": "project", - "entityType": "tables" - }, - { - "name": "message", - "entityType": "tables" - }, - { - "name": "part", - "entityType": "tables" - }, - { - "name": "session_context_epoch", - "entityType": "tables" - }, - { - "name": "session_input", - "entityType": "tables" - }, - { - "name": "session_message", - "entityType": "tables" - }, - { - "name": "session", - "entityType": "tables" - }, - { - "name": "todo", - "entityType": "tables" - }, - { - "name": "session_share", - "entityType": "tables" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": "''", - "generated": null, - "name": "name", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "branch", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "extra", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_used", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "name", - "entityType": "columns", - "table": "data_migration" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_completed", - "entityType": "columns", - "table": "data_migration" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active_account_id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active_org_id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "email", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "access_token", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "refresh_token", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "token_expiry", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "email", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "access_token", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "refresh_token", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "token_expiry", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "aggregate_id", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "owner_id", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "aggregate_id", - "entityType": "columns", - "table": "event" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "action", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "resource", - "entityType": "columns", - "table": "permission" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "permission" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "worktree", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "vcs", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "name", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_url", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_url_override", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_color", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_initialized", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "sandboxes", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "commands", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "message_id", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "part" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "part" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "baseline", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "checkpoint", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "baseline_seq", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": true, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "prompt", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "delivery", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "promoted_seq", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "workspace_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "parent_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "slug", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "path", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "title", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "version", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "share_url", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_additions", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_deletions", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_files", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_diffs", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "metadata", - "entityType": "columns", - "table": "session" - }, - { - "type": "real", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "cost", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_input", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_output", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_reasoning", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_cache_read", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_cache_write", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "revert", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "permission", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "agent", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "model", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_compacting", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_archived", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "content", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "status", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "priority", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "position", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "secret", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session_share" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_workspace_project_id_project_id_fk", - "entityType": "fks", - "table": "workspace" - }, - { - "columns": [ - "active_account_id" - ], - "tableTo": "account", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "SET NULL", - "nameExplicit": false, - "name": "fk_account_state_active_account_id_account_id_fk", - "entityType": "fks", - "table": "account_state" - }, - { - "columns": [ - "aggregate_id" - ], - "tableTo": "event_sequence", - "columnsTo": [ - "aggregate_id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_event_aggregate_id_event_sequence_aggregate_id_fk", - "entityType": "fks", - "table": "event" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_permission_project_id_project_id_fk", - "entityType": "fks", - "table": "permission" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_project_directory_project_id_project_id_fk", - "entityType": "fks", - "table": "project_directory" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_message_session_id_session_id_fk", - "entityType": "fks", - "table": "message" - }, - { - "columns": [ - "message_id" - ], - "tableTo": "message", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_part_message_id_message_id_fk", - "entityType": "fks", - "table": "part" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_context_epoch_session_id_session_id_fk", - "entityType": "fks", - "table": "session_context_epoch" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_input_session_id_session_id_fk", - "entityType": "fks", - "table": "session_input" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_message_session_id_session_id_fk", - "entityType": "fks", - "table": "session_message" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_project_id_project_id_fk", - "entityType": "fks", - "table": "session" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_todo_session_id_session_id_fk", - "entityType": "fks", - "table": "todo" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_share_session_id_session_id_fk", - "entityType": "fks", - "table": "session_share" - }, - { - "columns": [ - "email", - "url" - ], - "nameExplicit": false, - "name": "control_account_pk", - "entityType": "pks", - "table": "control_account" - }, - { - "columns": [ - "project_id", - "directory" - ], - "nameExplicit": false, - "name": "project_directory_pk", - "entityType": "pks", - "table": "project_directory" - }, - { - "columns": [ - "session_id", - "position" - ], - "nameExplicit": false, - "name": "todo_pk", - "entityType": "pks", - "table": "todo" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "workspace_pk", - "table": "workspace", - "entityType": "pks" - }, - { - "columns": [ - "name" - ], - "nameExplicit": false, - "name": "data_migration_pk", - "table": "data_migration", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "account_state_pk", - "table": "account_state", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "account_pk", - "table": "account", - "entityType": "pks" - }, - { - "columns": [ - "aggregate_id" - ], - "nameExplicit": false, - "name": "event_sequence_pk", - "table": "event_sequence", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "event_pk", - "table": "event", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "permission_pk", - "table": "permission", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "project_pk", - "table": "project", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "message_pk", - "table": "message", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "part_pk", - "table": "part", - "entityType": "pks" - }, - { - "columns": [ - "session_id" - ], - "nameExplicit": false, - "name": "session_context_epoch_pk", - "table": "session_context_epoch", - "entityType": "pks" - }, - { - "columns": [ - "seq" - ], - "nameExplicit": false, - "name": "session_input_pk", - "table": "session_input", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_message_pk", - "table": "session_message", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_pk", - "table": "session", - "entityType": "pks" - }, - { - "columns": [ - "session_id" - ], - "nameExplicit": false, - "name": "session_share_pk", - "table": "session_share", - "entityType": "pks" - }, - { - "columns": [ - { - "value": "aggregate_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "event_aggregate_seq_idx", - "entityType": "indexes", - "table": "event" - }, - { - "columns": [ - { - "value": "aggregate_id", - "isExpression": false - }, - { - "value": "type", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "event_aggregate_type_seq_idx", - "entityType": "indexes", - "table": "event" - }, - { - "columns": [ - { - "value": "project_id", - "isExpression": false - }, - { - "value": "action", - "isExpression": false - }, - { - "value": "resource", - "isExpression": false - } - ], - "isUnique": true, - "where": null, - "origin": "manual", - "name": "permission_project_action_resource_idx", - "entityType": "indexes", - "table": "permission" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "time_created", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "message_session_time_created_id_idx", - "entityType": "indexes", - "table": "message" - }, - { - "columns": [ - { - "value": "message_id", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "part_message_id_id_idx", - "entityType": "indexes", - "table": "part" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "part_session_idx", - "entityType": "indexes", - "table": "part" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "promoted_seq", - "isExpression": false - }, - { - "value": "delivery", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_input_session_pending_delivery_seq_idx", - "entityType": "indexes", - "table": "session_input" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_seq_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "type", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_type_seq_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "time_created", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_time_created_id_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "time_created", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_time_created_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "project_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_project_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "workspace_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_workspace_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "parent_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_parent_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "todo_session_idx", - "entityType": "indexes", - "table": "todo" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_input_id_unique", - "entityType": "uniques", - "table": "session_input" - } - ], - "renames": [] -} \ No newline at end of file diff --git a/packages/core/migration/20260604181329_add_session_context_updates/migration.sql b/packages/core/migration/20260604181329_add_session_context_updates/migration.sql deleted file mode 100644 index c44ac8ae4ea..00000000000 --- a/packages/core/migration/20260604181329_add_session_context_updates/migration.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE `session_context_message` ( - `session_id` text NOT NULL, - `seq` integer NOT NULL, - `parts` text NOT NULL, - CONSTRAINT `session_context_message_pk` PRIMARY KEY(`session_id`, `seq`), - CONSTRAINT `fk_session_context_message_session_id_session_id_fk` FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE -); ---> statement-breakpoint -ALTER TABLE `session_context_epoch` ADD `revision` integer DEFAULT 0 NOT NULL;--> statement-breakpoint -CREATE INDEX `session_context_message_session_seq_idx` ON `session_context_message` (`session_id`,`seq`); \ No newline at end of file diff --git a/packages/core/migration/20260604181706_add_session_context_replacement/migration.sql b/packages/core/migration/20260604181706_add_session_context_replacement/migration.sql deleted file mode 100644 index 046a793890d..00000000000 --- a/packages/core/migration/20260604181706_add_session_context_replacement/migration.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `session_context_epoch` ADD `replacement_pending` integer DEFAULT false NOT NULL; \ No newline at end of file diff --git a/packages/core/migration/20260604181706_add_session_context_replacement/snapshot.json b/packages/core/migration/20260604181706_add_session_context_replacement/snapshot.json deleted file mode 100644 index c5baf161a05..00000000000 --- a/packages/core/migration/20260604181706_add_session_context_replacement/snapshot.json +++ /dev/null @@ -1,2123 +0,0 @@ -{ - "version": "7", - "dialect": "sqlite", - "id": "5d4aa1b8-68a2-4aca-8890-b40b16679706", - "prevIds": [ - "85667f6a-603f-4041-be9b-783a34eb74d4" - ], - "ddl": [ - { - "name": "workspace", - "entityType": "tables" - }, - { - "name": "data_migration", - "entityType": "tables" - }, - { - "name": "account_state", - "entityType": "tables" - }, - { - "name": "account", - "entityType": "tables" - }, - { - "name": "control_account", - "entityType": "tables" - }, - { - "name": "event_sequence", - "entityType": "tables" - }, - { - "name": "event", - "entityType": "tables" - }, - { - "name": "permission", - "entityType": "tables" - }, - { - "name": "project_directory", - "entityType": "tables" - }, - { - "name": "project", - "entityType": "tables" - }, - { - "name": "message", - "entityType": "tables" - }, - { - "name": "part", - "entityType": "tables" - }, - { - "name": "session_context_epoch", - "entityType": "tables" - }, - { - "name": "session_context_message", - "entityType": "tables" - }, - { - "name": "session_input", - "entityType": "tables" - }, - { - "name": "session_message", - "entityType": "tables" - }, - { - "name": "session", - "entityType": "tables" - }, - { - "name": "todo", - "entityType": "tables" - }, - { - "name": "session_share", - "entityType": "tables" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": "''", - "generated": null, - "name": "name", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "branch", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "extra", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_used", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "name", - "entityType": "columns", - "table": "data_migration" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_completed", - "entityType": "columns", - "table": "data_migration" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active_account_id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active_org_id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "email", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "access_token", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "refresh_token", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "token_expiry", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "email", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "access_token", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "refresh_token", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "token_expiry", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "aggregate_id", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "owner_id", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "aggregate_id", - "entityType": "columns", - "table": "event" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "action", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "resource", - "entityType": "columns", - "table": "permission" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "permission" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "worktree", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "vcs", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "name", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_url", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_url_override", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_color", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_initialized", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "sandboxes", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "commands", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "message_id", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "part" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "part" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "baseline", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "checkpoint", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "baseline_seq", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "false", - "generated": null, - "name": "replacement_pending", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "revision", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_context_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_context_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "parts", - "entityType": "columns", - "table": "session_context_message" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": true, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "prompt", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "delivery", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "promoted_seq", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "workspace_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "parent_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "slug", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "path", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "title", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "version", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "share_url", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_additions", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_deletions", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_files", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_diffs", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "metadata", - "entityType": "columns", - "table": "session" - }, - { - "type": "real", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "cost", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_input", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_output", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_reasoning", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_cache_read", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_cache_write", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "revert", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "permission", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "agent", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "model", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_compacting", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_archived", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "content", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "status", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "priority", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "position", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "secret", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session_share" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_workspace_project_id_project_id_fk", - "entityType": "fks", - "table": "workspace" - }, - { - "columns": [ - "active_account_id" - ], - "tableTo": "account", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "SET NULL", - "nameExplicit": false, - "name": "fk_account_state_active_account_id_account_id_fk", - "entityType": "fks", - "table": "account_state" - }, - { - "columns": [ - "aggregate_id" - ], - "tableTo": "event_sequence", - "columnsTo": [ - "aggregate_id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_event_aggregate_id_event_sequence_aggregate_id_fk", - "entityType": "fks", - "table": "event" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_permission_project_id_project_id_fk", - "entityType": "fks", - "table": "permission" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_project_directory_project_id_project_id_fk", - "entityType": "fks", - "table": "project_directory" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_message_session_id_session_id_fk", - "entityType": "fks", - "table": "message" - }, - { - "columns": [ - "message_id" - ], - "tableTo": "message", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_part_message_id_message_id_fk", - "entityType": "fks", - "table": "part" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_context_epoch_session_id_session_id_fk", - "entityType": "fks", - "table": "session_context_epoch" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_context_message_session_id_session_id_fk", - "entityType": "fks", - "table": "session_context_message" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_input_session_id_session_id_fk", - "entityType": "fks", - "table": "session_input" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_message_session_id_session_id_fk", - "entityType": "fks", - "table": "session_message" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_project_id_project_id_fk", - "entityType": "fks", - "table": "session" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_todo_session_id_session_id_fk", - "entityType": "fks", - "table": "todo" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_share_session_id_session_id_fk", - "entityType": "fks", - "table": "session_share" - }, - { - "columns": [ - "email", - "url" - ], - "nameExplicit": false, - "name": "control_account_pk", - "entityType": "pks", - "table": "control_account" - }, - { - "columns": [ - "project_id", - "directory" - ], - "nameExplicit": false, - "name": "project_directory_pk", - "entityType": "pks", - "table": "project_directory" - }, - { - "columns": [ - "session_id", - "seq" - ], - "nameExplicit": false, - "name": "session_context_message_pk", - "entityType": "pks", - "table": "session_context_message" - }, - { - "columns": [ - "session_id", - "position" - ], - "nameExplicit": false, - "name": "todo_pk", - "entityType": "pks", - "table": "todo" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "workspace_pk", - "table": "workspace", - "entityType": "pks" - }, - { - "columns": [ - "name" - ], - "nameExplicit": false, - "name": "data_migration_pk", - "table": "data_migration", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "account_state_pk", - "table": "account_state", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "account_pk", - "table": "account", - "entityType": "pks" - }, - { - "columns": [ - "aggregate_id" - ], - "nameExplicit": false, - "name": "event_sequence_pk", - "table": "event_sequence", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "event_pk", - "table": "event", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "permission_pk", - "table": "permission", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "project_pk", - "table": "project", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "message_pk", - "table": "message", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "part_pk", - "table": "part", - "entityType": "pks" - }, - { - "columns": [ - "session_id" - ], - "nameExplicit": false, - "name": "session_context_epoch_pk", - "table": "session_context_epoch", - "entityType": "pks" - }, - { - "columns": [ - "seq" - ], - "nameExplicit": false, - "name": "session_input_pk", - "table": "session_input", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_message_pk", - "table": "session_message", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_pk", - "table": "session", - "entityType": "pks" - }, - { - "columns": [ - "session_id" - ], - "nameExplicit": false, - "name": "session_share_pk", - "table": "session_share", - "entityType": "pks" - }, - { - "columns": [ - { - "value": "aggregate_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "event_aggregate_seq_idx", - "entityType": "indexes", - "table": "event" - }, - { - "columns": [ - { - "value": "aggregate_id", - "isExpression": false - }, - { - "value": "type", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "event_aggregate_type_seq_idx", - "entityType": "indexes", - "table": "event" - }, - { - "columns": [ - { - "value": "project_id", - "isExpression": false - }, - { - "value": "action", - "isExpression": false - }, - { - "value": "resource", - "isExpression": false - } - ], - "isUnique": true, - "where": null, - "origin": "manual", - "name": "permission_project_action_resource_idx", - "entityType": "indexes", - "table": "permission" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "time_created", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "message_session_time_created_id_idx", - "entityType": "indexes", - "table": "message" - }, - { - "columns": [ - { - "value": "message_id", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "part_message_id_id_idx", - "entityType": "indexes", - "table": "part" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "part_session_idx", - "entityType": "indexes", - "table": "part" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_context_message_session_seq_idx", - "entityType": "indexes", - "table": "session_context_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "promoted_seq", - "isExpression": false - }, - { - "value": "delivery", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_input_session_pending_delivery_seq_idx", - "entityType": "indexes", - "table": "session_input" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_seq_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "type", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_type_seq_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "time_created", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_time_created_id_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "time_created", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_time_created_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "project_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_project_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "workspace_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_workspace_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "parent_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_parent_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "todo_session_idx", - "entityType": "indexes", - "table": "todo" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_input_id_unique", - "entityType": "uniques", - "table": "session_input" - } - ], - "renames": [] -} \ No newline at end of file diff --git a/packages/core/migration/20260604181807_add_session_context_replacement_sequence/migration.sql b/packages/core/migration/20260604181807_add_session_context_replacement_sequence/migration.sql deleted file mode 100644 index 35ada3e2bc6..00000000000 --- a/packages/core/migration/20260604181807_add_session_context_replacement_sequence/migration.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `session_context_epoch` ADD `replacement_seq` integer; \ No newline at end of file diff --git a/packages/core/migration/20260604181807_add_session_context_replacement_sequence/snapshot.json b/packages/core/migration/20260604181807_add_session_context_replacement_sequence/snapshot.json deleted file mode 100644 index 902c531801c..00000000000 --- a/packages/core/migration/20260604181807_add_session_context_replacement_sequence/snapshot.json +++ /dev/null @@ -1,2133 +0,0 @@ -{ - "version": "7", - "dialect": "sqlite", - "id": "297cd5f2-b759-46d2-b4c1-7490a65dff3a", - "prevIds": [ - "5d4aa1b8-68a2-4aca-8890-b40b16679706" - ], - "ddl": [ - { - "name": "workspace", - "entityType": "tables" - }, - { - "name": "data_migration", - "entityType": "tables" - }, - { - "name": "account_state", - "entityType": "tables" - }, - { - "name": "account", - "entityType": "tables" - }, - { - "name": "control_account", - "entityType": "tables" - }, - { - "name": "event_sequence", - "entityType": "tables" - }, - { - "name": "event", - "entityType": "tables" - }, - { - "name": "permission", - "entityType": "tables" - }, - { - "name": "project_directory", - "entityType": "tables" - }, - { - "name": "project", - "entityType": "tables" - }, - { - "name": "message", - "entityType": "tables" - }, - { - "name": "part", - "entityType": "tables" - }, - { - "name": "session_context_epoch", - "entityType": "tables" - }, - { - "name": "session_context_message", - "entityType": "tables" - }, - { - "name": "session_input", - "entityType": "tables" - }, - { - "name": "session_message", - "entityType": "tables" - }, - { - "name": "session", - "entityType": "tables" - }, - { - "name": "todo", - "entityType": "tables" - }, - { - "name": "session_share", - "entityType": "tables" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": "''", - "generated": null, - "name": "name", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "branch", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "extra", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_used", - "entityType": "columns", - "table": "workspace" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "name", - "entityType": "columns", - "table": "data_migration" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_completed", - "entityType": "columns", - "table": "data_migration" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active_account_id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active_org_id", - "entityType": "columns", - "table": "account_state" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "email", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "access_token", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "refresh_token", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "token_expiry", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "email", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "access_token", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "refresh_token", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "token_expiry", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "active", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "control_account" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "aggregate_id", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "owner_id", - "entityType": "columns", - "table": "event_sequence" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "aggregate_id", - "entityType": "columns", - "table": "event" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "event" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "action", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "resource", - "entityType": "columns", - "table": "permission" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "permission" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "permission" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "project_directory" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "worktree", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "vcs", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "name", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_url", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_url_override", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "icon_color", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "project" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_initialized", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "sandboxes", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "commands", - "entityType": "columns", - "table": "project" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "message" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "message_id", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "part" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "part" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "part" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "baseline", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "checkpoint", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "baseline_seq", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "false", - "generated": null, - "name": "replacement_pending", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "replacement_seq", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "revision", - "entityType": "columns", - "table": "session_context_epoch" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_context_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_context_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "parts", - "entityType": "columns", - "table": "session_context_message" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": true, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "prompt", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "delivery", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "promoted_seq", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_input" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "type", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "seq", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "data", - "entityType": "columns", - "table": "session_message" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "project_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "workspace_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "parent_id", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "slug", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "directory", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "path", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "title", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "version", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "share_url", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_additions", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_deletions", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_files", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "summary_diffs", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "metadata", - "entityType": "columns", - "table": "session" - }, - { - "type": "real", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "cost", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_input", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_output", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_reasoning", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_cache_read", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": "0", - "generated": null, - "name": "tokens_cache_write", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "revert", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "permission", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "agent", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "model", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_compacting", - "entityType": "columns", - "table": "session" - }, - { - "type": "integer", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_archived", - "entityType": "columns", - "table": "session" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "content", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "status", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "priority", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "position", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "todo" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "todo" - }, - { - "type": "text", - "notNull": false, - "autoincrement": false, - "default": null, - "generated": null, - "name": "session_id", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "id", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "secret", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "text", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "url", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_created", - "entityType": "columns", - "table": "session_share" - }, - { - "type": "integer", - "notNull": true, - "autoincrement": false, - "default": null, - "generated": null, - "name": "time_updated", - "entityType": "columns", - "table": "session_share" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_workspace_project_id_project_id_fk", - "entityType": "fks", - "table": "workspace" - }, - { - "columns": [ - "active_account_id" - ], - "tableTo": "account", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "SET NULL", - "nameExplicit": false, - "name": "fk_account_state_active_account_id_account_id_fk", - "entityType": "fks", - "table": "account_state" - }, - { - "columns": [ - "aggregate_id" - ], - "tableTo": "event_sequence", - "columnsTo": [ - "aggregate_id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_event_aggregate_id_event_sequence_aggregate_id_fk", - "entityType": "fks", - "table": "event" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_permission_project_id_project_id_fk", - "entityType": "fks", - "table": "permission" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_project_directory_project_id_project_id_fk", - "entityType": "fks", - "table": "project_directory" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_message_session_id_session_id_fk", - "entityType": "fks", - "table": "message" - }, - { - "columns": [ - "message_id" - ], - "tableTo": "message", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_part_message_id_message_id_fk", - "entityType": "fks", - "table": "part" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_context_epoch_session_id_session_id_fk", - "entityType": "fks", - "table": "session_context_epoch" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_context_message_session_id_session_id_fk", - "entityType": "fks", - "table": "session_context_message" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_input_session_id_session_id_fk", - "entityType": "fks", - "table": "session_input" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_message_session_id_session_id_fk", - "entityType": "fks", - "table": "session_message" - }, - { - "columns": [ - "project_id" - ], - "tableTo": "project", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_project_id_project_id_fk", - "entityType": "fks", - "table": "session" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_todo_session_id_session_id_fk", - "entityType": "fks", - "table": "todo" - }, - { - "columns": [ - "session_id" - ], - "tableTo": "session", - "columnsTo": [ - "id" - ], - "onUpdate": "NO ACTION", - "onDelete": "CASCADE", - "nameExplicit": false, - "name": "fk_session_share_session_id_session_id_fk", - "entityType": "fks", - "table": "session_share" - }, - { - "columns": [ - "email", - "url" - ], - "nameExplicit": false, - "name": "control_account_pk", - "entityType": "pks", - "table": "control_account" - }, - { - "columns": [ - "project_id", - "directory" - ], - "nameExplicit": false, - "name": "project_directory_pk", - "entityType": "pks", - "table": "project_directory" - }, - { - "columns": [ - "session_id", - "seq" - ], - "nameExplicit": false, - "name": "session_context_message_pk", - "entityType": "pks", - "table": "session_context_message" - }, - { - "columns": [ - "session_id", - "position" - ], - "nameExplicit": false, - "name": "todo_pk", - "entityType": "pks", - "table": "todo" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "workspace_pk", - "table": "workspace", - "entityType": "pks" - }, - { - "columns": [ - "name" - ], - "nameExplicit": false, - "name": "data_migration_pk", - "table": "data_migration", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "account_state_pk", - "table": "account_state", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "account_pk", - "table": "account", - "entityType": "pks" - }, - { - "columns": [ - "aggregate_id" - ], - "nameExplicit": false, - "name": "event_sequence_pk", - "table": "event_sequence", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "event_pk", - "table": "event", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "permission_pk", - "table": "permission", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "project_pk", - "table": "project", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "message_pk", - "table": "message", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "part_pk", - "table": "part", - "entityType": "pks" - }, - { - "columns": [ - "session_id" - ], - "nameExplicit": false, - "name": "session_context_epoch_pk", - "table": "session_context_epoch", - "entityType": "pks" - }, - { - "columns": [ - "seq" - ], - "nameExplicit": false, - "name": "session_input_pk", - "table": "session_input", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_message_pk", - "table": "session_message", - "entityType": "pks" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_pk", - "table": "session", - "entityType": "pks" - }, - { - "columns": [ - "session_id" - ], - "nameExplicit": false, - "name": "session_share_pk", - "table": "session_share", - "entityType": "pks" - }, - { - "columns": [ - { - "value": "aggregate_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "event_aggregate_seq_idx", - "entityType": "indexes", - "table": "event" - }, - { - "columns": [ - { - "value": "aggregate_id", - "isExpression": false - }, - { - "value": "type", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "event_aggregate_type_seq_idx", - "entityType": "indexes", - "table": "event" - }, - { - "columns": [ - { - "value": "project_id", - "isExpression": false - }, - { - "value": "action", - "isExpression": false - }, - { - "value": "resource", - "isExpression": false - } - ], - "isUnique": true, - "where": null, - "origin": "manual", - "name": "permission_project_action_resource_idx", - "entityType": "indexes", - "table": "permission" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "time_created", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "message_session_time_created_id_idx", - "entityType": "indexes", - "table": "message" - }, - { - "columns": [ - { - "value": "message_id", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "part_message_id_id_idx", - "entityType": "indexes", - "table": "part" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "part_session_idx", - "entityType": "indexes", - "table": "part" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_context_message_session_seq_idx", - "entityType": "indexes", - "table": "session_context_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "promoted_seq", - "isExpression": false - }, - { - "value": "delivery", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_input_session_pending_delivery_seq_idx", - "entityType": "indexes", - "table": "session_input" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_seq_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "type", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_type_seq_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "time_created", - "isExpression": false - }, - { - "value": "id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_session_time_created_id_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "time_created", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_message_time_created_idx", - "entityType": "indexes", - "table": "session_message" - }, - { - "columns": [ - { - "value": "project_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_project_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "workspace_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_workspace_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "parent_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_parent_idx", - "entityType": "indexes", - "table": "session" - }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "todo_session_idx", - "entityType": "indexes", - "table": "todo" - }, - { - "columns": [ - "id" - ], - "nameExplicit": false, - "name": "session_input_id_unique", - "entityType": "uniques", - "table": "session_input" - } - ], - "renames": [] -} \ No newline at end of file diff --git a/packages/core/migration/20260604184448_add_session_context_epoch/migration.sql b/packages/core/migration/20260604184448_add_session_context_epoch/migration.sql new file mode 100644 index 00000000000..a10df47539c --- /dev/null +++ b/packages/core/migration/20260604184448_add_session_context_epoch/migration.sql @@ -0,0 +1,17 @@ +CREATE TABLE `session_context_epoch` ( + `session_id` text PRIMARY KEY, + `baseline` text NOT NULL, + `checkpoint` text NOT NULL, + `baseline_seq` integer NOT NULL, + `replacement_seq` integer, + `revision` integer DEFAULT 0 NOT NULL, + CONSTRAINT `fk_session_context_epoch_session_id_session_id_fk` FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE +); +--> statement-breakpoint +CREATE TABLE `session_context_message` ( + `session_id` text NOT NULL, + `seq` integer NOT NULL, + `parts` text NOT NULL, + CONSTRAINT `session_context_message_pk` PRIMARY KEY(`session_id`, `seq`), + CONSTRAINT `fk_session_context_message_session_id_session_id_fk` FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE +); diff --git a/packages/core/migration/20260604181329_add_session_context_updates/snapshot.json b/packages/core/migration/20260604184448_add_session_context_epoch/snapshot.json similarity index 98% rename from packages/core/migration/20260604181329_add_session_context_updates/snapshot.json rename to packages/core/migration/20260604184448_add_session_context_epoch/snapshot.json index 32058c614c7..4715fa89fe0 100644 --- a/packages/core/migration/20260604181329_add_session_context_updates/snapshot.json +++ b/packages/core/migration/20260604184448_add_session_context_epoch/snapshot.json @@ -1,9 +1,9 @@ { "version": "7", "dialect": "sqlite", - "id": "85667f6a-603f-4041-be9b-783a34eb74d4", + "id": "6fe30aa9-5772-49a6-b688-d022dbd28903", "prevIds": [ - "f08074bb-2b27-4365-924c-5a4eae9a5194" + "fc92fa34-8074-44c3-88f0-a5417f7fd92d" ], "ddl": [ { @@ -822,6 +822,16 @@ "entityType": "columns", "table": "session_context_epoch" }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "replacement_seq", + "entityType": "columns", + "table": "session_context_epoch" + }, { "type": "integer", "notNull": true, @@ -1923,24 +1933,6 @@ "entityType": "indexes", "table": "part" }, - { - "columns": [ - { - "value": "session_id", - "isExpression": false - }, - { - "value": "seq", - "isExpression": false - } - ], - "isUnique": false, - "where": null, - "origin": "manual", - "name": "session_context_message_session_seq_idx", - "entityType": "indexes", - "table": "session_context_message" - }, { "columns": [ { diff --git a/packages/core/src/database/migration.gen.ts b/packages/core/src/database/migration.gen.ts index 2bb36b01a73..e0d8d04bfec 100644 --- a/packages/core/src/database/migration.gen.ts +++ b/packages/core/src/database/migration.gen.ts @@ -32,9 +32,6 @@ export const migrations = ( import("./migration/20260603141458_session_input_inbox"), import("./migration/20260603160727_jittery_ezekiel_stane"), import("./migration/20260604172448_event_sourced_session_input"), - import("./migration/20260604180746_add_session_context_epoch"), - import("./migration/20260604181329_add_session_context_updates"), - import("./migration/20260604181706_add_session_context_replacement"), - import("./migration/20260604181807_add_session_context_replacement_sequence"), + import("./migration/20260604184448_add_session_context_epoch"), ]) ).map((module) => module.default) satisfies DatabaseMigration.Migration[] diff --git a/packages/core/src/database/migration/20260604180746_add_session_context_epoch.ts b/packages/core/src/database/migration/20260604180746_add_session_context_epoch.ts deleted file mode 100644 index 3bc87317f95..00000000000 --- a/packages/core/src/database/migration/20260604180746_add_session_context_epoch.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Effect } from "effect" -import type { DatabaseMigration } from "../migration" - -export default { - id: "20260604180746_add_session_context_epoch", - up(tx) { - return Effect.gen(function* () { - yield* tx.run(` - CREATE TABLE \`session_context_epoch\` ( - \`session_id\` text PRIMARY KEY, - \`baseline\` text NOT NULL, - \`checkpoint\` text NOT NULL, - \`baseline_seq\` integer NOT NULL, - CONSTRAINT \`fk_session_context_epoch_session_id_session_id_fk\` FOREIGN KEY (\`session_id\`) REFERENCES \`session\`(\`id\`) ON DELETE CASCADE - ); - `) - }) - }, -} satisfies DatabaseMigration.Migration diff --git a/packages/core/src/database/migration/20260604181706_add_session_context_replacement.ts b/packages/core/src/database/migration/20260604181706_add_session_context_replacement.ts deleted file mode 100644 index 69040dc61de..00000000000 --- a/packages/core/src/database/migration/20260604181706_add_session_context_replacement.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Effect } from "effect" -import type { DatabaseMigration } from "../migration" - -export default { - id: "20260604181706_add_session_context_replacement", - up(tx) { - return Effect.gen(function* () { - yield* tx.run(`ALTER TABLE \`session_context_epoch\` ADD \`replacement_pending\` integer DEFAULT false NOT NULL;`) - }) - }, -} satisfies DatabaseMigration.Migration diff --git a/packages/core/src/database/migration/20260604181807_add_session_context_replacement_sequence.ts b/packages/core/src/database/migration/20260604181807_add_session_context_replacement_sequence.ts deleted file mode 100644 index 5298c0d6448..00000000000 --- a/packages/core/src/database/migration/20260604181807_add_session_context_replacement_sequence.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Effect } from "effect" -import type { DatabaseMigration } from "../migration" - -export default { - id: "20260604181807_add_session_context_replacement_sequence", - up(tx) { - return Effect.gen(function* () { - yield* tx.run(`ALTER TABLE \`session_context_epoch\` ADD \`replacement_seq\` integer;`) - }) - }, -} satisfies DatabaseMigration.Migration diff --git a/packages/core/src/database/migration/20260604181329_add_session_context_updates.ts b/packages/core/src/database/migration/20260604184448_add_session_context_epoch.ts similarity index 54% rename from packages/core/src/database/migration/20260604181329_add_session_context_updates.ts rename to packages/core/src/database/migration/20260604184448_add_session_context_epoch.ts index 6988aa8fbd9..45ff9e53358 100644 --- a/packages/core/src/database/migration/20260604181329_add_session_context_updates.ts +++ b/packages/core/src/database/migration/20260604184448_add_session_context_epoch.ts @@ -2,9 +2,20 @@ import { Effect } from "effect" import type { DatabaseMigration } from "../migration" export default { - id: "20260604181329_add_session_context_updates", + id: "20260604184448_add_session_context_epoch", up(tx) { return Effect.gen(function* () { + yield* tx.run(` + CREATE TABLE \`session_context_epoch\` ( + \`session_id\` text PRIMARY KEY, + \`baseline\` text NOT NULL, + \`checkpoint\` text NOT NULL, + \`baseline_seq\` integer NOT NULL, + \`replacement_seq\` integer, + \`revision\` integer DEFAULT 0 NOT NULL, + CONSTRAINT \`fk_session_context_epoch_session_id_session_id_fk\` FOREIGN KEY (\`session_id\`) REFERENCES \`session\`(\`id\`) ON DELETE CASCADE + ); + `) yield* tx.run(` CREATE TABLE \`session_context_message\` ( \`session_id\` text NOT NULL, @@ -14,10 +25,6 @@ export default { CONSTRAINT \`fk_session_context_message_session_id_session_id_fk\` FOREIGN KEY (\`session_id\`) REFERENCES \`session\`(\`id\`) ON DELETE CASCADE ); `) - yield* tx.run(`ALTER TABLE \`session_context_epoch\` ADD \`revision\` integer DEFAULT 0 NOT NULL;`) - yield* tx.run( - `CREATE INDEX \`session_context_message_session_seq_idx\` ON \`session_context_message\` (\`session_id\`,\`seq\`);`, - ) }) }, } satisfies DatabaseMigration.Migration diff --git a/packages/core/src/session/context-epoch.ts b/packages/core/src/session/context-epoch.ts index ed37c2794b9..dec7e564d20 100644 --- a/packages/core/src/session/context-epoch.ts +++ b/packages/core/src/session/context-epoch.ts @@ -1,6 +1,6 @@ export * as SessionContextEpoch from "./context-epoch" -import { and, eq, sql } from "drizzle-orm" +import { and, eq, isNull, lt, sql } from "drizzle-orm" import { DateTime, Effect, Schema } from "effect" import type { Database } from "../database/database" import { EventV2 } from "../event" @@ -24,28 +24,33 @@ export const prepare = Effect.fn("SessionContextEpoch.prepare")(function* ( const stored = yield* find(db, sessionID) if (!stored) { const initialized = SystemContext.initialize(snapshot) - yield* events.publish(SessionEvent.ContextInitialized, { + const event = yield* events.publish(SessionEvent.ContextInitialized, { sessionID, timestamp: yield* DateTime.now, baseline: initialized.baseline, checkpoint: initialized.checkpoint, }) - return initialized.baseline + if (event.seq === undefined) return yield* Effect.die("Synchronized Session event is missing aggregate sequence") + return { baseline: initialized.baseline, baselineSeq: event.seq } } - if (stored.replacement_pending) { + if (stored.replacement_seq !== null) { + if (SystemContext.replacementBlocked(snapshot, stored.checkpoint)) + return { baseline: stored.baseline, baselineSeq: stored.baseline_seq } const initialized = SystemContext.initialize(snapshot) - yield* events.publish(SessionEvent.ContextReplaced, { + const event = yield* events.publish(SessionEvent.ContextReplaced, { sessionID, timestamp: yield* DateTime.now, expectedRevision: stored.revision, baseline: initialized.baseline, checkpoint: initialized.checkpoint, }) - return initialized.baseline + if (event.seq === undefined) return yield* Effect.die("Synchronized Session event is missing aggregate sequence") + return { baseline: initialized.baseline, baselineSeq: event.seq } } const refreshed = SystemContext.refresh(snapshot, stored.checkpoint) - if (sameCheckpoint(refreshed.checkpoint, stored.checkpoint)) return stored.baseline + if (sameCheckpoint(refreshed.checkpoint, stored.checkpoint)) + return { baseline: stored.baseline, baselineSeq: stored.baseline_seq } yield* events.publish(SessionEvent.ContextUpdated, { sessionID, timestamp: yield* DateTime.now, @@ -53,7 +58,7 @@ export const prepare = Effect.fn("SessionContextEpoch.prepare")(function* ( parts: refreshed.changes, checkpoint: refreshed.checkpoint, }) - return stored.baseline + return { baseline: stored.baseline, baselineSeq: stored.baseline_seq } }) export const find = Effect.fn("SessionContextEpoch.find")(function* (db: DatabaseService, sessionID: SessionSchema.ID) { @@ -84,7 +89,6 @@ export const projectInitialized = Effect.fn("SessionContextEpoch.projectInitiali baseline: event.data.baseline, checkpoint: event.data.checkpoint, baseline_seq: seq, - replacement_pending: false, replacement_seq: null, revision: 0, }) @@ -99,7 +103,9 @@ export const projectUpdated = Effect.fn("SessionContextEpoch.projectUpdated")(fu ) { const stored = yield* find(db, event.data.sessionID) if (!stored) return yield* Effect.die("Session context epoch is not initialized") - if (stored.replacement_pending) return yield* Effect.die("Session context epoch replacement is pending") + if (stored.baseline_seq > seq) return yield* Effect.void + if (stored.replacement_seq !== null && seq >= stored.replacement_seq) + return yield* Effect.die("Session context epoch replacement is pending") if (stored.revision > event.data.expectedRevision) { if (event.data.parts.length === 0) return yield* Effect.void const projected = yield* db @@ -141,8 +147,9 @@ export const projectReplaced = Effect.fn("SessionContextEpoch.projectReplaced")( ) { const stored = yield* find(db, event.data.sessionID) if (!stored) return yield* Effect.die("Session context epoch is not initialized") - if (!stored.replacement_pending) { - if (stored.baseline_seq === seq && sameBaseline(stored.baseline, event.data.baseline)) return yield* Effect.void + if (stored.baseline_seq > seq) return yield* Effect.void + if (stored.baseline_seq === seq && sameBaseline(stored.baseline, event.data.baseline)) return yield* Effect.void + if (stored.replacement_seq === null) { return yield* Effect.die("Session context epoch replacement was not requested") } const updated = yield* db @@ -151,7 +158,6 @@ export const projectReplaced = Effect.fn("SessionContextEpoch.projectReplaced")( baseline: event.data.baseline, checkpoint: event.data.checkpoint, baseline_seq: seq, - replacement_pending: false, replacement_seq: null, revision: event.data.expectedRevision + 1, }) @@ -173,12 +179,16 @@ export const requestReplacement = Effect.fn("SessionContextEpoch.requestReplacem sessionID: SessionSchema.ID, seq: number, ) { - const stored = yield* find(db, sessionID) - if (!stored || stored.baseline_seq >= seq || stored.replacement_seq === seq) return yield* Effect.void return yield* db .update(SessionContextEpochTable) - .set({ replacement_pending: true, replacement_seq: seq, revision: sql`${SessionContextEpochTable.revision} + 1` }) - .where(eq(SessionContextEpochTable.session_id, sessionID)) + .set({ replacement_seq: seq, revision: sql`${SessionContextEpochTable.revision} + 1` }) + .where( + and( + eq(SessionContextEpochTable.session_id, sessionID), + isNull(SessionContextEpochTable.replacement_seq), + lt(SessionContextEpochTable.baseline_seq, seq), + ), + ) .run() .pipe(Effect.orDie) }) diff --git a/packages/core/src/session/context.ts b/packages/core/src/session/context.ts index 4f4634529c3..d4fa8769bba 100644 --- a/packages/core/src/session/context.ts +++ b/packages/core/src/session/context.ts @@ -4,7 +4,7 @@ import { Database } from "../database/database" import { MessageDecodeError } from "./error" import { SessionMessage } from "./message" import { SessionSchema } from "./schema" -import { SessionContextEpochTable, SessionContextMessageTable, SessionMessageTable } from "./sql" +import { SessionContextMessageTable, SessionMessageTable } from "./sql" import type { SystemContext } from "../system-context" type DatabaseService = Database.Interface["db"] @@ -65,24 +65,14 @@ export const load = Effect.fn("SessionContext.load")(function* (db: DatabaseServ export const loadForRunner = Effect.fn("SessionContext.loadForRunner")(function* ( db: DatabaseService, sessionID: SessionSchema.ID, + baselineSeq: number, ) { const compaction = yield* latestCompaction(db, sessionID) const messages = yield* messageRows(db, sessionID, compaction) - const epoch = yield* db - .select({ baselineSeq: SessionContextEpochTable.baseline_seq }) - .from(SessionContextEpochTable) - .where(eq(SessionContextEpochTable.session_id, sessionID)) - .get() - .pipe(Effect.orDie) const updates = yield* db .select() .from(SessionContextMessageTable) - .where( - and( - eq(SessionContextMessageTable.session_id, sessionID), - epoch ? gt(SessionContextMessageTable.seq, epoch.baselineSeq) : undefined, - ), - ) + .where(and(eq(SessionContextMessageTable.session_id, sessionID), gt(SessionContextMessageTable.seq, baselineSeq))) .orderBy(asc(SessionContextMessageTable.seq)) .all() .pipe(Effect.orDie) diff --git a/packages/core/src/session/runner/llm.ts b/packages/core/src/session/runner/llm.ts index 8d7db38157e..087fe0a3287 100644 --- a/packages/core/src/session/runner/llm.ts +++ b/packages/core/src/session/runner/llm.ts @@ -98,8 +98,11 @@ export const layer = Layer.effect( const getContext = Effect.fn("SessionRunner.getContext")(function* (sessionID: SessionSchema.ID) { return yield* store.context(sessionID) }) - const getRunnerContext = Effect.fn("SessionRunner.getRunnerContext")(function* (sessionID: SessionSchema.ID) { - return yield* store.runnerContext(sessionID) + const getRunnerContext = Effect.fn("SessionRunner.getRunnerContext")(function* ( + sessionID: SessionSchema.ID, + baselineSeq: number, + ) { + return yield* store.runnerContext(sessionID, baselineSeq) }) const failInterruptedTools = Effect.fn("SessionRunner.failInterruptedTools")(function* ( @@ -132,9 +135,10 @@ export const layer = Layer.effect( cause.reasons.some((reason) => Cause.isDieReason(reason) && reason.defect instanceof QuestionV2.RejectedError) const runTurn = Effect.fn("SessionRunner.runTurn")(function* ( - session: SessionSchema.Info, + sessionID: SessionSchema.ID, promotion: "steer" | "queue" | undefined, ) { + const session = yield* getSession(sessionID) const model = yield* models.resolve(session) const toolFibers = yield* FiberSet.make() let needsContinuation = false @@ -146,12 +150,11 @@ export const layer = Layer.effect( yield* SessionInput.promoteSteers(db, events, session.id, cutoff) } } - yield* failInterruptedTools(session.id) const system = yield* SessionContextEpoch.prepare(db, events, systemContext, session.id) - const context = yield* getRunnerContext(session.id) + const context = yield* getRunnerContext(session.id, system.baselineSeq) const request = LLM.request({ model, - system: system.map((part) => SystemPart.make(part.text)), + system: system.baseline.map((part) => SystemPart.make(part.text)), messages: toLLMMessages(context, model), tools: yield* tools.definitions(), }) @@ -251,12 +254,13 @@ export const layer = Layer.effect( const hasSteer = yield* SessionInput.hasPending(db, input.sessionID, "steer") const hasQueue = hasSteer ? false : yield* SessionInput.hasPending(db, input.sessionID, "queue") if (input.force !== true && !hasSteer && !hasQueue) return + yield* failInterruptedTools(input.sessionID) let promotion: "steer" | "queue" | undefined = hasSteer ? "steer" : hasQueue ? "queue" : undefined let openActivity = input.force === true || hasSteer || hasQueue while (openActivity) { let needsContinuation = true for (let step = 0; step < MAX_STEPS; step++) { - needsContinuation = yield* runTurn(session, promotion) + needsContinuation = yield* runTurn(session.id, promotion) promotion = "steer" if (!needsContinuation) needsContinuation = yield* SessionInput.hasPending(db, input.sessionID, "steer") if (!needsContinuation) break diff --git a/packages/core/src/session/runner/to-llm-message.ts b/packages/core/src/session/runner/to-llm-message.ts index e2ee07516ce..82020c85385 100644 --- a/packages/core/src/session/runner/to-llm-message.ts +++ b/packages/core/src/session/runner/to-llm-message.ts @@ -10,7 +10,6 @@ import { import { SessionMessage } from "../message" import type { FileAttachment } from "../prompt" import { SessionContext } from "../context" -import { SystemContext } from "../../system-context" const media = (file: FileAttachment): ContentPart => ({ type: "media", @@ -134,7 +133,7 @@ function toLLMMessage(message: SessionContext.RunnerMessage, model: Model): Mess }), ] case "system-context": - return [Message.system(SystemContext.render(message.parts))] + return [Message.system(message.parts.map((part) => ({ type: "text", text: part.text })))] } } diff --git a/packages/core/src/session/sql.ts b/packages/core/src/session/sql.ts index fd73a164ac1..5564610d188 100644 --- a/packages/core/src/session/sql.ts +++ b/packages/core/src/session/sql.ts @@ -171,7 +171,6 @@ export const SessionContextEpochTable = sqliteTable("session_context_epoch", { baseline: text({ mode: "json" }).notNull().$type>(), checkpoint: text({ mode: "json" }).notNull().$type(), baseline_seq: integer().notNull(), - replacement_pending: integer({ mode: "boolean" }).notNull().default(false), replacement_seq: integer(), revision: integer().notNull().default(0), }) @@ -186,8 +185,5 @@ export const SessionContextMessageTable = sqliteTable( seq: integer().notNull(), parts: text({ mode: "json" }).notNull().$type>(), }, - (table) => [ - primaryKey({ columns: [table.session_id, table.seq] }), - index("session_context_message_session_seq_idx").on(table.session_id, table.seq), - ], + (table) => [primaryKey({ columns: [table.session_id, table.seq] })], ) diff --git a/packages/core/src/session/store.ts b/packages/core/src/session/store.ts index b262a774952..ad60c56d416 100644 --- a/packages/core/src/session/store.ts +++ b/packages/core/src/session/store.ts @@ -15,6 +15,7 @@ export interface Interface { readonly context: (sessionID: SessionSchema.ID) => Effect.Effect readonly runnerContext: ( sessionID: SessionSchema.ID, + baselineSeq: number, ) => Effect.Effect readonly message: ( messageID: SessionMessage.ID, @@ -37,8 +38,8 @@ export const layer = Layer.effect( context: Effect.fn("SessionStore.context")(function* (sessionID) { return yield* SessionContext.load(db, sessionID) }), - runnerContext: Effect.fn("SessionStore.runnerContext")(function* (sessionID) { - return yield* SessionContext.loadForRunner(db, sessionID) + runnerContext: Effect.fn("SessionStore.runnerContext")(function* (sessionID, baselineSeq) { + return yield* SessionContext.loadForRunner(db, sessionID, baselineSeq) }), message: Effect.fn("SessionStore.message")(function* (messageID) { const row = yield* db diff --git a/packages/core/src/system-context.ts b/packages/core/src/system-context.ts index ac52cfda91e..67aa6ad75d0 100644 --- a/packages/core/src/system-context.ts +++ b/packages/core/src/system-context.ts @@ -54,7 +54,7 @@ export const PartSchema = Schema.Struct({ text: Schema.String, }) export const PartsSchema = Schema.Array(PartSchema) -export const CheckpointSchema = Schema.Record(Schema.String, Schema.String) +export const CheckpointSchema = Schema.Record(Key, Schema.String) export type Checkpoint = Readonly> @@ -111,6 +111,7 @@ export function initialize(snapshot: Snapshot): Initialized { } export function refresh(snapshot: Snapshot, previous: Checkpoint): Refreshed { + const keys = new Set(snapshot.entries.map((entry) => entry.key)) return { changes: [ ...snapshot.entries.flatMap((entry) => @@ -119,18 +120,15 @@ export function refresh(snapshot: Snapshot, previous: Checkpoint): Refreshed { : [], ), ...Object.keys(previous).flatMap((key) => - snapshot.entries.some((entry) => entry.key === key) - ? [] - : [{ key: Key.make(key), text: `System context component removed: ${key}` }], + keys.has(Key.make(key)) ? [] : [{ key: Key.make(key), text: `System context component removed: ${key}` }], ), ], checkpoint: nextCheckpoint(snapshot, previous), } } -export function render(parts: ReadonlyArray) { - return parts.map((part) => part.text).join("\n\n") -} +export const replacementBlocked = (snapshot: Snapshot, previous: Checkpoint) => + snapshot.entries.some((entry) => entry._tag === "Unavailable" && getCheckpoint(previous, entry.key) !== undefined) function nextCheckpoint(snapshot: Snapshot, previous: Checkpoint) { return Object.fromEntries( diff --git a/packages/core/test/database-migration.test.ts b/packages/core/test/database-migration.test.ts index 366ea7e495d..d840c2c6d86 100644 --- a/packages/core/test/database-migration.test.ts +++ b/packages/core/test/database-migration.test.ts @@ -69,16 +69,15 @@ describe("DatabaseMigration", () => { expect( yield* db.get(sql`SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'session_context_message'`), ).toEqual({ name: "session_context_message" }) - expect(yield* db.get(sql`SELECT count(*) as count FROM migration`)).toEqual({ count: 34 }) + expect(yield* db.get(sql`SELECT count(*) as count FROM migration`)).toEqual({ count: 31 }) expect( yield* db.all( - sql`SELECT name FROM sqlite_master WHERE type = 'index' AND name IN ('event_aggregate_seq_idx', 'event_aggregate_type_seq_idx', 'session_context_message_session_seq_idx', 'session_input_session_pending_seq_idx', 'session_input_session_pending_delivery_seq_idx', 'session_input_session_admitted_seq_idx', 'session_input_session_promoted_seq_idx', 'session_message_session_idx', 'session_message_session_type_idx', 'session_message_session_seq_idx', 'session_message_session_type_seq_idx', 'session_message_session_time_created_id_idx') ORDER BY name`, + sql`SELECT name FROM sqlite_master WHERE type = 'index' AND name IN ('event_aggregate_seq_idx', 'event_aggregate_type_seq_idx', 'session_input_session_pending_seq_idx', 'session_input_session_pending_delivery_seq_idx', 'session_input_session_admitted_seq_idx', 'session_input_session_promoted_seq_idx', 'session_message_session_idx', 'session_message_session_type_idx', 'session_message_session_seq_idx', 'session_message_session_type_seq_idx', 'session_message_session_time_created_id_idx') ORDER BY name`, ), ).toEqual([ { name: "event_aggregate_seq_idx" }, { name: "event_aggregate_type_seq_idx" }, { name: "session_input_session_admitted_seq_idx" }, - { name: "session_context_message_session_seq_idx" }, { name: "session_input_session_pending_delivery_seq_idx" }, { name: "session_input_session_promoted_seq_idx" }, { name: "session_message_session_seq_idx" }, diff --git a/packages/core/test/session-runner-message.test.ts b/packages/core/test/session-runner-message.test.ts index 259e0a28167..e00346cd1ee 100644 --- a/packages/core/test/session-runner-message.test.ts +++ b/packages/core/test/session-runner-message.test.ts @@ -90,10 +90,23 @@ describe("toLLMMessages", () => { test("maps hidden Session context updates into chronological system messages", () => { expect( toLLMMessages( - [{ type: "system-context", parts: [{ key: SystemContext.Key.make("test/context"), text: "Updated context" }] }], + [ + { + type: "system-context", + parts: [ + { key: SystemContext.Key.make("test/context"), text: "Updated context" }, + { key: SystemContext.Key.make("test/other"), text: "Other context" }, + ], + }, + ], model, ), - ).toEqual([Message.system("Updated context")]) + ).toEqual([ + Message.system([ + { type: "text", text: "Updated context" }, + { type: "text", text: "Other context" }, + ]), + ]) }) test("expands assistant tool calls and settled outcomes into canonical tool messages", () => { diff --git a/packages/core/test/session-runner.test.ts b/packages/core/test/session-runner.test.ts index 1f8d4a2317b..7b31b913580 100644 --- a/packages/core/test/session-runner.test.ts +++ b/packages/core/test/session-runner.test.ts @@ -57,6 +57,7 @@ let streamStarted: Deferred.Deferred | undefined let streamFailure: LLMError | undefined let toolExecutionGate: Deferred.Deferred | undefined let toolExecutionsStarted: Deferred.Deferred | undefined +let toolExecutionsReady = 5 let activeToolExecutions = 0 let maxActiveToolExecutions = 0 const client = Layer.succeed( @@ -85,6 +86,7 @@ const client = Layer.succeed( }), ) const model = Model.make({ id: "fake-model", provider: "fake", route: OpenAIChat.route }) +const replacementModel = Model.make({ id: "replacement", provider: "fake", route: OpenAIChat.route }) const authorizations: ToolRegistry.AuthorizeInput[] = [] const executions: string[] = [] const permission = Layer.succeed( @@ -118,7 +120,7 @@ const echo = Layer.effectDiscard( executions.push(text) activeToolExecutions++ maxActiveToolExecutions = Math.max(maxActiveToolExecutions, activeToolExecutions) - if (activeToolExecutions === 5 && toolExecutionsStarted) { + if (activeToolExecutions === toolExecutionsReady && toolExecutionsStarted) { yield* Deferred.succeed(toolExecutionsStarted, undefined) } if (toolExecutionGate) yield* Deferred.await(toolExecutionGate) @@ -137,10 +139,13 @@ const echo = Layer.effectDiscard( }), ), ).pipe(Layer.provide(registry)) -const models = SessionRunnerModel.layerWith(() => Effect.succeed(model)) +const models = SessionRunnerModel.layerWith((session) => + Effect.succeed(session.model?.id === "replacement" ? replacementModel : model), +) const systemContextKey = SystemContext.Key.make("test/context") let systemBaseline = "Initial context" let systemRemoved = false +let systemUnavailable = false const systemContext = Layer.succeed( SessionSystemContext.Service, SessionSystemContext.Service.of({ @@ -148,15 +153,17 @@ const systemContext = Layer.succeed( Effect.sync(() => ({ entries: systemRemoved ? [] - : [ - { - _tag: "Available" as const, - key: systemContextKey, - baseline: systemBaseline, - update: systemBaseline, - hash: Hash.sha256(systemBaseline), - }, - ], + : systemUnavailable + ? [{ _tag: "Unavailable" as const, key: systemContextKey }] + : [ + { + _tag: "Available" as const, + key: systemContextKey, + baseline: systemBaseline, + update: systemBaseline, + hash: Hash.sha256(systemBaseline), + }, + ], })), }), ) @@ -229,6 +236,7 @@ const setup = Effect.gen(function* () { response = [] systemBaseline = "Initial context" systemRemoved = false + systemUnavailable = false responses = undefined streamFailure = undefined responseStream = undefined @@ -236,6 +244,7 @@ const setup = Effect.gen(function* () { streamStarted = undefined toolExecutionGate = undefined toolExecutionsStarted = undefined + toolExecutionsReady = 5 activeToolExecutions = 0 maxActiveToolExecutions = 0 yield* db @@ -656,6 +665,105 @@ describe("SessionRunnerLLM", () => { }), ) + it.effect("defers replacement while admitted context is temporarily unavailable", () => + Effect.gen(function* () { + yield* setup + const session = yield* SessionV2.Service + const events = yield* EventV2.Service + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false }) + + requests.length = 0 + response = [] + yield* session.resume(sessionID) + yield* events.publish(SessionEvent.ModelSwitched, { + sessionID, + timestamp: DateTime.makeUnsafe(1), + model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") }, + }) + systemUnavailable = true + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false }) + yield* session.resume(sessionID) + systemUnavailable = false + systemBaseline = "Replacement context" + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false }) + yield* session.resume(sessionID) + + expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([ + ["Initial context"], + ["Initial context"], + ["Replacement context"], + ]) + const { db } = yield* Database.Service + expect( + yield* db + .select({ id: EventTable.id }) + .from(EventTable) + .where(eq(EventTable.type, "session.next.context.replaced.1")) + .all() + .pipe(Effect.orDie), + ).toHaveLength(1) + }), + ) + + it.effect("replays retained context projections while replacement is pending", () => + Effect.gen(function* () { + yield* setup + const session = yield* SessionV2.Service + const events = yield* EventV2.Service + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false }) + + requests.length = 0 + response = [] + yield* session.resume(sessionID) + systemBaseline = "Changed context" + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false }) + yield* session.resume(sessionID) + yield* events.publish(SessionEvent.ModelSwitched, { + sessionID, + timestamp: DateTime.makeUnsafe(1), + model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") }, + }) + + yield* replaySessionProjection(sessionID) + systemBaseline = "Replacement context" + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false }) + yield* session.resume(sessionID) + expect(requests.at(-1)?.system.map((part) => part.text)).toEqual(["Replacement context"]) + }), + ) + + it.effect("replays retained context projections after multiple replacements", () => + Effect.gen(function* () { + yield* setup + const session = yield* SessionV2.Service + const events = yield* EventV2.Service + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "First" }), resume: false }) + + requests.length = 0 + response = [] + yield* session.resume(sessionID) + yield* events.publish(SessionEvent.ModelSwitched, { + sessionID, + timestamp: DateTime.makeUnsafe(1), + model: { id: ModelV2.ID.make("replacement-1"), providerID: ProviderV2.ID.make("fake") }, + }) + systemBaseline = "Replacement context 1" + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Second" }), resume: false }) + yield* session.resume(sessionID) + yield* events.publish(SessionEvent.ModelSwitched, { + sessionID, + timestamp: DateTime.makeUnsafe(2), + model: { id: ModelV2.ID.make("replacement-2"), providerID: ProviderV2.ID.make("fake") }, + }) + systemBaseline = "Replacement context 2" + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Third" }), resume: false }) + yield* session.resume(sessionID) + + yield* replaySessionProjection(sessionID) + expect(requests.at(-1)?.system.map((part) => part.text)).toEqual(["Replacement context 2"]) + }), + ) + it.effect("replaces the baseline lazily after completed compaction without reopening replacement on replay", () => Effect.gen(function* () { yield* setup @@ -863,6 +971,49 @@ describe("SessionRunnerLLM", () => { }), ) + it.effect("reloads a model switch before a tool-driven continuation turn", () => + Effect.gen(function* () { + yield* setup + const session = yield* SessionV2.Service + const events = yield* EventV2.Service + yield* session.prompt({ sessionID, prompt: new Prompt({ text: "Echo this" }), resume: false }) + + requests.length = 0 + responses = [ + [ + LLMEvent.stepStart({ index: 0 }), + LLMEvent.toolCall({ id: "call-echo", name: "echo", input: { text: "hello" } }), + LLMEvent.stepFinish({ index: 0, reason: "tool-calls" }), + LLMEvent.finish({ reason: "tool-calls" }), + ], + [ + LLMEvent.stepStart({ index: 0 }), + LLMEvent.stepFinish({ index: 0, reason: "stop" }), + LLMEvent.finish({ reason: "stop" }), + ], + ] + toolExecutionGate = yield* Deferred.make() + toolExecutionsStarted = yield* Deferred.make() + toolExecutionsReady = 1 + const run = yield* Effect.forkChild(session.resume(sessionID)) + yield* Deferred.await(toolExecutionsStarted) + yield* events.publish(SessionEvent.ModelSwitched, { + sessionID, + timestamp: DateTime.makeUnsafe(1), + model: { id: ModelV2.ID.make("replacement"), providerID: ProviderV2.ID.make("fake") }, + }) + systemBaseline = "Replacement context" + yield* Deferred.succeed(toolExecutionGate, undefined) + yield* Fiber.join(run) + + expect(requests.map((request) => request.model)).toEqual([model, replacementModel]) + expect(requests.map((request) => request.system.map((part) => part.text))).toEqual([ + ["Initial context"], + ["Replacement context"], + ]) + }), + ) + it.effect("restores durable reasoning provider metadata in a second-turn request", () => Effect.gen(function* () { yield* setup diff --git a/packages/core/test/system-context.test.ts b/packages/core/test/system-context.test.ts index 406d4f8c629..92acf5ad30f 100644 --- a/packages/core/test/system-context.test.ts +++ b/packages/core/test/system-context.test.ts @@ -69,7 +69,6 @@ describe("SystemContext", () => { "core/skills": Hash.sha256("Available skills: effect"), }, }) - expect(SystemContext.render(refreshed.changes)).toBe("The current date is 2026-06-04.\n\nAvailable skills: effect") }) test("omits unavailable initial context and admits it after its first successful load", async () => { @@ -112,6 +111,23 @@ describe("SystemContext", () => { expect(refreshed).toEqual({ changes: [], checkpoint: previous }) }) + test("blocks replacement while admitted context is unavailable", async () => { + const previous = { "core/remote-instructions": Hash.sha256("Remote instructions: old") } + const snapshot = await Effect.runPromise( + SystemContext.load( + SystemContext.struct({ + remote: SystemContext.value({ + key: key("core/remote-instructions"), + load: Effect.succeed(SystemContext.unavailable), + }), + }), + ), + ) + + expect(SystemContext.replacementBlocked(snapshot, previous)).toBe(true) + expect(SystemContext.replacementBlocked(snapshot, {})).toBe(false) + }) + test("emits tombstones and drops checkpoints for removed components", async () => { const context = SystemContext.struct({ date: SystemContext.value({ @@ -185,4 +201,13 @@ describe("SystemContext", () => { expect(() => decode("date")).toThrow() expect(() => decode("core/")).toThrow() }) + + test("requires namespaced checkpoint keys", () => { + const decode = Schema.decodeUnknownSync(SystemContext.CheckpointSchema) + const valid = JSON.parse('{"core/date":"hash"}') + const invalid = JSON.parse('{"date":"hash"}') + + expect(decode(valid)).toEqual(valid) + expect(() => decode(invalid)).toThrow() + }) }) diff --git a/packages/llm/src/protocols/anthropic-messages.ts b/packages/llm/src/protocols/anthropic-messages.ts index c83cd7288be..366e1107929 100644 --- a/packages/llm/src/protocols/anthropic-messages.ts +++ b/packages/llm/src/protocols/anthropic-messages.ts @@ -386,7 +386,7 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* ( for (const [index, message] of request.messages.entries()) { if (message.role === "system") { - yield* ProviderShared.guardSystemUpdatePlacement("Anthropic Messages", request.messages[index - 1]) + yield* ProviderShared.guardSystemUpdatePlacement("Anthropic Messages", request.messages, index) if (supportsNativeSystemUpdates(request) && canUseNativeSystemUpdate(request.messages, index)) { messages.push(yield* lowerNativeSystemUpdate(message, breakpoints)) continue diff --git a/packages/llm/src/protocols/bedrock-converse.ts b/packages/llm/src/protocols/bedrock-converse.ts index 52affab7b90..097fb195e4f 100644 --- a/packages/llm/src/protocols/bedrock-converse.ts +++ b/packages/llm/src/protocols/bedrock-converse.ts @@ -294,7 +294,7 @@ const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* ( for (const [index, message] of request.messages.entries()) { if (message.role === "system") { - yield* ProviderShared.guardSystemUpdatePlacement("Bedrock Converse", request.messages[index - 1]) + yield* ProviderShared.guardSystemUpdatePlacement("Bedrock Converse", request.messages, index) const part = yield* ProviderShared.wrappedSystemUpdate("Bedrock Converse", message) const content = textWithCache(breakpoints, part.text, part.cache) const previous = messages.at(-1) diff --git a/packages/llm/src/protocols/gemini.ts b/packages/llm/src/protocols/gemini.ts index 5b3487b0263..b0348074e24 100644 --- a/packages/llm/src/protocols/gemini.ts +++ b/packages/llm/src/protocols/gemini.ts @@ -202,7 +202,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR for (const [index, message] of request.messages.entries()) { if (message.role === "system") { - yield* ProviderShared.guardSystemUpdatePlacement("Gemini", request.messages[index - 1]) + yield* ProviderShared.guardSystemUpdatePlacement("Gemini", request.messages, index) const part = yield* ProviderShared.wrappedSystemUpdate("Gemini", message) const previous = contents.at(-1) if (previous?.role === "user") diff --git a/packages/llm/src/protocols/openai-chat.ts b/packages/llm/src/protocols/openai-chat.ts index 00ad65c9670..9f07179c3df 100644 --- a/packages/llm/src/protocols/openai-chat.ts +++ b/packages/llm/src/protocols/openai-chat.ts @@ -254,7 +254,7 @@ const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request: const messages = [...system] for (const [index, message] of request.messages.entries()) { if (message.role === "system") { - yield* ProviderShared.guardSystemUpdatePlacement("OpenAI Chat", request.messages[index - 1]) + yield* ProviderShared.guardSystemUpdatePlacement("OpenAI Chat", request.messages, index) const part = yield* ProviderShared.wrappedSystemUpdate("OpenAI Chat", message) const previous = messages.at(-1) if (previous?.role === "user") diff --git a/packages/llm/src/protocols/openai-responses.ts b/packages/llm/src/protocols/openai-responses.ts index 400f4e7a6b0..f20dc07e7a9 100644 --- a/packages/llm/src/protocols/openai-responses.ts +++ b/packages/llm/src/protocols/openai-responses.ts @@ -340,7 +340,7 @@ const lowerMessages = Effect.fn("OpenAIResponses.lowerMessages")(function* (requ for (const [index, message] of request.messages.entries()) { if (message.role === "system") { - yield* ProviderShared.guardSystemUpdatePlacement("OpenAI Responses", request.messages[index - 1]) + yield* ProviderShared.guardSystemUpdatePlacement("OpenAI Responses", request.messages, index) const part = yield* ProviderShared.wrappedSystemUpdate("OpenAI Responses", message) const previous = input.at(-1) if (previous && "role" in previous && previous.role === "user") diff --git a/packages/llm/src/protocols/shared.ts b/packages/llm/src/protocols/shared.ts index 98323a7ffed..980870952b4 100644 --- a/packages/llm/src/protocols/shared.ts +++ b/packages/llm/src/protocols/shared.ts @@ -179,12 +179,18 @@ export const wrappedSystemUpdate = Effect.fn("ProviderShared.wrappedSystemUpdate export const guardSystemUpdatePlacement = Effect.fn("ProviderShared.guardSystemUpdatePlacement")(function* ( route: string, - previous: LLMRequest["messages"][number] | undefined, + messages: LLMRequest["messages"], + index: number, ) { - if ( - previous?.role === "assistant" && - previous.content.some((part) => part.type === "tool-call" && part.providerExecuted !== true) - ) + const pending = new Set() + for (const message of messages.slice(0, index)) { + for (const part of message.content) { + if (message.role === "assistant" && part.type === "tool-call" && part.providerExecuted !== true) + pending.add(part.id) + if (message.role === "tool" && part.type === "tool-result") pending.delete(part.id) + } + } + if (pending.size > 0) return yield* invalidRequest( `${route} chronological system updates cannot appear between a local tool call and its tool result`, ) diff --git a/packages/llm/test/schema.test.ts b/packages/llm/test/schema.test.ts index b824544d0b3..0dbf90f2823 100644 --- a/packages/llm/test/schema.test.ts +++ b/packages/llm/test/schema.test.ts @@ -65,12 +65,28 @@ describe("llm schema", () => { }) test("rejects chronological system updates between a local tool call and its result", async () => { - const previous = Message.assistant([ - ToolCallPart.make({ id: "call_1", name: "lookup", input: {} }), - { type: "text", text: "Waiting." }, - ]) + const messages = [ + Message.assistant([ + ToolCallPart.make({ id: "call_1", name: "lookup", input: {} }), + { type: "text", text: "Waiting." }, + ]), + ] - await expect(Effect.runPromise(ProviderShared.guardSystemUpdatePlacement("Test", previous))).rejects.toThrow( + await expect(Effect.runPromise(ProviderShared.guardSystemUpdatePlacement("Test", messages, 1))).rejects.toThrow( + "Test chronological system updates cannot appear between a local tool call and its tool result", + ) + }) + + test("rejects chronological system updates between results for multiple local tool calls", async () => { + const messages = [ + Message.assistant([ + ToolCallPart.make({ id: "call_1", name: "lookup", input: {} }), + ToolCallPart.make({ id: "call_2", name: "lookup", input: {} }), + ]), + Message.tool({ id: "call_1", name: "lookup", result: "first" }), + ] + + await expect(Effect.runPromise(ProviderShared.guardSystemUpdatePlacement("Test", messages, 2))).rejects.toThrow( "Test chronological system updates cannot appear between a local tool call and its tool result", ) }) diff --git a/specs/v2/schema-changelog.md b/specs/v2/schema-changelog.md index a2db44a13ae..441435eb5dc 100644 --- a/specs/v2/schema-changelog.md +++ b/specs/v2/schema-changelog.md @@ -703,7 +703,7 @@ Change: Compatibility: -- This adds one database migration and one synchronized Session event type. +- The unpublished Context Epoch schema is consolidated into one database migration and this adds one synchronized Session event type. - Existing experimental V2 Session databases remain disposable across incompatible pre-launch event-schema changes. - Chronological context updates, replacement epochs after compaction or model switches, project instructions, skills guidance, and plugin transforms remain follow-up slices. @@ -719,13 +719,13 @@ Change: - Refresh Location-scoped Context Components at each safe provider-turn boundary. - Keep the stored baseline immutable while admitting changed component values as runner-private chronological `Message.system(...)` history. -- Advance component-hash checkpoints transactionally even when a removed component produces no visible update text. +- Emit an explicit tombstone update and advance component-hash checkpoints transactionally when a component is removed. - Keep ordinary Session transcript APIs unchanged while runner history merges visible Session messages and hidden context updates by durable aggregate sequence. - Reject chronological system updates that would split a local tool call from its result across provider protocols; use wrapped user fallback when Anthropic native system-update placement is unsupported. Compatibility: -- This adds one database migration and one synchronized Session event type. +- The unpublished Context Epoch schema remains consolidated into one database migration and this adds one synchronized Session event type. - Existing experimental V2 Session databases remain disposable across incompatible pre-launch event-schema changes. - Replacement epochs after compaction or model switches, project instructions, skills guidance, and plugin transforms remain follow-up slices. @@ -734,7 +734,7 @@ Compatibility: Affected schema: - Add synchronized `session.next.context.replaced.1` Session events. -- Add `session_context_epoch.replacement_pending` and `session_context_epoch.replacement_seq` for idempotent lazy replacement requests. +- Add nullable `session_context_epoch.replacement_seq` for idempotent lazy replacement requests. Change: @@ -745,6 +745,6 @@ Change: Compatibility: -- This adds two additive database migrations and one synchronized Session event type. +- The unpublished Context Epoch schema remains consolidated into one database migration and this adds one synchronized Session event type. - Existing experimental V2 Session databases remain disposable across incompatible pre-launch event-schema changes. - Compaction execution, project instructions, skills guidance, and plugin transforms remain follow-up slices.