feat(ark): add Code Plan mode preset and guided setup (#617)

This commit is contained in:
Lingxuan Zuo
2026-03-22 16:26:12 +08:00
committed by GitHub
Unverified
parent f16e8062e1
commit d39982bad8
12 changed files with 299 additions and 10 deletions

View File

@@ -727,6 +727,7 @@ function ProviderContent({
const providerMenuRef = useRef<HTMLDivElement | null>(null);
const [authMode, setAuthMode] = useState<'oauth' | 'apikey'>('oauth');
const [arkMode, setArkMode] = useState<'apikey' | 'codeplan'>('apikey');
// OAuth Flow State
const [oauthFlowing, setOauthFlowing] = useState(false);
@@ -939,9 +940,22 @@ function ProviderContent({
onApiKeyChange(storedKey || '');
const info = providers.find((p) => p.id === selectedProvider);
setBaseUrl(savedProvider?.baseUrl || info?.defaultBaseUrl || '');
setModelId(savedProvider?.model || info?.defaultModelId || '');
const nextBaseUrl = savedProvider?.baseUrl || info?.defaultBaseUrl || '';
const nextModelId = savedProvider?.model || info?.defaultModelId || '';
setBaseUrl(nextBaseUrl);
setModelId(nextModelId);
setApiProtocol(savedProvider?.apiProtocol || 'openai-completions');
if (
selectedProvider === 'ark'
&& info?.codePlanPresetBaseUrl
&& info?.codePlanPresetModelId
&& nextBaseUrl.trim() === info.codePlanPresetBaseUrl
&& nextModelId.trim() === info.codePlanPresetModelId
) {
setArkMode('codeplan');
} else {
setArkMode('apikey');
}
}
} catch (error) {
if (!cancelled) {
@@ -977,11 +991,20 @@ function ProviderContent({
const selectedProviderData = providers.find((p) => p.id === selectedProvider);
const providerDocsUrl = getProviderDocsUrl(selectedProviderData, i18n.language);
const effectiveProviderDocsUrl = selectedProvider === 'ark' && arkMode === 'codeplan'
? (selectedProviderData?.codePlanDocsUrl || providerDocsUrl)
: providerDocsUrl;
const selectedProviderIconUrl = selectedProviderData
? getProviderIconUrl(selectedProviderData.id)
: undefined;
const showBaseUrlField = selectedProviderData?.showBaseUrl ?? false;
const showModelIdField = shouldShowProviderModelId(selectedProviderData, devModeUnlocked);
const codePlanPreset = selectedProviderData?.codePlanPresetBaseUrl && selectedProviderData?.codePlanPresetModelId
? {
baseUrl: selectedProviderData.codePlanPresetBaseUrl,
modelId: selectedProviderData.codePlanPresetModelId,
}
: null;
const requiresKey = selectedProviderData?.requiresApiKey ?? false;
const isOAuth = selectedProviderData?.isOAuth ?? false;
const supportsApiKey = selectedProviderData?.supportsApiKey ?? false;
@@ -1135,6 +1158,7 @@ function ProviderContent({
setKeyValid(null);
setProviderMenuOpen(false);
setAuthMode('oauth');
setArkMode('apikey');
};
return (
@@ -1143,9 +1167,9 @@ function ProviderContent({
<div className="space-y-2">
<div className="flex items-center justify-between gap-3">
<Label>{t('provider.label')}</Label>
{selectedProvider && providerDocsUrl && (
{selectedProvider && effectiveProviderDocsUrl && (
<a
href={providerDocsUrl}
href={effectiveProviderDocsUrl}
target="_blank"
rel="noopener noreferrer"
className="text-[13px] text-blue-500 hover:text-blue-600 font-medium inline-flex items-center gap-1"
@@ -1241,6 +1265,68 @@ function ProviderContent({
animate={{ opacity: 1, y: 0 }}
className="space-y-4"
>
{codePlanPreset && (
<div className="space-y-2">
<div className="flex items-center justify-between gap-3">
<Label>{t('provider.codePlanPreset')}</Label>
{selectedProviderData?.codePlanDocsUrl && (
<a
href={selectedProviderData.codePlanDocsUrl}
target="_blank"
rel="noopener noreferrer"
className="text-[13px] text-blue-500 hover:text-blue-600 font-medium inline-flex items-center gap-1"
>
{t('provider.codePlanDoc')}
<ExternalLink className="h-3 w-3" />
</a>
)}
</div>
<div className="flex gap-2 text-sm">
<button
type="button"
onClick={() => {
setArkMode('apikey');
setBaseUrl(selectedProviderData?.defaultBaseUrl || '');
if (modelId.trim() === codePlanPreset.modelId) {
setModelId(selectedProviderData?.defaultModelId || '');
}
onConfiguredChange(false);
}}
className={cn(
'flex-1 py-2 px-3 rounded-lg border transition-colors',
arkMode === 'apikey'
? 'bg-primary/10 border-primary/30 font-medium'
: 'border-border bg-muted/40 text-muted-foreground hover:bg-muted'
)}
>
{t('settings:aiProviders.authModes.apiKey')}
</button>
<button
type="button"
onClick={() => {
setArkMode('codeplan');
setBaseUrl(codePlanPreset.baseUrl);
setModelId(codePlanPreset.modelId);
onConfiguredChange(false);
}}
className={cn(
'flex-1 py-2 px-3 rounded-lg border transition-colors',
arkMode === 'codeplan'
? 'bg-primary/10 border-primary/30 font-medium'
: 'border-border bg-muted/40 text-muted-foreground hover:bg-muted'
)}
>
{t('provider.codePlanMode')}
</button>
</div>
{arkMode === 'codeplan' && (
<p className="text-xs text-muted-foreground">
{t('provider.codePlanPresetDesc')}
</p>
)}
</div>
)}
{/* Base URL field (for siliconflow, ollama, custom) */}
{showBaseUrlField && (
<div className="space-y-2">