fix(gastown): use the configured BYOK model for review-thread classification - #6035
Open
maphew wants to merge 4 commits into
Open
fix(gastown): use the configured BYOK model for review-thread classification#6035maphew wants to merge 4 commits into
maphew wants to merge 4 commits into
Conversation
…ication areThreadsBlocking() hardcoded a Workers AI Gemma call for the auto-merge review-thread classifier. Direct-BYOK towns now run the classifier on role_models.refinery ?? default_model through the Kilo gateway, so the call bills the user's own provider key. Non-BYOK towns keep the Workers AI path. A rejected BYOK call blocks without falling back to a Kilo-billed path. Refs Kilo-Org#4268 Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
A reasoning-tagged BYOK model can spend the 256-token budget on a thinking
trace and return no JSON content, which makes areThreadsBlocking()
conservatively block auto-merge. Send reasoning: { enabled: false,
effort: 'none' }, the gateway's "none" variant, and add tests for the
refinery-override and gateway network-failure paths.
Refs Kilo-Org#4268
maphew
marked this pull request as ready for review
September 10, 2026 03:05
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (7 files)
Reviewed by grok-4.6 · Input: 100K · Output: 11.3K · Cached: 256.1K Review guidance: REVIEW.md from base branch |
jrf0110
approved these changes
Sep 10, 2026
…t-nsr Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #4268 (does not close it — the issue also asks for disclosure/configurability of the auxiliary model for non-BYOK users).
Problem
areThreadsBlocking()inservices/gastown/src/dos/town/town-scm.tsalways classified unresolved PR review threads with a hardcoded Cloudflare Workers AI call (@cf/google/gemma-4-26b-a4b-it). A BYOK town therefore had one review-path call that ignored the town's configured model, with no UI control or disclosure.This is a separate follow-up from the Code Reviewer credit-balance fix. The Workers AI call runs on the Cloudflare binding, not the Kilo gateway, so it does not draw Kilo credits; the motivation here is BYOK users expecting the configured model to be used throughout the flow (and the issue's request that the auxiliary call be honored/configurable).
Change
role_models.refinery ?? default_modelis a direct-BYOK model and the town has akilocode_token, classify viaPOST {KILO_API_URL}/api/openrouter/chat/completionson that model. The call uses the town's Kilo token (the same token injected into the container asKILOCODE_TOKEN), sendsX-KiloCode-Feature: gastownand, for org towns,X-KiloCode-OrganizationId. The gateway resolves the direct-BYOK model to the user's own provider key (getDirectByokModel), so the call bills that key.areThreadsBlocking()conservatively returnstrue(blocks auto-merge) rather than silently substituting a different model.@kilocode/worker-utils/direct-byok-modelexportsisDirectByokModelId()/DIRECT_BYOK_PROVIDER_IDS, plus a drift-guard test inapps/webthat keeps the list equal toDIRECT_BYOK_PROVIDERS_META.Adversarial review
An independent review pass and a second round of checks found two issues, both fixed in the second commit:
content. Reasoning-tagged BYOK models (e.g.zai-coding, the recommendedneuralwattmodels) can spend the 256-token budget on a thinking trace and return no JSON, which would block auto-merge for BYOK towns. The request now sendsreasoning: { enabled: false, effort: 'none' }(the gateway's canonical "none" variant), mirroring the Gemma path'senable_thinking: false. Test asserts it.Also reviewed and accepted:
KILO_GATEWAY_AUDIENCE, butisKiloResourceAudienceAllowed(..., mode: 'allow-legacy')accepts the town token's missingaudclaim, so existing gastown tokens work.X-KiloCode-OrganizationIdmatchesORGANIZATION_ID_HEADER(case-insensitive); verified againstsecurity-auto-analysisandreview-memorycallers.isDirectByokModelId()matches on the provider prefix, while the gateway routes to BYOK only for catalog model ids. The configured model comes from the same picker/catalog that mints these ids; an unknownprovider/modelunder a direct-BYOK prefix is rejected (4xx) by the gateway and fails closed. Documented in the module.role_models.refinery ?? default_model), consistent with the rest of the auto-merge path;SCMContextcarries no rig. Noted in a code comment.Verification
services/gastown:tsgo --noEmit,oxlint(0 warnings/errors),vitest run— 344 passed (9 in the newtown-scm.test.ts: BYOK→gateway incl. headers/body/reasoning, refinery-model preference, managed-refinery override of a BYOK default, org header, non-BYOK→Workers AI, no-token→Workers AI, 402→blocking without fallback, network error→blocking without fallback, empty content→blocking).packages/worker-utils:tsgo --noEmit,oxlint,vitest run— 602 passed.apps/web:tsgo --noEmitpasses with the new drift guard. The drift test itself could not run in this sandbox because apps/web Jest's per-worker setup requires a live PostgreSQL (no Docker available); the list equality was validated directly and CI covers the Jest run.oxfmt --list-differentclean on all changed files.Notes
model-selection.tsresolution is not onmain; this PR keeps the self-contained provider list + drift guard rather than depending on it.Refs, notFixes.