
























@@ -322,6 +322,37 @@ describe("createStreamFnWithExtraParams sampling overrides", () => {
322322expect(first.temperature).toBe(0.4);
323323});
324324325+it("keeps request-scoped stop out of prepared extra params cache", () => {
326+const prepareProviderExtraParams = vi.fn((params) => ({
327+ ...params.context.extraParams,
328+prepared: true,
329+}));
330+extraParamsTesting.setProviderRuntimeDepsForTest({
331+ prepareProviderExtraParams,
332+resolveProviderExtraParamsForTransport: () => undefined,
333+wrapProviderStreamFn: () => undefined,
334+});
335+336+const cfg = { agents: { defaults: {} } } as never;
337+const first = resolvePreparedExtraParams({
338+ cfg,
339+provider: "openai",
340+modelId: "gpt-5.4",
341+extraParamsOverride: { temperature: 0.4, stop: ["User:"] },
342+});
343+const second = resolvePreparedExtraParams({
344+ cfg,
345+provider: "openai",
346+modelId: "gpt-5.4",
347+extraParamsOverride: { temperature: 0.4, stop: ["Assistant:", "\n\n"] },
348+});
349+350+expect(prepareProviderExtraParams).toHaveBeenCalledTimes(1);
351+expect(first).toBe(second);
352+expect(first).not.toHaveProperty("stop");
353+expect(first.temperature).toBe(0.4);
354+});
355+325356it("forwards frequency_penalty, presence_penalty, and seed from override into stream options", () => {
326357const underlying = vi.fn(() => ({
327358push: vi.fn(),
@@ -360,6 +391,34 @@ describe("createStreamFnWithExtraParams sampling overrides", () => {
360391expect(callOptions?.seed).toBe(12345);
361392});
362393394+it("forwards stop sequences from override into stream options", () => {
395+const underlying = vi.fn(() => ({
396+push: vi.fn(),
397+result: vi.fn(async () => undefined),
398+[Symbol.asyncIterator]: vi.fn(async function* () {}),
399+})) as unknown as StreamFn;
400+const agent: { streamFn?: StreamFn } = { streamFn: underlying };
401+402+applyExtraParamsToAgent(agent, undefined, "openai", "gpt-5.4", {
403+stop: ["User:", "Assistant:"],
404+});
405+406+if (!agent.streamFn) {
407+throw new Error("expected extra params to wrap streamFn");
408+}
409+410+void agent.streamFn(
411+{ id: "gpt-5.4", api: "openai-completions", provider: "openai" } as never,
412+{ messages: [], tools: [] } as never,
413+undefined,
414+);
415+416+expect(underlying).toHaveBeenCalledTimes(1);
417+const callOptions = (underlying as unknown as { mock: { calls: unknown[][] } }).mock
418+.calls[0]?.[2] as { stop?: string[] } | undefined;
419+expect(callOptions?.stop).toEqual(["User:", "Assistant:"]);
420+});
421+363422it("prefers camelCase runtime overrides over snake_case config for penalty params", () => {
364423const underlying = vi.fn(() => ({
365424push: vi.fn(),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。