Replace legacy daily report with generated text daily report
This commit is contained in:
@@ -105,6 +105,11 @@ func TestGenerateReportWritesReportAndPreflight(t *testing.T) {
|
||||
ExitCode: 0,
|
||||
OutputPath: "",
|
||||
},
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{
|
||||
Command: []string{"scriptorium", "run"},
|
||||
Stderr: "wrote generated text",
|
||||
ExitCode: 0,
|
||||
},
|
||||
runBody: "# Daily Report\n\nRain this morning.\n",
|
||||
}
|
||||
outputPath := filepath.Join(t.TempDir(), "daily.md")
|
||||
@@ -128,25 +133,28 @@ func TestGenerateReportWritesReportAndPreflight(t *testing.T) {
|
||||
if renderer.renderCalls != 1 {
|
||||
t.Fatalf("render calls = %d, want 1", renderer.renderCalls)
|
||||
}
|
||||
if renderer.runCalls != 1 {
|
||||
t.Fatalf("run calls = %d, want 1", renderer.runCalls)
|
||||
if renderer.structuredRunCalls != 1 {
|
||||
t.Fatalf("structured run calls = %d, want 1", renderer.structuredRunCalls)
|
||||
}
|
||||
if renderer.renderRequest.PromptID != "weather.daily_report" {
|
||||
t.Fatalf("render PromptID = %q, want weather.daily_report", renderer.renderRequest.PromptID)
|
||||
if renderer.runCalls != 0 {
|
||||
t.Fatalf("markdown run calls = %d, want none", renderer.runCalls)
|
||||
}
|
||||
if renderer.renderRequest.PromptID != "weather.daily_generated_text" {
|
||||
t.Fatalf("render PromptID = %q, want weather.daily_generated_text", renderer.renderRequest.PromptID)
|
||||
}
|
||||
if renderer.renderRequest.DataPackagePath != result.DataPackagePath {
|
||||
t.Fatalf("render DataPackagePath = %q, want managed path %q", renderer.renderRequest.DataPackagePath, result.DataPackagePath)
|
||||
}
|
||||
if renderer.runRequest.DataPackagePath != result.DataPackagePath {
|
||||
t.Fatalf("run DataPackagePath = %q, want managed path %q", renderer.runRequest.DataPackagePath, result.DataPackagePath)
|
||||
if renderer.structuredRunRequest.DataPackagePath != result.DataPackagePath {
|
||||
t.Fatalf("structured run DataPackagePath = %q, want managed path %q", renderer.structuredRunRequest.DataPackagePath, result.DataPackagePath)
|
||||
}
|
||||
if renderer.runRequest.OutputPath != result.ReportPath {
|
||||
t.Fatalf("run OutputPath = %q, want managed report path %q", renderer.runRequest.OutputPath, result.ReportPath)
|
||||
if renderer.structuredRunRequest.OutputPath != result.GeneratedTextRawPath {
|
||||
t.Fatalf("structured run OutputPath = %q, want raw generated text path %q", renderer.structuredRunRequest.OutputPath, result.GeneratedTextRawPath)
|
||||
}
|
||||
if got, want := strings.Join(store.calls, ","), "module_snapshot,data_package,preflight,metadata,prepare_report,metadata"; !strings.HasPrefix(got, want) {
|
||||
if got, want := strings.Join(store.calls, ","), "module_snapshot,data_package,preflight,metadata,generated_text_result,metadata,generated_text,metadata,render_context,metadata,prepare_report,metadata"; !strings.HasPrefix(got, want) {
|
||||
t.Fatalf("store calls = %v, want prefix %s", store.calls, want)
|
||||
}
|
||||
assertPathsExist(t, result.ModuleSnapshotPath, result.DataPackagePath, result.PreflightPath, result.ReportPath, result.MetadataPath, outputPath)
|
||||
assertPathsExist(t, result.ModuleSnapshotPath, result.DataPackagePath, result.PreflightPath, result.GeneratedTextRawPath, result.GeneratedTextResultPath, result.GeneratedTextPath, result.RenderContextPath, result.ReportPath, result.MetadataPath, outputPath)
|
||||
snapshotData, err := os.ReadFile(result.ModuleSnapshotPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read module snapshot: %v", err)
|
||||
@@ -252,7 +260,7 @@ func TestGenerateReportWritesReportAndPreflight(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("read report output: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(report), "# Daily Report") {
|
||||
if !strings.Contains(string(report), "# Friday's Weather") {
|
||||
t.Fatalf("report output missing markdown:\n%s", string(report))
|
||||
}
|
||||
}
|
||||
@@ -754,8 +762,7 @@ func TestGenerateReportSavesFinalMetadataForMarkdownAndGeneratedTextReports(t *t
|
||||
cfg.Workspace.Root = t.TempDir()
|
||||
resolved, err := ResolveGenerate(GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportDaily,
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
Report: ReportThreeDay,
|
||||
}, mustParse("2026-05-29T05:00:00-05:00"))
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveGenerate() error = %v", err)
|
||||
@@ -764,7 +771,7 @@ func TestGenerateReportSavesFinalMetadataForMarkdownAndGeneratedTextReports(t *t
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Resolved: resolved,
|
||||
Renderer: successfulRenderer("# Daily Report\n"),
|
||||
Renderer: successfulRenderer("# 3-Day Outlook\n"),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
@@ -1125,7 +1132,7 @@ func TestGenerateReportNotifiesManagedReportPath(t *testing.T) {
|
||||
if req.PipelineID != "weatherreporter.daily" {
|
||||
t.Fatalf("notification PipelineID = %q, want rendered pipeline", req.PipelineID)
|
||||
}
|
||||
if req.BundleID != "weatherreporter.home.daily_today" {
|
||||
if req.BundleID != "weatherreporter.home.daily" {
|
||||
t.Fatalf("notification BundleID = %q, want default template", req.BundleID)
|
||||
}
|
||||
if req.IdempotencyKey != req.BundleID+"."+result.Metadata.RunID {
|
||||
@@ -1208,10 +1215,9 @@ func TestGenerateReportDoesNotNotifyAfterRenderOrRunFailure(t *testing.T) {
|
||||
{
|
||||
name: "Run",
|
||||
renderer: &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 2, Stderr: "run failed"},
|
||||
runErr: errors.New("run failed"),
|
||||
runBody: "# Daily Report\n",
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{ExitCode: 2, Stderr: "run failed"},
|
||||
structuredRunErr: errors.New("run failed"),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1350,12 +1356,11 @@ func TestGenerateReportReturnsRunErrorAfterPreflight(t *testing.T) {
|
||||
}
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{
|
||||
Stderr: "validation failed",
|
||||
ExitCode: 2,
|
||||
},
|
||||
runErr: errors.New("scriptorium run exited with code 2: validation failed"),
|
||||
runBody: "# Daily Report\n",
|
||||
structuredRunErr: errors.New("scriptorium run exited with code 2: validation failed"),
|
||||
}
|
||||
|
||||
_, err = GenerateReport(context.Background(), ReportRequest{
|
||||
@@ -1366,8 +1371,8 @@ func TestGenerateReportReturnsRunErrorAfterPreflight(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("GenerateReport() error = nil, want run error")
|
||||
}
|
||||
if renderer.renderCalls != 1 || renderer.runCalls != 1 {
|
||||
t.Fatalf("calls render=%d run=%d, want one of each", renderer.renderCalls, renderer.runCalls)
|
||||
if renderer.renderCalls != 1 || renderer.structuredRunCalls != 1 || renderer.runCalls != 0 {
|
||||
t.Fatalf("calls render=%d structured=%d run=%d, want render and structured run only", renderer.renderCalls, renderer.structuredRunCalls, renderer.runCalls)
|
||||
}
|
||||
store, err := state.NewFilesystemStore(cfg.Workspace)
|
||||
if err != nil {
|
||||
@@ -1380,8 +1385,11 @@ func TestGenerateReportReturnsRunErrorAfterPreflight(t *testing.T) {
|
||||
if _, err := os.Stat(paths.Metadata); err != nil {
|
||||
t.Fatalf("expected metadata for failed run %q: %v", paths.Metadata, err)
|
||||
}
|
||||
if _, err := os.Stat(paths.RenderedReport); err != nil {
|
||||
t.Fatalf("expected report from validation exit %q: %v", paths.RenderedReport, err)
|
||||
if _, err := os.Stat(paths.GeneratedTextRaw); err != nil {
|
||||
t.Fatalf("expected raw generated text from failed run %q: %v", paths.GeneratedTextRaw, err)
|
||||
}
|
||||
if _, err := os.Stat(paths.RenderedReport); !os.IsNotExist(err) {
|
||||
t.Fatalf("rendered report exists after failed generated-text run: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2552,6 +2560,10 @@ func validTodayGeneratedTextJSON() string {
|
||||
return `{"summary":"Today starts with showers before improving.","forecast_discussion":["Morning showers should taper as drier air arrives.","Afternoon conditions trend quieter."],"precipitation_timing":"The best rain chance is during the morning."}`
|
||||
}
|
||||
|
||||
func validDailyGeneratedTextJSON() string {
|
||||
return `{"summary":"Showers are possible during the selected day.","forecast_discussion":["A front will keep rain chances in the forecast.","Temperatures stay seasonable by afternoon."],"precipitation_timing":"Rain is most likely during the afternoon.","confidence":"Medium"}`
|
||||
}
|
||||
|
||||
func generateDailyReportForTest(t *testing.T, cfg config.Config) *ReportResult {
|
||||
t.Helper()
|
||||
cfg.Workspace.Root = t.TempDir()
|
||||
@@ -2835,9 +2847,10 @@ func (s *recordingStore) SaveMetadata(ctx context.Context, metadata state.Metada
|
||||
|
||||
func successfulRenderer(body string) *recordingRenderer {
|
||||
return &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: body,
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{ExitCode: 0},
|
||||
runBody: body,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2913,6 +2926,9 @@ func (r *selectiveRenderer) StructuredRun(_ context.Context, req scriptorium.Str
|
||||
if req.PromptID == "weather.tomorrow_generated_text" {
|
||||
body = validTomorrowGeneratedTextJSON()
|
||||
}
|
||||
if req.PromptID == "weather.daily_generated_text" {
|
||||
body = validDailyGeneratedTextJSON()
|
||||
}
|
||||
if err := os.WriteFile(req.OutputPath, []byte(body), 0o600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2942,8 +2958,12 @@ func (r *recordingRenderer) Run(_ context.Context, req scriptorium.RunRequest) (
|
||||
func (r *recordingRenderer) StructuredRun(_ context.Context, req scriptorium.StructuredRunRequest) (*scriptorium.StructuredRunResult, error) {
|
||||
r.structuredRunCalls++
|
||||
r.structuredRunRequest = req
|
||||
if r.structuredRunBody != "" {
|
||||
if err := os.WriteFile(req.OutputPath, []byte(r.structuredRunBody), 0o600); err != nil {
|
||||
body := r.structuredRunBody
|
||||
if body == "" {
|
||||
body = validGeneratedTextJSONForPrompt(req.PromptID)
|
||||
}
|
||||
if body != "" {
|
||||
if err := os.WriteFile(req.OutputPath, []byte(body), 0o600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -2952,3 +2972,18 @@ func (r *recordingRenderer) StructuredRun(_ context.Context, req scriptorium.Str
|
||||
}
|
||||
return r.structuredRunResult, r.structuredRunErr
|
||||
}
|
||||
|
||||
func validGeneratedTextJSONForPrompt(promptID string) string {
|
||||
switch promptID {
|
||||
case "weather.daily_generated_text":
|
||||
return validDailyGeneratedTextJSON()
|
||||
case "weather.today_generated_text":
|
||||
return validTodayGeneratedTextJSON()
|
||||
case "weather.tomorrow_generated_text":
|
||||
return validTomorrowGeneratedTextJSON()
|
||||
case "weather.hourly_generated_text":
|
||||
return validHourlyGeneratedTextJSON()
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user