"""Prompts CRUD.""" from .connection import query, execute, execute_returning def get_active(role): rows = query( "SELECT * FROM prompts WHERE role = %s AND is_active = true ORDER BY created_at DESC LIMIT 1", (role,), ) return rows[0] if rows else None def get(prompt_id): rows = query("SELECT * FROM prompts WHERE id = %s", (prompt_id,)) return rows[0] if rows else None def seed_defaults(): """Auto-seed default prompts if table is empty.""" count = query("SELECT COUNT(*) as cnt FROM prompts") if count[0]["cnt"] > 0: return execute(""" INSERT INTO prompts (role, name, body, is_active, notes) VALUES ( 'extract', 'default-v1', 'Ты — анализатор договоров облачного провайдера.\n\nНиже текст спецификации услуг из ПЕРВОГО документа (базовый договор).\nИзвлеки ВСЕ строки спецификации в JSON-массив.\n\nВерни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\nФОРМАТ:\n{\n "mode": "partial",\n "ops": [\n {"action": "ADD", "new_row": {"name": "полное наименование", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": ""}\n ]\n}\n\nПРАВИЛА:\n1. Извлеки КАЖДУЮ строку таблицы спецификации как отдельную ADD-операцию.\n2. Пропускай итоговые строки ("Итого...") и строки с подписями.\n3. Если ячейка пустая — ставь null (не пиши 0).\n4. price, qty, sum — ЧИСЛА, не строки.\n\nТЕКСТ ДОКУМЕНТА:\n---\n{doc_text}\n---', true, 'Авто-создан из llm_prompt.py _build_initial' ) """) execute(""" INSERT INTO prompts (role, name, body, is_active, notes) VALUES ( 'diff', 'default-v1', 'Ты — анализатор допсоглашений к договорам облачного провайдера.\n\nУ тебя есть текущая спецификация услуг и текст нового допсоглашения (ДС).\nТвоя задача — определить, какие изменения вносит ДС в текущую спецификацию.\n\nВерни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\nФОРМАТ:\n{\n "mode": "partial" | "full_replace",\n "ops": [\n {"action": "ADD", "new_row": {"name": "...", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": "..."},\n {"action": "UPDATE", "target_id": "rN", "new_values": {"price": число}, "comment": "..."},\n {"action": "DELETE", "target_id": "rN", "comment": "..."},\n {"action": "UNRESOLVED", "new_values": {"name": "...", "price": число, ...}, "reason": "почему не смог сопоставить"}\n ]\n}\n\nПРАВИЛА:\n1. mode = "full_replace" — если в тексте есть фразы: «в следующей редакции», «заменить приложение», «излагается в следующей редакции». При full_replace — опиши ВСЕ новые строки как ADD.\n2. mode = "partial" — если ДС меняет только отдельные строки.\n3. Для UPDATE/DELETE — укажи target_id (r1, r2...) из списка текущей спецификации. НЕ придумывай новые id.\n4. new_values в UPDATE — только ИЗМЕНЁННЫЕ поля (не все).\n5. Если не можешь однозначно сопоставить строку — action: UNRESOLVED с reason.\n6. Пропускай итоговые строки и подписи.\n7. price, qty, sum — ЧИСЛА (не строки).\n\nТЕКУЩАЯ СПЕЦИФИКАЦИЯ:\n{spec_current}\n\nТЕКСТ ДОПСОГЛАШЕНИЯ:\n---\n{doc_text}\n---', true, 'Авто-создан из llm_prompt.py _build_diff' ) """)