NAME

Database::BI::Summary - Narrative summary generation for an analysis result

SYNOPSIS

use Database::BI::Summary;

my $result = Database::BI::Summary::generate(
    insights  => $insights_aref,   # from Database::BI::Insights::compute()
    label     => 'sales',
    row_count => 39,
);
# $result = { text => "...", source => "template", cached => 0 }

DESCRIPTION

Generates a 2-4 sentence plain-English summary of an analysis result. Two paths are available:

Template path (default, always offline)

Composes deterministic sentences from the insight kinds and headlines. No external service required.

LLM path (opt-in)

Sends only aggregate facts (insight kinds, headlines, and detail strings) to the Anthropic Messages API. Raw row data, file paths, and the spec_key are never included in the LLM prompt. The LLM path falls back silently to the template path if the provider call fails.

Results are cached in a package-level hash keyed by an MD5 fingerprint of the insight content. Cached results are served for up to one hour.

FUNCTIONS

generate(%args)

my $result = Database::BI::Summary::generate(
    insights  => \@insights,
    spec_key  => 'table:sales',
    label     => 'sales',
    row_count => 39,
    use_ai    => 0,
    ai_config => undef,
);

Returns a hashref with keys text, source ('template', 'template_fallback', or 'llm'), and cached (1 if served from cache, 0 if freshly generated).

use_ai is only honoured when ai_config is provided and ai_config->{api_key} is non-empty.

AUTHOR

Nigel Horne <njh@nigelhorne.com>

LICENCE AND COPYRIGHT

Copyright 2026 Nigel Horne.

Usage is subject to the GPL2 licence terms.