defmodule Agentix.Repo.Migrations.CreateAgentixTables do @moduledoc """ Creates the five Agentix tables for the Ecto/Postgres persistence adapter. Copy this file into your repo's `priv/repo/migrations/` with a timestamp prefix (e.g. `20260101000000_create_agentix_tables.exs`) and run `mix ecto.migrate`. The Ecto-backed suspension expiry additionally needs Oban's own migration. Conversation ids are host-chosen strings (the Registry key), so conversation id columns are `:text`, not `uuid`. Internal row ids are `uuid`; `tool_calls.id` is the provider-supplied tool_call_id (`:text`). """ use Ecto.Migration def change do create table(:agentix_conversations, primary_key: false) do add(:id, :text, primary_key: true) add(:settings, :map, null: false, default: %{}) add(:fsm_state, :map, null: false, default: %{}) add(:status, :text, null: false, default: "active") timestamps(type: :utc_datetime_usec) end create( constraint(:agentix_conversations, :agentix_conversations_status, check: "status IN ('active','suspended','idle','ended')" ) ) create table(:agentix_events, primary_key: false) do add(:id, :binary_id, primary_key: true) add(:conversation_id, references(:agentix_conversations, type: :text, on_delete: :delete_all), null: false ) add(:seq, :bigint, null: false) add(:type, :text, null: false) add(:content, :map, null: false) add(:inserted_at, :utc_datetime_usec, null: false) end create(unique_index(:agentix_events, [:conversation_id, :seq])) create( constraint(:agentix_events, :agentix_events_type, check: "type IN ('user_msg','assistant_msg','tool_call','tool_result','suspension','resolution')" ) ) create table(:agentix_summaries, primary_key: false) do add(:id, :binary_id, primary_key: true) add(:conversation_id, references(:agentix_conversations, type: :text, on_delete: :delete_all), null: false ) add(:from_seq, :bigint, null: false) add(:to_seq, :bigint, null: false) add(:content, :map, null: false) add(:version, :text, null: false) add(:inserted_at, :utc_datetime_usec, null: false) end create(index(:agentix_summaries, [:conversation_id, "to_seq DESC"])) create( constraint(:agentix_summaries, :agentix_summaries_seq_range, check: "to_seq >= from_seq") ) create table(:agentix_tool_calls, primary_key: false) do add(:id, :text, primary_key: true) add(:conversation_id, references(:agentix_conversations, type: :text, on_delete: :delete_all), null: false ) add(:name, :text) add(:executor, :text, null: false) add(:status, :text, null: false, default: "pending") add(:args, :map) add(:result, :map) add(:inserted_at, :utc_datetime_usec, null: false) add(:resolved_at, :utc_datetime_usec) end create(index(:agentix_tool_calls, [:conversation_id, :status])) create( constraint(:agentix_tool_calls, :agentix_tool_calls_executor, check: "executor IN ('server','human','client','provider')" ) ) create( constraint(:agentix_tool_calls, :agentix_tool_calls_status, check: "status IN ('pending','resolved','errored','expired')" ) ) create table(:agentix_model_calls, primary_key: false) do add(:id, :binary_id, primary_key: true) add(:conversation_id, references(:agentix_conversations, type: :text, on_delete: :delete_all), null: false ) add(:turn_ref, :bigint, null: false) add(:rendered_context, :map, null: false) add(:model, :text) add(:usage, :map) add(:latency_ms, :integer) add(:summary_version, :text) add(:evictions, {:array, :map}) add(:inserted_at, :utc_datetime_usec, null: false) end create(index(:agentix_model_calls, [:conversation_id, :turn_ref])) create(index(:agentix_model_calls, [:inserted_at])) end end