Skip to content

Commit 3e66d04

Browse files
committed
feat(openai): add support for OpenAI reasoning API
Signed-off-by: Adrien Kara <[email protected]>
1 parent 9ddda65 commit 3e66d04

File tree

5 files changed

+93
-12
lines changed

5 files changed

+93
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useEffect } from 'react'
2+
import { Select, MenuItem, Typography, Box } from '@mui/material'
3+
import { useTranslation } from 'react-i18next'
4+
5+
export interface Props {
6+
value: string
7+
onChange: (value: string) => void
8+
className?: string
9+
}
10+
11+
export default function ReasoningEffortSelect(props: Props) {
12+
const { t } = useTranslation()
13+
14+
useEffect(() => {
15+
if (!props.value) {
16+
props.onChange('medium')
17+
}
18+
}, [])
19+
20+
const handleChange = (event: any) => {
21+
props.onChange(event.target.value as string)
22+
}
23+
24+
return (
25+
<Box sx={{ margin: '10px' }} className={props.className}>
26+
<Box>
27+
<Typography id="reasoning-effort-select" gutterBottom>
28+
{t('Reasoning Effort')}
29+
</Typography>
30+
</Box>
31+
<Box sx={{ display: 'flex', alignItems: 'center' }}>
32+
<Select
33+
value={props.value || 'medium'}
34+
onChange={handleChange}
35+
fullWidth
36+
size="small"
37+
>
38+
<MenuItem value="low">{t('Low')}</MenuItem>
39+
<MenuItem value="medium">{t('Medium')}</MenuItem>
40+
<MenuItem value="high">{t('High')}</MenuItem>
41+
</Select>
42+
</Box>
43+
</Box>
44+
)
45+
}

src/renderer/packages/models/openai.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ interface Options {
88
apiPath?: string
99
model: Model | 'custom-model'
1010
openaiCustomModel?: string
11+
openaiReasoningEffort: string
1112
temperature: number
1213
topP: number
1314
}
@@ -48,10 +49,25 @@ export default class OpenAI extends Base {
4849

4950
rawMessages = injectModelSystemPrompt(model, rawMessages)
5051

51-
if (model.startsWith('o1')) {
52-
const messages = await populateO1Message(rawMessages)
53-
return this.requestChatCompletionsNotStream({ model, messages }, signal, onResultChange)
52+
// o1-mini and o1-preview does not support reasoning unlike o1 relase
53+
if (model.startsWith('o1-mini') || model.startsWith('o1-preview')) {
54+
const messages = await populateReasoningMessage(rawMessages)
55+
return this.requestChatCompletionsNotStream({
56+
model,
57+
messages,
58+
}, signal, onResultChange)
5459
}
60+
61+
// https://platform.openai.com/docs/guides/reasoning
62+
if (model.startsWith('o')) {
63+
const messages = await populateReasoningMessage(rawMessages)
64+
return this.requestChatCompletionsNotStream({
65+
model,
66+
messages,
67+
reasoning_effort: this.options.openaiReasoningEffort,
68+
}, signal, onResultChange)
69+
}
70+
5571
const messages = await populateGPTMessage(rawMessages)
5672
return this.requestChatCompletionsStream({
5773
messages,
@@ -286,7 +302,7 @@ export async function populateGPTMessage(rawMessages: Message[]): Promise<OpenAI
286302
return messages
287303
}
288304

289-
export async function populateO1Message(rawMessages: Message[]): Promise<OpenAIMessage[]> {
305+
export async function populateReasoningMessage(rawMessages: Message[]): Promise<OpenAIMessage[]> {
290306
const messages: OpenAIMessage[] = rawMessages.map((m) => ({
291307
role: m.role === 'system' ? 'user' : m.role,
292308
content: m.content,

src/renderer/pages/SettingDialog/OpenAISetting.tsx

+26-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Typography, Box } from '@mui/material'
22
import { ModelSettings } from '../../../shared/types'
33
import { useTranslation } from 'react-i18next'
44
import { Accordion, AccordionSummary, AccordionDetails } from '../../components/Accordion'
5+
import ReasoningEffortSelect from '../../components/ReasoningEffortSelect'
56
import TemperatureSlider from '../../components/TemperatureSlider'
67
import TopPSlider from '../../components/TopPSlider'
78
import PasswordTextField from '../../components/PasswordTextField'
@@ -17,6 +18,11 @@ interface ModelConfigProps {
1718
export default function OpenAISetting(props: ModelConfigProps) {
1819
const { settingsEdit, setSettingsEdit } = props
1920
const { t } = useTranslation()
21+
const model = settingsEdit.model;
22+
const isReasoningModel = model?.startsWith('o') &&
23+
!model?.startsWith('o1-preview') &&
24+
!model?.startsWith('o1-mini');
25+
2026
return (
2127
<Box>
2228
<PasswordTextField
@@ -61,14 +67,26 @@ export default function OpenAISetting(props: ModelConfigProps) {
6167
}
6268
/>
6369

64-
<TemperatureSlider
65-
value={settingsEdit.temperature}
66-
onChange={(value) => setSettingsEdit({ ...settingsEdit, temperature: value })}
67-
/>
68-
<TopPSlider
69-
topP={settingsEdit.topP}
70-
setTopP={(v) => setSettingsEdit({ ...settingsEdit, topP: v })}
71-
/>
70+
{isReasoningModel && (
71+
<ReasoningEffortSelect
72+
value={settingsEdit.openaiReasoningEffort}
73+
onChange={(value) => setSettingsEdit({ ...settingsEdit, openaiReasoningEffort: value })}
74+
/>
75+
)}
76+
77+
{!model?.startsWith('o') && (
78+
<>
79+
<TemperatureSlider
80+
value={settingsEdit.temperature}
81+
onChange={(value) => setSettingsEdit({ ...settingsEdit, temperature: value })}
82+
/>
83+
<TopPSlider
84+
topP={settingsEdit.topP}
85+
setTopP={(v) => setSettingsEdit({ ...settingsEdit, topP: v })}
86+
/>
87+
</>
88+
)}
89+
7290
<MaxContextMessageCountSlider
7391
value={settingsEdit.openaiMaxContextMessageCount}
7492
onChange={(v) => setSettingsEdit({ ...settingsEdit, openaiMaxContextMessageCount: v })}

src/shared/defaults.ts

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function settings(): Settings {
5353
siliconCloudModel: 'THUDM/glm-4-9b-chat',
5454

5555
autoGenerateTitle: true,
56+
openaiReasoningEffort: 'medium',
5657
}
5758
}
5859

src/shared/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export interface ModelSettings {
118118
temperature: number
119119
topP: number
120120
openaiMaxContextMessageCount: number
121+
openaiReasoningEffort: string
121122
}
122123

123124
export interface Settings extends ModelSettings {

0 commit comments

Comments
 (0)