Repository navigation
fix(kimi): omit explicit empty assistant history on native Responses - #6931
yuanyuanlove wants to merge 2 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Deterministic PR hygiene checks passed. |
⏳ DRAFT
What to do
Review readiness checklist
0/4 boxes ticked. This PR stays in draft until every box above is ticked. |
Ingwannu
left a comment
There was a problem hiding this comment.
Source review of b49d4f6b5824a63998f1b82ee4cadb17c2a9f79d against trusted dev 9b6f4b2632492b3df637dccc009d6a01ed47c85d (nine files).
The Responses filter is narrow: exact Kimi Coding host/path, explicit empty message content, an allowlist of harmless message/text metadata, and same-input reference preservation. Unknown fields/parts, nonempty annotations, whitespace, refusals and independent reasoning/tool carriers are not treated as empty. It returns a detached input only when needed and leaves caller history unchanged. In translated Chat the check occurs before flushing pending calls; it drops an empty joined answer only when neither tool calls nor serialized reasoning remain. That matters for the tool-result pairing and reasoning-only cases.
I read the complete 20-case fixture and the production/doc/layout changes. No concrete source-level blocker found in this scope. The position-585 case is correctly labeled synthetic: it demonstrates the stated rejection shape with a strict offline fixture, not reproduction of the reporter's original conversation or a real Kimi response.
Independent execution is not completed. I prepared an exact-head ubuntu-owned worktree and a fresh private-home, CPU75% / memoryHigh1280MiB / max1536MiB / swap0 / tasks64 / finite-deadline unit. Its admission guard waited 60 seconds for foreign Cargo/rustc work and exited 75 before Bun started. This is neither a failing regression nor a passing test receipt; I did not overlap the foreign build or raise limits. The 20-case and broader receipts in the description remain yours, not mine.
Please retain Draft until readiness/required review and current-head CI complete. Cross-platform 38113761756, Catalog 38113761789 and React Doctor 38113761780 are action_required; target and hygiene success alone are not runtime validation. No live Kimi/provider/native-client call, scan, workflow authorization, sponsorship or contributor-branch modification was performed. This review is COMMENTED, not APPROVED.
|
Carried into #6947 with credit to you (Co-authored-by trailers in the commit and description). The Responses filter for |
…(carry #6931) (#6947) Kimi Code's native Responses endpoint rejects a content-empty assistant message ("the message at position N with role 'assistant' must not be empty"). For the exact api.kimi.com/coding/v1/responses destination, the outgoing input now drops assistant messages whose content is "" or only empty text parts, keeping any message referenced by a same-input item_reference and any message with unknown fields. On the translated Chat wire, an empty assistant turn between a tool call and its result no longer splits the pair: it used to close the pending call with a synthetic "no tool result was recorded" message and turn the real result into an orphan. A standalone empty answer keeps its slot so chat templates with strict role alternation still accept the history. Co-authored-by: panyuanyuan <panyuanyuan@hetao101.com> Co-authored-by: yuanyuanlove <yuanyuanlove@users.noreply.github.com>
Summary
Invalid request: the message at position 585 with role 'assistant' must not be emptyon a native Responses → Responses request, so a Chat-only fix would miss the affected wire.inputfor the exactapi.kimi.com/coding/v1/responseshost/path omits assistant messages whose content is explicitly"",[], or a list of empty text parts. Do not trim whitespace, invent answer text, rewrite the client's saved history, add retries, or change other Responses destinations. Keep refusal/multimodal/unknown content, nonempty annotations and extension fields, tools and reasoning carriers. Empty messages with same-input stored-item references are retained to avoid creating dangling references.Verification
Fetched and merged upstream
devcommit9b6f4b2632492b3df637dccc009d6a01ed47c85dwithout conflicts (no rebase). Incoming upstream commits did not change these runtime sites. The PR diff is nine files; no unrelated runtime overlay is included.Test-first development of the original empty shapes: 7 pass / 7 fail before implementation, then 18 pass / 0 fail. The added referenced-item regression independently failed before its guard: 19 pass / 1 fail; after the fix all 20 synthetic behavior cases pass, including explicit empty shapes, the synthetic 585th-message rejection, references, multimodal/refusal/unknown content, whitespace, native destination exclusions, tool/reasoning carriers and immutable caller input.
Final merged tree, pinned Bun 1.4.0:
bun test --isolate --parallel=4 --timeout=15000 --changed=origin/dev ./tests/responses ./tests/adapters/openai: 4,133 pass / 1 skip / 0 fail, 165 files and 226,456 assertions. This is bounded import-connected adapter/Responses coverage, not the full repository suite. Test timeout is a runner setting, not a production timeout change. An earlier development batch at a 5-second test budget had timeout/handoff failures; its failed file passed independently on both candidate and unchanged baseline. Those old failures are recorded, not asserted to be baseline source defects; both this final batch and the preceding merged batch at a 15-second budget completed without failures.bun test --isolate tests/adapters/openai/openai-empty-assistant-history.test.ts tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/ci-workflows/file-size-ratchet.test.ts tests/ci-workflows/structure-ssot.test.ts: 99 pass / 0 fail, 826 assertions. Subsequently only the new test's index placement moved next to existing OpenAI entries to avoid shared hunks with the separate Sol PR; the three index/layout/ratchet files passed again (28 pass / 0 fail, 643 assertions). Runtime and behavior tests were unchanged by that placement edit.Final
bun x --no-install tsc --noEmit,bun run structure:check,bun run privacy:scan: passed. English/Chinese docs build passed with existing compatible dependencies and isolated output/cache: 569 pages and 79,288 internal links checked; no install or lockfile change.git diff --check origin/devandgit diff --cached --check origin/dev: passed for the proposed PR. As in upstream itself, comparing the merge to the old HEAD reports an unrelated existing blank line at EOF intests/providers/github-copilot/github-copilot-auto-runtime.test.ts; that file is unchanged relative to the base and not cleaned up in this PR.Independent read-only review raised the reference-preservation case, now fixed and covered; no implementation blocker remained. The runtime boundary is reviewed on the merged tree, not assumed from a pre-merge test result.
Full repository suite, live Kimi long-history acceptance and cross-platform validation remain outstanding. The PR is submitted as draft, not as a full-CI/review-readiness attestation. No real request body, ciphertext, token or private capture is committed.
Checklist
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
Required local validation passed; commands, results, and any full-suite exception are documented.
I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.