Files
pulse/internal/ai/chat
rcourtman 03463c1bfe Thread per-tenant AI narrators into pulse_summarize via chat session
v1 of pulse_summarize (1fe5d6853) shipped with heuristic narrative
only. The follow-up wiring promised in that commit now lands: the
chat session carries optional report-narration providers that the
tool's handler reads when building requests, so AI-narrated synthesis
flows into chat using the same provider, sanitizer, model selection,
cost ledger, and budget gate the report PDF endpoint already uses.

Pipeline:
- pkg/reporting Narrator / FleetNarrator / FindingsProvider interfaces
  are already implemented by internal/ai.Service. No new
  implementations.
- tools.ExecutorConfig + PulseToolExecutor gain three optional fields
  (ReportNarrator, ReportFleetNarrator, ReportFindingsProvider).
  Clone() copies them so per-session executors inherit the wiring.
- chat.Config gains the same three fields; NewService threads them
  into ExecutorConfig.
- tools_summarize.go reads e.reportNarrator/FleetNarrator/
  FindingsProvider and populates MetricReportRequest /
  MultiReportRequest. The engine already accepts these on the request
  and falls back to heuristic when they are nil — no engine changes
  needed.
- AIHandler gains SetReportNarratorResolver(ctx -> narrators); both
  per-tenant and default chat.Config construction sites invoke the
  resolver. Router wires the resolver to AISettingsHandler.GetAIService
  with the same Enabled-gate the reporting handler uses.

Unconfigured tenants are unchanged: the resolver returns nil, the
tool returns heuristic narrative — identical to today. Configured
tenants get AI synthesis in chat that matches what their report PDF
already carries, billed and budget-gated the same way.
2026-05-10 22:50:17 +01:00
..
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00
2026-03-18 16:06:30 +00:00