Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
2ea9500f
Unverified
提交
2ea9500f
authored
6月 25, 2025
作者:
Will Chen
提交者:
GitHub
6月 25, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Configurable thinking budget (default to medium) (#494)
上级
52aebae9
全部展开
显示空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
241 行增加
和
8 行删除
+241
-8
context_manage.spec.ts_manage-context---smart-context---auto-includes-only-1.txt
...manage-context---smart-context---auto-includes-only-1.txt
+2
-1
context_manage.spec.ts_manage-context---smart-context-1.txt
...ntext_manage.spec.ts_manage-context---smart-context-1.txt
+2
-1
context_manage.spec.ts_manage-context---smart-context-3.txt
...ntext_manage.spec.ts_manage-context---smart-context-3.txt
+2
-1
context_manage.spec.ts_manage-context---smart-context-4.txt
...ntext_manage.spec.ts_manage-context---smart-context-4.txt
+2
-1
engine.spec.ts_regular-auto-should-send-message-to-engine-1.txt
....spec.ts_regular-auto-should-send-message-to-engine-1.txt
+2
-1
engine.spec.ts_send-message-to-engine-1.txt
...sts/snapshots/engine.spec.ts_send-message-to-engine-1.txt
+2
-1
engine.spec.ts_smart-auto-should-send-message-to-engine-1.txt
...ne.spec.ts_smart-auto-should-send-message-to-engine-1.txt
+2
-1
thinking_budget.spec.ts_thinking-budget-1.txt
...s/snapshots/thinking_budget.spec.ts_thinking-budget-1.txt
+26
-0
thinking_budget.spec.ts_thinking-budget-2.txt
...s/snapshots/thinking_budget.spec.ts_thinking-budget-2.txt
+0
-0
thinking_budget.spec.ts_thinking-budget-3.txt
...s/snapshots/thinking_budget.spec.ts_thinking-budget-3.txt
+26
-0
thinking_budget.spec.ts_thinking-budget-4.txt
...s/snapshots/thinking_budget.spec.ts_thinking-budget-4.txt
+0
-0
thinking_budget.spec.ts_thinking-budget-5.txt
...s/snapshots/thinking_budget.spec.ts_thinking-budget-5.txt
+26
-0
thinking_budget.spec.ts_thinking-budget-6.txt
...s/snapshots/thinking_budget.spec.ts_thinking-budget-6.txt
+0
-0
thinking_budget.spec.ts
e2e-tests/thinking_budget.spec.ts
+34
-0
ThinkingBudgetSelector.tsx
src/components/ThinkingBudgetSelector.tsx
+80
-0
chat_stream_handlers.ts
src/ipc/handlers/chat_stream_handlers.ts
+1
-0
get_model_client.ts
src/ipc/utils/get_model_client.ts
+1
-0
llm_engine_provider.ts
src/ipc/utils/llm_engine_provider.ts
+6
-1
thinking_utils.ts
src/ipc/utils/thinking_utils.ts
+21
-0
schemas.ts
src/lib/schemas.ts
+1
-0
settings.tsx
src/pages/settings.tsx
+5
-0
没有找到文件。
e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context---auto-includes-only-1.txt
浏览文件 @
2ea9500f
...
...
@@ -16,7 +16,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-1.txt
浏览文件 @
2ea9500f
...
...
@@ -16,7 +16,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-3.txt
浏览文件 @
2ea9500f
...
...
@@ -24,7 +24,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-4.txt
浏览文件 @
2ea9500f
...
...
@@ -32,7 +32,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/engine.spec.ts_regular-auto-should-send-message-to-engine-1.txt
浏览文件 @
2ea9500f
...
...
@@ -16,7 +16,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/engine.spec.ts_send-message-to-engine-1.txt
浏览文件 @
2ea9500f
...
...
@@ -16,7 +16,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/engine.spec.ts_smart-auto-should-send-message-to-engine-1.txt
浏览文件 @
2ea9500f
...
...
@@ -16,7 +16,8 @@
"stream": true,
"thinking": {
"type": "enabled",
"include_thoughts": true
"include_thoughts": true,
"budget_tokens": 4000
},
"dyad_options": {
"files": [
...
...
e2e-tests/snapshots/thinking_budget.spec.ts_thinking-budget-1.txt
0 → 100644
浏览文件 @
2ea9500f
{
"selectedModel": {
"name": "gemini-2.5-pro",
"provider": "google"
},
"providerSettings": {
"auto": {
"apiKey": {
"value": "testdyadkey",
"encryptionType": "plaintext"
}
}
},
"telemetryConsent": "unset",
"telemetryUserId": "[UUID]",
"hasRunBefore": true,
"enableDyadPro": true,
"experiments": {},
"lastShownReleaseNotesVersion": "[scrubbed]",
"thinkingBudget": "low",
"enableProLazyEditsMode": true,
"enableProSmartFilesContextMode": true,
"selectedChatMode": "build",
"isTestMode": true
}
\ No newline at end of file
e2e-tests/snapshots/thinking_budget.spec.ts_thinking-budget-2.txt
0 → 100644
浏览文件 @
2ea9500f
差异被折叠。
点击展开。
e2e-tests/snapshots/thinking_budget.spec.ts_thinking-budget-3.txt
0 → 100644
浏览文件 @
2ea9500f
{
"selectedModel": {
"name": "gemini-2.5-pro",
"provider": "google"
},
"providerSettings": {
"auto": {
"apiKey": {
"value": "testdyadkey",
"encryptionType": "plaintext"
}
}
},
"telemetryConsent": "unset",
"telemetryUserId": "[UUID]",
"hasRunBefore": true,
"enableDyadPro": true,
"experiments": {},
"lastShownReleaseNotesVersion": "[scrubbed]",
"thinkingBudget": "medium",
"enableProLazyEditsMode": true,
"enableProSmartFilesContextMode": true,
"selectedChatMode": "build",
"isTestMode": true
}
\ No newline at end of file
e2e-tests/snapshots/thinking_budget.spec.ts_thinking-budget-4.txt
0 → 100644
浏览文件 @
2ea9500f
差异被折叠。
点击展开。
e2e-tests/snapshots/thinking_budget.spec.ts_thinking-budget-5.txt
0 → 100644
浏览文件 @
2ea9500f
{
"selectedModel": {
"name": "gemini-2.5-pro",
"provider": "google"
},
"providerSettings": {
"auto": {
"apiKey": {
"value": "testdyadkey",
"encryptionType": "plaintext"
}
}
},
"telemetryConsent": "unset",
"telemetryUserId": "[UUID]",
"hasRunBefore": true,
"enableDyadPro": true,
"experiments": {},
"lastShownReleaseNotesVersion": "[scrubbed]",
"thinkingBudget": "high",
"enableProLazyEditsMode": true,
"enableProSmartFilesContextMode": true,
"selectedChatMode": "build",
"isTestMode": true
}
\ No newline at end of file
e2e-tests/snapshots/thinking_budget.spec.ts_thinking-budget-6.txt
0 → 100644
浏览文件 @
2ea9500f
差异被折叠。
点击展开。
e2e-tests/thinking_budget.spec.ts
0 → 100644
浏览文件 @
2ea9500f
import
{
testSkipIfWindows
}
from
"./helpers/test_helper"
;
testSkipIfWindows
(
"thinking budget"
,
async
({
po
})
=>
{
await
po
.
setUpDyadPro
();
await
po
.
selectModel
({
provider
:
"Google"
,
model
:
"Gemini 2.5 Pro"
});
await
po
.
sendPrompt
(
"tc=1"
);
// Low
await
po
.
goToSettingsTab
();
await
po
.
page
.
getByRole
(
"combobox"
,
{
name
:
"Thinking Budget"
}).
click
();
await
po
.
page
.
getByRole
(
"option"
,
{
name
:
"Low"
}).
click
();
await
po
.
snapshotSettings
();
await
po
.
page
.
getByText
(
"Go Back"
).
click
();
await
po
.
sendPrompt
(
"[dump] hi"
);
await
po
.
snapshotServerDump
(
"request"
);
// Medium
await
po
.
goToSettingsTab
();
await
po
.
page
.
getByRole
(
"combobox"
,
{
name
:
"Thinking Budget"
}).
click
();
await
po
.
page
.
getByRole
(
"option"
,
{
name
:
"Medium (default)"
}).
click
();
await
po
.
snapshotSettings
();
await
po
.
page
.
getByText
(
"Go Back"
).
click
();
await
po
.
sendPrompt
(
"[dump] hi"
);
await
po
.
snapshotServerDump
(
"request"
);
// High
await
po
.
goToSettingsTab
();
await
po
.
page
.
getByRole
(
"combobox"
,
{
name
:
"Thinking Budget"
}).
click
();
await
po
.
page
.
getByRole
(
"option"
,
{
name
:
"High"
}).
click
();
await
po
.
snapshotSettings
();
await
po
.
page
.
getByText
(
"Go Back"
).
click
();
await
po
.
sendPrompt
(
"[dump] hi"
);
await
po
.
snapshotServerDump
(
"request"
);
});
src/components/ThinkingBudgetSelector.tsx
0 → 100644
浏览文件 @
2ea9500f
import
React
from
"react"
;
import
{
useSettings
}
from
"@/hooks/useSettings"
;
import
{
Select
,
SelectContent
,
SelectItem
,
SelectTrigger
,
SelectValue
,
}
from
"@/components/ui/select"
;
interface
OptionInfo
{
value
:
string
;
label
:
string
;
description
:
string
;
}
const
defaultValue
=
"medium"
;
const
options
:
OptionInfo
[]
=
[
{
value
:
"low"
,
label
:
"Low"
,
description
:
"Minimal thinking tokens for faster responses and lower costs."
,
},
{
value
:
defaultValue
,
label
:
"Medium (default)"
,
description
:
"Balanced thinking for most conversations."
,
},
{
value
:
"high"
,
label
:
"High"
,
description
:
"Extended thinking for complex problems requiring deep analysis."
,
},
];
export
const
ThinkingBudgetSelector
:
React
.
FC
=
()
=>
{
const
{
settings
,
updateSettings
}
=
useSettings
();
const
handleValueChange
=
(
value
:
string
)
=>
{
updateSettings
({
thinkingBudget
:
value
as
"low"
|
"medium"
|
"high"
});
};
// Determine the current value
const
currentValue
=
settings
?.
thinkingBudget
||
defaultValue
;
// Find the current option to display its description
const
currentOption
=
options
.
find
((
opt
)
=>
opt
.
value
===
currentValue
)
||
options
[
1
];
return
(
<
div
className=
"space-y-1"
>
<
div
className=
"flex items-center gap-4"
>
<
label
htmlFor=
"thinking-budget"
className=
"text-sm font-medium text-gray-700 dark:text-gray-300"
>
Thinking Budget
</
label
>
<
Select
value=
{
currentValue
}
onValueChange=
{
handleValueChange
}
>
<
SelectTrigger
className=
"w-[180px]"
id=
"thinking-budget"
>
<
SelectValue
placeholder=
"Select budget"
/>
</
SelectTrigger
>
<
SelectContent
>
{
options
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
option
.
label
}
</
SelectItem
>
))
}
</
SelectContent
>
</
Select
>
</
div
>
<
div
className=
"text-sm text-gray-500 dark:text-gray-400"
>
{
currentOption
.
description
}
</
div
>
</
div
>
);
};
src/ipc/handlers/chat_stream_handlers.ts
浏览文件 @
2ea9500f
...
...
@@ -464,6 +464,7 @@ This conversation includes one or more image attachments. When the user uploads
providerOptions
:
{
"dyad-gateway"
:
getExtraProviderOptions
(
modelClient
.
builtinProviderId
,
settings
,
),
google
:
{
thinkingConfig
:
{
...
...
src/ipc/utils/get_model_client.ts
浏览文件 @
2ea9500f
...
...
@@ -84,6 +84,7 @@ export async function getModelClient(
:
settings
.
enableProLazyEditsMode
,
enableSmartFilesContext
:
settings
.
enableProSmartFilesContextMode
,
},
settings
,
})
:
createOpenAICompatible
({
name
:
"dyad-gateway"
,
...
...
src/ipc/utils/llm_engine_provider.ts
浏览文件 @
2ea9500f
...
...
@@ -12,6 +12,7 @@ import {
import
{
OpenAICompatibleChatSettings
}
from
"@ai-sdk/openai-compatible"
;
import
log
from
"electron-log"
;
import
{
getExtraProviderOptions
}
from
"./thinking_utils"
;
import
type
{
UserSettings
}
from
"../../lib/schemas"
;
const
logger
=
log
.
scope
(
"llm_engine_provider"
);
...
...
@@ -48,6 +49,7 @@ or to provide a custom fetch implementation for e.g. testing.
enableLazyEdits
?:
boolean
;
enableSmartFilesContext
?:
boolean
;
};
settings
:
UserSettings
;
}
export
interface
DyadEngineProvider
{
...
...
@@ -125,7 +127,10 @@ export function createDyadEngine(
// Parse the request body to manipulate it
const
parsedBody
=
{
...
JSON
.
parse
(
init
.
body
),
...
getExtraProviderOptions
(
options
.
originalProviderId
),
...
getExtraProviderOptions
(
options
.
originalProviderId
,
options
.
settings
,
),
};
// Add files to the request if they exist
...
...
src/ipc/utils/thinking_utils.ts
浏览文件 @
2ea9500f
import
{
PROVIDERS_THAT_SUPPORT_THINKING
}
from
"../shared/language_model_helpers"
;
import
type
{
UserSettings
}
from
"../../lib/schemas"
;
function
getThinkingBudgetTokens
(
thinkingBudget
?:
"low"
|
"medium"
|
"high"
,
):
number
{
switch
(
thinkingBudget
)
{
case
"low"
:
return
1
_000
;
case
"medium"
:
return
4
_000
;
case
"high"
:
return
-
1
;
default
:
return
4
_000
;
// Default to medium
}
}
export
function
getExtraProviderOptions
(
providerId
:
string
|
undefined
,
settings
:
UserSettings
,
):
Record
<
string
,
any
>
{
if
(
!
providerId
)
{
return
{};
}
if
(
PROVIDERS_THAT_SUPPORT_THINKING
.
includes
(
providerId
))
{
const
budgetTokens
=
getThinkingBudgetTokens
(
settings
?.
thinkingBudget
);
return
{
thinking
:
{
type
:
"enabled"
,
include_thoughts
:
true
,
// -1 means dynamic thinking where model determines.
// budget_tokens: 128, // minimum for Gemini Pro is 128
budget_tokens
:
budgetTokens
,
},
};
}
...
...
src/lib/schemas.ts
浏览文件 @
2ea9500f
...
...
@@ -142,6 +142,7 @@ export const UserSettingsSchema = z.object({
experiments
:
ExperimentsSchema
.
optional
(),
lastShownReleaseNotesVersion
:
z
.
string
().
optional
(),
maxChatTurnsInContext
:
z
.
number
().
optional
(),
thinkingBudget
:
z
.
enum
([
"low"
,
"medium"
,
"high"
]).
optional
(),
enableProLazyEditsMode
:
z
.
boolean
().
optional
(),
enableProSmartFilesContextMode
:
z
.
boolean
().
optional
(),
selectedTemplateId
:
z
.
string
().
optional
(),
...
...
src/pages/settings.tsx
浏览文件 @
2ea9500f
...
...
@@ -7,6 +7,7 @@ import { showSuccess, showError } from "@/lib/toast";
import
{
AutoApproveSwitch
}
from
"@/components/AutoApproveSwitch"
;
import
{
TelemetrySwitch
}
from
"@/components/TelemetrySwitch"
;
import
{
MaxChatTurnsSelector
}
from
"@/components/MaxChatTurnsSelector"
;
import
{
ThinkingBudgetSelector
}
from
"@/components/ThinkingBudgetSelector"
;
import
{
useSettings
}
from
"@/hooks/useSettings"
;
import
{
useAppVersion
}
from
"@/hooks/useAppVersion"
;
import
{
Button
}
from
"@/components/ui/button"
;
...
...
@@ -138,6 +139,10 @@ export default function SettingsPage() {
</
div
>
</
div
>
<
div
className=
"mt-4"
>
<
ThinkingBudgetSelector
/>
</
div
>
<
div
className=
"mt-4"
>
<
MaxChatTurnsSelector
/>
</
div
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论