Skip to content

Commit b367fdd

Browse files
authored
fix(ai): send top_k and drop penalties for xAI Responses (#58868)
1 parent b7321f7 commit b367fdd

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

‎packages/ai/src/protocols/xai-responses.ts‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ const XAIResponsesHostedToolItem = Schema.Union([
3131
),
3232
])
3333

34+
const Body = Schema.Struct({
35+
...OpenResponses.OpenResponsesBody.fields,
36+
top_k: Schema.optional(Schema.Number),
37+
})
38+
3439
const adapter = {
3540
id: ADAPTER,
3641
name: NAME,
@@ -53,7 +58,14 @@ const fromRequest = Effect.fn("XAIResponses.fromRequest")(function* (request: LL
5358
message:
5459
"xAI requires explicit compaction through LLMClient.compact; automatic context management is not supported",
5560
})
56-
return yield* OpenResponses.fromRequestWithAdapter(request, adapter)
61+
const body = yield* OpenResponses.fromRequestWithAdapter(request, adapter)
62+
// xAI Responses does not support penalties (they are ignored), but does support top_k.
63+
return {
64+
...body,
65+
presence_penalty: undefined,
66+
frequency_penalty: undefined,
67+
top_k: request.generation?.topK,
68+
}
5769
})
5870

5971
const HOSTED_TOOLS = {
@@ -83,7 +95,7 @@ const step = (state: OpenResponses.ParserState, input: OpenResponses.Event) => {
8395
export const protocol = Protocol.make({
8496
id: ADAPTER,
8597
body: {
86-
schema: OpenResponses.OpenResponsesBody,
98+
schema: Body,
8799
from: fromRequest,
88100
},
89101
stream: {

‎packages/ai/test/provider/xai-responses.test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ describe("xAI Responses route", () => {
7373
}),
7474
)
7575

76+
it.effect("sends top_k and omits unsupported penalties", () =>
77+
Effect.gen(function* () {
78+
const prepared = yield* compileRequest(
79+
LLM.request({
80+
model,
81+
prompt: "Hello",
82+
generation: { topK: 20, presencePenalty: 0.5, frequencyPenalty: 0.5 },
83+
}),
84+
)
85+
86+
expect(prepared.body.top_k).toBe(20)
87+
expect(prepared.body.presence_penalty).toBeUndefined()
88+
expect(prepared.body.frequency_penalty).toBeUndefined()
89+
}),
90+
)
91+
7692
it.effect("parses xAI reasoning summaries", () =>
7793
Effect.gen(function* () {
7894
const response = yield* LLMClient.generate(LLM.request({ model, prompt: "Think" })).pipe(

0 commit comments

Comments
 (0)