Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
4848b2f0
Unverified
提交
4848b2f0
authored
4月 26, 2025
作者:
Will Chen
提交者:
GitHub
4月 26, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add toggle for disabling Dyad Pro (#24)
* Add toggle for disabling Dyad Pro * Entering key for Dyad pro enables dyad pro
上级
2ad10ba0
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
118 行增加
和
57 行删除
+118
-57
TitleBar.tsx
src/app/TitleBar.tsx
+7
-3
ProviderSettingsPage.tsx
src/components/settings/ProviderSettingsPage.tsx
+109
-53
get_model_client.ts
src/ipc/utils/get_model_client.ts
+1
-1
schemas.ts
src/lib/schemas.ts
+1
-0
没有找到文件。
src/app/TitleBar.tsx
浏览文件 @
4848b2f0
...
@@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button";
...
@@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button";
// @ts-ignore
// @ts-ignore
import
logo
from
"../../assets/logo_transparent.png"
;
import
logo
from
"../../assets/logo_transparent.png"
;
import
{
providerSettingsRoute
}
from
"@/routes/settings/providers/$provider"
;
import
{
providerSettingsRoute
}
from
"@/routes/settings/providers/$provider"
;
import
{
cn
}
from
"@/lib/utils"
;
export
const
TitleBar
=
()
=>
{
export
const
TitleBar
=
()
=>
{
const
[
selectedAppId
]
=
useAtom
(
selectedAppIdAtom
);
const
[
selectedAppId
]
=
useAtom
(
selectedAppIdAtom
);
const
{
apps
}
=
useLoadApps
();
const
{
apps
}
=
useLoadApps
();
...
@@ -27,6 +27,7 @@ export const TitleBar = () => {
...
@@ -27,6 +27,7 @@ export const TitleBar = () => {
};
};
const
isDyadPro
=
!!
settings
?.
providerSettings
?.
auto
?.
apiKey
?.
value
;
const
isDyadPro
=
!!
settings
?.
providerSettings
?.
auto
?.
apiKey
?.
value
;
const
isDyadProEnabled
=
settings
?.
enableDyadPro
;
return
(
return
(
<
div
className=
"@container z-11 w-full h-11 bg-(--sidebar) absolute top-0 left-0 app-region-drag flex items-center"
>
<
div
className=
"@container z-11 w-full h-11 bg-(--sidebar) absolute top-0 left-0 app-region-drag flex items-center"
>
...
@@ -51,10 +52,13 @@ export const TitleBar = () => {
...
@@ -51,10 +52,13 @@ export const TitleBar = () => {
});
});
}
}
}
}
variant=
"outline"
variant=
"outline"
className=
"ml-4 no-app-region-drag h-7 bg-indigo-600 text-white dark:bg-indigo-600 dark:text-white"
className=
{
cn
(
"ml-4 no-app-region-drag h-7 bg-indigo-600 text-white dark:bg-indigo-600 dark:text-white"
,
!
isDyadProEnabled
&&
"bg-zinc-600 dark:bg-zinc-600"
)
}
size=
"sm"
size=
"sm"
>
>
Dyad Pro
{
isDyadProEnabled
?
"Dyad Pro"
:
"Dyad Pro (disabled)"
}
</
Button
>
</
Button
>
)
}
)
}
</
div
>
</
div
>
...
...
src/components/settings/ProviderSettingsPage.tsx
浏览文件 @
4848b2f0
...
@@ -23,6 +23,9 @@ import {
...
@@ -23,6 +23,9 @@ import {
import
{
Input
}
from
"@/components/ui/input"
;
import
{
Input
}
from
"@/components/ui/input"
;
import
{
Button
}
from
"@/components/ui/button"
;
import
{
Button
}
from
"@/components/ui/button"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
import
{
Switch
}
from
"@/components/ui/switch"
;
import
{
showError
}
from
"@/lib/toast"
;
import
{
UserSettings
}
from
"@/lib/schemas"
;
interface
ProviderSettingsPageProps
{
interface
ProviderSettingsPageProps
{
provider
:
string
;
provider
:
string
;
...
@@ -44,6 +47,8 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
...
@@ -44,6 +47,8 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
updateSettings
,
updateSettings
,
}
=
useSettings
();
}
=
useSettings
();
const
isDyad
=
provider
===
"auto"
;
const
[
apiKeyInput
,
setApiKeyInput
]
=
useState
(
""
);
const
[
apiKeyInput
,
setApiKeyInput
]
=
useState
(
""
);
const
[
isSaving
,
setIsSaving
]
=
useState
(
false
);
const
[
isSaving
,
setIsSaving
]
=
useState
(
false
);
const
[
saveError
,
setSaveError
]
=
useState
<
string
|
null
>
(
null
);
const
[
saveError
,
setSaveError
]
=
useState
<
string
|
null
>
(
null
);
...
@@ -95,7 +100,7 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
...
@@ -95,7 +100,7 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
setIsSaving
(
true
);
setIsSaving
(
true
);
setSaveError
(
null
);
setSaveError
(
null
);
try
{
try
{
await
updateSettings
(
{
const
settingsUpdate
:
Partial
<
UserSettings
>
=
{
providerSettings
:
{
providerSettings
:
{
...
settings
?.
providerSettings
,
...
settings
?.
providerSettings
,
[
provider
]:
{
[
provider
]:
{
...
@@ -105,7 +110,11 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
...
@@ -105,7 +110,11 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
},
},
},
},
},
},
});
};
if
(
isDyad
)
{
settingsUpdate
.
enableDyadPro
=
true
;
}
await
updateSettings
(
settingsUpdate
);
setApiKeyInput
(
""
);
// Clear input on success
setApiKeyInput
(
""
);
// Clear input on success
// Optionally show a success message
// Optionally show a success message
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
...
@@ -139,6 +148,20 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
...
@@ -139,6 +148,20 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
}
}
};
};
// --- Toggle Dyad Pro Handler ---
const
handleToggleDyadPro
=
async
(
enabled
:
boolean
)
=>
{
setIsSaving
(
true
);
try
{
await
updateSettings
({
enableDyadPro
:
enabled
,
});
}
catch
(
error
:
any
)
{
showError
(
`Error toggling Dyad Pro:
${
error
}
`
);
}
finally
{
setIsSaving
(
false
);
}
};
// Effect to clear input error when input changes
// Effect to clear input error when input changes
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
saveError
)
{
if
(
saveError
)
{
...
@@ -205,7 +228,7 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
...
@@ -205,7 +228,7 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
)
:
(
)
:
(
<
KeyRound
className=
"mr-2 h-4 w-4"
/>
<
KeyRound
className=
"mr-2 h-4 w-4"
/>
)
}
)
}
{
isConfigured
?
"Manage API Keys"
:
"Setup API Key"
}
{
getKeyButtonText
({
isConfigured
,
isDyad
})
}
<
ExternalLink
className=
"ml-2 h-4 w-4"
/>
<
ExternalLink
className=
"ml-2 h-4 w-4"
/>
</
Button
>
</
Button
>
)
}
)
}
...
@@ -299,60 +322,93 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
...
@@ -299,60 +322,93 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
</
AccordionContent
>
</
AccordionContent
>
</
AccordionItem
>
</
AccordionItem
>
<
AccordionItem
{
!
isDyad
&&
(
value=
"env-key"
<
AccordionItem
className=
"border rounded-lg px-4 bg-(--background-lightest)"
value=
"env-key"
>
className=
"border rounded-lg px-4 bg-(--background-lightest)"
<
AccordionTrigger
className=
"text-lg font-medium hover:no-underline cursor-pointer"
>
>
API Key from Environment Variable
<
AccordionTrigger
className=
"text-lg font-medium hover:no-underline cursor-pointer"
>
</
AccordionTrigger
>
API Key from Environment Variable
<
AccordionContent
className=
"pt-4"
>
</
AccordionTrigger
>
{
hasEnvKey
?
(
<
AccordionContent
className=
"pt-4"
>
<
Alert
variant=
"default"
>
{
hasEnvKey
?
(
<
KeyRound
className=
"h-4 w-4"
/>
<
Alert
variant=
"default"
>
<
AlertTitle
>
<
KeyRound
className=
"h-4 w-4"
/>
Environment Variable Key (
{
envVarName
}
)
<
AlertTitle
>
</
AlertTitle
>
Environment Variable Key (
{
envVarName
}
)
<
AlertDescription
>
</
AlertTitle
>
<
p
className=
"font-mono text-sm"
>
<
AlertDescription
>
{
maskEnvApiKey
(
envApiKey
)
}
<
p
className=
"font-mono text-sm"
>
</
p
>
{
maskEnvApiKey
(
envApiKey
)
}
{
activeKeySource
===
"env"
&&
(
<
p
className=
"text-xs text-green-600 dark:text-green-400 mt-1"
>
This key is currently active (no settings key set).
</
p
>
</
p
>
)
}
{
activeKeySource
===
"env"
&&
(
{
activeKeySource
===
"settings"
&&
(
<
p
className=
"text-xs text-green-600 dark:text-green-400 mt-1"
>
<
p
className=
"text-xs text-yellow-600 dark:text-yellow-400 mt-1"
>
This key is currently active (no settings key set).
This key is currently being overridden by the key set
</
p
>
in Settings.
)
}
</
p
>
{
activeKeySource
===
"settings"
&&
(
)
}
<
p
className=
"text-xs text-yellow-600 dark:text-yellow-400 mt-1"
>
</
AlertDescription
>
This key is currently being overridden by the key
</
Alert
>
set in Settings.
)
:
(
</
p
>
<
Alert
variant=
"default"
>
)
}
<
Info
className=
"h-4 w-4"
/>
</
AlertDescription
>
<
AlertTitle
>
Environment Variable Not Set
</
AlertTitle
>
</
Alert
>
<
AlertDescription
>
)
:
(
The
{
" "
}
<
Alert
variant=
"default"
>
<
code
className=
"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs"
>
<
Info
className=
"h-4 w-4"
/>
{
envVarName
}
<
AlertTitle
>
Environment Variable Not Set
</
AlertTitle
>
</
code
>
{
" "
}
<
AlertDescription
>
environment variable is not set.
The
{
" "
}
</
AlertDescription
>
<
code
className=
"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs"
>
</
Alert
>
{
envVarName
}
)
}
</
code
>
{
" "
}
<
p
className=
"text-xs text-gray-500 dark:text-gray-400 mt-3"
>
environment variable is not set.
This key is set outside the application. If present, it will
</
AlertDescription
>
be used only if no key is configured in the Settings section
</
Alert
>
above. Requires app restart to detect changes.
)
}
</
p
>
<
p
className=
"text-xs text-gray-500 dark:text-gray-400 mt-3"
>
</
AccordionContent
>
This key is set outside the application. If present, it will
</
AccordionItem
>
be used only if no key is configured in the Settings section
above. Requires app restart to detect changes.
</
p
>
</
AccordionContent
>
</
AccordionItem
>
)
}
</
Accordion
>
</
Accordion
>
)
}
)
}
{
isDyad
&&
!
settingsLoading
&&
(
<
div
className=
"mt-6 flex items-center justify-between p-4 bg-(--background-lightest) rounded-lg border"
>
<
div
>
<
h3
className=
"font-medium"
>
Enable Dyad Pro
</
h3
>
<
p
className=
"text-sm text-gray-600 dark:text-gray-400"
>
Toggle to enable Dyad Pro
</
p
>
</
div
>
<
Switch
checked=
{
settings
?.
enableDyadPro
}
onCheckedChange=
{
handleToggleDyadPro
}
disabled=
{
isSaving
}
/>
</
div
>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
);
);
}
}
function
getKeyButtonText
({
isConfigured
,
isDyad
,
}:
{
isConfigured
:
boolean
;
isDyad
:
boolean
;
})
{
if
(
isDyad
)
{
return
isConfigured
?
"Manage Dyad Pro Subscription"
:
"Setup Dyad Pro Subscription"
;
}
return
isConfigured
?
"Manage API Keys"
:
"Setup API Key"
;
}
src/ipc/utils/get_model_client.ts
浏览文件 @
4848b2f0
...
@@ -46,7 +46,7 @@ export function getModelClient(
...
@@ -46,7 +46,7 @@ export function getModelClient(
}
}
const
dyadApiKey
=
settings
.
providerSettings
?.
auto
?.
apiKey
?.
value
;
const
dyadApiKey
=
settings
.
providerSettings
?.
auto
?.
apiKey
?.
value
;
if
(
dyadApiKey
)
{
if
(
dyadApiKey
&&
settings
.
enableDyadPro
)
{
const
provider
=
createOpenAI
({
const
provider
=
createOpenAI
({
apiKey
:
dyadApiKey
,
apiKey
:
dyadApiKey
,
baseURL
:
"https://llm-gateway.dyad.sh/v1"
,
baseURL
:
"https://llm-gateway.dyad.sh/v1"
,
...
...
src/lib/schemas.ts
浏览文件 @
4848b2f0
...
@@ -107,6 +107,7 @@ export const UserSettingsSchema = z.object({
...
@@ -107,6 +107,7 @@ export const UserSettingsSchema = z.object({
telemetryConsent
:
z
.
enum
([
"opted_in"
,
"opted_out"
,
"unset"
]).
optional
(),
telemetryConsent
:
z
.
enum
([
"opted_in"
,
"opted_out"
,
"unset"
]).
optional
(),
telemetryUserId
:
z
.
string
().
optional
(),
telemetryUserId
:
z
.
string
().
optional
(),
hasRunBefore
:
z
.
boolean
().
optional
(),
hasRunBefore
:
z
.
boolean
().
optional
(),
enableDyadPro
:
z
.
boolean
().
optional
(),
experiments
:
ExperimentsSchema
.
optional
(),
experiments
:
ExperimentsSchema
.
optional
(),
// DEPRECATED.
// DEPRECATED.
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论