Skip to content

Parse genkit structured output with ChatTemplateEngine.parseRendered - #1574

Merged
leehack merged 4 commits into
mainfrom
feat/genkit-parse-rendered
Oct 29, 2026
Merged

leehack merged 4 commits into
mainfrom
feat/genkit-parse-rendered

Conversation

@leehack

@leehack leehack commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • genkit_llamadart structured output parses with ChatTemplateEngine.parseRendered(template, generatedText, ...) instead of ChatTemplateEngine.parse(template.format, ..., thinkingForcedOpen, parser), so it matches llamadart's engine and llama.cpp 620d2225: after the stock Seed-OSS template, Plan</seed:think>{...} is content (and fails JSON validation) instead of reasoning Plan plus the JSON. The old call also never passed the template-closed thought mark, which parseRendered reads from the render.
  • parseRendered is new in llamadart 0.17.0, so the package floor moves to llamadart: ^0.17.0 and the lower-bound/publish workflow pins to [email protected] (genkit_llamadart_floor_pin_test.dart enforces they match). README, migration guide, tool-schema guide, changelog (## Unreleased) and the website Genkit page follow; the website keeps the published 3.5.0 / 0.16.1 pairing and notes the next release targets 0.17.
  • Clears the genkit half of the #1565 item; stacked on #1573.

How it ships: blocked until llamadart 0.17.0 is on pub.dev. The adapter's published-dependency lane and the lower-bound lane resolve hosted llamadart, so they fail before then by design. After the core 0.17.0 publish: retarget to main (once #1573 merges), rerun CI, audit, merge; then a separate two-file genkit release prep (release/genkit_llamadart-vX.Y.Z) per website/docs/maintainers/genkit-package.md. It can fold into the planned genkit 0.17 move (#1211 part 2) if that lands first.

Production-readiness scope

  • User-facing scope: Genkit structured output and constrained tool envelopes parse as llamadart's engine does.
  • Supported platforms/paths: Same as the adapter.
  • Unsupported or intentionally unavailable paths: Unchanged.
  • Out of scope / follow-ups: Release prep after merge; Apple companion 0.17.x availability is the core release's.

Completeness checklist

  • Declared scope is fully implemented, or explicitly reduced above.
  • Unsupported platform/option combinations fail loudly with actionable diagnostics or are clearly documented as unavailable. (N/A: none changed)
  • Public API docs, README/website docs, examples, support matrices, and changelog entries are updated where relevant.
  • Regression coverage covers the original issue plus key negative/version-skew paths where relevant.
  • Public capability changes update the validation coverage registry with a pack or a reasoned, issue-linked exemption; inventory checks pass (or N/A with scope). (N/A: no core capability change)
  • Security/privacy review completed: no secrets, bearer tokens, signed URLs, or raw secret-bearing paths leak through logs, cache keys, metadata, errors, or snapshots.
  • Follow-up work that is useful but not required for this PR is tracked in GitHub Issues, or explicitly marked "None" above.

PR type guidance

  • Bugfix PR: root cause: the adapter parsed with the format-only public parse, which cannot see how the render left the thought. Regression test parses_structured_output_from_its_render_test.dart (FakeRuntime with real ChatTemplateEngine.render results): fails at the old call (the stock Seed-OSS stray end tag was accepted as reasoning), passes now.
  • Feature PR: N/A. Docs-only PR: N/A.

Test Plan

  • dart run tool/prepare_workspace.dart
  • dart format --output=none --set-exit-if-changed .
  • dart analyze N/A at root for the adapter; package dart analyze --fatal-infos passes against checkout core
  • dart test -p vm -j 1 --exclude-tags local-only N/A: no root change beyond Add ChatTemplateEngine.parseRendered to parse a reply as the engine does #1573; test/unit/tooling/genkit_llamadart_floor_pin_test.dart passes
  • dart test -p chrome --exclude-tags local-only N/A locally; CI runs the adapter browser lane
  • Other: from packages/genkit_llamadart with a checkout-core pubspec_overrides.yaml (as CI's second phase): dart pub get, format, dart analyze --fatal-infos, python3 .github/check_docs.py, dart test -x real-model (+467). Published-core and lower-bound lanes: blocked on the 0.17.0 publish.

Matrix Evidence

Matrix row Scope covered Platform / model / backend Result Evidence / notes
structured-output-adversarial adapter structured parse vs engine parse FakeRuntime with Seed-OSS stock/opened renders PASS failing-first at the old call; the envelope (tools) parse switch is behavior-equivalent (constrained tools require the generic format, where the marks do not apply)
high-risk-exact-head-independent-qa independent blocking review of exact head fresh auditor session, exact head 035a566 PASS CLEAR: CLEAR independent audit at 035a566; evidence /opt/UnitySrc/personal/llama/llamadart-evidence/pr-1574/evidence-1574-035a566.json
release-metadata-verification release metadata — N/A no version bump here; release prep is separate
litert-lm-json-schema LiteRT-LM JSON Schema — N/A not touched

Review Notes

  • Independent review status: CLEAR at exact head 035a566 by a fresh auditor session (0 P1, 0 P2).
  • CI status / head SHA: 9d5225c (published-dependency lanes expected red until llamadart 0.17.0 is published)

High-risk regression review

  • Classification: high-risk (surfaces: artifactConsumer, backendRuntime, regressionPolicy, releaseAutomation, structuredOutput)
  • Implementation task: llamadart 0.17.0 lane for the #1565 genkit-parse item
  • Independent blocking QA task: fresh auditor session, CLEAR, 0 known PR-caused P1, 0 unresolved threads
  • Exact head / current base: 035a566 / 79c082f (merge-tree clean)
  • Production-branch deletion, bypass, or miswire proof: failing-first test above
  • Affected-family real-model/artifact evidence: unavailable (Seed-OSS weights)
  • Explicit unavailable-family or other N/A evidence: Seed-OSS GGUF weights unavailable
  • Known PR-caused P1 regressions: 0
  • Unresolved review threads: 0

The public parse takes only a format and flags, so it cannot see how a render
left the prompt's thought: after the stock Seed-OSS template it returns
reasoning Plan for Plan</seed:think>Sunny., where llama.cpp and the engine
return content. parseRendered takes the render result and parses through the
engine's own parseRenderedOutput with its thought marks. parse is unchanged.
Structured output now parses as llamadart's engine parses its final message,
from the render result, so a Seed-OSS reply after the stock template matches
llama-server. parseRendered is new in llamadart 0.17.0, so the package floor
and the workflow lower-bound pins move to 0.17.0.
# Conflicts:
#	lib/src/core/template/chat_template_engine.dart
@leehack
leehack marked this pull request as ready for review October 29, 2026 12:44
@leehack
leehack merged commit 9f1179a into main Oct 29, 2026
38 checks passed
@leehack
leehack deleted the feat/genkit-parse-rendered branch October 29, 2026 12:45
@github-actions

Copy link
Copy Markdown
Contributor

Chat app preview removed for leehack/llamadart-chat-pr-1574.

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