Skip to content

Commit ceb3a1a

Browse files
authored
feat(ai): allow setting temperature and top_p for agents (The-Commit-Company#1703)
1 parent 55f6826 commit ceb3a1a

File tree

4 files changed

+134
-66
lines changed

4 files changed

+134
-66
lines changed

frontend/src/components/feature/settings/ai/bots/AIFeaturesBotForm.tsx

Lines changed: 96 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Label, ErrorText, HelperText } from '@/components/common/Form'
22
import { Stack, HStack } from '@/components/layout/Stack'
33
import { RavenBot } from '@/types/RavenBot/RavenBot'
4-
import { Box, TextField, Checkbox, Text, Separator, Tooltip, Heading, Select } from '@radix-ui/themes'
4+
import { Box, TextField, Checkbox, Text, Separator, Tooltip, Heading, Select, Slider, Code } from '@radix-ui/themes'
55
import { useFrappeGetCall } from 'frappe-react-sdk'
66
import { useFormContext, Controller } from 'react-hook-form'
77
import { BiInfoCircle } from 'react-icons/bi'
@@ -13,6 +13,9 @@ const AIFeaturesBotForm = (props: Props) => {
1313

1414
const openAIAssistantID = watch('openai_assistant_id')
1515

16+
const temperature = watch('temperature')
17+
const top_p = watch('top_p')
18+
1619
return (
1720
<Stack gap='4'>
1821
<Stack maxWidth={'480px'}>
@@ -54,69 +57,70 @@ const AIFeaturesBotForm = (props: Props) => {
5457
</HelperText>
5558
</Stack>
5659
<Separator className='w-full' />
57-
<Stack maxWidth={'560px'}>
58-
<Text as="label" size="2">
59-
<HStack align='center'>
60-
<Controller
61-
control={control}
62-
name='enable_file_search'
63-
render={({ field }) => (
64-
<Checkbox
65-
checked={field.value ? true : false}
66-
onCheckedChange={(v) => field.onChange(v ? 1 : 0)}
67-
/>
68-
)} />
69-
<span>Enable File Search</span>
70-
<Tooltip content='View OpenAI documentation about File Search'>
71-
<a href='https://platform.openai.com/docs/assistants/tools/file-search'
72-
title='View OpenAI documentation about File Search'
73-
aria-label='View OpenAI documentation about File Search'
74-
target='_blank' className='text-gray-11 -mb-1'>
75-
<BiInfoCircle size={16} /></a>
76-
</Tooltip>
60+
<HStack gap='8'>
61+
<Stack>
62+
<Text as="label" size="2">
63+
<HStack align='center'>
64+
<Controller
65+
control={control}
66+
name='enable_file_search'
67+
render={({ field }) => (
68+
<Checkbox
69+
checked={field.value ? true : false}
70+
onCheckedChange={(v) => field.onChange(v ? 1 : 0)}
71+
/>
72+
)} />
73+
<span>Enable File Search</span>
74+
<Tooltip content='View OpenAI documentation about File Search'>
75+
<a href='https://platform.openai.com/docs/assistants/tools/file-search'
76+
title='View OpenAI documentation about File Search'
77+
aria-label='View OpenAI documentation about File Search'
78+
target='_blank' className='text-gray-11 -mb-1'>
79+
<BiInfoCircle size={16} /></a>
80+
</Tooltip>
7781

78-
</HStack>
79-
</Text>
80-
<HelperText>
81-
Enable this if you want the bot to be able to read PDF files and scan them.
82-
<br /><br />
83-
File search enables the assistant with knowledge from files that you upload.
84-
<br /><br />
85-
Once a file is uploaded, the assistant automatically decides when to retrieve content based on user requests.
86-
</HelperText>
87-
</Stack>
88-
<Separator className='w-full' />
89-
<Stack maxWidth={'560px'}>
90-
<Text as="label" size="2">
91-
<HStack align='center'>
92-
<Controller
93-
control={control}
94-
name='enable_code_interpreter'
95-
render={({ field }) => (
96-
<Checkbox
97-
checked={field.value ? true : false}
98-
onCheckedChange={(v) => field.onChange(v ? 1 : 0)}
99-
/>
100-
)} />
101-
<span>Enable Code Interpreter</span>
102-
<Tooltip content='View OpenAI documentation about Code Interpreter'>
103-
<a href='https://platform.openai.com/docs/assistants/tools/code-interpreter'
104-
title='View OpenAI documentation about Code Interpreter'
105-
aria-label='View OpenAI documentation about Code Interpreter'
106-
target='_blank' className='text-gray-11 -mb-1'>
107-
<BiInfoCircle size={16} /></a>
108-
</Tooltip>
82+
</HStack>
83+
</Text>
84+
<HelperText>
85+
Enable this if you want the bot to be able to read PDF files and scan them.
86+
<br /><br />
87+
File search enables the assistant with knowledge from files that you upload.
88+
<br />
89+
Once a file is uploaded, the assistant automatically decides when to retrieve content based on user requests.
90+
</HelperText>
91+
</Stack>
92+
<Stack>
93+
<Text as="label" size="2">
94+
<HStack align='center'>
95+
<Controller
96+
control={control}
97+
name='enable_code_interpreter'
98+
render={({ field }) => (
99+
<Checkbox
100+
checked={field.value ? true : false}
101+
onCheckedChange={(v) => field.onChange(v ? 1 : 0)}
102+
/>
103+
)} />
104+
<span>Enable Code Interpreter</span>
105+
<Tooltip content='View OpenAI documentation about Code Interpreter'>
106+
<a href='https://platform.openai.com/docs/assistants/tools/code-interpreter'
107+
title='View OpenAI documentation about Code Interpreter'
108+
aria-label='View OpenAI documentation about Code Interpreter'
109+
target='_blank' className='text-gray-11 -mb-1'>
110+
<BiInfoCircle size={16} /></a>
111+
</Tooltip>
109112

110-
</HStack>
111-
</Text>
112-
<HelperText>
113-
Enable this if you want the bot to be able to process files like Excel sheets or data from Insights.
114-
<br />
115-
OpenAI Assistants run code in a sandboxed environment (on OpenAI servers) to do this.
116-
</HelperText>
117-
</Stack>
113+
</HStack>
114+
</Text>
115+
<HelperText>
116+
Enable this if you want the bot to be able to process files like Excel sheets or data from Insights.
117+
<br /><br />
118+
OpenAI Assistants run code in a sandboxed environment (on OpenAI servers) to do this.
119+
</HelperText>
120+
</Stack>
121+
</HStack>
118122
<Separator className='w-full' />
119-
<Heading as='h5' size='2' className='not-cal' weight='medium'>Advanced</Heading>
123+
<Heading as='h5' size='3' className='not-cal' weight='bold'>Advanced</Heading>
120124
<Stack maxWidth={'560px'}>
121125
<Text as="label" size="2">
122126
<HStack align='center'>
@@ -139,6 +143,36 @@ const AIFeaturesBotForm = (props: Props) => {
139143
</HelperText>
140144
</Stack>
141145

146+
<HStack gap='8' align='start'>
147+
<Stack maxWidth={'560px'}>
148+
<HStack justify='between' align='center'>
149+
<Label htmlFor='temperature'>Temperature <Text as='span' color='gray' weight='regular'>(Default: 1)</Text></Label>
150+
<Code color='gray' size='2' variant='ghost' weight='regular'>{(temperature ?? 1).toFixed(2)}</Code>
151+
</HStack>
152+
<Controller control={control} name='temperature' render={({ field }) => (
153+
<Slider color='gray' variant='soft' value={[field.value ?? 1]} defaultValue={[1]} className='w-full' min={0} max={2} step={0.01} name={field.name} onValueChange={(value) => field.onChange(value[0])} />
154+
)} />
155+
<HelperText>
156+
What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
157+
</HelperText>
158+
</Stack>
159+
160+
<Stack maxWidth={'560px'}>
161+
<HStack justify='between' align='center'>
162+
<Label htmlFor='top_p'>Top P <Text as='span' color='gray' weight='regular'>(Default: 1)</Text></Label>
163+
<Code color='gray' variant='ghost' size='2' weight='regular'>{(top_p ?? 1).toFixed(2)}</Code>
164+
</HStack>
165+
<Controller control={control} name='top_p' render={({ field }) => (
166+
<Slider variant='soft' color='gray' value={[field.value ?? 1]} defaultValue={[1]} className='w-full' min={0} max={1} step={0.01} name={field.name} onValueChange={(value) => field.onChange(value[0])} />
167+
)} />
168+
<HelperText>
169+
An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
170+
<br /><br />
171+
We generally recommend altering this or temperature but not both.
172+
</HelperText>
173+
</Stack>
174+
</HStack>
175+
142176
</Stack>
143177
)
144178
}
@@ -171,7 +205,7 @@ const ModelSelector = () => {
171205
<Select.Content>
172206
{models?.message.map((model: string) => (
173207
<Select.Item key={model} value={model}>{model}</Select.Item>
174-
))}
208+
)) || <Select.Item value='gpt-4o'>gpt-4o</Select.Item>}
175209
</Select.Content>
176210
</Select.Root>
177211
)} />

