























@@ -4,6 +4,7 @@ import { createPiAiStreamSimpleMock } from "../../../test/helpers/agents/pi-ai-s
44import {
55__testing as extraParamsTesting,
66applyExtraParamsToAgent,
7+resolveExtraParams,
78resolvePreparedExtraParams,
89} from "./extra-params.js";
910@@ -63,6 +64,100 @@ describe("createStreamFnWithExtraParams sampling overrides", () => {
6364expect(callOptions?.maxTokens).toBe(512);
6465});
656667+it("forwards OpenAI completions token aliases into the underlying streamFn options", () => {
68+const underlying = vi.fn(() => ({
69+push: vi.fn(),
70+result: vi.fn(async () => undefined),
71+[Symbol.asyncIterator]: vi.fn(async function* () {
72+// empty stream
73+}),
74+})) as unknown as StreamFn;
75+const agent: { streamFn?: StreamFn } = { streamFn: underlying };
76+77+applyExtraParamsToAgent(agent, undefined, "dashscope", "kimi-k2.6", {
78+max_completion_tokens: 64_000,
79+});
80+81+if (!agent.streamFn) {
82+throw new Error("expected extra params to wrap streamFn");
83+}
84+85+void agent.streamFn(
86+{ id: "kimi-k2.6", api: "openai-completions", provider: "dashscope" } as never,
87+{ messages: [], tools: [] } as never,
88+undefined,
89+);
90+91+const callOptions = (underlying as unknown as { mock: { calls: unknown[][] } }).mock
92+.calls[0]?.[2] as { maxTokens?: number } | undefined;
93+expect(callOptions?.maxTokens).toBe(64_000);
94+});
95+96+it("keeps runtime maxTokens ahead of OpenAI completions token alias defaults", () => {
97+const underlying = vi.fn(() => ({
98+push: vi.fn(),
99+result: vi.fn(async () => undefined),
100+[Symbol.asyncIterator]: vi.fn(async function* () {
101+// empty stream
102+}),
103+})) as unknown as StreamFn;
104+const agent: { streamFn?: StreamFn } = { streamFn: underlying };
105+106+applyExtraParamsToAgent(agent, undefined, "dashscope", "kimi-k2.6", {
107+max_completion_tokens: 64_000,
108+});
109+110+if (!agent.streamFn) {
111+throw new Error("expected extra params to wrap streamFn");
112+}
113+114+void agent.streamFn(
115+{ id: "kimi-k2.6", api: "openai-completions", provider: "dashscope" } as never,
116+{ messages: [], tools: [] } as never,
117+{ maxTokens: 32_000 } as never,
118+);
119+120+const callOptions = (underlying as unknown as { mock: { calls: unknown[][] } }).mock
121+.calls[0]?.[2] as { maxTokens?: number } | undefined;
122+expect(callOptions?.maxTokens).toBe(32_000);
123+});
124+125+it("canonicalizes token aliases with config precedence before preparing stream params", () => {
126+const resolved = resolveExtraParams({
127+cfg: {
128+agents: {
129+defaults: {
130+params: {
131+maxTokens: 32_000,
132+},
133+models: {
134+"dashscope/kimi-k2.6": {
135+params: {
136+max_completion_tokens: 64_000,
137+},
138+},
139+},
140+},
141+list: [
142+{
143+id: "bot",
144+params: {
145+max_tokens: 48_000,
146+},
147+},
148+],
149+},
150+} as never,
151+provider: "dashscope",
152+modelId: "kimi-k2.6",
153+agentId: "bot",
154+});
155+156+expect(resolved?.maxTokens).toBe(48_000);
157+expect(resolved).not.toHaveProperty("max_completion_tokens");
158+expect(resolved).not.toHaveProperty("max_tokens");
159+});
160+66161it("lets runtime options override the wrapper sampling defaults", () => {
67162const underlying = vi.fn(() => ({
68163push: vi.fn(),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。