150 lines
5.6 KiB
Markdown
150 lines
5.6 KiB
Markdown
# 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 `Daily` generated text
|
|
- typed `Today` generated text
|
|
- typed `Tomorrow` generated text
|
|
- typed `Hourly` generated text
|
|
- normalized stable JSON for validated generated text
|
|
- typed `DailyRenderContext` values for `internal/reporttemplate`
|
|
- typed `TodayRenderContext` values for `internal/reporttemplate`
|
|
- typed `TomorrowRenderContext` values for `internal/reporttemplate`
|
|
- typed `HourlyRenderContext` values for `internal/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:
|
|
|
|
```json
|
|
{
|
|
"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:
|
|
|
|
```json
|
|
{
|
|
"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
|
|
in `internal/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.go`
|
|
- `internal/generatedtext/daily_test.go`
|
|
- `internal/generatedtext/today_test.go`
|
|
- `internal/generatedtext/tomorrow_test.go`
|
|
- `internal/generatedtext/catalog_test.go`
|
|
- `internal/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.
|