Files
tutti/packages/agent/store-sqlite/migrations_session_entities.go
agent-radar 2ed3415fb7
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
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

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
}