ALTER TABLE ias_context_messages ADD COLUMN IF NOT EXISTS raw_message JSONB; ALTER TABLE ias_context_messages ADD COLUMN IF NOT EXISTS external_message_id VARCHAR(255); CREATE UNIQUE INDEX IF NOT EXISTS idx_ias_context_messages_external_unique ON ias_context_messages(session_id, role, external_message_id) WHERE external_message_id IS NOT NULL; WITH ranked AS ( SELECT id, ROW_NUMBER() OVER ( PARTITION BY scope_key ORDER BY started_at DESC, id DESC ) AS rank FROM ias_context_sessions WHERE ended_at IS NULL ) UPDATE ias_context_sessions AS session SET ended_at = last_message_at, end_reason = 'active_session_deduplicated', summary = COALESCE(summary, '创建活跃会话唯一约束时自动结束的重复活跃上下文。') FROM ranked WHERE session.id = ranked.id AND ranked.rank > 1; CREATE UNIQUE INDEX IF NOT EXISTS idx_ias_context_sessions_one_active ON ias_context_sessions(scope_key) WHERE ended_at IS NULL; CREATE TABLE IF NOT EXISTS ias_tool_call_instructions ( id BIGSERIAL PRIMARY KEY, scope_key VARCHAR(768) NOT NULL UNIQUE, channel VARCHAR(64) NOT NULL, account_id VARCHAR(255) NOT NULL, from_user_id VARCHAR(255) NOT NULL, context_label TEXT, content TEXT NOT NULL DEFAULT '', last_reason TEXT, updated_by VARCHAR(64) NOT NULL DEFAULT 'ai', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_ias_tool_call_instructions_scope_updated ON ias_tool_call_instructions(scope_key, updated_at DESC); INSERT INTO ias_tool_call_instructions ( scope_key, channel, account_id, from_user_id, context_label, content, last_reason, updated_by, created_at, updated_at ) SELECT scope_key, channel, account_id, from_user_id, context_label, content, last_reason, updated_by, created_at, updated_at FROM ias_additional_system_prompts WHERE content <> '' ON CONFLICT (scope_key) DO NOTHING;