feat: ИИ-проверка объекта по частям (временные файлы вход/выход по блокам)
This commit is contained in:
@@ -1066,6 +1066,8 @@ class DokoGenApp:
|
||||
command=self._auto_fill_security_click).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(sec_main_btns, text="🤖 Проверить безопасность через ИИ",
|
||||
command=self._check_security_ai).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Button(sec_main_btns, text="🧩 Проверить объект по частям (ИИ)",
|
||||
command=self._check_object_partial_click).pack(side=tk.LEFT, padx=2)
|
||||
ttk.Label(sec_main_btns,
|
||||
text="Подбор по данным объекта — как рекомендация, оператор подтверждает.",
|
||||
foreground='gray').pack(side=tk.LEFT, padx=8)
|
||||
@@ -3507,6 +3509,83 @@ class DokoGenApp:
|
||||
self._verify_log("🤖 Проверка категорий ИИ завершена")
|
||||
self.log("🤖 Проверка категорий ИИ завершена")
|
||||
|
||||
def _check_object_partial_click(self):
|
||||
"""🧩 ИИ-проверка всего объекта по частям: каждый блок — отдельный запрос,
|
||||
данные и ответы ИИ пишутся во временную папку (dokogen_ai_*)."""
|
||||
if self._current_is_idx is None:
|
||||
messagebox.showinfo("Проверка", "Сначала выберите объект КИИ в списке слева")
|
||||
return
|
||||
settings = load_api_settings()
|
||||
if not settings.get('ai_api_key'):
|
||||
messagebox.showwarning("Настройки", "Не задан API-ключ ИИ.\nМеню «Файл → Настройки»")
|
||||
return
|
||||
self._collect_company()
|
||||
self._collect_is()
|
||||
c = self.model
|
||||
isys = self.model.information_systems[self._current_is_idx]
|
||||
|
||||
blocks = [
|
||||
{'name': 'Реквизиты организации', 'prompt': 'check_company',
|
||||
'data': {'full_name': c.full_name, 'short_name': c.short_name, 'address': c.address,
|
||||
'inn': c.inn, 'kpp': c.kpp, 'ogrn': c.ogrn, 'ogrn_date': c.ogrn_date,
|
||||
'chief_position': c.chief_position, 'chief_fio': c.chief_fio}},
|
||||
{'name': 'Характеристики объекта КИИ', 'prompt': 'suggest_object_params',
|
||||
'data': {'name': isys.name, 'description': isys.description, 'purpose': isys.purpose,
|
||||
'sphere': isys.sphere, 'object_type': isys.object_type,
|
||||
'architecture': isys.architecture, 'typical_object': isys.typical_object,
|
||||
'net_category': isys.net_category, 'net_purpose': isys.net_purpose}},
|
||||
{'name': 'Безопасность (нарушитель, угрозы, меры)', 'prompt': 'check_security',
|
||||
'data': {'name': isys.name, 'description': isys.description, 'category': isys.category,
|
||||
'sphere': isys.sphere, 'attacker_category': isys.attacker_category,
|
||||
'attacker_level': isys.attacker_level, 'attacker_types': isys.attacker_types,
|
||||
'threats': isys.threats, 'incidents': isys.incidents,
|
||||
'org_measures': isys.org_measures, 'tech_measures': isys.tech_measures}},
|
||||
{'name': 'Категории значимости (ПП 127)', 'prompt': 'check_criteria',
|
||||
'data': {'name': isys.name, 'description': isys.description, 'category': isys.category,
|
||||
'sphere': isys.sphere, 'object_type': isys.object_type,
|
||||
'criteria_values': isys.criteria_values,
|
||||
'criteria_justification': isys.criteria_justification}},
|
||||
{'name': 'Средства защиты (СЗИ)', 'prompt': 'suggest_defense',
|
||||
'data': {'name': isys.name, 'category': isys.category, 'sphere': isys.sphere,
|
||||
'threats': isys.threats,
|
||||
'defense_tools': list(self.defense_tools_listbox.get(0, tk.END)) or []}},
|
||||
]
|
||||
self._verify_log(f"🧩 ИИ-проверка объекта «{isys.name}» по частям ({len(blocks)} блоков)…")
|
||||
self.log(f"🧩 ИИ-проверка объекта «{isys.name}» по частям: {len(blocks)} блоков")
|
||||
|
||||
def _run():
|
||||
try:
|
||||
from .verify import check_object_partial
|
||||
res, err = check_object_partial(
|
||||
blocks, settings['ai_api_key'], settings.get('ai_model'),
|
||||
settings.get('ai_base_url'))
|
||||
self.root.after(0, lambda: self._check_object_partial_done(res, err, isys.name))
|
||||
except Exception as e:
|
||||
self.root.after(0, lambda: self._check_object_partial_done(None, str(e), isys.name))
|
||||
|
||||
threading.Thread(target=_run, daemon=True).start()
|
||||
|
||||
def _check_object_partial_done(self, res, err, obj_name):
|
||||
if err:
|
||||
self._verify_log(f"❌ {err}")
|
||||
self.log(f"❌ Проверка объекта по частям: {err}")
|
||||
return
|
||||
if not res:
|
||||
self._verify_log("❌ ИИ не вернул результат")
|
||||
return
|
||||
lines = [f"🧩 ИИ-проверка объекта «{obj_name}» по частям", ""]
|
||||
for r in res:
|
||||
status = "✅" if r.get('ok') else "❌"
|
||||
lines.append(f"{status} {r['name']}")
|
||||
if r.get('files', {}).get('out'):
|
||||
lines.append(f" ответ ИИ: {r['files']['out']}")
|
||||
lines.append("")
|
||||
lines.append("Полные ответы ИИ по каждому блоку — во временных файлах выше.")
|
||||
lines.append("Рекомендации применяются по кнопкам разделов (по галочкам).")
|
||||
self._show_security_ai_result(lines)
|
||||
self._verify_log("🧩 Проверка объекта по частям завершена")
|
||||
self.log("🧩 Проверка объекта по частям завершена")
|
||||
|
||||
def _select_from_defense_list(self):
|
||||
"""Выбор СЗИ из JSON словаря."""
|
||||
import json
|
||||
|
||||
Reference in New Issue
Block a user