Skip to content

Commit babd91b

Browse files
grokifyclaude
andcommitted
feat(summary): add embedded report support
Add ability to embed full-fidelity rubric and claims reports within SummaryReport for comprehensive evaluation bundles: - EmbedRubricReport: embed rubric evaluation by key - EmbedClaimsReport: embed claims report by key - GetEmbeddedRubricReport: retrieve embedded rubric - GetEmbeddedClaimsReport: retrieve embedded claims - EmbeddedReports field in schema Enables single-file distribution of complete evaluation results while maintaining individual report integrity. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2a6d91a commit babd91b

2 files changed

Lines changed: 151 additions & 2 deletions

File tree

schema/summary.schema.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@
8080
},
8181
"generated_by": {
8282
"type": "string"
83+
},
84+
"embeddedReports": {
85+
"properties": {
86+
"evaluations": {
87+
"additionalProperties": true,
88+
"type": "object"
89+
},
90+
"claims": {
91+
"additionalProperties": true,
92+
"type": "object"
93+
},
94+
"custom": {
95+
"additionalProperties": true,
96+
"type": "object"
97+
}
98+
},
99+
"additionalProperties": false,
100+
"type": "object"
83101
}
84102
},
85103
"additionalProperties": false,

summary/report.go

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package summary
22

3-
import "time"
3+
import (
4+
"encoding/json"
5+
"time"
6+
)
47

