"""generation_tool_log: per-turn tool-call telemetry

Revision ID: 0046
Revises: 0045
Create Date: 2026-05-21

Captures one row per assistant turn, recording which tools the model
could have used, which it attempted, which fired successfully, and
which failed (with error details). The empirical surface for
evaluating model swaps and answering "does model X actually fire
record_moment when it should?" without relying on anecdote.
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ARRAY, JSONB


revision = "0046"
down_revision = "0045"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.create_table(
        "generation_tool_log",
        sa.Column("id", sa.Integer, primary_key=True),
        sa.Column(
            "user_id",
            sa.Integer,
            sa.ForeignKey("users.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column(
            "conv_id",
            sa.Integer,
            sa.ForeignKey("conversations.id", ondelete="CASCADE"),
            nullable=False,
        ),
        # SET NULL (not CASCADE) so the telemetry row survives if the
        # underlying assistant message is later deleted — we want to keep
        # the per-turn outcome record for retrospective analysis.
        sa.Column(
            "assistant_message_id",
            sa.Integer,
            sa.ForeignKey("messages.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column("model", sa.Text, nullable=False),
        sa.Column("think_enabled", sa.Boolean, nullable=False),
        sa.Column(
            "tools_available",
            ARRAY(sa.Text),
            nullable=False,
            server_default=sa.text("'{}'::text[]"),
        ),
        sa.Column(
            "tools_attempted",
            ARRAY(sa.Text),
            nullable=False,
            server_default=sa.text("'{}'::text[]"),
        ),
        sa.Column(
            "tools_succeeded",
            ARRAY(sa.Text),
            nullable=False,
            server_default=sa.text("'{}'::text[]"),
        ),
        # JSONB array of {name, error} objects so failed-tool details are
        # queryable without a separate failure table.
        sa.Column(
            "tools_failed",
            JSONB,
            nullable=False,
            server_default=sa.text("'[]'::jsonb"),
        ),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("now()"),
        ),
    )
    # Common query: "recent tool outcomes for this user, filterable by model."
    op.create_index(
        "ix_generation_tool_log_user_created",
        "generation_tool_log",
        ["user_id", sa.text("created_at DESC")],
    )
    # Per-conversation lookup for the journal page's own retrospection.
    op.create_index(
        "ix_generation_tool_log_conv",
        "generation_tool_log",
        ["conv_id"],
    )


def downgrade() -> None:
    op.drop_index("ix_generation_tool_log_conv", table_name="generation_tool_log")
    op.drop_index(
        "ix_generation_tool_log_user_created", table_name="generation_tool_log"
    )
    op.drop_table("generation_tool_log")
