mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-08-04 05:12:25 +00:00
The reporting engine's synthesis layer was reachable only through Generate/GenerateMulti, which always rendered PDF or CSV. Pulse Assistant needs the same retrospective synthesis (per-resource summary, fleet outliers, period comparison) in a form it can present in chat, not as a downloaded artifact. Add two non-rendering entry points to the Engine interface: NarrativeFor(req MetricReportRequest) (*Narrative, error) FleetNarrativeFor(req MultiReportRequest) (*FleetNarrative, error) Both run the same query path and the same narrator resolution as their rendering counterparts (heuristic by default, AI when the request supplies a narrator, fail-closed-to-heuristic on any narrator error) and return the structured narrative without invoking the fpdf/csv output stage. Test stubs in pkg/reporting and internal/api are updated to implement the extended interface. These are the seams the upcoming pulse_summarize Assistant tools wrap to answer questions like "what's hot on pve1 this week" or "where should I look across my fleet" without round-tripping through report generation. Same synthesis layer, no PDF involved. Also fixes a pre-existing flake in TestEngineGenerate_UsesSuppliedNarrator (metrics writes are async; the first Generate sometimes ran before the raw tier flushed). Wrapped in the same eventually-pattern used by the prior-period and findings-provider tests.
40 lines
938 B
Go
40 lines
938 B
Go
package reporting
|
|
|
|
import "testing"
|
|
|
|
type fakeEngine struct {
|
|
called bool
|
|
}
|
|
|
|
func (f *fakeEngine) Generate(req MetricReportRequest) ([]byte, string, error) {
|
|
f.called = true
|
|
return []byte("ok"), "text/plain", nil
|
|
}
|
|
|
|
func (f *fakeEngine) GenerateMulti(req MultiReportRequest) ([]byte, string, error) {
|
|
f.called = true
|
|
return []byte("ok"), "text/plain", nil
|
|
}
|
|
|
|
func (f *fakeEngine) NarrativeFor(req MetricReportRequest) (*Narrative, error) {
|
|
f.called = true
|
|
return &Narrative{Source: NarrativeSourceHeuristic}, nil
|
|
}
|
|
|
|
func (f *fakeEngine) FleetNarrativeFor(req MultiReportRequest) (*FleetNarrative, error) {
|
|
f.called = true
|
|
return &FleetNarrative{Source: NarrativeSourceHeuristic}, nil
|
|
}
|
|
|
|
func TestSetGetEngine(t *testing.T) {
|
|
engine := &fakeEngine{}
|
|
SetEngine(engine)
|
|
if GetEngine() != engine {
|
|
t.Fatal("expected engine to be set")
|
|
}
|
|
|
|
SetEngine(nil)
|
|
if GetEngine() != nil {
|
|
t.Fatal("expected engine to be cleared")
|
|
}
|
|
}
|