Repository navigation
feat(gooddata-eval): score v2 Publisher documents - #1874
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1874 +/- ##
==========================================
+ Coverage 84.65% 84.69% +0.03%
==========================================
Files 335 335
Lines 23696 23745 +49
==========================================
+ Hits 20061 20110 +49
Misses 3635 3635 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The Publisher content v2 model stores pages under `content`, optionally
grouped into sections, lays them out as typed widgets inside
`row`/`column` containers with `children`, references visualizations
as `{identifier, type}`, writes summaries as `takeaway` widgets and
states the period as a dashboard date filter. The document-skill
evaluator only understood the v1 shape, so a v2 draft failed every
structural check.
A document with top-level `version: "2"` is now read as v2: pages come
from `content`, falling back to the top level when `content` is
missing, sections are flattened in order (and win over `pages` if both
are present), visualization ids are read as a bare string or as
`{identifier}`, and title/heading widgets give the page heading. Only
`takeaway` widgets are summaries, and every one on a content page must
be written: the default page templates ship an empty `text` widget with
id `summary`, while the copilot writes its summaries into takeaways, so
that text widget is ignored. An absolute period is compared on
`from`/`to`; a relative one cannot match fixed dates and fails the
period check with the range it states.
Hidden pages (`visible: false`) are out of the viewer, exports and page
numbering, so they are left out of everything scored: the page count
the part and the tool report (which is what the user is told), the
cover/content rule, the chart and summary checks, and the page
numbering the judge reads.
v1 documents score exactly as before.
jira: LX-3336
risk: nonprod
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
romrak
force-pushed
the
rr/LX-3336-eval-v2-documents
branch
from
October 13, 2026 15:17
2962735 to
7fcae3a
Compare
chrisbonilla95
approved these changes
Oct 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Publisher copilot evaluation now reads and scores v2 documents. v1 documents score exactly as before. The rerun of the evaluation on v2 belongs to LX-3342.
LX-3336, epic GDP-3491.
What this implements
The document-skill evaluator (
core/agentic/document_skill.py;report_skill.pyis only the deprecated re-export) recognises a document with top-levelversion: "2"and walks the v2 model:{ "id": "sales_overview", "type": "document", "version": "2", "title": "Sales overview", "period": {"type": "absolute", "granularity": "GDC.time.date", "from": "2026-01-01", "to": "2026-06-30"}, "content": { "sections": [{"id": "section_1", "pages": [ {"id": "page1", "kind": "cover", "layout": {"type": "column", "children": [{"type": "title", "id": "t", "markdown": "{documentName}"}]}}, {"id": "page2", "kind": "content", "visible": true, "layout": {"type": "column", "children": [ {"type": "title", "id": "t", "markdown": "Revenue"}, {"type": "row", "children": [{"type": "visualization", "id": "widget1", "visualization": {"identifier": "revenue_trend", "type": "insight"}}]}, {"type": "takeaway", "id": "takeaway", "markdown": "Revenue grew 12 % ..."} ]}} ]}] } }The text the judge reads is the same for a v1 and a v2 version of the same document:
content.pages, or fromcontent.sections[*].pagesin order.childrenlists and the v1row/columnlists.{identifier}.titleandheadingwidgets give the page heading.takeawaywidgets are the page summaries.Decisions
version == "2"(a string), not by the part'sformat.gen-ai still sends
format: "aac-v1", and the spec putsversionon the entity.version: 2is read as v1 and fails every check.visible: false) are excluded frompage_countand from every other check.page_countis what the user is told ("a document with 3 pages"), and a hidden page is out of the viewer, the exports and the page numbering.page_countmust equal the number of visible pages.document_period_correct.Fixtures state fixed
start/enddates, and a relative range cannot be compared with them. The failure shows the range, e.g.the relative range GDC.time.month -6 to -1.takeawaywidgets count as summaries, and every one on a content page must be written.The copilot writes generated text into takeaways. The default page templates ship an empty
{"type": "text", "id": "summary"}widget, which is static text.textwidget with idsummaryis ignored: it is not counted, it does not fail as unwritten, and it is not shown to the judge.content, falling back to the top level, andsectionswin overpagesif both are present.Only
contentis in the spec. The fallback is lenient, and metadata-api rejects bothpagesandsectionstogether anyway.type: "document".type, failsdocument_part_present.What comes next
format(e.g.aac-v2); detection does not depend on it.Test plan
make -C packages/gooddata-eval format lint type-check: clean.TEST_ENVS=py314 make -C packages/gooddata-eval test: 1757 passed, 1 skipped.risk: nonprod
🤖 Generated with Claude Code
Summary by CodeRabbit