"""initial_schema Revision ID: 001 Revises: Create Date: 2026-07-09 19:36:42.745763 """ from collections.abc import Sequence import sqlalchemy as sa from alembic import op # revision identifiers, used by Alembic. revision: str = "001" down_revision: str | Sequence[str] | None = None branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None def upgrade() -> None: """Upgrade schema.""" # 天工阁角色名册 op.create_table( "agent_roster", sa.Column("role", sa.String(length=80), nullable=False), sa.Column("name", sa.String(length=120), nullable=False), sa.Column("responsibility", sa.Text(), nullable=False), sa.Column("enabled", sa.Boolean(), nullable=False), sa.Column("last_active_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("role"), ) # 人物主表 op.create_table( "characters", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("name", sa.String(length=120), nullable=False), sa.Column("display_name", sa.String(length=120), nullable=True), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("language", sa.String(length=20), nullable=False), sa.Column("profile_json", sa.Text(), nullable=False), sa.Column("model_policy_json", sa.Text(), nullable=False), sa.Column("safety_policy_id", sa.String(length=80), nullable=True), sa.Column("current_personality_version_id", sa.String(length=80), nullable=True), sa.Column("current_mood_id", sa.String(length=80), nullable=True), sa.Column("privacy_level", sa.String(length=40), nullable=False), sa.Column("owner_scope", sa.String(length=80), nullable=False), sa.Column("is_system_template", sa.Boolean(), nullable=False), sa.Column("source_template_id", sa.String(length=80), nullable=True), sa.Column("template_key", sa.String(length=80), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.Column("activated_at", sa.DateTime(timezone=True), nullable=True), sa.Column("archived_at", sa.DateTime(timezone=True), nullable=True), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_characters_is_system_template"), "characters", ["is_system_template"], unique=False ) op.create_index(op.f("ix_characters_owner_scope"), "characters", ["owner_scope"], unique=False) op.create_index( op.f("ix_characters_source_template_id"), "characters", ["source_template_id"], unique=False ) op.create_index(op.f("ix_characters_status"), "characters", ["status"], unique=False) op.create_index( op.f("ix_characters_template_key"), "characters", ["template_key"], unique=False ) # 生成偏好 op.create_table( "generation_preferences", sa.Column("owner_scope", sa.String(length=80), nullable=False), sa.Column("default_model_hint", sa.String(length=120), nullable=False), sa.Column("temperature", sa.Float(), nullable=False), sa.Column("top_p", sa.Float(), nullable=False), sa.Column("max_output_tokens", sa.Integer(), nullable=False), sa.Column("streaming", sa.Boolean(), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("owner_scope"), ) # 幂等键 op.create_table( "idempotency_keys", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("key", sa.String(length=200), nullable=False), sa.Column("scope", sa.String(length=120), nullable=False), sa.Column("method", sa.String(length=20), nullable=False), sa.Column("path", sa.String(length=500), nullable=False), sa.Column("request_hash", sa.String(length=128), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("response_status_code", sa.Integer(), nullable=False), sa.Column("response_body_json", sa.Text(), nullable=False), sa.Column("resource_type", sa.String(length=80), nullable=True), sa.Column("resource_id", sa.String(length=120), nullable=True), sa.Column("trace_id", sa.String(length=80), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.Column("expires_at", sa.DateTime(timezone=True), nullable=True), sa.PrimaryKeyConstraint("id"), sa.UniqueConstraint("scope", "key", name="uq_idempotency_scope_key"), ) op.create_index( op.f("ix_idempotency_keys_expires_at"), "idempotency_keys", ["expires_at"], unique=False ) op.create_index(op.f("ix_idempotency_keys_key"), "idempotency_keys", ["key"], unique=False) op.create_index(op.f("ix_idempotency_keys_scope"), "idempotency_keys", ["scope"], unique=False) op.create_index( op.f("ix_idempotency_keys_trace_id"), "idempotency_keys", ["trace_id"], unique=False ) # MCP 服务器注册 op.create_table( "mcp_servers", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("name", sa.String(length=120), nullable=False), sa.Column("transport", sa.String(length=40), nullable=False), sa.Column("endpoint_url", sa.String(length=500), nullable=True), sa.Column("auth_token", sa.String(length=500), nullable=True), sa.Column("command", sa.String(length=500), nullable=True), sa.Column("args_json", sa.Text(), nullable=True), sa.Column("env_json", sa.Text(), nullable=True), sa.Column("cwd", sa.String(length=500), nullable=True), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("tools_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("id"), sa.UniqueConstraint("name"), ) op.create_index(op.f("ix_mcp_servers_status"), "mcp_servers", ["status"], unique=False) # 模型端点覆盖 op.create_table( "model_endpoint_overrides", sa.Column("logical_model_name", sa.String(length=120), nullable=False), sa.Column("endpoint_name", sa.String(length=120), nullable=False), sa.Column("base_url", sa.String(length=500), nullable=True), sa.Column("api_key", sa.String(length=500), nullable=True), sa.Column("status", sa.String(length=40), nullable=True), sa.Column("weight", sa.Integer(), nullable=True), sa.Column("priority", sa.Integer(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("logical_model_name", "endpoint_name"), ) # 司命待确认记录 op.create_table( "pending_confirmations", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("tool", sa.String(length=120), nullable=False), sa.Column("input_json", sa.Text(), nullable=False), sa.Column("risk_level", sa.String(length=40), nullable=False), sa.Column("reason", sa.Text(), nullable=False), sa.Column("run_id", sa.String(length=80), nullable=True), sa.Column("character_id", sa.String(length=80), nullable=True), sa.Column("trace_id", sa.String(length=80), nullable=True), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("resolved_at", sa.DateTime(timezone=True), nullable=True), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_pending_confirmations_character_id"), "pending_confirmations", ["character_id"], unique=False, ) op.create_index( op.f("ix_pending_confirmations_run_id"), "pending_confirmations", ["run_id"], unique=False ) op.create_index( op.f("ix_pending_confirmations_status"), "pending_confirmations", ["status"], unique=False ) # 烛照感知通道 op.create_table( "perception_channels", sa.Column("channel", sa.String(length=80), nullable=False), sa.Column("name", sa.String(length=120), nullable=False), sa.Column("description", sa.Text(), nullable=False), sa.Column("enabled", sa.Boolean(), nullable=False), sa.Column("consent_status", sa.String(length=40), nullable=False), sa.Column("privacy_level", sa.String(length=40), nullable=False), sa.Column("risk_level", sa.String(length=20), nullable=False), sa.Column("last_active_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("channel"), ) # Skill 能力包 op.create_table( "skills", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("name", sa.String(length=120), nullable=False), sa.Column("description", sa.Text(), nullable=False), sa.Column("trigger", sa.Text(), nullable=False), sa.Column("prompt_fragment", sa.Text(), nullable=False), sa.Column("tool_bindings_json", sa.Text(), nullable=False), sa.Column("risk_level", sa.String(length=8), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("id"), sa.UniqueConstraint("name"), ) op.create_index(op.f("ix_skills_status"), "skills", ["status"], unique=False) # 工具安全策略 op.create_table( "tool_policies", sa.Column("name", sa.String(length=80), nullable=False), sa.Column("description", sa.Text(), nullable=False), sa.Column("risk_level", sa.String(length=20), nullable=False), sa.Column("permission_policy", sa.String(length=20), nullable=False), sa.Column("side_effect", sa.Boolean(), nullable=False), sa.Column("audit_required", sa.Boolean(), nullable=False), sa.Column("source", sa.String(length=20), nullable=False), sa.Column("enabled", sa.Boolean(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("name"), ) # 用户 op.create_table( "users", sa.Column("id", sa.String(length=40), nullable=False), sa.Column("username", sa.String(length=80), nullable=False), sa.Column("email", sa.String(length=255), nullable=False), sa.Column("password_hash", sa.String(length=255), nullable=False), sa.Column("is_active", sa.Boolean(), nullable=False), sa.Column("is_admin", sa.Boolean(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("id"), sa.UniqueConstraint("email"), ) op.create_index(op.f("ix_users_username"), "users", ["username"], unique=True) # 河图世界实体 op.create_table( "world_entities", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("type", sa.String(length=40), nullable=False), sa.Column("name", sa.String(length=200), nullable=False), sa.Column("attributes_json", sa.Text(), nullable=False), sa.Column("state_type", sa.String(length=40), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("sources_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_index(op.f("ix_world_entities_type"), "world_entities", ["type"], unique=False) # 大周天运行记录 op.create_table( "big_cycles", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("trigger", sa.String(length=40), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("phase", sa.String(length=40), nullable=True), sa.Column("memory_count_at_trigger", sa.Integer(), nullable=False), sa.Column("evaluation_snapshot_json", sa.Text(), nullable=True), sa.Column("summary", sa.Text(), nullable=True), sa.Column("error_code", sa.String(length=80), nullable=True), sa.Column("error_message", sa.Text(), nullable=True), sa.Column("started_at", sa.DateTime(timezone=True), nullable=True), sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_big_cycles_character_id"), "big_cycles", ["character_id"], unique=False ) op.create_index( op.f("ix_big_cycles_completed_at"), "big_cycles", ["completed_at"], unique=False ) op.create_index(op.f("ix_big_cycles_status"), "big_cycles", ["status"], unique=False) # 灵核情绪状态 op.create_table( "character_emotion_states", sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("mood", sa.String(length=40), nullable=False), sa.Column("intensity", sa.Float(), nullable=False), sa.Column("baseline_mood", sa.String(length=40), nullable=False), sa.Column("baseline_intensity", sa.Float(), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.Column("last_trigger_event_id", sa.String(length=80), nullable=True), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("character_id"), ) # 资料导入任务 op.create_table( "character_import_jobs", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("material_type", sa.String(length=40), nullable=False), sa.Column("source_type", sa.String(length=40), nullable=False), sa.Column("title", sa.String(length=200), nullable=True), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("format", sa.String(length=40), nullable=False), sa.Column("media_type", sa.String(length=40), nullable=True), sa.Column("mime_type", sa.String(length=80), nullable=True), sa.Column("source_description", sa.Text(), nullable=True), sa.Column("speaker_label", sa.String(length=120), nullable=True), sa.Column("consent_status", sa.String(length=40), nullable=False), sa.Column("usage_scope", sa.String(length=40), nullable=False), sa.Column("checksum", sa.String(length=120), nullable=True), sa.Column("item_count", sa.Integer(), nullable=False), sa.Column("storage_path", sa.String(length=500), nullable=True), sa.Column("raw_content", sa.Text(), nullable=True), sa.Column("error_code", sa.String(length=80), nullable=True), sa.Column("error_message", sa.Text(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_character_import_jobs_character_id"), "character_import_jobs", ["character_id"], unique=False, ) op.create_index( op.f("ix_character_import_jobs_checksum"), "character_import_jobs", ["checksum"], unique=False, ) op.create_index( op.f("ix_character_import_jobs_material_type"), "character_import_jobs", ["material_type"], unique=False, ) op.create_index( op.f("ix_character_import_jobs_status"), "character_import_jobs", ["status"], unique=False ) # 人物视角世界实体 op.create_table( "character_world_entities", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("type", sa.String(length=40), nullable=False), sa.Column("name", sa.String(length=200), nullable=False), sa.Column("attributes_json", sa.Text(), nullable=False), sa.Column("state_type", sa.String(length=40), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("sources_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_character_world_entities_character_id"), "character_world_entities", ["character_id"], unique=False, ) op.create_index( op.f("ix_character_world_entities_status"), "character_world_entities", ["status"], unique=False, ) op.create_index( op.f("ix_character_world_entities_type"), "character_world_entities", ["type"], unique=False ) # 对话会话 op.create_table( "chat_sessions", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("title", sa.String(length=200), nullable=True), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_chat_sessions_character_id"), "chat_sessions", ["character_id"], unique=False ) op.create_index(op.f("ix_chat_sessions_status"), "chat_sessions", ["status"], unique=False) # 太一目标 op.create_table( "goals", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=True), sa.Column("title", sa.String(length=300), nullable=False), sa.Column("description", sa.Text(), nullable=False), sa.Column("level", sa.String(length=40), nullable=False), sa.Column("type", sa.String(length=40), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("priority", sa.Integer(), nullable=False), sa.Column("progress", sa.Float(), nullable=False), sa.Column("constraints_json", sa.Text(), nullable=False), sa.Column("parent_id", sa.String(length=80), nullable=True), sa.Column("success_criteria_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["parent_id"], ["goals.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index(op.f("ix_goals_character_id"), "goals", ["character_id"], unique=False) op.create_index(op.f("ix_goals_level"), "goals", ["level"], unique=False) op.create_index(op.f("ix_goals_status"), "goals", ["status"], unique=False) # 息壤记忆 op.create_table( "memories", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("type", sa.String(length=60), nullable=False), sa.Column("title", sa.String(length=200), nullable=False), sa.Column("content", sa.Text(), nullable=False), sa.Column("source", sa.String(length=80), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("importance", sa.Float(), nullable=False), sa.Column("sensitivity", sa.String(length=40), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True), sa.Column("expires_at", sa.DateTime(timezone=True), nullable=True), sa.Column("temporal_context_json", sa.Text(), server_default="{}", nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index(op.f("ix_memories_character_id"), "memories", ["character_id"], unique=False) op.create_index(op.f("ix_memories_status"), "memories", ["status"], unique=False) # 人格版本 op.create_table( "personality_versions", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("version", sa.Integer(), nullable=False), sa.Column("identity_profile", sa.Text(), nullable=False), sa.Column("role_destiny", sa.Text(), nullable=False), sa.Column("personality_seed", sa.Text(), nullable=False), sa.Column("traits", sa.Text(), nullable=False), sa.Column("expression_style", sa.Text(), nullable=False), sa.Column("values", sa.Text(), nullable=False), sa.Column("relationship_pattern", sa.Text(), nullable=False), sa.Column("emotion_baseline", sa.Text(), nullable=False), sa.Column("reason", sa.Text(), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("created_by", sa.String(length=80), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("rolled_back_at", sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_personality_versions_character_id"), "personality_versions", ["character_id"], unique=False, ) # 辰正纪念日 op.create_table( "time_anniversaries", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("name", sa.String(length=200), nullable=False), sa.Column("calendar", sa.String(length=20), nullable=False), sa.Column("date", sa.String(length=20), nullable=False), sa.Column("recurs_yearly", sa.Boolean(), nullable=False), sa.Column("kind", sa.String(length=40), nullable=False), sa.Column("subject_type", sa.String(length=40), nullable=False), sa.Column("source", sa.String(length=40), nullable=False), sa.Column("metadata_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_time_anniversaries_character_id"), "time_anniversaries", ["character_id"], unique=False, ) # 档案导入候选 op.create_table( "character_profile_candidates", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("import_job_id", sa.String(length=80), nullable=True), sa.Column("field", sa.String(length=60), nullable=False), sa.Column("value", sa.Text(), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("reason", sa.Text(), nullable=True), sa.Column("reviewed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["import_job_id"], ["character_import_jobs.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_character_profile_candidates_character_id"), "character_profile_candidates", ["character_id"], unique=False, ) op.create_index( op.f("ix_character_profile_candidates_import_job_id"), "character_profile_candidates", ["import_job_id"], unique=False, ) op.create_index( op.f("ix_character_profile_candidates_status"), "character_profile_candidates", ["status"], unique=False, ) # 大周天内驱力·好奇问题 op.create_table( "curiosity_questions", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("cycle_id", sa.String(length=80), nullable=False), sa.Column("question", sa.Text(), nullable=False), sa.Column("source", sa.String(length=60), nullable=False), sa.Column("related_entities_json", sa.Text(), nullable=False), sa.Column("expected_value", sa.Float(), nullable=False), sa.Column("urgency", sa.Float(), nullable=False), sa.Column("risk_level", sa.String(length=8), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["cycle_id"], ["big_cycles.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_curiosity_questions_character_id"), "curiosity_questions", ["character_id"], unique=False, ) op.create_index( op.f("ix_curiosity_questions_cycle_id"), "curiosity_questions", ["cycle_id"], unique=False ) # 演化候选 op.create_table( "evolution_candidates", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("cycle_id", sa.String(length=80), nullable=False), sa.Column("type", sa.String(length=60), nullable=False), sa.Column("source", sa.String(length=60), nullable=False), sa.Column("level", sa.String(length=8), nullable=False), sa.Column("scope", sa.String(length=40), nullable=False), sa.Column("title", sa.String(length=200), nullable=False), sa.Column("proposal", sa.Text(), nullable=False), sa.Column("delta_json", sa.Text(), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("benefit_score", sa.Float(), nullable=False), sa.Column("risk_score", sa.Float(), nullable=False), sa.Column("drift_score", sa.Float(), nullable=False), sa.Column("auto_apply_allowed", sa.Boolean(), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("resulting_target_id", sa.String(length=80), nullable=True), sa.Column("error_message", sa.Text(), nullable=True), sa.Column("reviewed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("reviewed_by", sa.String(length=80), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["cycle_id"], ["big_cycles.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_evolution_candidates_character_id"), "evolution_candidates", ["character_id"], unique=False, ) op.create_index( op.f("ix_evolution_candidates_cycle_id"), "evolution_candidates", ["cycle_id"], unique=False ) op.create_index( op.f("ix_evolution_candidates_status"), "evolution_candidates", ["status"], unique=False ) # 资料导入条目 op.create_table( "import_items", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("import_job_id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("item_type", sa.String(length=40), nullable=False), sa.Column("role", sa.String(length=40), nullable=False), sa.Column("sequence", sa.Integer(), nullable=False), sa.Column("content", sa.Text(), nullable=False), sa.Column("metadata_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["import_job_id"], ["character_import_jobs.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_import_items_character_id"), "import_items", ["character_id"], unique=False ) op.create_index( op.f("ix_import_items_import_job_id"), "import_items", ["import_job_id"], unique=False ) # 记忆候选 op.create_table( "memory_candidates", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("import_job_id", sa.String(length=80), nullable=True), sa.Column("cycle_id", sa.String(length=80), nullable=True), sa.Column("type", sa.String(length=60), nullable=False), sa.Column("title", sa.String(length=200), nullable=False), sa.Column("content", sa.Text(), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("importance", sa.Float(), nullable=False), sa.Column("sensitivity", sa.String(length=40), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("reason", sa.Text(), nullable=True), sa.Column("reviewed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["cycle_id"], ["big_cycles.id"], ), sa.ForeignKeyConstraint( ["import_job_id"], ["character_import_jobs.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_memory_candidates_character_id"), "memory_candidates", ["character_id"], unique=False, ) op.create_index( op.f("ix_memory_candidates_cycle_id"), "memory_candidates", ["cycle_id"], unique=False ) op.create_index( op.f("ix_memory_candidates_import_job_id"), "memory_candidates", ["import_job_id"], unique=False, ) op.create_index( op.f("ix_memory_candidates_status"), "memory_candidates", ["status"], unique=False ) # 记忆关联 op.create_table( "memory_links", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("source_memory_id", sa.String(length=80), nullable=False), sa.Column("target_memory_id", sa.String(length=80), nullable=False), sa.Column("relation", sa.String(length=80), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["source_memory_id"], ["memories.id"], ), sa.ForeignKeyConstraint( ["target_memory_id"], ["memories.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_memory_links_character_id"), "memory_links", ["character_id"], unique=False ) op.create_index( op.f("ix_memory_links_source_memory_id"), "memory_links", ["source_memory_id"], unique=False ) op.create_index( op.f("ix_memory_links_target_memory_id"), "memory_links", ["target_memory_id"], unique=False ) # 人格建议 op.create_table( "personality_proposals", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("fields_json", sa.Text(), nullable=False), sa.Column("reason", sa.Text(), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("resulting_version_id", sa.String(length=80), nullable=True), sa.Column("reviewed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("reviewed_by", sa.String(length=80), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["resulting_version_id"], ["personality_versions.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_personality_proposals_character_id"), "personality_proposals", ["character_id"], unique=False, ) op.create_index( op.f("ix_personality_proposals_status"), "personality_proposals", ["status"], unique=False ) # 洛书计划 op.create_table( "plans", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("goal_id", sa.String(length=80), nullable=True), sa.Column("title", sa.String(length=300), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("assumptions_json", sa.Text(), nullable=False), sa.Column("risks_json", sa.Text(), nullable=False), sa.Column("required_tools_json", sa.Text(), nullable=False), sa.Column("success_criteria_json", sa.Text(), nullable=False), sa.Column("step_count", sa.Integer(), nullable=False), sa.Column("completed_steps", sa.Integer(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["goal_id"], ["goals.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index(op.f("ix_plans_goal_id"), "plans", ["goal_id"], unique=False) op.create_index(op.f("ix_plans_status"), "plans", ["status"], unique=False) # 运行记录 op.create_table( "runs", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("session_id", sa.String(length=80), nullable=True), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("goal", sa.String(length=300), nullable=True), sa.Column("origin", sa.String(length=40), nullable=False), sa.Column("model_hint", sa.String(length=120), nullable=True), sa.Column("started_at", sa.DateTime(timezone=True), nullable=True), sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("error_code", sa.String(length=80), nullable=True), sa.Column("error_message", sa.Text(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["session_id"], ["chat_sessions.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index(op.f("ix_runs_character_id"), "runs", ["character_id"], unique=False) op.create_index(op.f("ix_runs_session_id"), "runs", ["session_id"], unique=False) op.create_index(op.f("ix_runs_status"), "runs", ["status"], unique=False) # 世界关系 op.create_table( "world_relations", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("subject_id", sa.String(length=80), nullable=False), sa.Column("predicate", sa.String(length=120), nullable=False), sa.Column("object_id", sa.String(length=80), nullable=False), sa.Column("confidence", sa.Float(), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["object_id"], ["character_world_entities.id"], ), sa.ForeignKeyConstraint( ["subject_id"], ["character_world_entities.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_world_relations_character_id"), "world_relations", ["character_id"], unique=False ) op.create_index( op.f("ix_world_relations_object_id"), "world_relations", ["object_id"], unique=False ) op.create_index( op.f("ix_world_relations_subject_id"), "world_relations", ["subject_id"], unique=False ) # 起居注审计事件 op.create_table( "audit_events", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("pivot", sa.String(length=40), nullable=True), sa.Column("character_id", sa.String(length=80), nullable=True), sa.Column("run_id", sa.String(length=80), nullable=True), sa.Column("action", sa.String(length=120), nullable=False), sa.Column("actor", sa.String(length=80), nullable=False), sa.Column("risk_level", sa.String(length=20), nullable=False), sa.Column("decision", sa.String(length=40), nullable=False), sa.Column("reason", sa.Text(), nullable=True), sa.Column("input_summary", sa.Text(), nullable=True), sa.Column("output_summary", sa.Text(), nullable=True), sa.Column("trace_id", sa.String(length=80), nullable=True), sa.Column("resource_type", sa.String(length=80), nullable=True), sa.Column("resource_id", sa.String(length=120), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["run_id"], ["runs.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_audit_events_character_id"), "audit_events", ["character_id"], unique=False ) op.create_index(op.f("ix_audit_events_pivot"), "audit_events", ["pivot"], unique=False) op.create_index(op.f("ix_audit_events_run_id"), "audit_events", ["run_id"], unique=False) op.create_index(op.f("ix_audit_events_trace_id"), "audit_events", ["trace_id"], unique=False) # 对话消息 op.create_table( "chat_messages", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("session_id", sa.String(length=80), nullable=False), sa.Column("role", sa.String(length=40), nullable=False), sa.Column("content", sa.Text(), nullable=False), sa.Column("modality", sa.String(length=40), nullable=False), sa.Column("run_id", sa.String(length=80), nullable=True), sa.Column("metadata_json", sa.Text(), nullable=False), sa.Column("sensitivity", sa.String(length=40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["run_id"], ["runs.id"], ), sa.ForeignKeyConstraint( ["session_id"], ["chat_sessions.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_chat_messages_character_id"), "chat_messages", ["character_id"], unique=False ) op.create_index(op.f("ix_chat_messages_run_id"), "chat_messages", ["run_id"], unique=False) op.create_index( op.f("ix_chat_messages_session_id"), "chat_messages", ["session_id"], unique=False ) # 一炁事件 op.create_table( "events", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=True), sa.Column("run_id", sa.String(length=80), nullable=True), sa.Column("type", sa.String(length=80), nullable=False), sa.Column("source", sa.String(length=40), nullable=False), sa.Column("payload_json", sa.Text(), nullable=False), sa.Column("visibility", sa.String(length=40), nullable=False), sa.Column("sensitivity", sa.String(length=40), nullable=False), sa.Column("trace_id", sa.String(length=80), nullable=True), sa.Column("parent_id", sa.String(length=80), nullable=True), sa.Column("sequence", sa.Integer(), nullable=False), sa.Column("evidence_ids_json", sa.Text(), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["run_id"], ["runs.id"], ), sa.PrimaryKeyConstraint("id"), sa.UniqueConstraint("run_id", "sequence", name="uq_events_run_sequence"), ) op.create_index(op.f("ix_events_character_id"), "events", ["character_id"], unique=False) op.create_index(op.f("ix_events_run_id"), "events", ["run_id"], unique=False) op.create_index(op.f("ix_events_trace_id"), "events", ["trace_id"], unique=False) op.create_index(op.f("ix_events_type"), "events", ["type"], unique=False) # 探索性次生目标 op.create_table( "exploratory_subgoals", sa.Column("id", sa.String(length=80), nullable=False), sa.Column("character_id", sa.String(length=80), nullable=False), sa.Column("cycle_id", sa.String(length=80), nullable=False), sa.Column("parent_goal_id", sa.String(length=80), nullable=True), sa.Column("curiosity_question_id", sa.String(length=80), nullable=False), sa.Column("title", sa.String(length=200), nullable=False), sa.Column("description", sa.Text(), nullable=False), sa.Column("expected_information_gain", sa.Float(), nullable=False), sa.Column("interruption_cost", sa.Float(), nullable=False), sa.Column("risk_level", sa.String(length=8), nullable=False), sa.Column("status", sa.String(length=40), nullable=False), sa.Column("reviewed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("reviewed_by", sa.String(length=80), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint( ["character_id"], ["characters.id"], ), sa.ForeignKeyConstraint( ["curiosity_question_id"], ["curiosity_questions.id"], ), sa.ForeignKeyConstraint( ["cycle_id"], ["big_cycles.id"], ), sa.PrimaryKeyConstraint("id"), ) op.create_index( op.f("ix_exploratory_subgoals_character_id"), "exploratory_subgoals", ["character_id"], unique=False, ) op.create_index( op.f("ix_exploratory_subgoals_curiosity_question_id"), "exploratory_subgoals", ["curiosity_question_id"], unique=False, ) op.create_index( op.f("ix_exploratory_subgoals_cycle_id"), "exploratory_subgoals", ["cycle_id"], unique=False ) op.create_index( op.f("ix_exploratory_subgoals_status"), "exploratory_subgoals", ["status"], unique=False ) # RBAC 角色 op.create_table( "roles", sa.Column("id", sa.String(40), nullable=False), sa.Column("name", sa.String(80), nullable=False), sa.Column("description", sa.Text(), nullable=False, server_default=""), sa.Column("is_system", sa.Boolean(), nullable=False, server_default=sa.text("false")), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_roles_name", "roles", ["name"], unique=True) # RBAC 权限 op.create_table( "permissions", sa.Column("id", sa.String(40), nullable=False), sa.Column("resource", sa.String(80), nullable=False), sa.Column("action", sa.String(80), nullable=False), sa.Column("description", sa.Text(), nullable=False, server_default=""), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_permissions_resource", "permissions", ["resource"]) # RBAC 用户-角色关联 op.create_table( "user_roles", sa.Column("user_id", sa.String(40), nullable=False), sa.Column("role_id", sa.String(40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("user_id", "role_id"), sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"), sa.ForeignKeyConstraint(["role_id"], ["roles.id"], ondelete="CASCADE"), ) # RBAC 角色-权限关联 op.create_table( "role_permissions", sa.Column("role_id", sa.String(40), nullable=False), sa.Column("permission_id", sa.String(40), nullable=False), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint("role_id", "permission_id"), sa.ForeignKeyConstraint(["role_id"], ["roles.id"], ondelete="CASCADE"), sa.ForeignKeyConstraint(["permission_id"], ["permissions.id"], ondelete="CASCADE"), ) # 消息版本历史 op.add_column( "chat_messages", sa.Column( "versions_json", sa.Text, nullable=False, server_default="[]", comment="版本历史 JSON 数组:[{content, created_at}],按生成顺序排列,末尾最新", ), ) op.add_column( "chat_messages", sa.Column( "active_version_idx", sa.Integer, nullable=False, server_default=sa.text("0"), comment="当前活跃版本在 versions_json 中的索引(0-based)", ), ) # ### end Alembic commands ### def downgrade() -> None: """Downgrade schema.""" op.drop_column("chat_messages", "active_version_idx") op.drop_column("chat_messages", "versions_json") op.drop_table("role_permissions") op.drop_table("user_roles") op.drop_index("ix_permissions_resource", table_name="permissions") op.drop_table("permissions") op.drop_index("ix_roles_name", table_name="roles") op.drop_table("roles") op.drop_index(op.f("ix_exploratory_subgoals_status"), table_name="exploratory_subgoals") op.drop_index(op.f("ix_exploratory_subgoals_cycle_id"), table_name="exploratory_subgoals") op.drop_index( op.f("ix_exploratory_subgoals_curiosity_question_id"), table_name="exploratory_subgoals" ) op.drop_index(op.f("ix_exploratory_subgoals_character_id"), table_name="exploratory_subgoals") op.drop_table("exploratory_subgoals") op.drop_index(op.f("ix_events_type"), table_name="events") op.drop_index(op.f("ix_events_trace_id"), table_name="events") op.drop_index(op.f("ix_events_run_id"), table_name="events") op.drop_index(op.f("ix_events_character_id"), table_name="events") op.drop_table("events") op.drop_index(op.f("ix_chat_messages_session_id"), table_name="chat_messages") op.drop_index(op.f("ix_chat_messages_run_id"), table_name="chat_messages") op.drop_index(op.f("ix_chat_messages_character_id"), table_name="chat_messages") op.drop_table("chat_messages") op.drop_index(op.f("ix_audit_events_trace_id"), table_name="audit_events") op.drop_index(op.f("ix_audit_events_run_id"), table_name="audit_events") op.drop_index(op.f("ix_audit_events_pivot"), table_name="audit_events") op.drop_index(op.f("ix_audit_events_character_id"), table_name="audit_events") op.drop_table("audit_events") op.drop_index(op.f("ix_world_relations_subject_id"), table_name="world_relations") op.drop_index(op.f("ix_world_relations_object_id"), table_name="world_relations") op.drop_index(op.f("ix_world_relations_character_id"), table_name="world_relations") op.drop_table("world_relations") op.drop_index(op.f("ix_runs_status"), table_name="runs") op.drop_index(op.f("ix_runs_session_id"), table_name="runs") op.drop_index(op.f("ix_runs_character_id"), table_name="runs") op.drop_table("runs") op.drop_index(op.f("ix_plans_status"), table_name="plans") op.drop_index(op.f("ix_plans_goal_id"), table_name="plans") op.drop_table("plans") op.drop_index(op.f("ix_personality_proposals_status"), table_name="personality_proposals") op.drop_index(op.f("ix_personality_proposals_character_id"), table_name="personality_proposals") op.drop_table("personality_proposals") op.drop_index(op.f("ix_memory_links_target_memory_id"), table_name="memory_links") op.drop_index(op.f("ix_memory_links_source_memory_id"), table_name="memory_links") op.drop_index(op.f("ix_memory_links_character_id"), table_name="memory_links") op.drop_table("memory_links") op.drop_index(op.f("ix_memory_candidates_status"), table_name="memory_candidates") op.drop_index(op.f("ix_memory_candidates_import_job_id"), table_name="memory_candidates") op.drop_index(op.f("ix_memory_candidates_cycle_id"), table_name="memory_candidates") op.drop_index(op.f("ix_memory_candidates_character_id"), table_name="memory_candidates") op.drop_table("memory_candidates") op.drop_index(op.f("ix_import_items_import_job_id"), table_name="import_items") op.drop_index(op.f("ix_import_items_character_id"), table_name="import_items") op.drop_table("import_items") op.drop_index(op.f("ix_evolution_candidates_status"), table_name="evolution_candidates") op.drop_index(op.f("ix_evolution_candidates_cycle_id"), table_name="evolution_candidates") op.drop_index(op.f("ix_evolution_candidates_character_id"), table_name="evolution_candidates") op.drop_table("evolution_candidates") op.drop_index(op.f("ix_curiosity_questions_cycle_id"), table_name="curiosity_questions") op.drop_index(op.f("ix_curiosity_questions_character_id"), table_name="curiosity_questions") op.drop_table("curiosity_questions") op.drop_index( op.f("ix_character_profile_candidates_status"), table_name="character_profile_candidates" ) op.drop_index( op.f("ix_character_profile_candidates_import_job_id"), table_name="character_profile_candidates", ) op.drop_index( op.f("ix_character_profile_candidates_character_id"), table_name="character_profile_candidates", ) op.drop_table("character_profile_candidates") op.drop_index(op.f("ix_time_anniversaries_character_id"), table_name="time_anniversaries") op.drop_table("time_anniversaries") op.drop_index(op.f("ix_personality_versions_character_id"), table_name="personality_versions") op.drop_table("personality_versions") op.drop_index(op.f("ix_memories_status"), table_name="memories") op.drop_index(op.f("ix_memories_character_id"), table_name="memories") op.drop_table("memories") op.drop_index(op.f("ix_goals_status"), table_name="goals") op.drop_index(op.f("ix_goals_level"), table_name="goals") op.drop_index(op.f("ix_goals_character_id"), table_name="goals") op.drop_table("goals") op.drop_index(op.f("ix_chat_sessions_status"), table_name="chat_sessions") op.drop_index(op.f("ix_chat_sessions_character_id"), table_name="chat_sessions") op.drop_table("chat_sessions") op.drop_index(op.f("ix_character_world_entities_type"), table_name="character_world_entities") op.drop_index(op.f("ix_character_world_entities_status"), table_name="character_world_entities") op.drop_index( op.f("ix_character_world_entities_character_id"), table_name="character_world_entities" ) op.drop_table("character_world_entities") op.drop_index(op.f("ix_character_import_jobs_status"), table_name="character_import_jobs") op.drop_index( op.f("ix_character_import_jobs_material_type"), table_name="character_import_jobs" ) op.drop_index(op.f("ix_character_import_jobs_checksum"), table_name="character_import_jobs") op.drop_index(op.f("ix_character_import_jobs_character_id"), table_name="character_import_jobs") op.drop_table("character_import_jobs") op.drop_table("character_emotion_states") op.drop_index(op.f("ix_big_cycles_status"), table_name="big_cycles") op.drop_index(op.f("ix_big_cycles_completed_at"), table_name="big_cycles") op.drop_index(op.f("ix_big_cycles_character_id"), table_name="big_cycles") op.drop_table("big_cycles") op.drop_index(op.f("ix_world_entities_type"), table_name="world_entities") op.drop_table("world_entities") op.drop_index(op.f("ix_users_username"), table_name="users") op.drop_table("users") op.drop_table("tool_policies") op.drop_index(op.f("ix_skills_status"), table_name="skills") op.drop_table("skills") op.drop_table("perception_channels") op.drop_index(op.f("ix_pending_confirmations_status"), table_name="pending_confirmations") op.drop_index(op.f("ix_pending_confirmations_run_id"), table_name="pending_confirmations") op.drop_index(op.f("ix_pending_confirmations_character_id"), table_name="pending_confirmations") op.drop_table("pending_confirmations") op.drop_table("model_endpoint_overrides") op.drop_index(op.f("ix_mcp_servers_status"), table_name="mcp_servers") op.drop_table("mcp_servers") op.drop_index(op.f("ix_idempotency_keys_trace_id"), table_name="idempotency_keys") op.drop_index(op.f("ix_idempotency_keys_scope"), table_name="idempotency_keys") op.drop_index(op.f("ix_idempotency_keys_key"), table_name="idempotency_keys") op.drop_index(op.f("ix_idempotency_keys_expires_at"), table_name="idempotency_keys") op.drop_table("idempotency_keys") op.drop_table("generation_preferences") op.drop_index(op.f("ix_characters_template_key"), table_name="characters") op.drop_index(op.f("ix_characters_status"), table_name="characters") op.drop_index(op.f("ix_characters_source_template_id"), table_name="characters") op.drop_index(op.f("ix_characters_owner_scope"), table_name="characters") op.drop_index(op.f("ix_characters_is_system_template"), table_name="characters") op.drop_table("characters") op.drop_table("agent_roster") # ### end Alembic commands ###