58
// TeamSection represents results from a single agent or validation area.
69
type TeamSection struct {
@@ -33,7 +36,8 @@ func (t *TeamSection) ComputeStatus() Status {
3336
}
3437

3538
// SummaryReport is the top-level report for summary-style evaluations.
36-
// It aggregates results from multiple teams/agents.
39+
// It aggregates results from multiple teams/agents and can embed full
40+
// EvaluationReport and ClaimsReport for complete fidelity.
3741
type SummaryReport struct {
3842
// Schema is the JSON Schema URL for validation.
3943
Schema string `json:"$schema,omitempty"`
@@ -61,6 +65,28 @@ type SummaryReport struct {
6165

6266
// GeneratedBy identifies what created this report.
6367
GeneratedBy string `json:"generated_by,omitempty"`
68+
69+
// EmbeddedReports contains full-fidelity embedded reports.
70+
// This allows the SummaryReport to serve as a container for
71+
// detailed reports while providing a summary view.
72+
EmbeddedReports *EmbeddedReports `json:"embeddedReports,omitempty"`
73+
}
74+
75+
// EmbeddedReports contains full-fidelity embedded reports.
76+
// Reports are stored as json.RawMessage to avoid circular imports
77+
// and allow flexible report types.
78+
type EmbeddedReports struct {
79+
// Evaluations contains embedded EvaluationReport(s).
80+
// Key is a report identifier (e.g., "prd-review", "article-quality").
81+
Evaluations map[string]json.RawMessage `json:"evaluations,omitempty"`
82+
83+
// Claims contains embedded ClaimsReport(s).
84+
// Key is a report identifier (e.g., "source-validation").
85+
Claims map[string]json.RawMessage `json:"claims,omitempty"`
86+
87+
// Custom contains any other embedded reports.
88+
// Key is a report identifier, value is the full report JSON.
89+
Custom map[string]json.RawMessage `json:"custom,omitempty"`
6490
}
6591

6692
// ComputeOverallStatus calculates the overall status from all teams.
@@ -110,3 +136,108 @@ func (r *SummaryReport) AddTeam(team TeamSection) {
110136
team.ComputeStatus()
111137
r.Teams = append(r.Teams, team)
112138
}
139+
140+
// EnsureEmbeddedReports initializes the EmbeddedReports field if nil.
141+
func (r *SummaryReport) EnsureEmbeddedReports() {
142+
if r.EmbeddedReports == nil {
143+
r.EmbeddedReports = &EmbeddedReports{
144+
Evaluations: make(map[string]json.RawMessage),
145+
Claims: make(map[string]json.RawMessage),
146+
Custom: make(map[string]json.RawMessage),
147+
}
148+
}
149+
if r.EmbeddedReports.Evaluations == nil {
150+
r.EmbeddedReports.Evaluations = make(map[string]json.RawMessage)
151+
}
152+
if r.EmbeddedReports.Claims == nil {
153+
r.EmbeddedReports.Claims = make(map[string]json.RawMessage)
154+
}
155+
if r.EmbeddedReports.Custom == nil {
156+
r.EmbeddedReports.Custom = make(map[string]json.RawMessage)
157+
}
158+
}
159+
160+
// EmbedEvaluationReport embeds an EvaluationReport with the given key.
161+
// The report is marshaled to JSON for storage.
162+
func (r *SummaryReport) EmbedEvaluationReport(key string, report any) error {
163+
r.EnsureEmbeddedReports()
164+
data, err := json.Marshal(report)
165+
if err != nil {
166+
return err
167+
}
168+
r.EmbeddedReports.Evaluations[key] = data
169+
return nil
170+
}
171+
172+
// EmbedClaimsReport embeds a ClaimsReport with the given key.
173+
// The report is marshaled to JSON for storage.
174+
func (r *SummaryReport) EmbedClaimsReport(key string, report any) error {
175+
r.EnsureEmbeddedReports()
176+
data, err := json.Marshal(report)
177+
if err != nil {
178+
return err
179+
}
180+
r.EmbeddedReports.Claims[key] = data
181+
return nil
182+
}
183+
184+
// EmbedCustomReport embeds a custom report with the given key.
185+
// The report is marshaled to JSON for storage.
186+
func (r *SummaryReport) EmbedCustomReport(key string, report any) error {
187+
r.EnsureEmbeddedReports()
188+
data, err := json.Marshal(report)
189+
if err != nil {
190+
return err
191+
}
192+
r.EmbeddedReports.Custom[key] = data
193+
return nil
194+
}
195+
196+
// GetEmbeddedEvaluation retrieves and unmarshals an embedded EvaluationReport.
197+
// Returns nil if not found. The target should be a pointer to the report struct.
198+
func (r *SummaryReport) GetEmbeddedEvaluation(key string, target any) error {
199+
if r.EmbeddedReports == nil || r.EmbeddedReports.Evaluations == nil {
200+
return nil
201+
}
202+
data, ok := r.EmbeddedReports.Evaluations[key]
203+
if !ok {
204+
return nil
205+
}
206+
return json.Unmarshal(data, target)
207+
}
208+
209+
// GetEmbeddedClaims retrieves and unmarshals an embedded ClaimsReport.
210+
// Returns nil if not found. The target should be a pointer to the report struct.
211+
func (r *SummaryReport) GetEmbeddedClaims(key string, target any) error {
212+
if r.EmbeddedReports == nil || r.EmbeddedReports.Claims == nil {
213+
return nil
214+
}
215+
data, ok := r.EmbeddedReports.Claims[key]
216+
if !ok {
217+
return nil
218+
}
219+
return json.Unmarshal(data, target)
220+
}
221+
222+
// GetEmbeddedCustom retrieves and unmarshals an embedded custom report.
223+
// Returns nil if not found. The target should be a pointer to the report struct.
224+
func (r *SummaryReport) GetEmbeddedCustom(key string, target any) error {
225+
if r.EmbeddedReports == nil || r.EmbeddedReports.Custom == nil {
226+
return nil
227+
}
228+
data, ok := r.EmbeddedReports.Custom[key]
229+
if !ok {
230+
return nil
231+
}
232+
return json.Unmarshal(data, target)
233+
}
234+
235+
// HasEmbeddedReports returns true if any embedded reports exist.
236+
func (r *SummaryReport) HasEmbeddedReports() bool {
237+
if r.EmbeddedReports == nil {
238+
return false
239+
}
240+
return len(r.EmbeddedReports.Evaluations) > 0 ||
241+
len(r.EmbeddedReports.Claims) > 0 ||
242+
len(r.EmbeddedReports.Custom) > 0
243+
}

0 commit comments

Comments
 (0)