diff --git a/src/api/providers/__tests__/deepseek.test.ts b/src/api/providers/__tests__/deepseek.test.ts index 00526dc..e510b19 100644 --- a/src/api/providers/__tests__/deepseek.test.ts +++ b/src/api/providers/__tests__/deepseek.test.ts @@ -71,7 +71,7 @@ describe("DeepSeekHandler", () => { beforeEach(() => { mockOptions = { deepSeekApiKey: "test-api-key", - deepSeekModelId: "deepseek-chat", + apiModelId: "deepseek-chat", deepSeekBaseUrl: "https://api.deepseek.com/v1", } handler = new DeepSeekHandler(mockOptions) @@ -81,7 +81,7 @@ describe("DeepSeekHandler", () => { describe("constructor", () => { it("should initialize with provided options", () => { expect(handler).toBeInstanceOf(DeepSeekHandler) - expect(handler.getModel().id).toBe(mockOptions.deepSeekModelId) + expect(handler.getModel().id).toBe(mockOptions.apiModelId) }) it("should throw error if API key is missing", () => { @@ -96,7 +96,7 @@ describe("DeepSeekHandler", () => { it("should use default model ID if not provided", () => { const handlerWithoutModel = new DeepSeekHandler({ ...mockOptions, - deepSeekModelId: undefined, + apiModelId: undefined, }) expect(handlerWithoutModel.getModel().id).toBe(deepSeekDefaultModelId) }) @@ -144,7 +144,7 @@ describe("DeepSeekHandler", () => { describe("getModel", () => { it("should return model info for valid model ID", () => { const model = handler.getModel() - expect(model.id).toBe(mockOptions.deepSeekModelId) + expect(model.id).toBe(mockOptions.apiModelId) expect(model.info).toBeDefined() expect(model.info.maxTokens).toBe(8192) expect(model.info.contextWindow).toBe(64_000) @@ -155,7 +155,7 @@ describe("DeepSeekHandler", () => { it("should return provided model ID with default model info if model does not exist", () => { const handlerWithInvalidModel = new DeepSeekHandler({ ...mockOptions, - deepSeekModelId: "invalid-model", + apiModelId: "invalid-model", }) const model = handlerWithInvalidModel.getModel() expect(model.id).toBe("invalid-model") // Returns provided ID @@ -166,7 +166,7 @@ describe("DeepSeekHandler", () => { it("should return default model if no model ID is provided", () => { const handlerWithoutModel = new DeepSeekHandler({ ...mockOptions, - deepSeekModelId: undefined, + apiModelId: undefined, }) const model = handlerWithoutModel.getModel() expect(model.id).toBe(deepSeekDefaultModelId) diff --git a/src/api/providers/__tests__/openai.test.ts b/src/api/providers/__tests__/openai.test.ts index ba65971..52d0c5c 100644 --- a/src/api/providers/__tests__/openai.test.ts +++ b/src/api/providers/__tests__/openai.test.ts @@ -193,7 +193,6 @@ describe("OpenAiHandler", () => { expect(mockCreate).toHaveBeenCalledWith({ model: mockOptions.openAiModelId, messages: [{ role: "user", content: "Test prompt" }], - temperature: 0, }) }) diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index e559f98..96be435 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -10,14 +10,15 @@ export class DeepSeekHandler extends OpenAiHandler { super({ ...options, openAiApiKey: options.deepSeekApiKey, - openAiModelId: options.deepSeekModelId ?? deepSeekDefaultModelId, + openAiModelId: options.apiModelId ?? deepSeekDefaultModelId, openAiBaseUrl: options.deepSeekBaseUrl ?? "https://api.deepseek.com/v1", + openAiStreamingEnabled: true, includeMaxTokens: true, }) } override getModel(): { id: string; info: ModelInfo } { - const modelId = this.options.deepSeekModelId ?? deepSeekDefaultModelId + const modelId = this.options.apiModelId ?? deepSeekDefaultModelId return { id: modelId, info: deepSeekModels[modelId as keyof typeof deepSeekModels] || deepSeekModels[deepSeekDefaultModelId], diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index f1dbe6e..13922a4 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -36,7 +36,9 @@ export class OpenAiHandler implements ApiHandler, SingleCompletionHandler { const modelInfo = this.getModel().info const modelId = this.options.openAiModelId ?? "" - if (this.options.openAiStreamingEnabled ?? true) { + const deepseekReasoner = modelId.includes("deepseek-reasoner") + + if (!deepseekReasoner && (this.options.openAiStreamingEnabled ?? true)) { const systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = { role: "system", content: systemPrompt, @@ -71,11 +73,20 @@ export class OpenAiHandler implements ApiHandler, SingleCompletionHandler { } } } else { + let systemMessage: OpenAI.Chat.ChatCompletionUserMessageParam | OpenAI.Chat.ChatCompletionSystemMessageParam + // o1 for instance doesnt support streaming, non-1 temp, or system prompt - const systemMessage: OpenAI.Chat.ChatCompletionUserMessageParam = { - role: "user", - content: systemPrompt, - } + // deepseek reasoner supports system prompt + systemMessage = deepseekReasoner + ? { + role: "system", + content: systemPrompt, + } + : { + role: "user", + content: systemPrompt, + } + const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { model: modelId, messages: [systemMessage, ...convertToOpenAiMessages(messages)], @@ -106,7 +117,6 @@ export class OpenAiHandler implements ApiHandler, SingleCompletionHandler { const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { model: this.getModel().id, messages: [{ role: "user", content: prompt }], - temperature: 0, } const response = await this.client.chat.completions.create(requestOptions) diff --git a/src/shared/api.ts b/src/shared/api.ts index 0ef7707..8f65c67 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -51,7 +51,6 @@ export interface ApiHandlerOptions { setAzureApiVersion?: boolean deepSeekBaseUrl?: string deepSeekApiKey?: string - deepSeekModelId?: string includeMaxTokens?: boolean }