v1.0.176: prompts — seed per-role + _serialize non-mutating
This commit is contained in:
+54
-51
@@ -3,8 +3,9 @@ from .connection import query, execute, execute_returning
|
|||||||
|
|
||||||
|
|
||||||
def _serialize(row):
|
def _serialize(row):
|
||||||
"""Convert datetime fields to strings for JSON serialization."""
|
"""Convert datetime fields to strings for JSON serialization (non-mutating)."""
|
||||||
if row and row.get("created_at"):
|
if row and row.get("created_at"):
|
||||||
|
row = dict(row)
|
||||||
row["created_at"] = str(row["created_at"])
|
row["created_at"] = str(row["created_at"])
|
||||||
return row
|
return row
|
||||||
|
|
||||||
@@ -24,57 +25,59 @@ def get(prompt_id):
|
|||||||
|
|
||||||
def seed_defaults():
|
def seed_defaults():
|
||||||
"""Auto-seed default prompts if table is empty."""
|
"""Auto-seed default prompts if table is empty."""
|
||||||
count = query("SELECT COUNT(*) as cnt FROM prompts")
|
# Check each role separately — don't skip if one is missing
|
||||||
if count[0]["cnt"] > 0:
|
existing_roles = set(r["role"] for r in query("SELECT DISTINCT role FROM prompts"))
|
||||||
return
|
|
||||||
|
|
||||||
extract_body = (
|
if "extract" not in existing_roles:
|
||||||
"Ты — анализатор договоров облачного провайдера.\n\n"
|
extract_body = (
|
||||||
"Ниже текст спецификации услуг из ПЕРВОГО документа (базовый договор).\n"
|
"Ты — анализатор договоров облачного провайдера.\n\n"
|
||||||
"Извлеки ВСЕ строки спецификации в JSON-массив.\n\n"
|
"Ниже текст спецификации услуг из ПЕРВОГО документа (базовый договор).\n"
|
||||||
"Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\n"
|
"Извлеки ВСЕ строки спецификации в JSON-массив.\n\n"
|
||||||
"ФОРМАТ:\n"
|
"Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\n"
|
||||||
'{\n "mode": "partial",\n "ops": [\n'
|
"ФОРМАТ:\n"
|
||||||
' {"action": "ADD", "new_row": {"name": "полное наименование", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": ""}\n'
|
'{\n "mode": "partial",\n "ops": [\n'
|
||||||
" ]\n}\n\n"
|
' {"action": "ADD", "new_row": {"name": "полное наименование", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": ""}\n'
|
||||||
"ПРАВИЛА:\n"
|
" ]\n}\n\n"
|
||||||
"1. Извлеки КАЖДУЮ строку таблицы спецификации как отдельную ADD-операцию.\n"
|
"ПРАВИЛА:\n"
|
||||||
'2. Пропускай итоговые строки ("Итого...") и строки с подписями.\n'
|
"1. Извлеки КАЖДУЮ строку таблицы спецификации как отдельную ADD-операцию.\n"
|
||||||
"3. Если ячейка пустая — ставь null (не пиши 0).\n"
|
'2. Пропускай итоговые строки ("Итого...") и строки с подписями.\n'
|
||||||
"4. price, qty, sum — ЧИСЛА, не строки.\n\n"
|
"3. Если ячейка пустая — ставь null (не пиши 0).\n"
|
||||||
"ТЕКСТ ДОКУМЕНТА:\n---\n{doc_text}\n---"
|
"4. price, qty, sum — ЧИСЛА, не строки.\n\n"
|
||||||
)
|
"ТЕКСТ ДОКУМЕНТА:\n---\n{doc_text}\n---"
|
||||||
execute(
|
)
|
||||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
execute(
|
||||||
("extract", "default-v1", extract_body, True, "Авто-создан из llm_prompt.py _build_initial"),
|
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||||
)
|
("extract", "default-v1", extract_body, True, "Авто-создан из llm_prompt.py _build_initial"),
|
||||||
diff_body = (
|
)
|
||||||
"Ты — анализатор допсоглашений к договорам облачного провайдера.\n\n"
|
|
||||||
"У тебя есть текущая спецификация услуг и текст нового допсоглашения (ДС).\n"
|
if "diff" not in existing_roles:
|
||||||
"Твоя задача — определить, какие изменения вносит ДС в текущую спецификацию.\n\n"
|
diff_body = (
|
||||||
"Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\n"
|
"Ты — анализатор допсоглашений к договорам облачного провайдера.\n\n"
|
||||||
"ФОРМАТ:\n"
|
"У тебя есть текущая спецификация услуг и текст нового допсоглашения (ДС).\n"
|
||||||
'{\n "mode": "partial" | "full_replace",\n "ops": [\n'
|
"Твоя задача — определить, какие изменения вносит ДС в текущую спецификацию.\n\n"
|
||||||
' {"action": "ADD", "new_row": {"name": "...", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": "..."},\n'
|
"Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\n"
|
||||||
' {"action": "UPDATE", "target_id": "rN", "new_values": {"price": число}, "comment": "..."},\n'
|
"ФОРМАТ:\n"
|
||||||
' {"action": "DELETE", "target_id": "rN", "comment": "..."},\n'
|
'{\n "mode": "partial" | "full_replace",\n "ops": [\n'
|
||||||
' {"action": "UNRESOLVED", "new_values": {"name": "...", "price": число, ...}, "reason": "почему не смог сопоставить"}\n'
|
' {"action": "ADD", "new_row": {"name": "...", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": "..."},\n'
|
||||||
" ]\n}\n\n"
|
' {"action": "UPDATE", "target_id": "rN", "new_values": {"price": число}, "comment": "..."},\n'
|
||||||
"ПРАВИЛА:\n"
|
' {"action": "DELETE", "target_id": "rN", "comment": "..."},\n'
|
||||||
'1. mode = "full_replace" — если в тексте есть фразы: «в следующей редакции», «заменить приложение», «излагается в следующей редакции». При full_replace — опиши ВСЕ новые строки как ADD.\n'
|
' {"action": "UNRESOLVED", "new_values": {"name": "...", "price": число, ...}, "reason": "почему не смог сопоставить"}\n'
|
||||||
'2. mode = "partial" — если ДС меняет только отдельные строки.\n'
|
" ]\n}\n\n"
|
||||||
"3. Для UPDATE/DELETE — укажи target_id (r1, r2...) из списка текущей спецификации. НЕ придумывай новые id.\n"
|
"ПРАВИЛА:\n"
|
||||||
"4. new_values в UPDATE — только ИЗМЕНЁННЫЕ поля (не все).\n"
|
'1. mode = "full_replace" — если в тексте есть фразы: «в следующей редакции», «заменить приложение», «излагается в следующей редакции». При full_replace — опиши ВСЕ новые строки как ADD.\n'
|
||||||
"5. Если не можешь однозначно сопоставить строку — action: UNRESOLVED с reason.\n"
|
'2. mode = "partial" — если ДС меняет только отдельные строки.\n'
|
||||||
"6. Пропускай итоговые строки и подписи.\n"
|
"3. Для UPDATE/DELETE — укажи target_id (r1, r2...) из списка текущей спецификации. НЕ придумывай новые id.\n"
|
||||||
"7. price, qty, sum — ЧИСЛА (не строки).\n\n"
|
"4. new_values в UPDATE — только ИЗМЕНЁННЫЕ поля (не все).\n"
|
||||||
"ТЕКУЩАЯ СПЕЦИФИКАЦИЯ:\n{spec_current}\n\n"
|
"5. Если не можешь однозначно сопоставить строку — action: UNRESOLVED с reason.\n"
|
||||||
"ТЕКСТ ДОПСОГЛАШЕНИЯ:\n---\n{doc_text}\n---"
|
"6. Пропускай итоговые строки и подписи.\n"
|
||||||
)
|
"7. price, qty, sum — ЧИСЛА (не строки).\n\n"
|
||||||
execute(
|
"ТЕКУЩАЯ СПЕЦИФИКАЦИЯ:\n{spec_current}\n\n"
|
||||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
"ТЕКСТ ДОПСОГЛАШЕНИЯ:\n---\n{doc_text}\n---"
|
||||||
("diff", "default-v1", diff_body, True, "Авто-создан из llm_prompt.py _build_diff"),
|
)
|
||||||
)
|
execute(
|
||||||
|
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||||
|
("diff", "default-v1", diff_body, True, "Авто-создан из llm_prompt.py _build_diff"),
|
||||||
|
)
|
||||||
_ensure_classify_prompt()
|
_ensure_classify_prompt()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user