Skip to content

fix(kimi): disable thinking and fail loudly on empty content - #15

Merged
klaus993 merged 1 commit into
mainfrom
fix/kimi-thinking-empty-content
Aug 31, 2026
Merged

fix(kimi): disable thinking and fail loudly on empty content#15
klaus993 merged 1 commit into
mainfrom
fix/kimi-thinking-empty-content

Conversation

@klaus993

Copy link
Copy Markdown
Contributor

Follow-up to #14. That PR cleared the 404, but Kimi reviews still never reached the PR.

What the test showed

Triggered /kimi on ethrex#7207 -> run 33441887902:

  • Resolved ai-review-kimi.yml@refs/tags/v1 (88321d9), input model: kimi-k2.7-code
  • Call Kimi API for review -> success, no 404
  • Post review comment -> success
  • Post error comment -> skipped
  • Comments on the PR: none

So the model id is valid and the account is fine. The good news buried in there: kimi-k2.5 really was retired, and there is no billing or permission problem.

Why nothing posted

Per the chat API docs:

thinking.type -- Thinking switch (kimi-k2.7-code is always enabled and cannot be disabled)

and max_tokens (deprecated alias of max_completion_tokens) is "the maximum number of tokens to generate for the chat completion" -- reasoning tokens count against it.

With max_tokens: 4096, k2.7-code spent the budget on reasoning_content and returned an empty content. The workflow reads only .choices[0].message.content, and the posting step wraps its call in if (review && review.trim() !== '') -- so it succeeded doing nothing. Green run, silent PR.

Changes

1. Default to kimi-k2.6 with a new thinking input, defaulting to 'disabled'.

Restores the non-thinking behaviour kimi-k2.5 had, for which 4096 output tokens is a proven budget.

The trap worth naming: kimi-k2.6 also defaults to {"type": "enabled"}, so swapping the model string alone would hit the identical wall. The difference is that k2.6 accepts "disabled"; k2.7-code rejects it.

The field is an input rather than hardcoded because it is not portable across models -- k2.7-code only accepts "enabled", and kimi-k3 always reasons and uses reasoning_effort instead. Pass thinking: '' to omit the field entirely:

```
jq '... } + (if $thinking == "" then {} else { thinking: { type: $thinking } } end)'
```

2. Treat empty content as an error, not a silent success.

Reports finish_reason and whether reasoning_content was present, so the next occurrence explains itself. Same silent-failure class #13 just fixed for Codex.

Verification

jq payload construction exercised for thinking = disabled / enabled / '' (field correctly omitted on the last). Empty-content branch tested against three response shapes: a real review (posts), empty content with reasoning present (errors, finish_reason=length), and whitespace-only content (errors). YAML parses.

Not yet verified end-to-end against the live API -- that needs the merge and a tag move. I would re-run /kimi on ethrex#7207 straight after.

Note

v1 currently points at 88321d9, which has the broken k2.7-code default. It needs moving again once this lands.

The kimi-k2.5 -> kimi-k2.7-code swap in #14 cleared the 404, but reviews
still never reached the PR. Verified on ethrex#7207 (run 33441887902):
the API returned 200, "Post review comment" reported success, and no
comment appeared.

kimi-k2.7-code has thinking permanently enabled -- per the API docs,
thinking.type "is always enabled and cannot be disabled" for that model.
max_tokens caps *all* generated tokens, reasoning included, so the 4096
budget went to reasoning_content and content came back empty. The
workflow reads only .choices[0].message.content, and the posting step
wraps its call in `if (review.trim() !== '')`, so it succeeded doing
nothing.

Two changes:

1. Default to kimi-k2.6 with a new `thinking` input defaulting to
   'disabled'. This restores the non-thinking behaviour kimi-k2.5 had,
   for which 4096 output tokens is a proven budget. Note kimi-k2.6 also
   defaults to {"type": "enabled"}, so changing the model string alone
   would hit the same wall -- the difference is that k2.6 accepts
   "disabled" while k2.7-code rejects it.

   The input is configurable rather than hardcoded because the field is
   not portable: kimi-k2.7-code only accepts "enabled", and kimi-k3
   always reasons and uses reasoning_effort instead. Pass '' to omit the
   field entirely for those.

2. Treat an empty content field as an error instead of a silent success,
   reporting finish_reason and whether reasoning_content was present.
   Same silent-failure class as #13: a green run that tells nobody why
   the review never showed up.
@klaus993
klaus993 merged commit d66ba3f into main Aug 31, 2026
@klaus993
klaus993 deleted the fix/kimi-thinking-empty-content branch August 31, 2026 21:45
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