frontend/src/types/RavenBot/RavenBot.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,18 @@ export interface RavenBot{
2626
module?: string
2727
/** Is AI Bot? : Check */
2828
is_ai_bot?: 0 | 1
29-
/** Debug Mode : Check - If enabled, stack traces of errors will be sent as messages by the bot */
30-
debug_mode?: 0 | 1
3129
/** Model : Data */
3230
model?: string
31+
/** Temperature : Float - What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. */
32+
temperature?: number
33+
/** Debug Mode : Check - If enabled, stack traces of errors will be sent as messages by the bot */
34+
debug_mode?: 0 | 1
3335
/** Reasoning Effort : Select - Only applicable for OpenAI o-series models */
3436
reasoning_effort?: "low" | "medium" | "high"
37+
/** Top P : Float - An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
38+
39+
We generally recommend altering this or temperature but not both. */
40+
top_p?: number
3541
/** OpenAI Assistant ID : Data */
3642
openai_assistant_id?: string
3743
/** Enable Code Interpreter : Check - Enable this if you want the bot to be able to process files like Excel sheets or data from Insights.

raven/raven_bot/doctype/raven_bot/raven_bot.json

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818
"module",
1919
"ai_tab",
2020
"is_ai_bot",
21-
"debug_mode",
2221
"model",
22+
"temperature",
23+
"column_break_ebil",
24+
"debug_mode",
2325
"reasoning_effort",
26+
"top_p",
2427
"ai_section",
2528
"openai_assistant_id",
2629
"enable_code_interpreter",
@@ -188,13 +191,32 @@
188191
"fieldtype": "Data",
189192
"label": "OpenAI Vector Store ID",
190193
"read_only": 1
194+
},
195+
{
196+
"default": "1",
197+
"description": "What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.",
198+
"fieldname": "temperature",
199+
"fieldtype": "Float",
200+
"label": "Temperature",
201+
"non_negative": 1
202+
},
203+
{
204+
"fieldname": "column_break_ebil",
205+
"fieldtype": "Column Break"
206+
},
207+
{
208+
"default": "1",
209+
"description": "An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.\n\nWe generally recommend altering this or temperature but not both.",
210+
"fieldname": "top_p",
211+
"fieldtype": "Float",
212+
"label": "Top P"
191213
}
192214
],
193215
"grid_page_length": 50,
194216
"image_field": "image",
195217
"index_web_pages_for_search": 1,
196218
"links": [],
197-
"modified": "2025-05-10 19:07:45.493080",
219+
"modified": "2025-05-23 10:54:59.313559",
198220
"modified_by": "Administrator",
199221
"module": "Raven Bot",
200222
"name": "Raven Bot",

raven/raven_bot/doctype/raven_bot/raven_bot.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class RavenBot(Document):
4747
openai_vector_store_id: DF.Data | None
4848
raven_user: DF.Link | None
4949
reasoning_effort: DF.Literal["low", "medium", "high"]
50+
temperature: DF.Float
51+
top_p: DF.Float
5052
# end: auto-generated types
5153

5254
def validate(self):
@@ -133,6 +135,8 @@ def create_openai_assistant(self):
133135
tools=self.get_tools_for_assistant(),
134136
tool_resources=self.get_tool_resources_for_assistant(),
135137
reasoning_effort=reasoning_effort if model.startswith("o") else None,
138+
temperature=self.temperature or 1,
139+
top_p=self.top_p or 1,
136140
)
137141
# Update the tools which were activated for the bot
138142
self.db_set("openai_assistant_id", assistant.id)
@@ -176,6 +180,8 @@ def update_openai_assistant(self):
176180
tool_resources=self.get_tool_resources_for_assistant(),
177181
model=model,
178182
reasoning_effort=reasoning_effort if model.startswith("o") else None,
183+
temperature=self.temperature or 1,
184+
top_p=self.top_p or 1,
179185
)
180186
self.check_and_update_enabled_tools(assistant)
181187
except Exception as e:

0 commit comments

Comments
 (0)