feat(agent): агент логов — фильтр, LLM-страж, планировщик grep (#18)
CI / ruff · mypy · pytest (pull_request) Successful in 39m13s

- prefilter: правила из config/agent_rules.yaml (длина, команды, shell,
  секреты и системные файлы, prompt injection) — без LLM
- guard: отдельный вызов, JSON {verdict, reason}; невалидный ответ = attack,
  недоступный LLM — «попробуйте позже», а не атака
- planner: только AgentLogQuery (контейнер из белого списка, ≤ 7 д, шаблон
  ≤ 200 без вложенных квантификаторов, лимит ≤ 500); логи в LLM не идут
- бот: «🤖 Спросить агента» → показывает построенный grep и строки;
  атака — вежливый отказ и 🛡 администраторам; квота 30 в сутки
- журнал agent_requests + log_queries (mode=agent)
- при LLM_PROVIDER=mock агент выключен

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 15:02:07 +03:00
co-authored by Claude Opus 5.5
parent f89338e015
commit 65acf3abf1
20 changed files with 917 additions and 26 deletions
+18 -1
View File
@@ -181,7 +181,24 @@ logs:
hours: "{n} ч"
grep_button: "🔎 Свой grep"
agent_button: "🤖 Спросить агента"
agent_soon: "Агент — в следующей версии."
agent_ask: |-
🤖 Вопрос агенту — по логу {name} или другого контейнера, если назовёте его.
Например: «когда были ошибки подключения за сутки?», «сколько таймаутов за час?»
Агент сам построит grep и покажет его. Осталось вопросов на сегодня: {left} из {quota}.
agent_off: "Агент не настроен: боту нужен LLM (LLM_PROVIDER)."
agent_thinking: "🤖 Строю запрос…"
agent_refused: "С таким запросом помочь не могу. Спросите о содержимом логов: ошибки, таймауты, падения, подключения."
agent_quota: "Лимит — {quota} вопросов агенту в сутки, он исчерпан. Свой grep работает без лимита."
agent_unavailable: "Агент сейчас недоступен. Попробуйте позже или воспользуйтесь своим grep."
agent_not_understood: "Не получилось построить запрос. Переформулируйте вопрос или воспользуйтесь своим grep."
head_agent: "🤖 <code>{command}</code>\n<b>{name}</b> · за {period} · совпадений: {matched}"
attack_alert: |-
🛡 Попытка атаки через агента логов
Кто: {who}
Отсечено: {stage} · {reason}
Запрос:
<pre>{prompt}</pre>
to_list: "⬅️ К контейнерам"
to_container: "⬅️ К контейнеру"
ask_grep: |-