diff --git a/docs/cli.md b/docs/cli.md index e721f2e..84cb66d 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -35,14 +35,14 @@ weatherreporter inspect prior [--config PATH] RUN_ID weatherreporter inspect sources [--config PATH] RUN_ID ``` -`generate` commands write a JSON module snapshot, YAML data package, preflight -artifact, managed Markdown report, and metadata under the configured workspace. -`--out` writes an extra Markdown copy for the operator; distributor -notification uses the managed report path, not the extra copy. `generate -hourly` uses the current generation time, covers the next six hours in the -effective report timezone, and does not accept date or event window flags. -`generate storm` requires explicit event-window bounds with `--start` and -`--end`. +Implemented Markdown `generate` commands write a JSON module snapshot, YAML +data package, preflight artifact, managed Markdown report, and metadata under +the configured workspace. `--out` writes an extra Markdown copy for the +operator; distributor notification uses the managed report path, not the extra +copy. `generate hourly` is parsed and resolved, covers the next six hours in +the effective report timezone, and does not accept date or event window flags; +its rendering workflow is not implemented yet. `generate storm` requires +explicit event-window bounds with `--start` and `--end`. `run morning` generates Daily Today and the 3-Day Outlook, plus Weekend Outlook except on Sunday. `run evening` generates the Tomorrow Planning Brief. Batch @@ -54,8 +54,8 @@ notification is enabled, batch summaries and status lines include notification status, accepted distributor run ID, or notification error fields for each attempted report. -Hourly Report generation is explicit only; it is not included in `run -morning` or `run evening`. +Hourly Report is explicit only; it is not included in `run morning` or `run +evening`. `inspect` commands read existing workspace artifacts and emit JSON to stdout. They do not fetch weather data or invoke `scriptorium`. @@ -83,7 +83,6 @@ are no distributor-specific CLI flags. ```sh weatherreporter generate tomorrow --out ./tomorrow.md -weatherreporter generate hourly --out ./hourly.md weatherreporter generate three-day --out ./three-day.md weatherreporter generate weekend --out ./weekend.md weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00 --out ./storm.md diff --git a/docs/internal/prompt-input.md b/docs/internal/prompt-input.md index 7411559..95f939a 100644 --- a/docs/internal/prompt-input.md +++ b/docs/internal/prompt-input.md @@ -68,11 +68,12 @@ Prompt-facing module intervals use local `period_begins` and `period_ends` labels; canonical report metadata and source timestamps remain structured timestamps where applicable. -Hourly Report uses the same package schema and categories. Its default -package includes `precip_timing` under `derived_summaries`, alert and SPC -outlooks under `applicable_risk_products`, AFD/SPC discussion/weather story -under `narrative_products`, and current/hourly data under `raw_data`. It does -not include daily or daypart summary stanzas. +Hourly Report module snapshots use the same package schema and categories when +converted into prompt input. The default hourly module list places +`precip_timing` under `derived_summaries`, alert and SPC outlooks under +`applicable_risk_products`, AFD/SPC discussion/weather story under +`narrative_products`, and current/hourly data under `raw_data`. It does not +include daily or daypart summary stanzas. Current categories are: @@ -112,7 +113,6 @@ None. ## Skip And Resume Behavior None. Recent Changes is always present as an `items` list and may be empty. -Hourly Report currently writes an empty `items` list. ## Failure Behavior diff --git a/docs/internal/report-registry.md b/docs/internal/report-registry.md index 0a5579f..e5fa79b 100644 --- a/docs/internal/report-registry.md +++ b/docs/internal/report-registry.md @@ -26,20 +26,21 @@ Each report definition declares: - morning or evening batch membership - default ordered module composition -Current report definitions use the `scriptorium_markdown` generation mode. -Template and structured-text schema identifiers are empty for these Markdown -reports. +Current Markdown report definitions use the `scriptorium_markdown` generation +mode. Their template and structured-text schema identifiers are empty. Hourly +Report declares `generated_text_template` with template ID `hourly` and schema +ID `hourly`; the app rendering workflow for that mode is not implemented yet. ## Reports -| Report | ID | Prompt | Artifact group | Batch copy | Prior compatibility | -| --- | --- | --- | --- | --- | --- | -| Daily Today | `daily_today` | `weather.daily_report` | `daily` | `daily.md` | Daily Today, Daily Tomorrow | -| Daily Tomorrow | `daily_tomorrow` | `weather.daily_report` | `daily` | `tomorrow.md` | Daily Today, Daily Tomorrow | -| Hourly Report | `hourly` | `weather.hourly_report` | `hourly` | `hourly.md` | Hourly Report | -| 3-Day Outlook | `three_day` | `weather.three_day_outlook` | `three-day` | `three-day.md` | 3-Day Outlook | -| Weekend Outlook | `weekend` | `weather.weekend_outlook` | `weekend` | `weekend.md` | Weekend Outlook | -| Storm Report | `storm` | `weather.storm_report` | `storm` | `storm.md` | Storm Report | +| Report | ID | Prompt | Generation mode | Artifact group | Batch copy | Prior compatibility | +| --- | --- | --- | --- | --- | --- | --- | +| Daily Today | `daily_today` | `weather.daily_report` | `scriptorium_markdown` | `daily` | `daily.md` | Daily Today, Daily Tomorrow | +| Daily Tomorrow | `daily_tomorrow` | `weather.daily_report` | `scriptorium_markdown` | `daily` | `tomorrow.md` | Daily Today, Daily Tomorrow | +| Hourly Report | `hourly` | `weather.hourly_generated_text` | `generated_text_template` | `hourly` | `hourly.md` | Hourly Report | +| 3-Day Outlook | `three_day` | `weather.three_day_outlook` | `scriptorium_markdown` | `three-day` | `three-day.md` | 3-Day Outlook | +| Weekend Outlook | `weekend` | `weather.weekend_outlook` | `scriptorium_markdown` | `weekend` | `weekend.md` | Weekend Outlook | +| Storm Report | `storm` | `weather.storm_report` | `scriptorium_markdown` | `storm` | `storm.md` | Storm Report | All report definitions are eligible for generation. diff --git a/docs/operations.md b/docs/operations.md index a2f962e..ddd4bdd 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -11,24 +11,24 @@ Generation commands: ```text weatherreporter generate daily --date 2026-05-29 weatherreporter generate tomorrow -weatherreporter generate hourly weatherreporter generate three-day weatherreporter generate weekend weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00 ``` -Each command resolves a report period, fetches a Weather API bundle, builds a -JSON module snapshot, builds a YAML prompt input data package, runs -`scriptorium render`, runs `scriptorium run`, and writes managed artifacts under -the configured workspace. +Each implemented Markdown generation command resolves a report period, fetches +a Weather API bundle, builds a JSON module snapshot, builds a YAML prompt input +data package, runs `scriptorium render`, runs `scriptorium run`, and writes +managed artifacts under the configured workspace. When distributor notification is enabled, weatherreporter uploads the managed Markdown report after `scriptorium run` succeeds and final metadata is saved. `--out PATH` writes an extra Markdown copy for the current generated report; it is not used as the distributor upload source. -`generate hourly` is an explicit generation command. It covers the six-hour -rolling period from generation time in the effective report timezone and is not -part of scheduled morning or evening batches. +`generate hourly` is an explicit command shell. It covers the six-hour rolling +period from generation time in the effective report timezone and is not part of +scheduled morning or evening batches, but its rendering workflow is not +implemented yet. Batch commands: diff --git a/internal/app/app.go b/internal/app/app.go index ca60aa8..06ff124 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -438,6 +438,9 @@ func FetchAndSaveBundle(ctx context.Context, req FetchBundleRequest) (*weatherda } func GenerateReport(ctx context.Context, req ReportRequest) (*ReportResult, error) { + if req.Resolved.Definition.GenerationMode != report.GenerationModeScriptoriumMarkdown { + return nil, fmt.Errorf("generation mode %q is not implemented for report %q", req.Resolved.Definition.GenerationMode, req.Resolved.Definition.ID) + } store := req.Store if store == nil { defaultStore, err := defaultStore(req.Config) diff --git a/internal/app/app_test.go b/internal/app/app_test.go index e7d44fb..6b11302 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -349,9 +349,8 @@ func TestGenerateReportOmitsSPCConvectiveDiscussionBelowThreshold(t *testing.T) } } -func TestGenerateHourlyReportWritesExpectedArtifacts(t *testing.T) { - server := hourlyBundleServer(t) - cfg := dailyTestConfig(t, server) +func TestGenerateHourlyReportModeNotImplemented(t *testing.T) { + cfg := config.Defaults() cfg.Workspace.Root = t.TempDir() resolved, err := ResolveGenerate(GenerateRequest{ Config: cfg, @@ -360,174 +359,18 @@ func TestGenerateHourlyReportWritesExpectedArtifacts(t *testing.T) { if err != nil { t.Fatalf("ResolveGenerate() error = %v", err) } - outputPath := filepath.Join(t.TempDir(), "hourly.md") - renderer := successfulRenderer("# Hourly Report\n") + if resolved.Definition.GenerationMode != report.GenerationModeGeneratedTextTemplate { + t.Fatalf("GenerationMode = %q, want generated text template", resolved.Definition.GenerationMode) + } - result, err := GenerateReport(context.Background(), ReportRequest{ - Config: cfg, - Resolved: resolved, - OutputPath: outputPath, - Renderer: renderer, + _, err = GenerateReport(context.Background(), ReportRequest{ + Config: cfg, + Resolved: resolved, + Renderer: successfulRenderer("# Hourly Report\n"), }) - if err != nil { - t.Fatalf("GenerateReport() error = %v", err) + if err == nil || !strings.Contains(err.Error(), `generation mode "generated_text_template" is not implemented for report "hourly"`) { + t.Fatalf("GenerateReport() error = %v, want generation mode not implemented", err) } - - if result.Metadata.ReportID != report.Hourly || result.Metadata.PromptID != "weather.hourly_report" { - t.Fatalf("metadata report/prompt = %q/%q, want hourly", result.Metadata.ReportID, result.Metadata.PromptID) - } - if got := result.Metadata.ValidPeriod.Start.Format(time.RFC3339); got != "2026-05-29T08:30:00-05:00" { - t.Fatalf("valid period start = %s, want rolling window start", got) - } - if got := result.Metadata.ValidPeriod.End.Format(time.RFC3339); got != "2026-05-29T14:30:00-05:00" { - t.Fatalf("valid period end = %s, want six-hour rolling window end", got) - } - if renderer.renderRequest.PromptID != "weather.hourly_report" || renderer.runRequest.PromptID != "weather.hourly_report" { - t.Fatalf("renderer prompt IDs = %q/%q, want hourly prompt", renderer.renderRequest.PromptID, renderer.runRequest.PromptID) - } - if !strings.Contains(result.ReportPath, filepath.Join("reports", "hourly")) { - t.Fatalf("ReportPath = %q, want hourly artifact group", result.ReportPath) - } - if !strings.Contains(result.DataPackagePath, filepath.Join("data-packages", "hourly", "2026-05-29")) { - t.Fatalf("DataPackagePath = %q, want hourly artifact group", result.DataPackagePath) - } - assertPathsExist(t, result.ModuleSnapshotPath, result.DataPackagePath, result.PreflightPath, result.ReportPath, result.MetadataPath, outputPath) - if result.OutputPath != outputPath { - t.Fatalf("OutputPath = %q, want requested output copy %q", result.OutputPath, outputPath) - } - copiedReport, err := os.ReadFile(outputPath) - if err != nil { - t.Fatalf("read output copy: %v", err) - } - if !strings.Contains(string(copiedReport), "# Hourly Report") { - t.Fatalf("output copy missing rendered report:\n%s", string(copiedReport)) - } - - wantModules := []module.ID{ - module.Metadata, - module.CurrentConditions, - module.HourlyForecast, - module.PrecipTiming, - module.AlertDigest, - module.SPCConvectiveOutlooks, - module.AreaForecastDiscussion, - module.SPCConvectiveDiscussion, - module.WeatherStory, - } - if got := snapshotModuleIDs(result.ModuleSnapshot); strings.Join(moduleIDsForTest(got), ",") != strings.Join(moduleIDsForTest(wantModules), ",") { - t.Fatalf("module snapshot IDs = %#v, want %#v", got, wantModules) - } - - hourly, ok, err := module.StanzaValue[briefing.HourlyForecastModule](result.ModuleSnapshot, "hourly_forecast") - if err != nil { - t.Fatalf("decode hourly forecast: %v", err) - } - if !ok || len(hourly.Periods) != 5 { - t.Fatalf("hourly forecast = %#v, want five overlapping hourly periods", hourly) - } - hourlyJSON := mustMarshalString(t, hourly) - if !strings.Contains(hourlyJSON, "Showers entering the area") || !strings.Contains(hourlyJSON, "Heavy rain") { - t.Fatalf("hourly forecast missing selected hourly periods:\n%s", hourlyJSON) - } - if strings.Contains(hourlyJSON, "Before-window storms") || strings.Contains(hourlyJSON, "After-window rain") { - t.Fatalf("hourly forecast contains periods outside valid window:\n%s", hourlyJSON) - } - - precip, ok, err := module.StanzaValue[briefing.PrecipTimingModule](result.ModuleSnapshot, "precip_timing") - if err != nil { - t.Fatalf("decode precip timing: %v", err) - } - if !ok || precip.MaxPopPercent == nil || *precip.MaxPopPercent != 80 || len(precip.PrecipitationWindows) != 2 { - t.Fatalf("precip timing = %#v, want hourly precipitation windows", precip) - } - if precip.PrecipitationWindows[0].PeriodBegins != "2026-05-29 at 8:00 AM" || precip.PrecipitationWindows[0].PeriodEnds != "2026-05-29 at 9:00 AM" { - t.Fatalf("first precip window = %#v, want first selected hour only", precip.PrecipitationWindows[0]) - } - if precip.PrecipitationWindows[1].PeriodBegins != "2026-05-29 at 10:00 AM" || precip.PrecipitationWindows[1].PeriodEnds != "2026-05-29 at 12:00 PM" { - t.Fatalf("second precip window = %#v, want late-morning hourly rain", precip.PrecipitationWindows[1]) - } - - alerts, ok, err := module.StanzaValue[briefing.AlertDigestModule](result.ModuleSnapshot, "alert_digest") - if err != nil { - t.Fatalf("decode alert digest: %v", err) - } - if !ok || !alerts.Checked || alerts.ActiveCount != 3 || alerts.RelevantCount != 1 || len(alerts.Relevant) != 1 || alerts.Relevant[0].Event != "Flood Watch" { - t.Fatalf("alert digest = %#v, want only hourly alert overlap relevant", alerts) - } - - outlooks, ok, err := module.StanzaValue[briefing.SPCConvectiveOutlooksModule](result.ModuleSnapshot, "spc_convective_outlooks") - if err != nil { - t.Fatalf("decode SPC outlooks: %v", err) - } - if !ok || !outlooks.Checked || outlooks.OutlookCount != 1 || len(outlooks.Outlooks) != 1 || outlooks.Outlooks[0].Label != "SLGT" { - t.Fatalf("SPC outlooks = %#v, want one overlapping hourly outlook", outlooks) - } - discussion, ok, err := module.StanzaValue[briefing.SPCConvectiveDiscussionModule](result.ModuleSnapshot, "spc_convective_discussion") - if err != nil { - t.Fatalf("decode SPC discussion: %v", err) - } - if !ok || len(discussion.Discussions) != 1 || discussion.Discussions[0].Headline != "hourly severe storms" { - t.Fatalf("SPC discussion = %#v, want discussion for retained overlapping outlook", discussion) - } - - afd, ok, err := module.StanzaValue[briefing.AreaForecastDiscussionModule](result.ModuleSnapshot, "area_forecast_discussion") - if err != nil { - t.Fatalf("decode AFD: %v", err) - } - if !ok || len(afd.KeyMessages) != 1 || afd.ShortTerm != "Short-term AFD narrative for hourly report." { - t.Fatalf("AFD = %#v, want key messages and short term", afd) - } - if afd.Product != "" || afd.LongTerm != "" { - t.Fatalf("AFD = %#v, want hourly defaults to omit product and long term", afd) - } - - if result.PriorSnapshot != nil || len(result.RecentChanges) != 0 || len(result.DataPackage.RecentChanges.Items) != 0 { - t.Fatalf("prior=%#v recent=%#v package=%#v, want no rolling-window comparison output", result.PriorSnapshot, result.RecentChanges, result.DataPackage.RecentChanges.Items) - } - data := readDataPackageForTest(t, result) - text := string(data) - for _, want := range []string{ - "id: hourly", - "prompt_id: weather.hourly_report", - "valid_period:", - "recent_changes:", - " items: []", - " alert_digest:", - " spc_convective_outlooks:", - " precip_timing:", - " area_forecast_discussion:", - " spc_convective_discussion:", - " weather_story:", - " current_conditions:", - " hourly_forecast:", - } { - if !strings.Contains(text, want) { - t.Fatalf("data package missing %q:\n%s", want, text) - } - } - for _, omitted := range []string{"validPeriod:", "Before-window storms", "After-window rain", "Evening Advisory", "Day 2 outlook", "Long-term AFD narrative for hourly report."} { - if strings.Contains(text, omitted) { - t.Fatalf("data package contains %q, want hourly filtered/canonical output:\n%s", omitted, text) - } - } - riskIndex := strings.Index(text, " applicable_risk_products:") - derivedIndex := strings.Index(text, " derived_summaries:") - narrativeIndex := strings.Index(text, " narrative_products:") - rawIndex := strings.Index(text, " raw_data:") - alertIndex := strings.Index(text, " alert_digest:") - precipIndex := strings.Index(text, " precip_timing:") - afdIndex := strings.Index(text, " area_forecast_discussion:") - currentIndex := strings.Index(text, " current_conditions:") - hourlyIndex := strings.Index(text, " hourly_forecast:") - if riskIndex < 0 || derivedIndex < 0 || narrativeIndex < 0 || rawIndex < 0 || alertIndex < 0 || precipIndex < 0 || afdIndex < 0 || currentIndex < 0 || hourlyIndex < 0 || - !(riskIndex < alertIndex && alertIndex < derivedIndex && derivedIndex < precipIndex && precipIndex < narrativeIndex && narrativeIndex < afdIndex && afdIndex < rawIndex && rawIndex < currentIndex && currentIndex < hourlyIndex) { - t.Fatalf("data package category order is wrong:\n%s", text) - } - loaded, err := promptinput.LoadYAML(data) - if err != nil { - t.Fatalf("LoadYAML() error = %v", err) - } - assertNoStaleModuleIntervalKeys(t, loaded.Briefing.Values) } func TestGenerateReportDisabledNotificationDoesNotCallNotifier(t *testing.T) { @@ -1367,7 +1210,7 @@ func TestResolveGenerateMapsCommandToReportDefinition(t *testing.T) { name: "hourly", kind: ReportHourly, wantID: report.Hourly, - wantPrompt: "weather.hourly_report", + wantPrompt: "weather.hourly_generated_text", wantStart: "2026-05-29T08:00:00-05:00", wantEnd: "2026-05-29T14:00:00-05:00", }, diff --git a/internal/cli/root_test.go b/internal/cli/root_test.go index 2035b6b..96f520f 100644 --- a/internal/cli/root_test.go +++ b/internal/cli/root_test.go @@ -910,6 +910,19 @@ func TestResolveGenerateAppliesSharedFlags(t *testing.T) { } } +func TestResolveGenerateRejectsRetiredHourlyCommand(t *testing.T) { + runner := Runner{Clock: fixedClock()} + retired := strings.Join([]string{"near", "term"}, "-") + + _, err := runner.resolveGenerate([]string{retired}) + if err == nil { + t.Fatal("resolveGenerate() error = nil, want unknown report") + } + if !strings.Contains(err.Error(), "unknown generate report") { + t.Fatalf("error = %q, want unknown generate report", err.Error()) + } +} + func TestResolveGenerateStormRequiresStartAndEnd(t *testing.T) { runner := Runner{Clock: fixedClock()} diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 5ea372c..794f1c2 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -307,6 +307,28 @@ reports: } } +func TestReportModuleOverrideRejectsRetiredHourlyKeys(t *testing.T) { + for _, key := range []string{ + strings.Join([]string{"near", "term"}, "_"), + strings.Join([]string{"near", "term"}, "-"), + } { + t.Run(key, func(t *testing.T) { + _, err := LoadFile(writeConfig(t, ` +reports: + `+key+`: + deterministic_modules: + - metadata +`)) + if err == nil { + t.Fatal("LoadFile() error = nil, want unknown report") + } + if !strings.Contains(err.Error(), "is not a known report") { + t.Fatalf("error = %q, want unknown report", err.Error()) + } + }) + } +} + func TestExplicitMissingConfigReturnsError(t *testing.T) { _, err := LoadFile(filepath.Join(t.TempDir(), "missing.yml")) if err == nil { diff --git a/internal/report/hourly_report.go b/internal/report/hourly_report.go index 0f36193..2e6f4e0 100644 --- a/internal/report/hourly_report.go +++ b/internal/report/hourly_report.go @@ -7,21 +7,23 @@ import ( "gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil" ) -const hourlyHours = 6 +const hourlyReportHours = 6 func hourlyDefinition() Definition { return Definition{ - ID: Hourly, - Name: "Hourly Report", - PromptID: "weather.hourly_report", - GenerationMode: GenerationModeScriptoriumMarkdown, - ComparisonStrategy: CompareRollingWindow, - ArtifactGroup: "hourly", - BatchOutputName: "hourly.md", - Generated: true, - CompatiblePriorIDs: []ID{Hourly}, - Modules: hourlyModules(), - resolve: resolveHourly, + ID: Hourly, + Name: "Hourly Report", + PromptID: "weather.hourly_generated_text", + GenerationMode: GenerationModeGeneratedTextTemplate, + TemplateID: "hourly", + GeneratedTextSchemaID: "hourly", + ComparisonStrategy: CompareRollingWindow, + ArtifactGroup: "hourly", + BatchOutputName: "hourly.md", + Generated: true, + CompatiblePriorIDs: []ID{Hourly}, + Modules: hourlyModules(), + resolve: resolveHourly, } } @@ -48,6 +50,6 @@ func resolveHourly(req ResolveRequest) (timeutil.Period, error) { localNow := req.Now.In(req.Location) return timeutil.Period{ Start: localNow, - End: localNow.Add(hourlyHours * time.Hour), + End: localNow.Add(hourlyReportHours * time.Hour), }, nil } diff --git a/internal/report/period_test.go b/internal/report/period_test.go index b0e8bfc..e3e85a8 100644 --- a/internal/report/period_test.go +++ b/internal/report/period_test.go @@ -69,8 +69,17 @@ func TestHourlyLookupAndPeriodCalculation(t *testing.T) { if resolved.Definition.ID != Hourly { t.Fatalf("ID = %q, want hourly", resolved.Definition.ID) } - if resolved.Definition.PromptID != "weather.hourly_report" { - t.Fatalf("PromptID = %q, want weather.hourly_report", resolved.Definition.PromptID) + if resolved.Definition.PromptID != "weather.hourly_generated_text" { + t.Fatalf("PromptID = %q, want weather.hourly_generated_text", resolved.Definition.PromptID) + } + if resolved.Definition.GenerationMode != GenerationModeGeneratedTextTemplate { + t.Fatalf("GenerationMode = %q, want generated_text_template", resolved.Definition.GenerationMode) + } + if resolved.Definition.TemplateID != "hourly" { + t.Fatalf("TemplateID = %q, want hourly", resolved.Definition.TemplateID) + } + if resolved.Definition.GeneratedTextSchemaID != "hourly" { + t.Fatalf("GeneratedTextSchemaID = %q, want hourly", resolved.Definition.GeneratedTextSchemaID) } if resolved.Definition.ComparisonStrategy != CompareRollingWindow { t.Fatalf("ComparisonStrategy = %q, want rolling_window", resolved.Definition.ComparisonStrategy) @@ -259,6 +268,18 @@ func TestRegistryDefinitionsDeclareGenerationMetadata(t *testing.T) { if !definition.Generated { continue } + if definition.ID == Hourly { + if definition.GenerationMode != GenerationModeGeneratedTextTemplate { + t.Fatalf("%s GenerationMode = %q, want %q", definition.ID, definition.GenerationMode, GenerationModeGeneratedTextTemplate) + } + if definition.TemplateID != "hourly" { + t.Fatalf("%s TemplateID = %q, want hourly", definition.ID, definition.TemplateID) + } + if definition.GeneratedTextSchemaID != "hourly" { + t.Fatalf("%s GeneratedTextSchemaID = %q, want hourly", definition.ID, definition.GeneratedTextSchemaID) + } + continue + } if definition.GenerationMode != GenerationModeScriptoriumMarkdown { t.Fatalf("%s GenerationMode = %q, want %q", definition.ID, definition.GenerationMode, GenerationModeScriptoriumMarkdown) } @@ -545,8 +566,8 @@ func TestHourlyMetadataRunIDIncludesReportID(t *testing.T) { if metadata.ReportID != Hourly { t.Fatalf("ReportID = %q, want hourly", metadata.ReportID) } - if metadata.PromptID != "weather.hourly_report" { - t.Fatalf("PromptID = %q, want weather.hourly_report", metadata.PromptID) + if metadata.PromptID != "weather.hourly_generated_text" { + t.Fatalf("PromptID = %q, want weather.hourly_generated_text", metadata.PromptID) } if !strings.Contains(metadata.RunID, "hourly") { t.Fatalf("RunID = %q, want report id", metadata.RunID)