PMFlow/backend/alembic/versions/20260517_agent_disclosure_g...

119 lines
3.3 KiB
Python

"""refresh agent goal frame disclosure contract
Revision ID: 20260517_agent_disclosure_goal_contract
Revises: 20260517_agent_runtime_llm_wait_alignment
Create Date: 2026-05-17
"""
from __future__ import annotations
import os
from typing import Any
from alembic import op
import sqlalchemy as sa
revision = "20260517_agent_disclosure_goal_contract"
down_revision = "20260517_agent_runtime_llm_wait_alignment"
branch_labels = None
depends_on = None
PROMPT_KEY = "PROMPT_PMFLOW_AI_AGENT_GOAL_FRAME"
REFRESH_NOTES = "Refreshed by 20260517_agent_disclosure_goal_contract for disclosure policy contract"
def _table_exists(bind: Any, table_name: str) -> bool:
return sa.inspect(bind).has_table(table_name)
def _prompt_body() -> str:
from app.config import ai_prompts
return str(getattr(ai_prompts, PROMPT_KEY, "") or "").strip()
def upgrade() -> None:
bind = op.get_bind()
if not _table_exists(bind, "prompt_releases"):
return
body_snapshot = _prompt_body()
if not body_snapshot:
return
tenant_id = int(os.getenv("PMFLOW_PLATFORM_RUNTIME_TENANT_ID", "1") or "1")
active = bind.execute(
sa.text(
"""
SELECT id, body_snapshot FROM prompt_releases
WHERE tenant_id = :tenant_id
AND prompt_key = :prompt_key
AND status = 'active'
LIMIT 1
"""
),
{"tenant_id": tenant_id, "prompt_key": PROMPT_KEY},
).mappings().first()
if active is not None and str(active.get("body_snapshot") or "").strip() == body_snapshot:
return
bind.execute(
sa.text(
"""
UPDATE prompt_releases
SET status = 'archived'
WHERE tenant_id = :tenant_id
AND prompt_key = :prompt_key
AND status = 'active'
"""
),
{"tenant_id": tenant_id, "prompt_key": PROMPT_KEY},
)
max_version = bind.execute(
sa.text(
"""
SELECT MAX(version) FROM prompt_releases
WHERE tenant_id = :tenant_id
AND prompt_key = :prompt_key
"""
),
{"tenant_id": tenant_id, "prompt_key": PROMPT_KEY},
).scalar()
bind.execute(
sa.text(
"""
INSERT INTO prompt_releases
(tenant_id, prompt_key, version, body_snapshot, status, notes, created_by, activated_by, activated_at)
VALUES
(:tenant_id, :prompt_key, :version, :body_snapshot, 'active', :notes, NULL, NULL, :activated_at)
"""
),
{
"tenant_id": tenant_id,
"prompt_key": PROMPT_KEY,
"version": int(max_version or 0) + 1,
"body_snapshot": body_snapshot,
"notes": REFRESH_NOTES,
"activated_at": "2026-05-17T00:00:00",
},
)
def downgrade() -> None:
bind = op.get_bind()
if not _table_exists(bind, "prompt_releases"):
return
tenant_id = int(os.getenv("PMFLOW_PLATFORM_RUNTIME_TENANT_ID", "1") or "1")
bind.execute(
sa.text(
"""
DELETE FROM prompt_releases
WHERE tenant_id = :tenant_id
AND prompt_key = :prompt_key
AND notes = :notes
"""
),
{"tenant_id": tenant_id, "prompt_key": PROMPT_KEY, "notes": REFRESH_NOTES},
)