mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: use Fireworks reasoning_effort parameter for DeepSeek V3.1/V3.2
- Changed from supportsReasoningBinary to supportsReasoningEffort for DeepSeek V3.1 and V3.2 models on Fireworks - Added default reasoningEffort: "medium" for both models - Override createStream in FireworksHandler to use getModelParams which passes reasoning_effort parameter (Fireworks API style) instead of thinking parameter (Anthropic style) - Added tests to verify reasoning_effort is passed correctly
This commit is contained in:
parent
b138557bda
commit
959d233fd7
3 changed files with 133 additions and 2 deletions
|
|
@ -101,6 +101,8 @@ export const fireworksModels = {
|
|||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
supportsNativeTools: true,
|
||||
supportsReasoningEffort: ["low", "medium", "high"],
|
||||
reasoningEffort: "medium",
|
||||
inputPrice: 0.56,
|
||||
outputPrice: 1.68,
|
||||
description:
|
||||
|
|
@ -112,7 +114,8 @@ export const fireworksModels = {
|
|||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
supportsNativeTools: true,
|
||||
supportsReasoningBinary: true,
|
||||
supportsReasoningEffort: ["low", "medium", "high"],
|
||||
reasoningEffort: "medium",
|
||||
inputPrice: 0.56,
|
||||
outputPrice: 1.68,
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -214,6 +214,8 @@ describe("FireworksHandler", () => {
|
|||
contextWindow: 163840,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: ["low", "medium", "high"],
|
||||
reasoningEffort: "medium",
|
||||
inputPrice: 0.56,
|
||||
outputPrice: 1.68,
|
||||
description: expect.stringContaining("DeepSeek v3.1 is an improved version"),
|
||||
|
|
@ -235,7 +237,8 @@ describe("FireworksHandler", () => {
|
|||
contextWindow: 163840,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningBinary: true,
|
||||
supportsReasoningEffort: ["low", "medium", "high"],
|
||||
reasoningEffort: "medium",
|
||||
inputPrice: 0.56,
|
||||
outputPrice: 1.68,
|
||||
description: expect.stringContaining("DeepSeek v3.2 is the latest version"),
|
||||
|
|
@ -243,6 +246,70 @@ describe("FireworksHandler", () => {
|
|||
)
|
||||
})
|
||||
|
||||
it("should include reasoning_effort parameter for DeepSeek V3.2 when reasoning is enabled", async () => {
|
||||
const testModelId: FireworksModelId = "accounts/fireworks/models/deepseek-v3p2"
|
||||
const handlerWithModel = new FireworksHandler({
|
||||
apiModelId: testModelId,
|
||||
fireworksApiKey: "test-fireworks-api-key",
|
||||
enableReasoningEffort: true,
|
||||
reasoningEffort: "high",
|
||||
})
|
||||
|
||||
mockCreate.mockImplementationOnce(() => {
|
||||
return {
|
||||
[Symbol.asyncIterator]: () => ({
|
||||
async next() {
|
||||
return { done: true }
|
||||
},
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
const systemPrompt = "Test system prompt"
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Test message" }]
|
||||
|
||||
const messageGenerator = handlerWithModel.createMessage(systemPrompt, messages)
|
||||
await messageGenerator.next()
|
||||
|
||||
// Check that reasoning_effort was included in the request
|
||||
expect(mockCreate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
model: testModelId,
|
||||
reasoning_effort: "high",
|
||||
}),
|
||||
undefined,
|
||||
)
|
||||
})
|
||||
|
||||
it("should not include reasoning_effort parameter when reasoning is disabled", async () => {
|
||||
const testModelId: FireworksModelId = "accounts/fireworks/models/deepseek-v3p2"
|
||||
const handlerWithModel = new FireworksHandler({
|
||||
apiModelId: testModelId,
|
||||
fireworksApiKey: "test-fireworks-api-key",
|
||||
enableReasoningEffort: false,
|
||||
})
|
||||
|
||||
mockCreate.mockImplementationOnce(() => {
|
||||
return {
|
||||
[Symbol.asyncIterator]: () => ({
|
||||
async next() {
|
||||
return { done: true }
|
||||
},
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
const systemPrompt = "Test system prompt"
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Test message" }]
|
||||
|
||||
const messageGenerator = handlerWithModel.createMessage(systemPrompt, messages)
|
||||
await messageGenerator.next()
|
||||
|
||||
// Check that reasoning_effort was NOT included in the request
|
||||
const callArgs = mockCreate.mock.calls[0][0]
|
||||
expect(callArgs.reasoning_effort).toBeUndefined()
|
||||
})
|
||||
|
||||
it("should return GLM-4.5 model with correct configuration", () => {
|
||||
const testModelId: FireworksModelId = "accounts/fireworks/models/glm-4p5"
|
||||
const handlerWithModel = new FireworksHandler({
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import OpenAI from "openai"
|
||||
|
||||
import { type FireworksModelId, fireworksDefaultModelId, fireworksModels } from "@roo-code/types"
|
||||
|
||||
import type { ApiHandlerOptions } from "../../shared/api"
|
||||
import { getModelParams } from "../transform/model-params"
|
||||
import { getModelMaxOutputTokens } from "../../shared/api"
|
||||
import { convertToOpenAiMessages } from "../transform/openai-format"
|
||||
|
||||
import type { ApiHandlerCreateMessageMetadata } from "../index"
|
||||
import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"
|
||||
import { handleOpenAIError } from "./utils/openai-error-handler"
|
||||
|
||||
export class FireworksHandler extends BaseOpenAiCompatibleProvider<FireworksModelId> {
|
||||
constructor(options: ApiHandlerOptions) {
|
||||
|
|
@ -16,4 +24,57 @@ export class FireworksHandler extends BaseOpenAiCompatibleProvider<FireworksMode
|
|||
defaultTemperature: 0.5,
|
||||
})
|
||||
}
|
||||
|
||||
override getModel() {
|
||||
const id =
|
||||
this.options.apiModelId && this.options.apiModelId in this.providerModels
|
||||
? (this.options.apiModelId as FireworksModelId)
|
||||
: this.defaultProviderModelId
|
||||
|
||||
const info = this.providerModels[id]
|
||||
const params = getModelParams({ format: "openai", modelId: id, model: info, settings: this.options })
|
||||
return { id, info, ...params }
|
||||
}
|
||||
|
||||
protected override createStream(
|
||||
systemPrompt: string,
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
metadata?: ApiHandlerCreateMessageMetadata,
|
||||
requestOptions?: OpenAI.RequestOptions,
|
||||
) {
|
||||
const { id: model, info, reasoning } = this.getModel()
|
||||
|
||||
// Centralized cap: clamp to 20% of the context window (unless provider-specific exceptions apply)
|
||||
const max_tokens =
|
||||
getModelMaxOutputTokens({
|
||||
modelId: model,
|
||||
model: info,
|
||||
settings: this.options,
|
||||
format: "openai",
|
||||
}) ?? undefined
|
||||
|
||||
const temperature = this.options.modelTemperature ?? this.defaultTemperature
|
||||
|
||||
const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {
|
||||
model,
|
||||
max_tokens,
|
||||
temperature,
|
||||
messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)],
|
||||
stream: true,
|
||||
stream_options: { include_usage: true },
|
||||
...(metadata?.tools && { tools: this.convertToolsForOpenAI(metadata.tools) }),
|
||||
...(metadata?.tool_choice && { tool_choice: metadata.tool_choice }),
|
||||
...(metadata?.toolProtocol === "native" && {
|
||||
parallel_tool_calls: metadata.parallelToolCalls ?? false,
|
||||
}),
|
||||
// Use Fireworks-style reasoning_effort parameter instead of Anthropic-style "thinking"
|
||||
...(reasoning && reasoning),
|
||||
}
|
||||
|
||||
try {
|
||||
return this.client.chat.completions.create(params, requestOptions)
|
||||
} catch (error) {
|
||||
throw handleOpenAIError(error, "Fireworks")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue