Skip to content

Commit 8d2f767

Browse files
committed
fix: always include temperature parameter for OpenAI compatible providers
- Modified base-openai-compatible-provider.ts to always include temperature with fallback to defaultTemperature - Modified openai.ts to always include temperature with fallback to 0 (or DEEP_SEEK_DEFAULT_TEMPERATURE for DeepSeek reasoner models) - Updated tests to expect temperature to always be included with appropriate defaults - This fixes TabbyApi/ExLlamaV2 crashes when temperature is undefined/null Fixes #7581
1 parent ae8a639 commit 8d2f767

File tree

5 files changed

+24
-26
lines changed

5 files changed

+24
-26
lines changed

src/api/providers/__tests__/groq.spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ describe("GroqHandler", () => {
195195
)
196196
})
197197

198-
it("should omit temperature when modelTemperature is undefined", async () => {
198+
it("should include default temperature of 0.5 when modelTemperature is undefined", async () => {
199199
const modelId: GroqModelId = "llama-3.1-8b-instant"
200200
const handlerWithoutTemp = new GroqHandler({
201201
apiModelId: modelId,
@@ -224,13 +224,10 @@ describe("GroqHandler", () => {
224224
model: modelId,
225225
messages: expect.arrayContaining([{ role: "system", content: systemPrompt }]),
226226
stream: true,
227+
temperature: 0.5, // Should include Groq's default temperature of 0.5
227228
}),
228229
undefined,
229230
)
230-
231-
// Verify temperature is NOT included
232-
const callArgs = mockCreate.mock.calls[0][0]
233-
expect(callArgs).not.toHaveProperty("temperature")
234231
})
235232

236233
it("should include temperature when modelTemperature is explicitly set", async () => {

src/api/providers/__tests__/openai.spec.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,20 +316,20 @@ describe("OpenAiHandler", () => {
316316
expect(callArgs.max_completion_tokens).toBe(4096)
317317
})
318318

319-
it("should omit temperature when modelTemperature is undefined", async () => {
319+
it("should include default temperature of 0 when modelTemperature is undefined", async () => {
320320
const optionsWithoutTemperature: ApiHandlerOptions = {
321321
...mockOptions,
322-
// modelTemperature is not set, should not include temperature
322+
// modelTemperature is not set, should include default temperature of 0
323323
}
324324
const handlerWithoutTemperature = new OpenAiHandler(optionsWithoutTemperature)
325325
const stream = handlerWithoutTemperature.createMessage(systemPrompt, messages)
326326
// Consume the stream to trigger the API call
327327
for await (const _chunk of stream) {
328328
}
329-
// Assert the mockCreate was called without temperature
329+
// Assert the mockCreate was called with default temperature of 0
330330
expect(mockCreate).toHaveBeenCalled()
331331
const callArgs = mockCreate.mock.calls[0][0]
332-
expect(callArgs).not.toHaveProperty("temperature")
332+
expect(callArgs.temperature).toBe(0)
333333
})
334334

335335
it("should include temperature when modelTemperature is explicitly set to 0", async () => {
@@ -431,6 +431,7 @@ describe("OpenAiHandler", () => {
431431
{
432432
model: mockOptions.openAiModelId,
433433
messages: [{ role: "user", content: "Test prompt" }],
434+
temperature: 0, // temperature should always be included with default of 0
434435
},
435436
{},
436437
)
@@ -515,7 +516,7 @@ describe("OpenAiHandler", () => {
515516
],
516517
stream: true,
517518
stream_options: { include_usage: true },
518-
// temperature should be omitted when not set
519+
temperature: 0, // temperature should always be included with default of 0
519520
},
520521
{ path: "/models/chat/completions" },
521522
)
@@ -562,6 +563,7 @@ describe("OpenAiHandler", () => {
562563
{ role: "user", content: systemPrompt },
563564
{ role: "user", content: "Hello!" },
564565
],
566+
temperature: 0, // temperature should always be included with default of 0
565567
},
566568
{ path: "/models/chat/completions" },
567569
)
@@ -579,6 +581,7 @@ describe("OpenAiHandler", () => {
579581
{
580582
model: azureOptions.openAiModelId,
581583
messages: [{ role: "user", content: "Test prompt" }],
584+
temperature: 0, // temperature should always be included with default of 0
582585
},
583586
{ path: "/models/chat/completions" },
584587
)

src/api/providers/__tests__/roo.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,16 +354,16 @@ describe("RooHandler", () => {
354354
})
355355

356356
describe("temperature and model configuration", () => {
357-
it("should omit temperature when not explicitly set", async () => {
357+
it("should include default temperature of 0.7 when not explicitly set", async () => {
358358
handler = new RooHandler(mockOptions)
359359
const stream = handler.createMessage(systemPrompt, messages)
360360
for await (const _chunk of stream) {
361361
// Consume stream
362362
}
363363

364364
expect(mockCreate).toHaveBeenCalledWith(
365-
expect.not.objectContaining({
366-
temperature: expect.anything(),
365+
expect.objectContaining({
366+
temperature: 0.7, // Should include Roo's default temperature of 0.7
367367
}),
368368
undefined,
369369
)

src/api/providers/base-openai-compatible-provider.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,9 @@ export abstract class BaseOpenAiCompatibleProvider<ModelName extends string>
7979
messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)],
8080
stream: true,
8181
stream_options: { include_usage: true },
82-
}
83-
84-
// Only include temperature if explicitly set
85-
if (this.options.modelTemperature !== undefined) {
86-
params.temperature = this.options.modelTemperature
82+
// Always include temperature to prevent TabbyApi/ExLlamaV2 crashes
83+
// Use explicitly set temperature, or fall back to defaultTemperature (which defaults to 0)
84+
temperature: this.options.modelTemperature ?? this.defaultTemperature,
8785
}
8886

8987
return this.client.chat.completions.create(params, requestOptions)

src/api/providers/openai.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,9 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
161161
stream: true as const,
162162
...(isGrokXAI ? {} : { stream_options: { include_usage: true } }),
163163
...(reasoning && reasoning),
164-
}
165-
166-
// Only include temperature if explicitly set
167-
if (this.options.modelTemperature !== undefined) {
168-
requestOptions.temperature = this.options.modelTemperature
169-
} else if (deepseekReasoner) {
170-
// DeepSeek Reasoner has a specific default temperature
171-
requestOptions.temperature = DEEP_SEEK_DEFAULT_TEMPERATURE
164+
// Always include temperature to prevent TabbyApi/ExLlamaV2 crashes
165+
// Use explicitly set temperature, or DeepSeek default for reasoner models, or fall back to 0
166+
temperature: this.options.modelTemperature ?? (deepseekReasoner ? DEEP_SEEK_DEFAULT_TEMPERATURE : 0),
172167
}
173168

174169
// Add max_tokens if needed
@@ -231,6 +226,9 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
231226
: enabledLegacyFormat
232227
? [systemMessage, ...convertToSimpleMessages(messages)]
233228
: [systemMessage, ...convertToOpenAiMessages(messages)],
229+
// Always include temperature to prevent TabbyApi/ExLlamaV2 crashes
230+
// Use explicitly set temperature, or DeepSeek default for reasoner models, or fall back to 0
231+
temperature: this.options.modelTemperature ?? (deepseekReasoner ? DEEP_SEEK_DEFAULT_TEMPERATURE : 0),
234232
}
235233

236234
// Add max_tokens if needed
@@ -276,6 +274,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
276274
const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = {
277275
model: model.id,
278276
messages: [{ role: "user", content: prompt }],
277+
// Always include temperature to prevent TabbyApi/ExLlamaV2 crashes
278+
temperature: this.options.modelTemperature ?? 0,
279279
}
280280

281281
// Add max_tokens if needed

0 commit comments

Comments
 (0)