feat(task): compact flow-style arrays in emitted task.md frontmatter - #967
Conversation
Frontmatter emitters used yaml.safe_dump, which renders every sequence as multiline block bullets — a hand-written 'tags: [parsing, nlp]' exploded into bullets on any migrate/normalize round-trip. Add _CompactDumper (SafeDumper subclass) in task/_document_parse.py whose sequence representer emits flow style for lists of short scalars (str/int/float/ bool/None, no embedded newlines) whose standalone flow rendering fits in 80 chars, and block style otherwise. One canonical dump_frontmatter_yaml helper is shared by all three frontmatter dump sites (render_task_md, render_normalized_task_md, skill_eval verifier.md); the machine-consumed litellm config dumps are intentionally untouched. Output remains deterministic and a dump/load/dump fixed point; PyYAML handles quoting for items with YAML metacharacters inside flow style.
…date scalars Review follow-ups: the 80-char cap measured the list standalone, so a list under a key prefix could render past the cap or wrap mid-flow at deep nesting (uglier than the block bullets it replaces) — charge a fixed 8-char allowance since PyYAML exposes no emit-time column. Also admit datetime.date/datetime items (SafeDumper renders them fine; date lists previously stayed block for no reason).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85817e7421
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
|
|
||
| def test_frontmatter_short_scalar_list_renders_flow_style() -> None: | ||
| """Short scalar-only lists stay compact instead of exploding into bullets.""" |
There was a problem hiding this comment.
Name the guarded commit in regression-test docstrings
The newly added tests guard this commit’s compact-array behavior, but their docstrings only restate the expected behavior—and two tests have no docstring—so none identifies the PR or commit being protected. Add the required reference to each regression-test docstring so future maintainers can trace the intended contract.
AGENTS.md reference: AGENTS.md:L17-L17
Useful? React with 👍 / 👎.
Version 0.6.7 (from 0.6.7.dev0), CITATION date 2026-08-09, and the 0.6.7 CHANGELOG section covering #949-#967. Also in this cut: - Point the wheel-shipped env0 pins at the org-owned ghcr.io/benchflow-ai/env0:0.2.0 base image (they named a personal Docker Hub image while their own comments and the docs declared ghcr authoritative) and drop the PR-archaeology comments from files that ship to PyPI. Validated on Daytona: 8/8 services ready, reward 1.0. - Document mean_reward in the summary.json layout, the per-task failure block and live-token footer in the CLI reference, and soften the external-agents cost figure (the underlying rate table is a placeholder).
User request: frontmatter YAML gets long — short lists like
tagsshould render as one-line arrays instead of multiline bullets. Parsing already accepted flow style (standard YAML); this fixes the emitters, so hand-writtentags: [parsing, nlp]survives migrate/normalize round-trips instead of exploding into bullets, and generated frontmatter is compact.What changed
_CompactDumper(yaml.SafeDumper)+ one representer intask/_document_parse.py: a list emits flow iff every item is a short scalar (str/int/float/bool/date/None, no embedded newlines) and its rendered flow form — measured with the real PyYAML emitter, so the predicate can never disagree with actual quoting — fits the width cap minus a fixed context allowance (PyYAML exposes no emit-time column, so the allowance stands in for key prefix/indentation). Block style otherwise. Deterministic; dump→load→dump is a fixed point.dump_frontmatter_yaml()replaces three independentyaml.safe_dumpcall sites (both_document_parserender paths +skill_eval/_corevia the existing façade).tags:/- parsing/- nlp→tags: [parsing, nlp]; mappings and scalars byte-identical.Review
Structural review (APPROVE-WITH-MINORS): measure-with-the-real-emitter called out as the right judo (no reimplemented quoting rules to drift); alias/anchor and self-reference safety verified empirically; the
tupleregistration confirmed an override, not a legalization (SafeDumper already serialized tuples); mutation-tested end-to-end throughrender_task_md. The one worth-taking minor — the standalone-width measurement could overflow or wrap in context — is fixed here with the context allowance; date scalars admitted per the same review.Gates: ruff format/check, ty; document/frontmatter/migrate/skill_eval sweep 244 passed (one pre-existing env-dependent collection error in test_daytona_download.py, untouched by this branch, excluded).