Skip to content

Commit c7bca64

Browse files
committed
fix: cover kimi tool choice normalization paths (#39854) (thanks @GeekCheyun)
1 parent 577fe57 commit c7bca64

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai
1414
- Mattermost replies: keep `root_id` pinned to the existing thread root when an agent replies inside a thread, while still using reply-target threading for top-level posts. (#27744) thanks @hnykda.
1515
- Agents/failover: detect Amazon Bedrock `Too many tokens per day` quota errors as rate limits across fallback, cron retry, and memory embeddings while keeping context-window `too many tokens per request` errors out of the rate-limit lane. (#39377) Thanks @gambletan.
1616
- Android/Play distribution: remove self-update, background location, `screen.record`, and background mic capture from the Android app, narrow the foreground service to `dataSync` only, and clean up the legacy `location.enabledMode=always` preference migration. (#39660) Thanks @obviyus.
17+
- Kimi coding tool calls: normalize Anthropic `tool_choice` modes like `auto`, `none`, and `required` before sending Kimi coding anthropic-messages requests so tool calls keep working on `.7`. (#39854) Thanks @GeekCheyun.
1718

1819
## 2026.3.7
1920

src/agents/pi-embedded-runner-extraparams.test.ts

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -804,37 +804,45 @@ describe("applyExtraParamsToAgent", () => {
804804
});
805805

806806
it("normalizes anthropic tool_choice modes for kimi-coding endpoints", () => {
807-
const payloads: Record<string, unknown>[] = [];
808-
const baseStreamFn: StreamFn = (_model, _context, options) => {
809-
const payload: Record<string, unknown> = {
810-
tools: [
811-
{
812-
name: "read",
813-
description: "Read file",
814-
input_schema: { type: "object", properties: {} },
815-
},
816-
],
817-
tool_choice: { type: "auto" },
807+
const cases = [
808+
{ input: { type: "auto" }, expected: "auto" },
809+
{ input: { type: "none" }, expected: "none" },
810+
{ input: { type: "required" }, expected: "required" },
811+
] as const;
812+
813+
for (const testCase of cases) {
814+
const payloads: Record<string, unknown>[] = [];
815+
const baseStreamFn: StreamFn = (_model, _context, options) => {
816+
const payload: Record<string, unknown> = {
817+
tools: [
818+
{
819+
name: "read",
820+
description: "Read file",
821+
input_schema: { type: "object", properties: {} },
822+
},
823+
],
824+
tool_choice: testCase.input,
825+
};
826+
options?.onPayload?.(payload);
827+
payloads.push(payload);
828+
return {} as ReturnType<StreamFn>;
818829
};
819-
options?.onPayload?.(payload);
820-
payloads.push(payload);
821-
return {} as ReturnType<StreamFn>;
822-
};
823-
const agent = { streamFn: baseStreamFn };
824-
825-
applyExtraParamsToAgent(agent, undefined, "kimi-coding", "k2p5", undefined, "low");
830+
const agent = { streamFn: baseStreamFn };
826831

827-
const model = {
828-
api: "anthropic-messages",
829-
provider: "kimi-coding",
830-
id: "k2p5",
831-
baseUrl: "https://api.kimi.com/coding/",
832-
} as Model<"anthropic-messages">;
833-
const context: Context = { messages: [] };
834-
void agent.streamFn?.(model, context, {});
832+
applyExtraParamsToAgent(agent, undefined, "kimi-coding", "k2p5", undefined, "low");
835833

836-
expect(payloads).toHaveLength(1);
837-
expect(payloads[0]?.tool_choice).toBe("auto");
834+
const model = {
835+
api: "anthropic-messages",
836+
provider: "kimi-coding",
837+
id: "k2p5",
838+
baseUrl: "https://api.kimi.com/coding/",
839+
} as Model<"anthropic-messages">;
840+
const context: Context = { messages: [] };
841+
void agent.streamFn?.(model, context, {});
842+
843+
expect(payloads).toHaveLength(1);
844+
expect(payloads[0]?.tool_choice).toBe(testCase.expected);
845+
}
838846
});
839847

840848
it("does not rewrite anthropic tool schema for non-kimi endpoints", () => {

0 commit comments

Comments
 (0)