Files
new-api/web/default/src/features/system-settings/models/section-registry.tsx
T
CaIon 0f9f094a48 feat(default): reorganize system settings pricing UI
Refine the default system settings structure and model pricing editor so pricing configuration is easier to scan and edit.
2026-05-06 16:29:45 +08:00

158 lines
5.4 KiB
TypeScript
Vendored

import type { ModelSettings } from '../types'
import { createSectionRegistry } from '../utils/section-registry'
import { ClaudeSettingsCard } from './claude-settings-card'
import { GeminiSettingsCard } from './gemini-settings-card'
import { GlobalSettingsCard } from './global-settings-card'
import { GrokSettingsCard } from './grok-settings-card'
import { ChannelAffinitySection } from '../general/channel-affinity'
import { IoNetDeploymentSettingsSection } from '../integrations/ionet-deployment-settings-section'
function formatJsonForEditor(value: string, fallback: string) {
const raw = (value ?? '').toString().trim()
if (!raw) return fallback
try {
return JSON.stringify(JSON.parse(raw), null, 2)
} catch {
return fallback
}
}
const MODELS_SECTIONS = [
{
id: 'global',
titleKey: 'Global Model Configuration',
descriptionKey: 'Configure global model settings',
build: (settings: ModelSettings) => (
<GlobalSettingsCard
defaultValues={{
global: {
pass_through_request_enabled:
settings['global.pass_through_request_enabled'],
thinking_model_blacklist: formatJsonForEditor(
settings['global.thinking_model_blacklist'],
'[]'
),
chat_completions_to_responses_policy: formatJsonForEditor(
settings['global.chat_completions_to_responses_policy'],
'{}'
),
},
general_setting: {
ping_interval_enabled:
settings['general_setting.ping_interval_enabled'],
ping_interval_seconds:
settings['general_setting.ping_interval_seconds'],
},
}}
/>
),
},
{
id: 'gemini',
titleKey: 'Gemini',
descriptionKey: 'Configure Gemini model settings',
build: (settings: ModelSettings) => (
<GeminiSettingsCard
defaultValues={{
gemini: {
safety_settings: settings['gemini.safety_settings'],
version_settings: settings['gemini.version_settings'],
supported_imagine_models:
settings['gemini.supported_imagine_models'],
thinking_adapter_enabled:
settings['gemini.thinking_adapter_enabled'],
thinking_adapter_budget_tokens_percentage:
settings['gemini.thinking_adapter_budget_tokens_percentage'],
function_call_thought_signature_enabled:
settings['gemini.function_call_thought_signature_enabled'],
remove_function_response_id_enabled:
settings['gemini.remove_function_response_id_enabled'],
},
}}
/>
),
},
{
id: 'claude',
titleKey: 'Claude',
descriptionKey: 'Configure Claude model settings',
build: (settings: ModelSettings) => (
<ClaudeSettingsCard
defaultValues={{
claude: {
model_headers_settings: settings['claude.model_headers_settings'],
default_max_tokens: settings['claude.default_max_tokens'],
thinking_adapter_enabled:
settings['claude.thinking_adapter_enabled'],
thinking_adapter_budget_tokens_percentage:
settings['claude.thinking_adapter_budget_tokens_percentage'],
},
}}
/>
),
},
{
id: 'grok',
titleKey: 'Grok',
descriptionKey: 'Configure xAI Grok model settings',
build: (settings: ModelSettings) => (
<GrokSettingsCard
defaultValues={{
'grok.violation_deduction_enabled':
settings['grok.violation_deduction_enabled'] ?? true,
'grok.violation_deduction_amount':
settings['grok.violation_deduction_amount'] ?? 0.05,
}}
/>
),
},
{
id: 'channel-affinity',
titleKey: 'Channel Affinity',
descriptionKey: 'Configure channel affinity (sticky routing) rules',
build: (settings: ModelSettings) => (
<ChannelAffinitySection
defaultValues={{
'channel_affinity_setting.enabled':
settings['channel_affinity_setting.enabled'],
'channel_affinity_setting.switch_on_success':
settings['channel_affinity_setting.switch_on_success'],
'channel_affinity_setting.max_entries':
settings['channel_affinity_setting.max_entries'],
'channel_affinity_setting.default_ttl_seconds':
settings['channel_affinity_setting.default_ttl_seconds'],
'channel_affinity_setting.rules':
settings['channel_affinity_setting.rules'],
}}
/>
),
},
{
id: 'model-deployment',
titleKey: 'Model Deployment',
descriptionKey: 'Configure model deployment provider settings',
build: (settings: ModelSettings) => (
<IoNetDeploymentSettingsSection
defaultValues={{
enabled: settings['model_deployment.ionet.enabled'],
apiKey: settings['model_deployment.ionet.api_key'],
}}
/>
),
},
] as const
export type ModelSectionId = (typeof MODELS_SECTIONS)[number]['id']
const modelsRegistry = createSectionRegistry<ModelSectionId, ModelSettings>({
sections: MODELS_SECTIONS,
defaultSection: 'global',
basePath: '/system-settings/models',
urlStyle: 'path',
})
export const MODELS_SECTION_IDS = modelsRegistry.sectionIds
export const MODELS_DEFAULT_SECTION = modelsRegistry.defaultSection
export const getModelsSectionNavItems = modelsRegistry.getSectionNavItems
export const getModelsSectionContent = modelsRegistry.getSectionContent