feat: папка dictionaries/prompts — словари промтов для каждой ИИ-кнопки
- prompts/suggest_object_params.json: жёсткие правила подбора характеристик — выбирать ТОЛЬКО из предоставленных списков (сферы/типы/архитектуры/ типовые объекты), ничего не выдумывать; назначение строго по форме «Объект предназначен для … с целью …»; типовой объект — дословно из 360-р - prompts/suggest_threats.json, check_security.json, check_company.json, declension.json — промты для остальных ИИ-кнопок - verify.py: _load_prompt() + подключение промтов в suggest_object_params_ai, suggest_threats_ai, check_security_ai; ИИ получает полные списки (spheres/object_types/architectures) и выбирает из них - ui.py: окно рекомендаций ИИ — галочки у каждого поля, применяются только отмеченные (ИИ может ошибаться в архитектуре — оператор решает)
This commit is contained in:
+31
-16
@@ -1671,6 +1671,10 @@ class DokoGenApp:
|
||||
'sphere': isys.sphere or '',
|
||||
'object_type': isys.object_type or '',
|
||||
}
|
||||
# Полные списки допустимых значений — ИИ выбирает ТОЛЬКО из них
|
||||
spheres = list(self.is_sphere_combo['values']) if hasattr(self, 'is_sphere_combo') else []
|
||||
object_types = list(self.is_object_type_combo['values']) if hasattr(self, 'is_object_type_combo') else []
|
||||
architectures = list(self.is_architecture_combo['values']) if hasattr(self, 'is_architecture_combo') else []
|
||||
self.log(f"🤖 Запрос к ИИ: подбор характеристик для «{isys.name}»")
|
||||
self._verify_log("Подбор характеристик через ИИ…")
|
||||
|
||||
@@ -1679,7 +1683,8 @@ class DokoGenApp:
|
||||
from .verify import suggest_object_params_ai
|
||||
res, err = suggest_object_params_ai(
|
||||
data, settings['ai_api_key'], settings.get('ai_model'),
|
||||
settings.get('ai_base_url'), typical_objects=typical_list)
|
||||
settings.get('ai_base_url'), typical_objects=typical_list,
|
||||
spheres=spheres, object_types=object_types, architectures=architectures)
|
||||
self.root.after(0, lambda: self._suggest_object_params_ai_done(res, err, isys.name))
|
||||
except Exception as e:
|
||||
self.root.after(0, lambda: self._suggest_object_params_ai_done(None, str(e), isys.name))
|
||||
@@ -1697,28 +1702,35 @@ class DokoGenApp:
|
||||
|
||||
dlg = tk.Toplevel(self.root)
|
||||
dlg.title("🤖 Рекомендации ИИ по характеристикам объекта")
|
||||
dlg.geometry("860x560")
|
||||
dlg.geometry("880x620")
|
||||
dlg.transient(self.root)
|
||||
frm = ttk.Frame(dlg, padding=8)
|
||||
frm.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
ttk.Label(frm, text=f"Объект: {obj_name} — рекомендации ИИ (подтвердите или скорректируйте)",
|
||||
font=('Arial', 10, 'bold')).pack(anchor=tk.W)
|
||||
ttk.Label(frm, text=f"Объект: {obj_name} — рекомендации ИИ. Отметьте галочками, "
|
||||
f"какие поля применить (ИИ может ошибаться — проверяйте).",
|
||||
font=('Arial', 10, 'bold'), wraplength=840, justify=tk.LEFT).pack(anchor=tk.W)
|
||||
|
||||
rows = [
|
||||
('назначение', 'Назначение объекта'),
|
||||
('назначение', 'Назначение объекта (форма: «Объект предназначен для … с целью …»)'),
|
||||
('сфера', 'Сфера деятельности'),
|
||||
('тип', 'Тип объекта'),
|
||||
('архитектура', 'Архитектура объекта'),
|
||||
('типовой_объект', 'Типовой отраслевой объект КИИ'),
|
||||
]
|
||||
entries = {}
|
||||
checks = {}
|
||||
for key, label in rows:
|
||||
ttk.Label(frm, text=label + ":").pack(anchor=tk.W, pady=(6, 0))
|
||||
e = tk.Text(frm, height=2 if key == 'типовой_объект' else 1, wrap=tk.WORD)
|
||||
row = ttk.Frame(frm)
|
||||
row.pack(fill=tk.X, pady=(6, 0))
|
||||
var = tk.BooleanVar(value=True)
|
||||
cb = ttk.Checkbutton(row, text=label, variable=var)
|
||||
cb.pack(anchor=tk.W)
|
||||
e = tk.Text(frm, height=2 if key in ('типовой_объект', 'назначение') else 1, wrap=tk.WORD)
|
||||
e.pack(fill=tk.X)
|
||||
e.insert('1.0', res.get(key, '') or '')
|
||||
entries[key] = e
|
||||
checks[key] = var
|
||||
|
||||
ttk.Label(frm, text="Обоснование ИИ:").pack(anchor=tk.W, pady=(6, 0))
|
||||
just = tk.Text(frm, height=2, wrap=tk.WORD)
|
||||
@@ -1727,20 +1739,23 @@ class DokoGenApp:
|
||||
|
||||
btn_row = ttk.Frame(frm)
|
||||
btn_row.pack(fill=tk.X, pady=(8, 0))
|
||||
ttk.Button(btn_row, text="✔️ Применить",
|
||||
command=lambda: self._apply_ai_params(entries, dlg)).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(btn_row, text="✔️ Применить отмеченное",
|
||||
command=lambda: self._apply_ai_params(entries, dlg, checks)).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(btn_row, text="Отмена", command=dlg.destroy).pack(side=tk.LEFT, padx=2)
|
||||
|
||||
def _apply_ai_params(self, entries, dlg):
|
||||
"""Применить рекомендации ИИ к полям объекта."""
|
||||
def _apply_ai_params(self, entries, dlg, checks=None):
|
||||
"""Применить рекомендации ИИ к полям объекта (только отмеченные галочками)."""
|
||||
def _get(e):
|
||||
return e.get('1.0', 'end-1c').strip()
|
||||
|
||||
purpose = _get(entries['назначение'])
|
||||
sphere = _get(entries['сфера'])
|
||||
otype = _get(entries['тип'])
|
||||
arch = _get(entries['архитектура'])
|
||||
typical = _get(entries['типовой_объект'])
|
||||
def _wanted(key):
|
||||
return checks is None or checks.get(key, tk.BooleanVar(value=True)).get()
|
||||
|
||||
purpose = _get(entries['назначение']) if _wanted('назначение') else ''
|
||||
sphere = _get(entries['сфера']) if _wanted('сфера') else ''
|
||||
otype = _get(entries['тип']) if _wanted('тип') else ''
|
||||
arch = _get(entries['архитектура']) if _wanted('архитектура') else ''
|
||||
typical = _get(entries['типовой_объект']) if _wanted('типовой_объект') else ''
|
||||
|
||||
if purpose and hasattr(self, 'is_purpose_entry'):
|
||||
self.is_purpose_entry.delete(0, tk.END)
|
||||
|
||||
Reference in New Issue
Block a user