Skip to content

Close template audit follow-ups: Cohere2 MoE closed thought, Seed-OSS trigger, mutant tests - #1550

Merged
leehack merged 1 commit into
mainfrom
fix/template-audit-followups
Oct 28, 2026
Merged

leehack merged 1 commit into
mainfrom
fix/template-audit-followups

Conversation

@leehack

@leehack leehack commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Summary

Closes #1523. Refs #1531 (lane of #922).

  • Cohere2 MoE: with enableThinking: false and a reasoning: true kwarg, the prompt now ends <|START_THINKING|><|END_THINKING|>, the template's own closed form, instead of adding \n. The new upstream fixture case matches llama.cpp 620d2225 with {reasoning: false, skip_thinking: true} byte for byte.
  • Seed-OSS: adds a second lazy trigger, <seed:tool_call><function=. The grammar (xml-space after the scope) and the parse already accept that form. GBNF-validated. buildGrammar now builds the non-parallel grammar that render uses by default.
  • Tests for surviving mutants: X2, an upstream case with two Qwen3.5 <tool_call>s in an unended thought. X7, a content opening inside a thought the model opens streams as it parses. Z2/Z5, a Hermes, DeepSeek V3 or Qwen3-Coder template that always opens the thought keeps parsing the reply's thought after the handler closes it. M11/M17, an empty first Qwen3-Coder scope starts no later calls (upstream returns 0). Hy3 reasoning_effort none/medium throws LlamaInferenceException. cities() checks exact values again, untrimmed for Qwen3-Coder and with line breaks for Seed-OSS.
  • Docs: the guide and llamadart-chat-streaming skill now cover the Kimi K3 thinking switch and the defaults llamadart sets (Hy3 high, MiniMax M3 enabled) where llama-server renders no_think/adaptive. They also note that under enableThinking: false a kwarg does not fully win: llamadart still closes a thought the kwarg opens, and Cohere2 MoE still drops earlier thoughts unless skip_thinking is set too. The changelog notes the Nemotron 3 Nano parallel-grammar fix from Parse each Qwen3-Coder XML parallel call in its own <tool_call> block (#1530) #1539 and the Cohere change.

Item status

Item Status
#1523 1 Cohere thought ends at <|START_TEXT|>/<|START_ACTION|> Done in #1524
#1523 2 MA11 Killed in #1526
#1523 3 WebGPU decoding of the control tokens and stops Checked in the source only, no Web Cohere model run. Bridge 883376d (assets v0.1.76) decodes every token with special=true (src/core/generation.inc 813/875), so the preserved markers reach Dart as text, as native renders its preserved tokens. Both backends drop stop sequences that are preserved tokens (_effectiveStopSequences, webgpu_backend.dart 1972), so neither stops on <|END_RESPONSE|>/<|END_ACTION|>; generation ends at the EOG token.
#1523 4 guide precedence #1526, qualified here
#1523 5 Hy3 values Documented in #1526; test here
#1523 6 Cohere \n Fixed here
#1523 7 MB6, MB10 Killed in #1526
#1523 7 MB7 Moved to #750, where #1526 recorded it. Upstream lets kwargs override messages/tools but not BOS/EOS, so a test of either order would pin a divergence.
#1523 comment: guide ~60, MiniMax M3 enabled, Hy3 throw test, Kimi K3 Done: qualified; documented as intended (same mapping as Hy3 high); test; listed
#1531 X2, X7, Z2/Z5, M11/M17, cities(), Seed buildGrammar, Nemotron changelog, Seed trigger Done

Production-readiness scope

  • User-facing scope: Cohere2 MoE prompt bytes for enableThinking: false plus an opening reasoning kwarg. Seed-OSS lazy grammar also starts on <seed:tool_call><function=. Docs.
  • Supported platforms/paths: all; Dart template render shared by native and Web.
  • Unsupported or intentionally unavailable paths: N/A, no new option. Hy3's existing LlamaInferenceException for other reasoning_effort values is now tested.
  • Out of scope / follow-ups (deferred, other lanes or decisions): #1532 streaming holdback. Ling parsed as Hermes (<think> in call arguments). Upstream dropping text after tool calls. Parse cap with parallel calls off. Dropping a partial </<tool_ at the end with thinking off. Also still open on Reasoning parity follow-ups from #1524/#1525 audit: mutants X2/X7, Ling <think> in args, partial-tag drop #1531 and not in this lane: Seed whitespace leniency, unknown tool in a later Seed scope, several <function=> in one Qwen3-Coder scope, truncated later scope, and Qwen3-Coder/StepFun thinking-off handling. A Seed empty first scope is not pinned: llama.cpp reads <seed:tool_call></seed:tool_call> as text and returns the later call, which is part of the Seed whitespace leniency.

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: no new option.)
  • Public API docs, README/website docs, examples, support matrices, and changelog entries are updated where relevant. (Guide, skill, both changelogs. README/examples/support matrix N/A: no capability change.)
  • 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 public 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. (Reasoning parity follow-ups from #1524/#1525 audit: mutants X2/X7, Ling <think> in args, partial-tag drop #1531 stays open for the deferred items.)

PR type guidance

  • Bugfix PR: Root cause, Cohere: CommandR7BHandler.render, which Cohere2 MoE inherits, closed a thought the template left open with <|END_THINKING|>\n, while the template's own off form has no newline. Root cause, Seed: Parse each Seed-OSS parallel call in its own <seed:tool_call> block (#1540) #1542 swapped the lazy trigger for llama.cpp's <seed:tool_call>\n, which dropped the compact form the grammar and parse still accept. Failing-first: the new kwargs fixture case and both Seed handler tests fail on main. Platforms: all.
  • Feature PR / Docs-only PR: N/A.

Test Plan

  • dart run tool/prepare_workspace.dart
  • dart format --output=none --set-exit-if-changed .
  • dart analyze lib test tool
  • dart test -p vm -j 1 --exclude-tags local-only (isolated TMPDIR): +9471 ~123, all passed
  • dart test -p chrome test/unit/core/template test/unit/core/engine/chat_completion_stream_parser_test.dart: +1118, all passed
  • Other targeted/local-only validation: dart run tool/testing/check_platform_boundaries.dart; ./tool/testing/run_template_parity_suites.sh (b10549 templates, GBNF validator): all five suites passed; oracle, render diff and mutation runs below.

Evidence (oracle built from llama.cpp 620d2225, harnesses from llamadart-evidence/pr-1542/audit/ and issue-1540/; logs in llamadart-evidence/pr-1550/):

Check Result
Oracle, full corpus (94 templates, 183,672 parse/stream records) OK on main 66,896, OK on head 66,896: 0 OK->BAD, 0 BAD->OK. The one differing record is a Gemma 4 3-byte-chunk stream (ps on both). Three sequential reruns of that template give identical main and head output, so the diff comes from the timing-based partial parse under 10-way load.
Oracle, Seed-OSS parallel corpus (13,944 records) 0 changes
Render diff, 2,256 renders (94 templates x 24 configs) Only the 8 Seed-OSS renders with a lazy grammar change, gaining the second trigger. No prompt or grammar changes.
Kwargs fixture vs oracle All 13 prompts byte-exact, the new Cohere case included
Mutants X2, X7, Z2, Z5, M11/M17, plus new N1 (Cohere \n back), N2/N4 (either Seed trigger dropped), N3 (Seed buildGrammar parallel): all killed, each by the new test. MB7 survives (moved, see above).

Matrix Evidence

Matrix row Scope covered Platform / model / backend Result Evidence / notes
static-format-analyze format, analyzer, web/native import boundaries macOS, Flutter 3.47.1 PASS local
root-vm native-safe unit/integration coverage on the Dart VM macOS VM PASS local, isolated TMPDIR
root-chrome browser-compatible unit/integration coverage Chrome PASS template + stream suites locally; full suite in CI
structured-output-adversarial render/history, compiled grammar acceptance, partial/final streaming, thinking prefixes, pinned upstream parity Dart vs llama.cpp 620d2225; GBNF validator PASS oracle 0 OK->BAD; parity suites; Seed compact scope accepted by the grammar
high-risk-exact-head-independent-qa independent blocking review of exact head fresh auditor session, exact head 5229835 PASS CLEAR: CLEAR at 5229835; evidence /opt/UnitySrc/personal/llama/llamadart-evidence/pr-1550/audit/evidence-1550-5229835.json
release-metadata-verification N/A not a release PR
litert-lm-json-schema N/A no LiteRT-LM change
docs-site website build CI guide paragraph and changelog

Review Notes

  • Independent review status: CLEAR at exact head 5229835 by a fresh auditor session (0 P1, 0 P2).
  • CI status / head SHA: 5229835, CI pending.

High-risk regression review

  • Classification: high-risk (structuredOutput)
  • Implementation task: #1523 and the Reasoning parity follow-ups from #1524/#1525 audit: mutants X2/X7, Ling <think> in args, partial-tag drop #1531 test-gap items, 0.17 lane of #922
  • Independent blocking QA task: fresh auditor session, CLEAR, 0 known PR-caused P1, 0 unresolved threads
  • Exact head / current base: 5229835 / d926c2f (merge-tree clean)
  • Production-branch deletion, bypass, or miswire proof: N1 to N4 delete or revert each production change, and each fails a new test (mutation table above).
  • Affected-family real-model/artifact evidence: Cohere2 MoE, Seed-OSS, Qwen3.5, Qwen3-Coder, Hermes, DeepSeek V3 and Hy3 weights are not used. The evidence is primary upstream emissions: the llama.cpp 620d2225 oracle renders and parses, plus durable fixtures.
  • Explicit unavailable-family or other N/A evidence: weights for these families are unavailable locally; the WebGPU control-token item was checked in the source only.
  • Known PR-caused P1 regressions: 0
  • Unresolved review threads: 0

Cohere2 MoE with enableThinking: false closes a thought a reasoning: true
kwarg opens as the template closes its own, without a trailing newline.
Seed-OSS also starts its lazy grammar on <seed:tool_call><function=, which
its grammar and parse already accept, and buildGrammar builds the
non-parallel grammar render uses by default.

Pin the surviving mutants with tests: two openings in an unended Qwen3.5
thought (X2), content openings in a thought the model opens (X7), the
Hermes and DeepSeek V3 closed-thought mark (Z2/Z5), an empty first
Qwen3-Coder scope (M11/M17), Hy3's reasoning_effort error, and exact
Qwen3-Coder values in the scope tests.

Document the thinking-switch defaults and the enableThinking: false
exceptions, and the Nemotron 3 Nano parallel-grammar fix.
@github-actions

Copy link
Copy Markdown
Contributor

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

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.

Template follow-ups from #1509/#1513 audits

1 participant