gendesign/backend/app/services/chat/__init__.py
Light1YT fceaaf9a2c
All checks were successful
CI / changes (push) Successful in 6s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 5s
CI / frontend-tests (pull_request) Has been skipped
Deploy / changes (push) Successful in 5s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 2m41s
CI / backend-tests (push) Successful in 6m24s
CI / backend-tests (pull_request) Successful in 6m23s
Deploy / build-worker (push) Successful in 3m26s
Deploy / deploy (push) Successful in 1m12s
feat(chat): LLM tool-loop + §19 redaction wiring for #957 (Step 2+3)
Add the LLM prose-composition path for the parcel-forecast chat, layered
over the deterministic Step-1 fallback which stays the safety net.

- chat/tools.py: 5 read-only section tools (exec_summary, product_recommendation,
  forecast, risks, scenarios) — pure slices of the loaded report dict, no DB/
  recompute, graceful on missing sections. market_now (raw analyze blob) and meta
  are deliberately NOT exposed -> highest-PII data cannot reach the LLM.
- chat/safe_payload.py: the §19 gate — single place that builds the outbound
  SafePayload from a section-aggregate allowlist; honors is_confidential hard-block.
- chat/orchestrator.py: manual tool-call loop with call-cap/termination, real
  grounded_in provenance; any LLMResult.ok=False (disabled/timeout/rate_limited/
  redaction_refused/call_cap/provider_error/empty) degrades to the deterministic answer.
- llm/prompts.py: versioned chat_system@v1 — answer only from sections, never
  fabricate numbers, advisory tone, decline out-of-scope.
- api/v1/chat.py: branch on settings.llm_enabled; sync complete bridged via
  run_in_threadpool. Default-off -> deterministic path, no provider built.
- Tests: fake provider only (no network), planted-secret redaction-boundary +
  per-reason fallback + call-cap + numbers-from-report coverage.

Refs #957
2026-06-08 17:45:01 +05:00

25 lines
1.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Чат по §22-форсайту участка (#957). Step 1 детерминированный + Step 2 LLM tool-loop.
Под-модули:
• retrieval — read-only достаёт персистентный SiteFinderReport участка.
• intents — роутинг RU-вопроса в intent + шаблонный RU-ответ (Step-1, FALLBACK).
• tools — read-only секционные tool'ы (срезы загруженного report_dict).
• safe_payload — §19-гейт: единственная сборка исходящего SafePayload (аллоулист).
• orchestrator — LLM tool-loop + RU-проза поверх отчёта; при сбое LLM → Step-1 fallback.
LLM-слой ОПЦИОНАЛЬНЫЙ: при llm_enabled=False или любом сбое возвращается детерм. Step-1.
"""
from __future__ import annotations
from app.services.chat.intents import render_answer, route_intent
from app.services.chat.orchestrator import ChatResult, orchestrate_chat
from app.services.chat.retrieval import get_report_for_chat
__all__ = [
"ChatResult",
"get_report_for_chat",
"orchestrate_chat",
"render_answer",
"route_intent",
]