Skip to content

Keep the Seed-OSS required-call grammar applied through a budgeted thought - #1962

Merged
leehack merged 2 commits into
mainfrom
lane-1958-seed-oss
Nov 12, 2026
Merged

leehack merged 2 commits into
mainfrom
lane-1958-seed-oss

Conversation

@leehack

@leehack leehack commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Fixes #1958

Summary

  • On native llama.cpp, a ThinkingBudget with ToolChoice.required on Seed-OSS no longer leaves the call unconstrained after the budget closes a thought the model opened.
  • Cause: the required root seed-thought? text-before-calls (...) accepts <seed:think>, then the budget sampler paused it (its root is not think-body), so it resumed inside seed-thought-text and the forced close and call were unconstrained.
  • Fix: ToolCallGrammarUtils.keepsAppliedThroughThought (the Keep the response-format grammar applied through a budgeted forced-open thought #1956 think-body predicate plus a seed-thought root) replaces takesForcedOpenThought in the pause decision in llama_cpp_service.dart. Chosen over teaching the paused grammar to accept the forced close: it is one predicate, and it matches upstream, which only pauses lazy grammars (grammar_should_apply in common/sampling.cpp).

Production-readiness scope

  • User-facing scope: Seed-OSS required tool calls stay grammar-constrained after a spent thinking budget.
  • Supported platforms/paths: native llama.cpp. WebGPU still pauses every grammar (#1954).
  • Unsupported or intentionally unavailable paths: N/A.
  • Out of scope / follow-ups: None. The broader pause-every-eager-grammar divergence from upstream is not widened here.

Completeness checklist

  • Declared scope is fully implemented.
  • Unsupported platform/option combinations: unchanged.
  • Dartdoc, website guide and both changelogs updated.
  • Regression coverage covers the original issue plus the unchanged paths.
  • Validation coverage registry: N/A, no new public capability.
  • Security/privacy review: no secrets, tokens or paths touched.
  • Follow-ups: None.

PR type guidance

  • Bugfix PR: root cause above; regression tests below; affected path is native llama.cpp only.

Test Plan

  • dart run tool/prepare_workspace.dart
  • dart format --output=none --set-exit-if-changed .
  • dart analyze
  • dart run tool/testing/check_platform_boundaries.dart
  • dart test -p vm -j 1 --exclude-tags local-only (macOS, isolated TMPDIR; 14237 passed) with coverage-lib: 93.87% lines
  • dart test -p chrome --exclude-tags local-only: left to CI (no Web code changed)
  • tool/testing/run_template_parity_suites.sh, dart test -p vm test/unit/tooling/

Matrix Evidence

Matrix row Scope covered Platform / model / backend Result Evidence / notes
coverage-lib lib/ line coverage macOS VM 93.87% full VM suite passed
template-parity vendored template detection/render/parse, grammar acceptance macOS VM pass run_template_parity_suites.sh
structured-output-adversarial required grammar under a budgeted thought stories15M (mechanism), Seed-OSS template fixture (grammar acceptance) pass see below

Failing-first and mutations (stories15M integration test test/integration/thinking_budget_grammar_test.dart, plus unit tests):

Mutation Result
M0: service uses takesForcedOpenThought (pre-fix) integration test fails
M1: pause every grammar both existing and new integration tests fail
M2: predicate matches any root predicate unit test and the caller-grammar integration test fail
M3: predicate requires seed-thought without ? predicate unit test and integration test fail

Cross-format probe (460 template x mode combinations from every .jinja fixture, before vs after pause decision): exactly 2 change, both Seed-OSS required (think on and off). Ling3, Kimi K3, MiniMax M3, DeepSeek R1/V32/V4, Laguna, Qwen3-Coder XML and every other format are unchanged.

Upstream comparison: upstream llama-server never pauses an eager grammar under a reasoning budget (common/sampling.cpp grammar_should_apply: lazy grammars only), so the Seed-OSS grammar stays applied there. A live run was not possible: the Seed-OSS weights are too large to run locally, and llama-server b12110 refuses to initialise the Seed-OSS required grammar on stories15M (common_sampler_init: error initializing grammar sampler). The evidence is the durable template fixture (ByteDance-Seed-OSS.jinja), the grammar-acceptance unit test (forced budget close accepted, free text after it rejected) and the stories15M test with a seed-thought-rooted grammar. The test uses <s> as the start tag because the model's greedy tokenization of a grammar-forced <seed:think> never equals the tag's own tokens.

Review Notes

  • Independent review status: PASS (fresh Opus audit at ee6384e, delta re-audit at 69a7e21)
  • CI status / head SHA: green, run 43266650445 (32 pass, 9 skipped) / 69a7e21

High-risk regression review

  • Classification: high-risk (surfaces: backendRuntime, structuredOutput)
  • Implementation task: this PR, lane 3 of plan 0.19.8 release plan: thinking-budget grammar fixes (native, WebGPU, Seed-OSS) and #1950 sweep #1959
  • Independent blocking QA task: fresh auditor-deep delta re-audit, PASS, 0 P1/P2; P3s logged in 0.19.8 audit follow-ups #1950
  • Exact head / current base: 69a7e217af221d7950c9327e028bf2aace8baad6 / 083166ef; readiness evaluator exit 2 (unverifiedPrerequisites)
  • Production-branch deletion, bypass, or miswire proof: 11/13 mutants killed; M7/M8 equivalent
  • Affected-family real-model/artifact evidence: Seed-OSS weights unavailable; durable template fixture, grammar-acceptance test and upstream grammar_should_apply comparison used
  • Explicit unavailable-family or other N/A evidence: Seed-OSS model not run locally; unrelated stories15M is mechanism-only evidence
  • Known PR-caused P1 regressions: 0
  • Unresolved review threads: 0

…ought (#1958)

Seed-OSS's required-call root starts with seed-thought?. The native budget sampler paused it when the model opened the thought, resumed it inside seed-thought-text and left the call after the forced close unconstrained. A grammar that models the thought it opens now stays applied, as upstream llama-server applies every eager grammar.
@leehack leehack mentioned this pull request Nov 12, 2026
17 of 20 tasks
@leehack
leehack marked this pull request as ready for review November 12, 2026 17:44
@leehack
leehack merged commit ec62e97 into main Nov 12, 2026
43 checks passed
@leehack
leehack deleted the lane-1958-seed-oss branch November 12, 2026 17:45
@github-actions

Copy link
Copy Markdown
Contributor

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

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.

Seed-OSS: required tool call unconstrained after a thinking budget (template doesn't open the thought)

1 participant