| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- import { sqliteTable, text, integer, index, primaryKey, real, uniqueIndex } from "drizzle-orm/sqlite-core"
- import * as DatabasePath from "../database/path"
- import { ProjectTable } from "../project/sql"
- import type { SessionMessage } from "./message"
- import type { Prompt } from "./prompt"
- import type { SessionInput } from "./input"
- import type { Snapshot } from "../snapshot"
- import { PermissionV1 } from "../v1/permission"
- import { ProjectV2 } from "../project"
- import type { SessionSchema } from "./schema"
- import type { MessageID, PartID, SessionV1 } from "../v1/session"
- import { WorkspaceV2 } from "../workspace"
- import { Timestamps } from "../database/schema.sql"
- import type { SystemContext } from "../system-context/index"
- import { AgentV2 } from "../agent"
- import type { Revert } from "@opencode-ai/schema/revert"
- type SessionMessageData = Omit<(typeof SessionMessage.Message)["Encoded"], "type" | "id">
- type V1MessageData = Omit<SessionV1.Info, "id" | "sessionID">
- type V1PartData = Omit<SessionV1.Part, "id" | "sessionID" | "messageID">
- export const SessionTable = sqliteTable(
- "session",
- {
- id: text().$type<SessionSchema.ID>().primaryKey(),
- project_id: text()
- .$type<ProjectV2.ID>()
- .notNull()
- .references(() => ProjectTable.id, { onDelete: "cascade" }),
- workspace_id: text().$type<WorkspaceV2.ID>(),
- parent_id: text().$type<SessionSchema.ID>(),
- slug: text().notNull(),
- directory: DatabasePath.directoryColumn().notNull(),
- path: DatabasePath.pathColumn(),
- title: text().notNull(),
- version: text().notNull(),
- share_url: text(),
- summary_additions: integer(),
- summary_deletions: integer(),
- summary_files: integer(),
- summary_diffs: text({ mode: "json" }).$type<Snapshot.LegacyFileDiff[]>(),
- metadata: text({ mode: "json" }).$type<Record<string, unknown>>(),
- cost: real().notNull().default(0),
- tokens_input: integer().notNull().default(0),
- tokens_output: integer().notNull().default(0),
- tokens_reasoning: integer().notNull().default(0),
- tokens_cache_read: integer().notNull().default(0),
- tokens_cache_write: integer().notNull().default(0),
- revert: text({ mode: "json" }).$type<Revert.State>(),
- permission: text({ mode: "json" }).$type<PermissionV1.Ruleset>(),
- agent: text(),
- model: text({ mode: "json" }).$type<{
- id: string
- providerID: string
- variant?: string
- }>(),
- ...Timestamps,
- time_compacting: integer(),
- time_archived: integer(),
- },
- (table) => [
- index("session_project_idx").on(table.project_id),
- index("session_workspace_idx").on(table.workspace_id),
- index("session_parent_idx").on(table.parent_id),
- ],
- )
- export const MessageTable = sqliteTable(
- "message",
- {
- id: text().$type<MessageID>().primaryKey(),
- session_id: text()
- .$type<SessionSchema.ID>()
- .notNull()
- .references(() => SessionTable.id, { onDelete: "cascade" }),
- ...Timestamps,
- data: text({ mode: "json" }).notNull().$type<V1MessageData>(),
- },
- (table) => [index("message_session_time_created_id_idx").on(table.session_id, table.time_created, table.id)],
- )
- export const PartTable = sqliteTable(
- "part",
- {
- id: text().$type<PartID>().primaryKey(),
- message_id: text()
- .$type<MessageID>()
- .notNull()
- .references(() => MessageTable.id, { onDelete: "cascade" }),
- session_id: text().$type<SessionSchema.ID>().notNull(),
- ...Timestamps,
- data: text({ mode: "json" }).notNull().$type<V1PartData>(),
- },
- (table) => [
- index("part_message_id_id_idx").on(table.message_id, table.id),
- index("part_session_idx").on(table.session_id),
- ],
- )
- export const TodoTable = sqliteTable(
- "todo",
- {
- session_id: text()
- .$type<SessionSchema.ID>()
- .notNull()
- .references(() => SessionTable.id, { onDelete: "cascade" }),
- content: text().notNull(),
- status: text().notNull(),
- priority: text().notNull(),
- position: integer().notNull(),
- ...Timestamps,
- },
- (table) => [
- primaryKey({ columns: [table.session_id, table.position] }),
- index("todo_session_idx").on(table.session_id),
- ],
- )
- export const SessionMessageTable = sqliteTable(
- "session_message",
- {
- id: text().$type<SessionMessage.ID>().primaryKey(),
- session_id: text()
- .$type<SessionSchema.ID>()
- .notNull()
- .references(() => SessionTable.id, { onDelete: "cascade" }),
- type: text().$type<SessionMessage.Type>().notNull(),
- seq: integer().notNull(),
- ...Timestamps,
- data: text({ mode: "json" }).notNull().$type<SessionMessageData>(),
- },
- (table) => [
- uniqueIndex("session_message_session_seq_idx").on(table.session_id, table.seq),
- index("session_message_session_type_seq_idx").on(table.session_id, table.type, table.seq),
- index("session_message_session_time_created_id_idx").on(table.session_id, table.time_created, table.id),
- index("session_message_time_created_idx").on(table.time_created),
- ],
- )
- export const SessionInputTable = sqliteTable(
- "session_input",
- {
- id: text().$type<SessionMessage.ID>().primaryKey(),
- session_id: text()
- .$type<SessionSchema.ID>()
- .notNull()
- .references(() => SessionTable.id, { onDelete: "cascade" }),
- prompt: text({ mode: "json" }).notNull().$type<Prompt>(),
- delivery: text().$type<SessionInput.Delivery>().notNull(),
- admitted_seq: integer().notNull(),
- promoted_seq: integer(),
- time_created: integer()
- .notNull()
- .$default(() => Date.now()),
- },
- (table) => [
- index("session_input_session_pending_delivery_seq_idx").on(
- table.session_id,
- table.promoted_seq,
- table.delivery,
- table.admitted_seq,
- ),
- uniqueIndex("session_input_session_admitted_seq_idx").on(table.session_id, table.admitted_seq),
- uniqueIndex("session_input_session_promoted_seq_idx").on(table.session_id, table.promoted_seq),
- ],
- )
- export const SessionContextEpochTable = sqliteTable("session_context_epoch", {
- session_id: text()
- .$type<SessionSchema.ID>()
- .primaryKey()
- .references(() => SessionTable.id, { onDelete: "cascade" }),
- baseline: text().notNull(),
- snapshot: text({ mode: "json" }).notNull().$type<SystemContext.Snapshot>(),
- baseline_seq: integer().notNull(),
- })
|