Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
131 lines
5.9 KiB
Go
131 lines
5.9 KiB
Go
package storesqlite
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
)
|
|
|
|
func (s *Store) applyWorkspaceAgentSessionEntitiesV3(ctx context.Context) error {
|
|
applied, err := s.hasMigration(ctx, schemaMigrationWorkspaceAgentSessionEntitiesV3)
|
|
if err != nil || applied {
|
|
return err
|
|
}
|
|
conn, err := s.db.Conn(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("open connection for workspace agent session entities v3: %w", err)
|
|
}
|
|
defer conn.Close()
|
|
if _, err := conn.ExecContext(ctx, `PRAGMA foreign_keys = OFF`); err != nil {
|
|
return fmt.Errorf("disable foreign keys for workspace agent session entities v3: %w", err)
|
|
}
|
|
defer func() { _, _ = conn.ExecContext(ctx, `PRAGMA foreign_keys = ON`) }()
|
|
return runInConnTx(ctx, conn, func(tx *sql.Tx) error {
|
|
if err := ensureSessionEntitySourceColumnsTx(ctx, tx); err != nil {
|
|
return err
|
|
}
|
|
if _, err := tx.ExecContext(ctx, `
|
|
CREATE TABLE workspace_agent_sessions_v3 (
|
|
workspace_id TEXT NOT NULL,
|
|
agent_session_id TEXT NOT NULL,
|
|
origin TEXT NOT NULL DEFAULT '',
|
|
user_id TEXT NOT NULL DEFAULT '',
|
|
agent_target_id TEXT,
|
|
provider TEXT NOT NULL DEFAULT '',
|
|
provider_session_id TEXT NOT NULL DEFAULT '',
|
|
model TEXT NOT NULL DEFAULT '',
|
|
settings_json TEXT NOT NULL DEFAULT '{}',
|
|
session_metadata_json TEXT NOT NULL DEFAULT '{"visible":true,"imported":false,"capabilities":[]}'
|
|
CHECK (json_valid(session_metadata_json)
|
|
AND json_type(session_metadata_json, '$.visible') IN ('true','false')
|
|
AND json_type(session_metadata_json, '$.imported') IN ('true','false')
|
|
AND json_type(session_metadata_json, '$.capabilities') = 'array'
|
|
AND (json_type(session_metadata_json, '$.goal') IS NULL OR json_type(session_metadata_json, '$.goal') IN ('null','object'))),
|
|
internal_runtime_context_json TEXT NOT NULL DEFAULT '{}'
|
|
CHECK (json_valid(internal_runtime_context_json) AND json_type(internal_runtime_context_json) = 'object'),
|
|
cwd TEXT NOT NULL DEFAULT '',
|
|
rail_section_kind TEXT NOT NULL DEFAULT 'conversations',
|
|
rail_project_path TEXT NOT NULL DEFAULT '',
|
|
rail_section_key TEXT NOT NULL DEFAULT 'conversations',
|
|
title TEXT NOT NULL DEFAULT '',
|
|
message_version INTEGER NOT NULL DEFAULT 0,
|
|
last_event_at_unix_ms INTEGER NOT NULL DEFAULT 0,
|
|
started_at_unix_ms INTEGER NOT NULL DEFAULT 0,
|
|
ended_at_unix_ms INTEGER NOT NULL DEFAULT 0,
|
|
pinned_at_unix_ms INTEGER NOT NULL DEFAULT 0,
|
|
deleted_at_unix_ms INTEGER NOT NULL DEFAULT 0,
|
|
created_at_unix_ms INTEGER NOT NULL,
|
|
updated_at_unix_ms INTEGER NOT NULL,
|
|
active_turn_id TEXT CHECK (active_turn_id IS NULL OR length(active_turn_id) > 0),
|
|
PRIMARY KEY (workspace_id, agent_session_id),
|
|
FOREIGN KEY (workspace_id, agent_session_id, active_turn_id)
|
|
REFERENCES workspace_agent_turns(workspace_id, agent_session_id, turn_id)
|
|
DEFERRABLE INITIALLY DEFERRED
|
|
);
|
|
INSERT INTO workspace_agent_sessions_v3 (
|
|
workspace_id, agent_session_id, origin, user_id, agent_target_id, provider,
|
|
provider_session_id, model, settings_json, session_metadata_json,
|
|
internal_runtime_context_json, cwd, rail_section_kind, rail_project_path,
|
|
rail_section_key, title, message_version, last_event_at_unix_ms,
|
|
started_at_unix_ms, ended_at_unix_ms, pinned_at_unix_ms, deleted_at_unix_ms,
|
|
created_at_unix_ms, updated_at_unix_ms, active_turn_id
|
|
)
|
|
SELECT workspace_id, agent_session_id, origin, user_id, agent_target_id, provider,
|
|
provider_session_id, model, settings_json, session_metadata_json,
|
|
internal_runtime_context_json, cwd, rail_section_kind, rail_project_path,
|
|
rail_section_key, title, message_version, last_event_at_unix_ms,
|
|
started_at_unix_ms, ended_at_unix_ms, pinned_at_unix_ms, deleted_at_unix_ms,
|
|
created_at_unix_ms, updated_at_unix_ms, NULLIF(TRIM(active_turn_id), '')
|
|
FROM workspace_agent_sessions;
|
|
DROP TABLE workspace_agent_sessions;
|
|
ALTER TABLE workspace_agent_sessions_v3 RENAME TO workspace_agent_sessions;
|
|
CREATE INDEX idx_workspace_agent_sessions_workspace_updated
|
|
ON workspace_agent_sessions(workspace_id, deleted_at_unix_ms, updated_at_unix_ms);
|
|
CREATE INDEX idx_workspace_agent_sessions_rail_section_page
|
|
ON workspace_agent_sessions(workspace_id, rail_section_key, deleted_at_unix_ms, updated_at_unix_ms DESC, agent_session_id ASC);
|
|
`); err != nil {
|
|
return fmt.Errorf("migrate workspace agent session entities v3: %w", err)
|
|
}
|
|
return recordMigrationTx(ctx, tx, schemaMigrationWorkspaceAgentSessionEntitiesV3)
|
|
})
|
|
}
|
|
|
|
func ensureSessionEntitySourceColumnsTx(ctx context.Context, tx *sql.Tx) error {
|
|
columns := []struct{ name, definition string }{
|
|
{"origin", "TEXT NOT NULL DEFAULT ''"},
|
|
{"user_id", "TEXT NOT NULL DEFAULT ''"},
|
|
{"agent_target_id", "TEXT"},
|
|
{"provider", "TEXT NOT NULL DEFAULT ''"},
|
|
{"provider_session_id", "TEXT NOT NULL DEFAULT ''"},
|
|
{"model", "TEXT NOT NULL DEFAULT ''"},
|
|
{"settings_json", "TEXT NOT NULL DEFAULT '{}'"},
|
|
{"cwd", "TEXT NOT NULL DEFAULT ''"},
|
|
{"rail_section_kind", "TEXT NOT NULL DEFAULT 'conversations'"},
|
|
{"rail_project_path", "TEXT NOT NULL DEFAULT ''"},
|
|
{"rail_section_key", "TEXT NOT NULL DEFAULT 'conversations'"},
|
|
{"title", "TEXT NOT NULL DEFAULT ''"},
|
|
{"message_version", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"last_event_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"started_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"ended_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"pinned_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"deleted_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"created_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"updated_at_unix_ms", "INTEGER NOT NULL DEFAULT 0"},
|
|
{"active_turn_id", "TEXT"},
|
|
}
|
|
for _, column := range columns {
|
|
exists, err := hasColumnTx(ctx, tx, "workspace_agent_sessions", column.name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if exists {
|
|
continue
|
|
}
|
|
if _, err := tx.ExecContext(ctx, `ALTER TABLE workspace_agent_sessions ADD COLUMN `+column.name+` `+column.definition); err != nil {
|
|
return fmt.Errorf("add workspace agent session entity source column %s: %w", column.name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|