feat: add field passthrough controls for gateway channels (#6847)
This commit is contained in:
@@ -138,13 +138,16 @@ import {
|
||||
} from '../../api'
|
||||
import {
|
||||
ADD_MODE_OPTIONS,
|
||||
CLAUDE_FIELD_PASSTHROUGH_TYPES,
|
||||
CHANNEL_STATUS_LABELS,
|
||||
CHANNEL_TYPE_OPTIONS,
|
||||
CHANNEL_TYPE_WARNINGS,
|
||||
ERROR_MESSAGES,
|
||||
FIELD_PASSTHROUGH_TYPES,
|
||||
FIELD_DESCRIPTIONS,
|
||||
FIELD_PLACEHOLDERS,
|
||||
MODEL_FETCHABLE_TYPES,
|
||||
OPENAI_FIELD_PASSTHROUGH_TYPES,
|
||||
} from '../../constants'
|
||||
import { useChannelMutateForm } from '../../hooks/use-channel-mutate-form'
|
||||
import {
|
||||
@@ -1026,7 +1029,7 @@ export function ChannelMutateDrawer({
|
||||
(currentHttp2ConnectionShards != null && currentHttp2ConnectionShards > 1)
|
||||
)
|
||||
let fieldPassthroughConfigured = false
|
||||
if (currentType === 1 || currentType === 57) {
|
||||
if (OPENAI_FIELD_PASSTHROUGH_TYPES.has(currentType)) {
|
||||
fieldPassthroughConfigured = Boolean(
|
||||
currentAllowServiceTier ||
|
||||
currentDisableStore ||
|
||||
@@ -1034,13 +1037,16 @@ export function ChannelMutateDrawer({
|
||||
currentAllowIncludeObfuscation ||
|
||||
currentAllowInferenceGeo
|
||||
)
|
||||
} else if (currentType === 14) {
|
||||
fieldPassthroughConfigured = Boolean(
|
||||
currentAllowServiceTier ||
|
||||
currentAllowInferenceGeo ||
|
||||
currentAllowSpeed ||
|
||||
currentClaudeBetaQuery
|
||||
)
|
||||
}
|
||||
if (CLAUDE_FIELD_PASSTHROUGH_TYPES.has(currentType)) {
|
||||
fieldPassthroughConfigured =
|
||||
fieldPassthroughConfigured ||
|
||||
Boolean(
|
||||
currentAllowServiceTier ||
|
||||
currentAllowInferenceGeo ||
|
||||
currentAllowSpeed ||
|
||||
(currentType === 14 && currentClaudeBetaQuery)
|
||||
)
|
||||
}
|
||||
const upstreamModelDetectionConfigured = Boolean(
|
||||
upstreamModelUpdateCheckEnabled ||
|
||||
@@ -1077,7 +1083,7 @@ export function ChannelMutateDrawer({
|
||||
configured: extraSettingsConfigured,
|
||||
},
|
||||
]
|
||||
if (currentType === 1 || currentType === 14 || currentType === 57) {
|
||||
if (FIELD_PASSTHROUGH_TYPES.has(currentType)) {
|
||||
advancedNavChildren.push({
|
||||
id: ADVANCED_SETTINGS_SECTION_IDS.fieldPassthrough,
|
||||
title: t('Field passthrough controls'),
|
||||
@@ -4233,9 +4239,7 @@ export function ChannelMutateDrawer({
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent
|
||||
alignItemWithTrigger={false}
|
||||
>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value='auto'>
|
||||
{t('Auto')}
|
||||
@@ -4369,9 +4373,7 @@ export function ChannelMutateDrawer({
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
{(currentType === 1 ||
|
||||
currentType === 14 ||
|
||||
currentType === 57) && (
|
||||
{FIELD_PASSTHROUGH_TYPES.has(currentType) && (
|
||||
<div
|
||||
id={ADVANCED_SETTINGS_SECTION_IDS.fieldPassthrough}
|
||||
className={sideDrawerSectionClassName(
|
||||
@@ -4416,7 +4418,9 @@ export function ChannelMutateDrawer({
|
||||
)}
|
||||
/>
|
||||
|
||||
{(currentType === 1 || currentType === 57) && (
|
||||
{OPENAI_FIELD_PASSTHROUGH_TYPES.has(
|
||||
currentType
|
||||
) && (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -4526,34 +4530,38 @@ export function ChannelMutateDrawer({
|
||||
</>
|
||||
)}
|
||||
|
||||
{currentType === 14 && (
|
||||
{CLAUDE_FIELD_PASSTHROUGH_TYPES.has(
|
||||
currentType
|
||||
) && (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='allow_inference_geo'
|
||||
render={({ field }) => (
|
||||
<FormItem className='flex items-center justify-between gap-3 px-4 py-3'>
|
||||
<div className='space-y-0.5'>
|
||||
<FormLabel className='text-sm'>
|
||||
{t(
|
||||
'Allow inference_geo passthrough'
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormDescription>
|
||||
{t(
|
||||
'Pass through the inference_geo field for Claude data residency region control'
|
||||
)}
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{currentType === 14 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='allow_inference_geo'
|
||||
render={({ field }) => (
|
||||
<FormItem className='flex items-center justify-between gap-3 px-4 py-3'>
|
||||
<div className='space-y-0.5'>
|
||||
<FormLabel className='text-sm'>
|
||||
{t(
|
||||
'Allow inference_geo passthrough'
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormDescription>
|
||||
{t(
|
||||
'Pass through the inference_geo field for Claude data residency region control'
|
||||
)}
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -4580,32 +4588,34 @@ export function ChannelMutateDrawer({
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='claude_beta_query'
|
||||
render={({ field }) => (
|
||||
<FormItem className='flex items-center justify-between gap-3 px-4 py-3'>
|
||||
<div className='space-y-0.5'>
|
||||
<FormLabel className='text-sm'>
|
||||
{t(
|
||||
'Allow Claude beta query passthrough'
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormDescription>
|
||||
{t(
|
||||
'Pass through the anthropic-beta header for beta features'
|
||||
)}
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{currentType === 14 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='claude_beta_query'
|
||||
render={({ field }) => (
|
||||
<FormItem className='flex items-center justify-between gap-3 px-4 py-3'>
|
||||
<div className='space-y-0.5'>
|
||||
<FormLabel className='text-sm'>
|
||||
{t(
|
||||
'Allow Claude beta query passthrough'
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormDescription>
|
||||
{t(
|
||||
'Pass through the anthropic-beta header for beta features'
|
||||
)}
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -392,6 +392,30 @@ export const MODEL_FETCHABLE_TYPES = new Set([
|
||||
59, 60,
|
||||
])
|
||||
|
||||
export const FIELD_PASSTHROUGH_TYPES = new Set([
|
||||
1,
|
||||
14,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
CHANNEL_TYPE_NEW_API,
|
||||
])
|
||||
|
||||
export const OPENAI_FIELD_PASSTHROUGH_TYPES = new Set([
|
||||
1,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
CHANNEL_TYPE_NEW_API,
|
||||
])
|
||||
|
||||
export const CLAUDE_FIELD_PASSTHROUGH_TYPES = new Set([
|
||||
14,
|
||||
58,
|
||||
59,
|
||||
CHANNEL_TYPE_NEW_API,
|
||||
])
|
||||
|
||||
export const TYPE_TO_KEY_PROMPT: Record<number, string> = {
|
||||
15: 'Format: APIKey|SecretKey',
|
||||
18: 'Format: APPID|APISecret|APIKey',
|
||||
|
||||
@@ -19,10 +19,13 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
import { z } from 'zod'
|
||||
|
||||
import {
|
||||
CLAUDE_FIELD_PASSTHROUGH_TYPES,
|
||||
CHANNEL_TYPE_NEW_API,
|
||||
CHANNEL_STATUS,
|
||||
ERROR_MESSAGES,
|
||||
FIELD_PASSTHROUGH_TYPES,
|
||||
MODEL_FETCHABLE_TYPES,
|
||||
OPENAI_FIELD_PASSTHROUGH_TYPES,
|
||||
} from '../constants'
|
||||
import type { Channel } from '../types'
|
||||
import {
|
||||
@@ -487,8 +490,7 @@ export function transformChannelToFormDefaults(
|
||||
thinking_to_content: parsed.thinking_to_content || false,
|
||||
proxy: parsed.proxy || '',
|
||||
http_protocol: protocol,
|
||||
http2_connection_shards:
|
||||
protocol === HTTP_PROTOCOL_HTTP1 ? 1 : shards,
|
||||
http2_connection_shards: protocol === HTTP_PROTOCOL_HTTP1 ? 1 : shards,
|
||||
pass_through_body_enabled: parsed.pass_through_body_enabled || false,
|
||||
system_prompt: parsed.system_prompt || '',
|
||||
system_prompt_override: parsed.system_prompt_override || false,
|
||||
@@ -672,21 +674,21 @@ function buildSettingsJSON(formData: ChannelFormValues): string {
|
||||
}
|
||||
|
||||
// Field passthrough controls:
|
||||
// - OpenAI (type 1) and Anthropic (type 14): allow_service_tier
|
||||
// - OpenAI only: disable_store, allow_safety_identifier
|
||||
if (formData.type === 1 || formData.type === 14 || formData.type === 57) {
|
||||
// - OpenAI, Anthropic, Codex, and New API: allow_service_tier
|
||||
// - OpenAI request fields: OpenAI, Codex, and New API
|
||||
// - Claude request fields: Anthropic and New API
|
||||
if (FIELD_PASSTHROUGH_TYPES.has(formData.type)) {
|
||||
settingsObj.allow_service_tier = formData.allow_service_tier === true
|
||||
} else if ('allow_service_tier' in settingsObj) {
|
||||
delete settingsObj.allow_service_tier
|
||||
}
|
||||
|
||||
if (formData.type === 1 || formData.type === 57) {
|
||||
if (OPENAI_FIELD_PASSTHROUGH_TYPES.has(formData.type)) {
|
||||
settingsObj.disable_store = formData.disable_store === true
|
||||
settingsObj.allow_safety_identifier =
|
||||
formData.allow_safety_identifier === true
|
||||
settingsObj.allow_include_obfuscation =
|
||||
formData.allow_include_obfuscation === true
|
||||
settingsObj.allow_inference_geo = formData.allow_inference_geo === true
|
||||
} else {
|
||||
if ('disable_store' in settingsObj) {
|
||||
delete settingsObj.disable_store
|
||||
@@ -697,23 +699,28 @@ function buildSettingsJSON(formData: ChannelFormValues): string {
|
||||
if ('allow_include_obfuscation' in settingsObj) {
|
||||
delete settingsObj.allow_include_obfuscation
|
||||
}
|
||||
if (formData.type !== 14 && 'allow_inference_geo' in settingsObj) {
|
||||
delete settingsObj.allow_inference_geo
|
||||
}
|
||||
}
|
||||
|
||||
// Anthropic (type 14): claude_beta_query, allow_inference_geo, allow_speed
|
||||
if (formData.type === 14) {
|
||||
if (
|
||||
OPENAI_FIELD_PASSTHROUGH_TYPES.has(formData.type) ||
|
||||
CLAUDE_FIELD_PASSTHROUGH_TYPES.has(formData.type)
|
||||
) {
|
||||
settingsObj.allow_inference_geo = formData.allow_inference_geo === true
|
||||
} else if ('allow_inference_geo' in settingsObj) {
|
||||
delete settingsObj.allow_inference_geo
|
||||
}
|
||||
|
||||
if (CLAUDE_FIELD_PASSTHROUGH_TYPES.has(formData.type)) {
|
||||
settingsObj.allow_speed = formData.allow_speed === true
|
||||
} else if ('allow_speed' in settingsObj) {
|
||||
delete settingsObj.allow_speed
|
||||
}
|
||||
|
||||
// Only the Anthropic adaptor supports forcing the Claude beta query.
|
||||
if (formData.type === 14) {
|
||||
settingsObj.claude_beta_query = formData.claude_beta_query === true
|
||||
} else {
|
||||
if ('allow_speed' in settingsObj) {
|
||||
delete settingsObj.allow_speed
|
||||
}
|
||||
if ('claude_beta_query' in settingsObj) {
|
||||
delete settingsObj.claude_beta_query
|
||||
}
|
||||
} else if ('claude_beta_query' in settingsObj) {
|
||||
delete settingsObj.claude_beta_query
|
||||
}
|
||||
|
||||
settingsObj.disable_task_polling_sleep =
|
||||
|
||||
Reference in New Issue
Block a user