Skip to content

Commit 6290f90

Browse files
committed
Refactor
1 parent 25987dd commit 6290f90

File tree

4 files changed

+38
-97
lines changed

4 files changed

+38
-97
lines changed

src/api/providers/__tests__/deepseek.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,13 @@ describe('DeepSeekHandler', () => {
137137
expect(mockCreate).toHaveBeenCalledWith(expect.objectContaining({
138138
messages: [
139139
{ role: 'system', content: systemPrompt },
140-
{ role: 'user', content: 'part 1part 2' }
140+
{
141+
role: 'user',
142+
content: [
143+
{ type: 'text', text: 'part 1' },
144+
{ type: 'text', text: 'part 2' }
145+
]
146+
}
141147
]
142148
}))
143149
})

src/api/providers/deepseek.ts

Lines changed: 25 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,26 @@
1-
import { Anthropic } from "@anthropic-ai/sdk"
2-
import OpenAI from "openai"
3-
import { ApiHandlerOptions, ModelInfo, deepSeekModels, deepSeekDefaultModelId } from "../../shared/api"
4-
import { ApiHandler } from "../index"
5-
import { ApiStream } from "../transform/stream"
6-
7-
export class DeepSeekHandler implements ApiHandler {
8-
private options: ApiHandlerOptions
9-
private client: OpenAI
10-
11-
constructor(options: ApiHandlerOptions) {
12-
this.options = options
13-
if (!options.deepSeekApiKey) {
14-
throw new Error("DeepSeek API key is required. Please provide it in the settings.")
15-
}
16-
this.client = new OpenAI({
17-
baseURL: this.options.deepSeekBaseUrl ?? "https://api.deepseek.com/v1",
18-
apiKey: this.options.deepSeekApiKey,
19-
})
20-
}
21-
22-
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
23-
const modelInfo = deepSeekModels[this.options.deepSeekModelId as keyof typeof deepSeekModels] || deepSeekModels[deepSeekDefaultModelId]
24-
25-
// Format all messages
26-
const messagesToInclude: OpenAI.Chat.ChatCompletionMessageParam[] = [
27-
{ role: 'system' as const, content: systemPrompt }
28-
]
29-
30-
// Add the rest of the messages
31-
for (const msg of messages) {
32-
let messageContent = ""
33-
if (typeof msg.content === "string") {
34-
messageContent = msg.content
35-
} else if (Array.isArray(msg.content)) {
36-
messageContent = msg.content.reduce((acc, part) => {
37-
if (part.type === "text") {
38-
return acc + part.text
39-
}
40-
return acc
41-
}, "")
42-
}
43-
44-
messagesToInclude.push({
45-
role: msg.role === 'user' ? 'user' as const : 'assistant' as const,
46-
content: messageContent
47-
})
48-
}
49-
50-
const requestOptions: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {
51-
model: this.options.deepSeekModelId ?? "deepseek-chat",
52-
messages: messagesToInclude,
53-
temperature: 0,
54-
stream: true,
55-
max_tokens: modelInfo.maxTokens,
56-
}
57-
58-
if (this.options.includeStreamOptions ?? true) {
59-
requestOptions.stream_options = { include_usage: true }
60-
}
61-
62-
let totalInputTokens = 0;
63-
let totalOutputTokens = 0;
64-
65-
try {
66-
const stream = await this.client.chat.completions.create(requestOptions)
67-
for await (const chunk of stream) {
68-
const delta = chunk.choices[0]?.delta
69-
if (delta?.content) {
70-
yield {
71-
type: "text",
72-
text: delta.content,
73-
}
74-
}
75-
if (chunk.usage) {
76-
yield {
77-
type: "usage",
78-
inputTokens: chunk.usage.prompt_tokens || 0,
79-
outputTokens: chunk.usage.completion_tokens || 0,
80-
}
81-
}
82-
}
83-
} catch (error) {
84-
console.error("DeepSeek API Error:", error)
85-
throw error
86-
}
87-
}
88-
89-
getModel(): { id: string; info: ModelInfo } {
90-
const modelId = this.options.deepSeekModelId ?? deepSeekDefaultModelId
91-
return {
92-
id: modelId,
93-
info: deepSeekModels[modelId as keyof typeof deepSeekModels] || deepSeekModels[deepSeekDefaultModelId],
94-
}
95-
}
1+
import { OpenAiHandler } from "./openai"
2+
import { ApiHandlerOptions, ModelInfo } from "../../shared/api"
3+
import { deepSeekModels, deepSeekDefaultModelId } from "../../shared/api"
4+
5+
export class DeepSeekHandler extends OpenAiHandler {
6+
constructor(options: ApiHandlerOptions) {
7+
if (!options.deepSeekApiKey) {
8+
throw new Error("DeepSeek API key is required. Please provide it in the settings.")
9+
}
10+
super({
11+
...options,
12+
openAiApiKey: options.deepSeekApiKey,
13+
openAiModelId: options.deepSeekModelId ?? deepSeekDefaultModelId,
14+
openAiBaseUrl: options.deepSeekBaseUrl ?? "https://api.deepseek.com/v1",
15+
includeMaxTokens: true
16+
})
17+
}
18+
19+
override getModel(): { id: string; info: ModelInfo } {
20+
const modelId = this.options.deepSeekModelId ?? deepSeekDefaultModelId
21+
return {
22+
id: modelId,
23+
info: deepSeekModels[modelId as keyof typeof deepSeekModels] || deepSeekModels[deepSeekDefaultModelId]
24+
}
25+
}
9626
}

src/api/providers/openai.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { convertToOpenAiMessages } from "../transform/openai-format"
1111
import { ApiStream } from "../transform/stream"
1212

1313
export class OpenAiHandler implements ApiHandler {
14-
private options: ApiHandlerOptions
14+
protected options: ApiHandlerOptions
1515
private client: OpenAI
1616

1717
constructor(options: ApiHandlerOptions) {
@@ -38,12 +38,16 @@ export class OpenAiHandler implements ApiHandler {
3838
{ role: "system", content: systemPrompt },
3939
...convertToOpenAiMessages(messages),
4040
]
41+
const modelInfo = this.getModel().info
4142
const requestOptions: OpenAI.Chat.ChatCompletionCreateParams = {
4243
model: this.options.openAiModelId ?? "",
4344
messages: openAiMessages,
4445
temperature: 0,
4546
stream: true,
4647
}
48+
if (this.options.includeMaxTokens) {
49+
requestOptions.max_tokens = modelInfo.maxTokens
50+
}
4751

4852
if (this.options.includeStreamOptions ?? true) {
4953
requestOptions.stream_options = { include_usage: true }

src/shared/api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export interface ApiHandlerOptions {
4242
deepSeekBaseUrl?: string
4343
deepSeekApiKey?: string
4444
deepSeekModelId?: string
45+
includeMaxTokens?: boolean
4546
}
4647

4748
export type ApiConfiguration = ApiHandlerOptions & {

0 commit comments

Comments
 (0)