Skip to content

Commit 7598753

Browse files
authored
Merge pull request #2238 from seefs001/feature/doubao-coding-plan
feat: support doubao coding plan
1 parent 68777bf commit 7598753

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ tiktoken_cache
1717
.eslintcache
1818
.gocache
1919
.cache
20+
web/bun.lock
2021

2122
electron/node_modules
2223
electron/dist

controller/channel.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/QuantumNous/new-api/constant"
1212
"github.com/QuantumNous/new-api/dto"
1313
"github.com/QuantumNous/new-api/model"
14+
"github.com/QuantumNous/new-api/relay/channel/volcengine"
1415
"github.com/QuantumNous/new-api/service"
1516

1617
"github.com/gin-gonic/gin"
@@ -192,6 +193,12 @@ func FetchUpstreamModels(c *gin.Context) {
192193
url = fmt.Sprintf("%s/compatible-mode/v1/models", baseURL)
193194
case constant.ChannelTypeZhipu_v4:
194195
url = fmt.Sprintf("%s/api/paas/v4/models", baseURL)
196+
case constant.ChannelTypeVolcEngine:
197+
if baseURL == volcengine.DoubaoCodingPlan {
198+
url = fmt.Sprintf("%s/v1/models", volcengine.DoubaoCodingPlanOpenAIBaseURL)
199+
} else {
200+
url = fmt.Sprintf("%s/v1/models", baseURL)
201+
}
195202
default:
196203
url = fmt.Sprintf("%s/v1/models", baseURL)
197204
}

relay/channel/volcengine/adaptor.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ import (
2323
)
2424

2525
const (
26-
contextKeyTTSRequest = "volcengine_tts_request"
27-
contextKeyResponseFormat = "response_format"
26+
contextKeyTTSRequest = "volcengine_tts_request"
27+
contextKeyResponseFormat = "response_format"
28+
DoubaoCodingPlan = "doubao-coding-plan"
29+
DoubaoCodingPlanClaudeBaseURL = "https://ark.cn-beijing.volces.com/api/coding"
30+
DoubaoCodingPlanOpenAIBaseURL = "https://ark.cn-beijing.volces.com/api/coding/v3"
2831
)
2932

3033
type Adaptor struct {
@@ -238,13 +241,19 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
238241

239242
switch info.RelayFormat {
240243
case types.RelayFormatClaude:
244+
if baseUrl == DoubaoCodingPlan {
245+
return fmt.Sprintf("%s/v1/messages", DoubaoCodingPlanClaudeBaseURL), nil
246+
}
241247
if strings.HasPrefix(info.UpstreamModelName, "bot") {
242248
return fmt.Sprintf("%s/api/v3/bots/chat/completions", baseUrl), nil
243249
}
244250
return fmt.Sprintf("%s/api/v3/chat/completions", baseUrl), nil
245251
default:
246252
switch info.RelayMode {
247253
case constant.RelayModeChatCompletions:
254+
if baseUrl == DoubaoCodingPlan {
255+
return fmt.Sprintf("%s/chat/completions", DoubaoCodingPlanOpenAIBaseURL), nil
256+
}
248257
if strings.HasPrefix(info.UpstreamModelName, "bot") {
249258
return fmt.Sprintf("%s/api/v3/bots/chat/completions", baseUrl), nil
250259
}

web/src/components/table/channels/modals/EditChannelModal.jsx

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ const EditChannelModal = (props) => {
189189
const [useManualInput, setUseManualInput] = useState(false); // 是否使用手动输入模式
190190
const [keyMode, setKeyMode] = useState('append'); // 密钥模式:replace(覆盖)或 append(追加)
191191
const [isEnterpriseAccount, setIsEnterpriseAccount] = useState(false); // 是否为企业账户
192+
const [doubaoApiEditUnlocked, setDoubaoApiEditUnlocked] = useState(false); // 豆包渠道自定义 API 地址隐藏入口
192193

193194
// 密钥显示状态
194195
const [keyDisplayState, setKeyDisplayState] = useState({
@@ -218,6 +219,7 @@ const EditChannelModal = (props) => {
218219
'channelExtraSettings',
219220
];
220221
const formContainerRef = useRef(null);
222+
const doubaoApiClickCountRef = useRef(0);
221223

222224
// 2FA状态更新辅助函数
223225
const updateTwoFAState = (updates) => {
@@ -306,6 +308,20 @@ const EditChannelModal = (props) => {
306308
scrollToSection(availableSections[newIndex]);
307309
};
308310

311+
const handleApiConfigSecretClick = () => {
312+
if (inputs.type !== 45) return;
313+
const next = doubaoApiClickCountRef.current + 1;
314+
doubaoApiClickCountRef.current = next;
315+
if (next >= 10) {
316+
setDoubaoApiEditUnlocked((unlocked) => {
317+
if (!unlocked) {
318+
showInfo(t('已解锁豆包自定义 API 地址编辑'));
319+
}
320+
return true;
321+
});
322+
}
323+
};
324+
309325
// 渠道额外设置状态
310326
const [channelSettings, setChannelSettings] = useState({
311327
force_format: false,
@@ -724,6 +740,13 @@ const EditChannelModal = (props) => {
724740
}
725741
};
726742

743+
useEffect(() => {
744+
if (inputs.type !== 45) {
745+
doubaoApiClickCountRef.current = 0;
746+
setDoubaoApiEditUnlocked(false);
747+
}
748+
}, [inputs.type]);
749+
727750
useEffect(() => {
728751
const modelMap = new Map();
729752

@@ -823,6 +846,9 @@ const EditChannelModal = (props) => {
823846
setKeyMode('append');
824847
// 重置企业账户状态
825848
setIsEnterpriseAccount(false);
849+
// 重置豆包隐藏入口状态
850+
setDoubaoApiEditUnlocked(false);
851+
doubaoApiClickCountRef.current = 0;
826852
// 清空表单中的key_mode字段
827853
if (formApiRef.current) {
828854
formApiRef.current.setValue('key_mode', undefined);
@@ -1959,7 +1985,10 @@ const EditChannelModal = (props) => {
19591985
<div ref={(el) => (formSectionRefs.current.apiConfig = el)}>
19601986
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
19611987
{/* Header: API Config */}
1962-
<div className='flex items-center mb-2'>
1988+
<div
1989+
className='flex items-center mb-2'
1990+
onClick={handleApiConfigSecretClick}
1991+
>
19631992
<Avatar
19641993
size='small'
19651994
color='green'
@@ -2094,7 +2123,7 @@ const EditChannelModal = (props) => {
20942123
inputs.type !== 8 &&
20952124
inputs.type !== 22 &&
20962125
inputs.type !== 36 &&
2097-
inputs.type !== 45 && (
2126+
(inputs.type !== 45 || doubaoApiEditUnlocked) && (
20982127
<div>
20992128
<Form.Input
21002129
field='base_url'
@@ -2147,7 +2176,7 @@ const EditChannelModal = (props) => {
21472176
</div>
21482177
)}
21492178

2150-
{inputs.type === 45 && (
2179+
{inputs.type === 45 && !doubaoApiEditUnlocked && (
21512180
<div>
21522181
<Form.Select
21532182
field='base_url'
@@ -2167,6 +2196,10 @@ const EditChannelModal = (props) => {
21672196
label:
21682197
'https://ark.ap-southeast.bytepluses.com',
21692198
},
2199+
{
2200+
value: 'doubao-coding-plan',
2201+
label: 'Doubao Coding Plan',
2202+
},
21702203
]}
21712204
defaultValue='https://ark.cn-beijing.volces.com'
21722205
/>

0 commit comments

Comments
 (0)