




















@@ -1,7 +1,12 @@
11import type { StreamFn } from "@mariozechner/pi-agent-core";
22import type { Context, Model } from "@mariozechner/pi-ai";
33import { describe, expect, it } from "vitest";
4-import { createKimiToolCallMarkupWrapper, wrapKimiProviderStream } from "./stream.js";
4+import {
5+createKimiThinkingWrapper,
6+createKimiToolCallMarkupWrapper,
7+resolveKimiThinkingType,
8+wrapKimiProviderStream,
9+} from "./stream.js";
510611type FakeStream = {
712result: () => Promise<unknown>;
@@ -29,6 +34,19 @@ const KIMI_MULTI_TOOL_TEXT =
2934' <|tool_calls_section_begin|> <|tool_call_begin|> functions.read:0 <|tool_call_argument_begin|> {"file_path":"./package.json"} <|tool_call_end|> <|tool_call_begin|> functions.write:1 <|tool_call_argument_begin|> {"file_path":"./out.txt","content":"done"} <|tool_call_end|> <|tool_calls_section_end|>';
30353136describe("kimi tool-call markup wrapper", () => {
37+it("defaults Kimi thinking to disabled unless explicitly enabled", () => {
38+expect(resolveKimiThinkingType({ configuredThinking: undefined })).toBe("disabled");
39+expect(resolveKimiThinkingType({ configuredThinking: undefined, thinkingLevel: "high" })).toBe(
40+"enabled",
41+);
42+expect(resolveKimiThinkingType({ configuredThinking: "off", thinkingLevel: "high" })).toBe(
43+"disabled",
44+);
45+expect(resolveKimiThinkingType({ configuredThinking: "enabled", thinkingLevel: "off" })).toBe(
46+"enabled",
47+);
48+});
49+3250it("converts tagged Kimi tool-call text into structured tool calls", async () => {
3351const partial = {
3452role: "assistant",
@@ -243,4 +261,105 @@ describe("kimi tool-call markup wrapper", () => {
243261stopReason: "toolUse",
244262});
245263});
264+265+it("forces Kimi thinking disabled and strips proxy reasoning fields", () => {
266+let capturedPayload: Record<string, unknown> | undefined;
267+const baseStreamFn: StreamFn = (model, _context, options) => {
268+const payload: Record<string, unknown> = {
269+reasoning: { effort: "high" },
270+reasoning_effort: "high",
271+reasoningEffort: "high",
272+};
273+options?.onPayload?.(payload as never, model as never);
274+capturedPayload = payload;
275+return createFakeStream({
276+events: [],
277+resultMessage: { role: "assistant", content: [] },
278+}) as never;
279+};
280+281+const wrapped = createKimiThinkingWrapper(baseStreamFn, "disabled");
282+void wrapped(
283+{
284+api: "anthropic-messages",
285+provider: "kimi",
286+id: "kimi-code",
287+} as Model<"anthropic-messages">,
288+{ messages: [] } as Context,
289+{},
290+);
291+292+expect(capturedPayload).toEqual({
293+thinking: { type: "disabled" },
294+});
295+});
296+297+it("lets explicit model params keep Kimi thinking disabled even when session thinking is on", () => {
298+let capturedPayload: Record<string, unknown> | undefined;
299+const baseStreamFn: StreamFn = (model, _context, options) => {
300+const payload: Record<string, unknown> = {};
301+options?.onPayload?.(payload as never, model as never);
302+capturedPayload = payload;
303+return createFakeStream({
304+events: [],
305+resultMessage: { role: "assistant", content: [] },
306+}) as never;
307+};
308+309+const wrapped = wrapKimiProviderStream({
310+provider: "kimi",
311+modelId: "kimi-code",
312+extraParams: { thinking: "off" },
313+thinkingLevel: "high",
314+streamFn: baseStreamFn,
315+} as never);
316+317+void wrapped(
318+{
319+api: "anthropic-messages",
320+provider: "kimi",
321+id: "kimi-code",
322+} as Model<"anthropic-messages">,
323+{ messages: [] } as Context,
324+{},
325+);
326+327+expect(capturedPayload).toEqual({
328+thinking: { type: "disabled" },
329+});
330+});
331+332+it("enables Kimi thinking only when explicitly requested", () => {
333+let capturedPayload: Record<string, unknown> | undefined;
334+const baseStreamFn: StreamFn = (model, _context, options) => {
335+const payload: Record<string, unknown> = {};
336+options?.onPayload?.(payload as never, model as never);
337+capturedPayload = payload;
338+return createFakeStream({
339+events: [],
340+resultMessage: { role: "assistant", content: [] },
341+}) as never;
342+};
343+344+const wrapped = wrapKimiProviderStream({
345+provider: "kimi",
346+modelId: "kimi-code",
347+thinkingLevel: "high",
348+streamFn: baseStreamFn,
349+} as never);
350+351+void wrapped(
352+{
353+api: "anthropic-messages",
354+provider: "kimi",
355+id: "kimi-code",
356+} as Model<"anthropic-messages">,
357+{ messages: [] } as Context,
358+{},
359+);
360+361+expect(capturedPayload).toEqual({
362+thinking: { type: "enabled" },
363+});
364+});
246365});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。