Skip to content

Commit 9abb946

Browse files
committed
test(gateway): cover OpenAI sampling parameter forwarding
1 parent 6a0d501 commit 9abb946

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

src/agents/openai-transport-stream.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,37 @@ describe("openai transport stream", () => {
19431943
expect(params.top_p).toBe(0.9);
19441944
});
19451945

1946+
it("forwards penalty params and seed to chat completions request params", () => {
1947+
const params = buildOpenAICompletionsParams(
1948+
{
1949+
id: "gpt-5.4",
1950+
name: "GPT-5.4",
1951+
api: "openai-completions",
1952+
provider: "openai",
1953+
baseUrl: "https://api.openai.com/v1",
1954+
reasoning: false,
1955+
input: ["text"],
1956+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1957+
contextWindow: 200000,
1958+
maxTokens: 8192,
1959+
} satisfies Model<"openai-completions">,
1960+
{
1961+
systemPrompt: "system",
1962+
messages: [{ role: "user", content: "hi", timestamp: 1 }],
1963+
tools: [],
1964+
} as never,
1965+
{
1966+
frequencyPenalty: -0.5,
1967+
presencePenalty: 1.25,
1968+
seed: 12345,
1969+
},
1970+
);
1971+
1972+
expect(params.frequency_penalty).toBe(-0.5);
1973+
expect(params.presence_penalty).toBe(1.25);
1974+
expect(params.seed).toBe(12345);
1975+
});
1976+
19461977
it("forwards response_format to chat completions request params", () => {
19471978
const model = {
19481979
id: "gpt-5.4",

src/gateway/openai-http.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,11 @@ type FirstAgentCommandOptions = {
112112
model?: string;
113113
sessionKey?: string;
114114
streamParams?: {
115+
frequencyPenalty?: number;
115116
maxTokens?: number;
117+
presencePenalty?: number;
116118
responseFormat?: Record<string, unknown>;
119+
seed?: number;
117120
temperature?: number;
118121
topP?: number;
119122
};
@@ -1402,6 +1405,46 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
14021405
}
14031406
});
14041407

1408+
it("forwards inbound penalty and seed params into streamParams", async () => {
1409+
const port = enabledPort;
1410+
const mockAgentOnce = (payloads: Array<{ text: string }>) => {
1411+
agentCommand.mockClear();
1412+
agentCommand.mockResolvedValueOnce({ payloads } as never);
1413+
};
1414+
const getStreamParams = () => firstAgentCommandOptions()?.streamParams;
1415+
1416+
{
1417+
mockAgentOnce([{ text: "hello" }]);
1418+
const res = await postChatCompletions(port, {
1419+
model: "openclaw",
1420+
frequency_penalty: -0.5,
1421+
presence_penalty: 1.25,
1422+
seed: 12345,
1423+
messages: [{ role: "user", content: "hi" }],
1424+
});
1425+
expect(res.status).toBe(200);
1426+
expect(getStreamParams()).toMatchObject({
1427+
frequencyPenalty: -0.5,
1428+
presencePenalty: 1.25,
1429+
seed: 12345,
1430+
});
1431+
await res.text();
1432+
}
1433+
1434+
for (const body of [{ frequency_penalty: 3 }, { presence_penalty: -3 }, { seed: 1.5 }]) {
1435+
agentCommand.mockClear();
1436+
const res = await postChatCompletions(port, {
1437+
model: "openclaw",
1438+
...body,
1439+
messages: [{ role: "user", content: "hi" }],
1440+
});
1441+
expect(res.status).toBe(400);
1442+
const json = (await res.json()) as { error?: { type?: string; message?: string } };
1443+
expect(json.error?.type).toBe("invalid_request_error");
1444+
expect(agentCommand).toHaveBeenCalledTimes(0);
1445+
}
1446+
});
1447+
14051448
it("maps provider format failures to OpenAI-compatible 400 errors", async () => {
14061449
const port = enabledPort;
14071450

0 commit comments

Comments
 (0)