5.6 KiB
Generated Text Internals
This document describes structured generated-text handling in
internal/generatedtext.
Purpose
internal/generatedtext validates structured text returned for
generated-text-template reports and builds curated render contexts for
templates. It also owns the generated-text catalog that connects report
definitions to validators, render-context builders, schema assets, and template
assets.
Inputs And Outputs
Inputs:
- raw GeneratedText JSON for Daily, Today, Tomorrow Report, or Hourly Report
- report metadata from
internal/briefing - a module snapshot from
internal/module - validated generated text
Outputs:
- typed
Dailygenerated text - typed
Todaygenerated text - typed
Tomorrowgenerated text - typed
Hourlygenerated text - normalized stable JSON for validated generated text
- typed
DailyRenderContextvalues forinternal/reporttemplate - typed
TodayRenderContextvalues forinternal/reporttemplate - typed
TomorrowRenderContextvalues forinternal/reporttemplate - typed
HourlyRenderContextvalues forinternal/reporttemplate - generated-text catalog handlers for report definitions that use
generated_text_template
JSON Contracts
Daily, Today, and Tomorrow use the same day-style generated-text JSON shape:
{
"summary": "string",
"forecast_discussion": ["string"],
"precipitation_timing": "string",
"confidence": "string"
}
The day-style contract requires summary after trimming whitespace.
forecast_discussion must contain at least one nonblank paragraph after
trimming blank items. precipitation_timing and confidence are optional and
omitted from normalized JSON when blank. Unknown fields are rejected.
The report-specific Go API is:
| Report | Type | Validator | Schema ID | Template ID | Prompt ID |
|---|---|---|---|---|---|
| Daily Report | Daily |
ValidateDaily |
daily |
daily |
weather.daily_generated_text |
| Today Report | Today |
ValidateToday |
today |
today |
weather.today_generated_text |
| Tomorrow Report | Tomorrow |
ValidateTomorrow |
tomorrow |
tomorrow |
weather.tomorrow_generated_text |
Hourly generated text uses the same top-level field names, but
forecast_discussion is a single string:
{
"summary": "string",
"forecast_discussion": "string",
"precipitation_timing": "string",
"confidence": "string"
}
Hourly summary and forecast_discussion are required after trimming
whitespace. precipitation_timing and confidence are optional and omitted
from normalized JSON when blank. Unknown fields are rejected. The Hourly catalog
entry uses type Hourly, validator ValidateHourly, schema ID hourly,
template ID hourly, and prompt ID weather.hourly_generated_text.
Render Contexts
Daily, Today, Tomorrow, and Hourly render contexts all include:
- display metadata derived from report metadata;
- validated generated text;
- typed module outputs decoded from the module snapshot;
- collected facts;
- derived facts.
Daily, Today, and Tomorrow share common civil-day render-context fields such as forecast date labels, valid period, generated-at labels, current conditions, hourly forecast, precipitation timing, alert digest, SPC outlooks, AFD, SPC discussion, weather story, daily summary, and ordered daypart summaries.
Each civil-day report keeps its report-specific planning module:
- Daily exposes
DailyPlanning. - Today exposes
TodayPlanning. - Tomorrow exposes
TomorrowPlanning.
Today's ordered daypart context omits unavailable or elapsed dayparts according to Today report rules. Daily and Tomorrow use fallback daypart behavior.
Boundaries
- This package owns typed generated-text validation and render-context shaping.
- It owns generated-text catalog lookup for schema/template combinations.
- It uses typed module snapshot decoding through
module.StanzaValue. - It does not invoke Scriptorium, write state artifacts, choose report definitions, compare snapshots, or own embedded template/schema files.
- It renders through
internal/reporttemplate; embedded asset lookup remains ininternal/reporttemplate. - It does not use a Go JSON Schema dependency; schema enforcement in Go is limited to typed JSON decoding, unknown-field rejection, and required-field checks.
Failure Behavior
- Malformed generated-text JSON fails with decode context.
- Unknown generated-text JSON fields fail during decoding.
- Empty required fields fail after trimming whitespace.
- Daily, Today, and Tomorrow forecast discussion fails when no nonblank paragraphs remain.
- Missing optional render-context stanzas become nil module pointers.
- Invalid render metadata, including missing timezone, missing generated time, or invalid valid period, fails before template rendering.
- Unsupported generated-text schema IDs, template IDs, or schema/template combinations fail during catalog lookup with report ID context.
Tests
Inspect:
internal/generatedtext/hourly_test.gointernal/generatedtext/daily_test.gointernal/generatedtext/today_test.gointernal/generatedtext/tomorrow_test.gointernal/generatedtext/catalog_test.gointernal/generatedtext/render_context_test.go
Invariants
- Render contexts are curated structs, not raw prompt-input packages.
- Required generated text is normalized before downstream artifact storage.
- Generated-text-template reports must have one catalog entry matching their report definition schema and template IDs.
- Missing optional weather narrative stanzas produce empty or fallback render context fields rather than forcing raw module data into templates.