Commit 43591fba by CaIon

feat: improve advanced custom route editor

parent 25f99859
......@@ -256,6 +256,7 @@ const ADVANCED_SETTINGS_SECTION_IDS = {
const ADVANCED_SETTINGS_CHILD_SECTION_IDS: string[] = Object.values(
ADVANCED_SETTINGS_SECTION_IDS
)
const ADVANCED_CUSTOM_ROUTE_TYPE_PREVIEW_LIMIT = 3
const UPSTREAM_DETECTED_MODEL_PREVIEW_LIMIT = 8
const SENSITIVE_FORM_FIELDS = [
'type',
......@@ -776,6 +777,18 @@ export function ChannelMutateDrawer({
() => getAdvancedCustomStats(currentAdvancedCustom),
[currentAdvancedCustom]
)
const advancedCustomRouteTypeLabels =
advancedCustomStats.routeTypeLabels.slice(
0,
ADVANCED_CUSTOM_ROUTE_TYPE_PREVIEW_LIMIT
)
const hiddenAdvancedCustomRouteTypeCount =
advancedCustomStats.routeTypeLabels.length -
advancedCustomRouteTypeLabels.length
const advancedCustomRouteTypeTitle =
hiddenAdvancedCustomRouteTypeCount > 0
? advancedCustomStats.routeTypeLabels.join(', ')
: undefined
// Get all models list
const allModelsList = useMemo(
......@@ -2647,6 +2660,30 @@ export function ChannelMutateDrawer({
{t('Routes')}:{' '}
{advancedCustomStats.routeCount}
</Badge>
{advancedCustomRouteTypeLabels.map(
(label) => (
<Badge
key={label}
variant='outline'
className='max-w-[12rem]'
title={label}
>
<span className='truncate'>
{label}
</span>
</Badge>
)
)}
{hiddenAdvancedCustomRouteTypeCount > 0 && (
<Badge
variant='outline'
title={
advancedCustomRouteTypeTitle
}
>
+{hiddenAdvancedCustomRouteTypeCount}
</Badge>
)}
{!advancedCustomStats.valid && (
<Badge variant='destructive'>
{t('Incomplete')}
......
......@@ -78,11 +78,7 @@ export const ADVANCED_CUSTOM_INCOMING_PATH_OPTIONS: AdvancedCustomIncomingPathOp
[
{
value: '/v1/chat/completions',
label: 'OpenAI Chat Completions',
},
{
value: '/v1/completions',
label: 'OpenAI Completions',
label: 'OpenAI Chat',
},
{
value: '/v1/responses',
......@@ -105,6 +101,10 @@ export const ADVANCED_CUSTOM_INCOMING_PATH_OPTIONS: AdvancedCustomIncomingPathOp
label: 'OpenAI Image Edits',
},
{
value: '/v1/completions',
label: 'OpenAI Completions',
},
{
value: '/v1/audio/speech',
label: 'OpenAI Audio Speech',
},
......@@ -142,6 +142,10 @@ export const ADVANCED_CUSTOM_INCOMING_PATH_OPTIONS: AdvancedCustomIncomingPathOp
},
]
const ADVANCED_CUSTOM_ROUTE_SUMMARY_LABELS: Record<string, string> = {
'/v1/chat/completions': 'OpenAI Chat',
}
export type AdvancedCustomValidationError = {
message: string
routeIndex?: number
......@@ -357,8 +361,17 @@ export function isAdvancedCustomIncomingPathAllowed(
incomingPath: string,
converter: AdvancedCustomConverter
): boolean {
return getAdvancedCustomIncomingPathOptions(converter).some(
(option) => option.value === incomingPath
return isConverterPathAllowed(incomingPath, converter)
}
export function getAdvancedCustomConverterOptions(
incomingPath: string
): typeof ADVANCED_CUSTOM_CONVERTER_OPTIONS {
const normalizedIncomingPath = incomingPath.trim()
return ADVANCED_CUSTOM_CONVERTER_OPTIONS.filter(
(option) =>
option.value === 'none' ||
isConverterPathAllowed(normalizedIncomingPath, option.value)
)
}
......@@ -483,15 +496,28 @@ export function advancedCustomConfigUsesRelativeUpstreamPath(
export function getAdvancedCustomStats(value: string | undefined): {
routeCount: number
valid: boolean
routeTypeLabels: string[]
} {
const config = parseAdvancedCustomConfig(value)
if (!config) {
return { routeCount: 0, valid: false }
return { routeCount: 0, valid: false, routeTypeLabels: [] }
}
const normalized = normalizeAdvancedCustomConfig(config)
const routes = normalized.advanced_routes || []
const routeTypeLabels: string[] = []
const seenRouteTypeLabels = new Set<string>()
for (const route of routes) {
const label = getAdvancedCustomRouteSummaryLabel(route)
if (!label || seenRouteTypeLabels.has(label)) continue
routeTypeLabels.push(label)
seenRouteTypeLabels.add(label)
}
return {
routeCount: normalized.advanced_routes?.length || 0,
routeCount: routes.length,
valid: validateAdvancedCustomConfig(normalized) === null,
routeTypeLabels,
}
}
......@@ -543,6 +569,17 @@ function getAdvancedCustomRouteUpstreamPath(route: AdvancedCustomRoute): string
return (route.upstream_path || '').trim()
}
function getAdvancedCustomRouteSummaryLabel(
route: AdvancedCustomRoute
): string | null {
const incomingPath = route.incoming_path?.trim() || ''
if (!incomingPath) return null
return (
ADVANCED_CUSTOM_ROUTE_SUMMARY_LABELS[incomingPath] ||
getAdvancedCustomIncomingPathLabel(incomingPath)
)
}
function isFullHttpURLOrAbsolutePath(value: string): boolean {
if (value.startsWith('/')) return !value.startsWith('//')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment