v3.3.1: редактор промпта LLM — сохранить/сбросить/по умолчанию
This commit is contained in:
@@ -94,6 +94,16 @@
|
||||
<button class="btn btn-primary" id="llmBtn" style="width:100%;justify-content:center;margin-top:8px;display:none;">
|
||||
<i data-lucide="scale" style="width:16px;height:16px;"></i> Сравнить (LLM)
|
||||
</button>
|
||||
|
||||
<details style="margin-top:8px;font-size:12px;">
|
||||
<summary style="cursor:pointer;color:var(--muted);">⚙ Промпт LLM</summary>
|
||||
<textarea id="promptEditor" style="width:100%;height:200px;font-family:monospace;font-size:11px;border:1px solid var(--brand-gray);border-radius:6px;padding:8px;margin-top:4px;" placeholder="Промпт для LLM..."></textarea>
|
||||
<div style="display:flex;gap:8px;margin-top:4px;">
|
||||
<button class="btn" id="promptSave" style="font-size:11px;height:28px;">Сохранить</button>
|
||||
<button class="btn" id="promptReset" style="font-size:11px;height:28px;">По умолчанию</button>
|
||||
<span id="promptStatus" style="font-size:11px;color:var(--muted);line-height:28px;"></span>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -135,6 +145,32 @@
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
|
||||
const DEFAULT_PROMPT = `Ты — анализатор договоров. Ниже текст спецификации услуг из договора облачного провайдера.
|
||||
|
||||
Найди ВСЕ таблицы со списком услуг. Извлеки каждую строку в JSON-массив.
|
||||
|
||||
Для каждой строки верни:
|
||||
- row_num: номер по порядку (целое число)
|
||||
- name: полное наименование услуги (весь текст из ячейки)
|
||||
- price: цена за единицу в рублях (число, из колонки "Цена")
|
||||
- qty: количество/объём (число, из колонки "Объем")
|
||||
- sum: итоговая сумма (число, из колонки "Сумма")
|
||||
- date_start: дата начала оказания (строка YYYY-MM-DD)
|
||||
|
||||
ПРАВИЛА:
|
||||
1. Пропускай итоговые строки ("Итого...") и строки с подписями.
|
||||
2. Если ячейка пустая — ставь null.
|
||||
3. Если не можешь определить значение — ставь null и добавь в unresolved.
|
||||
4. Верни ТОЛЬКО JSON, без пояснений.
|
||||
|
||||
Пример ответа:
|
||||
{"rows":[{"row_num":1,"name":"Аренда стойко-места","price":213905.44,"qty":3,"sum":641716.32,"date_start":"2026-04-01"}],"unresolved":[]}
|
||||
|
||||
Текст документа:
|
||||
---
|
||||
{parsed_text}
|
||||
---`;
|
||||
|
||||
const fileInput = document.getElementById('fileInput');
|
||||
const parseBtn = document.getElementById('parseBtn');
|
||||
const fileTable = document.getElementById('fileTable');
|
||||
@@ -452,6 +488,14 @@
|
||||
document.getElementById('llmBtn').addEventListener('click', function() {
|
||||
if (!contractId) return;
|
||||
|
||||
// Сохранить промпт на сервер перед стартом
|
||||
var p = promptEditor.value.trim() || DEFAULT_PROMPT;
|
||||
fetch('/llm/prompt/' + contractId, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({prompt: p})
|
||||
});
|
||||
|
||||
var llmBtn = document.getElementById('llmBtn');
|
||||
llmBtn.disabled = true;
|
||||
llmBtn.innerHTML = '<span style="display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite;"></span> LLM-анализ...';
|
||||
@@ -586,6 +630,41 @@
|
||||
if (e.key === 'Enter') document.getElementById('chatSend').click();
|
||||
});
|
||||
|
||||
// ── Редактор промпта ──────────────────────────────────────────
|
||||
|
||||
var promptEditor = document.getElementById('promptEditor');
|
||||
|
||||
// Загрузить из localStorage
|
||||
var saved = localStorage.getItem('llm_prompt');
|
||||
promptEditor.value = saved || DEFAULT_PROMPT;
|
||||
|
||||
document.getElementById('promptSave').addEventListener('click', function() {
|
||||
var p = promptEditor.value.trim();
|
||||
if (!p) return;
|
||||
localStorage.setItem('llm_prompt', p);
|
||||
document.getElementById('promptStatus').textContent = '✓ сохранено';
|
||||
setTimeout(function() { document.getElementById('promptStatus').textContent = ''; }, 1500);
|
||||
// Отправить на сервер
|
||||
if (contractId) {
|
||||
fetch('/llm/prompt/' + contractId, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({prompt: p})
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('promptReset').addEventListener('click', function() {
|
||||
promptEditor.value = DEFAULT_PROMPT;
|
||||
localStorage.removeItem('llm_prompt');
|
||||
document.getElementById('promptStatus').textContent = '✓ сброшен';
|
||||
setTimeout(function() { document.getElementById('promptStatus').textContent = ''; }, 1500);
|
||||
});
|
||||
|
||||
// При старте LLM — сохранить промпт для этого contractId
|
||||
var origLlmClick = document.getElementById('llmBtn').onclick;
|
||||
// Переопределим ниже...
|
||||
|
||||
var style = document.createElement('style');
|
||||
style.textContent = '@keyframes spin { to { transform: rotate(360deg); } }';
|
||||
document.head.appendChild(style);
|
||||
|
||||
Reference in New Issue
Block a user