Skip to content

QC-08 refactor(adapters): XMLAdapter and BAMLAdapter on engine formats - #13

Draft
MaximeRivest wants to merge 1 commit into
adapter-engine/qc-07from
adapter-engine/qc-08
Draft

MaximeRivest wants to merge 1 commit into
adapter-engine/qc-07from
adapter-engine/qc-08

Conversation

@MaximeRivest

Copy link
Copy Markdown
Owner

Stack: The Quiet Compiler

PR Title Status
QC-01–QC-07 corpora → IR → boundary → chat/json cutovers draft
QC-08 XML + BAML on engine formats 👈 this PR
QC-09..QC-12 TwoStep → type purification → LMResponse direct → consolidation queued

The headline gate

git diff QC-07..QC-08 -- dspy/adapters/_engine/render.py is empty. Two new wire formats (different tag syntax, different schema renderer) landed purely as Format objects — the mechanical proof that the seam the future preset/YAML epics need actually works.

What this PR does

  • XMLFormat(ChatFormat): tag wrapping, no completed marker, DOTALL first-match-wins parser with its known failure modes reproduced verbatim (incl. the error message that interpolates the FieldInfo repr — a quirk, pinned not fixed).
  • BAMLFormat(JSONFormat): only the two overridden surfaces; schema helpers imported from baml_adapter (single source of truth) rather than duplicated.
  • XMLAdapter.parse gains its engine branch; BAML inherits JSON's. XML keeps inheriting the Chat→JSON fallback. TwoStepAdapter is now the last unmigrated core.

Gate evidence

  • ✅ render.py: zero diff | ✅ 176 fixtures reproduce | ✅ tests/adapters 1,264 passed | ✅ 80 XML parse fuzz cases, zero divergence | ✅ XML/BAML dual-runs on both paths equal pre-engine fixtures | ✅ chat/json corpora re-proven unchanged | ✅ streaming (incl. XML closing-tag listener)/callback/predict/teleprompt green

🤖 Generated with Claude Code

Two more personalities proving the Format seam — with the hard gate that
dspy/adapters/_engine/render.py shows a ZERO diff in this PR: new wire
formats are Format objects, never renderer changes.

- formats/xml.py: XMLFormat(ChatFormat) — tag wrapping, schema section
  without a completed marker, single-call user content, the historical
  output-requirements wording, and the DOTALL first-match-wins parser
  with its known failure modes (nested tags, CDATA) reproduced verbatim,
  including the error-message quirk that interpolates the FieldInfo repr
  rather than the field name.
- formats/baml.py: BAMLFormat(JSONFormat) — only the two overridden
  surfaces ({name}-placeholder schema joined with single newlines;
  pydantic inputs as model_dump_json(indent=2, by_alias=True) with the
  empty-segment filter). The simplified-schema helpers are imported from
  baml_adapter (single source); the consolidation PR decides their final
  home. Parse and assistant side inherited from JSONFormat.
- XMLAdapter.parse gains its engine branch (it overrides parse);
  BAMLAdapter inherits JSONAdapter's branch and needs nothing.
- XMLAdapter keeps inheriting the Chat->JSON fallback unchanged.
- Stack tests updated for the migration state: TwoStepAdapter is now the
  last unmigrated core.

Verification: XML+BAML request dual-runs (engine AND forced-legacy, both
equal to pre-engine fixtures); XML parse corpus dual-run; 80 XML parse
fuzz cases (prose wrapping, duplicates, broken/nested tags, truncation)
with zero divergence; chat/json corpora re-proven unchanged. Full
battery: 176 fixtures reproduce exactly; tests/adapters 1264 passed;
streaming/callback/predict/teleprompt green. render.py diff vs QC-07: 0
lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaximeRivest
MaximeRivest force-pushed the adapter-engine/qc-07 branch from 3ebdd69 to d711d0f Compare June 10, 2026 10:56
@MaximeRivest
MaximeRivest force-pushed the adapter-engine/qc-08 branch from 0fd5da4 to cddaf50 Compare June 10, 2026 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant