Merge remote-tracking branch 'origin/alpha' into alpha

This commit is contained in:
t0ng7u
2025-08-10 21:14:47 +08:00
7 changed files with 92 additions and 33 deletions

View File

@@ -22,6 +22,7 @@ const (
ContextKeyChannelBaseUrl ContextKey = "base_url"
ContextKeyChannelType ContextKey = "channel_type"
ContextKeyChannelSetting ContextKey = "channel_setting"
ContextKeyChannelOtherSetting ContextKey = "channel_other_setting"
ContextKeyChannelParamOverride ContextKey = "param_override"
ContextKeyChannelOrganization ContextKey = "channel_organization"
ContextKeyChannelAutoBan ContextKey = "auto_ban"

View File

@@ -8,3 +8,7 @@ type ChannelSettings struct {
SystemPrompt string `json:"system_prompt,omitempty"`
SystemPromptOverride bool `json:"system_prompt_override,omitempty"`
}
type ChannelOtherSettings struct {
AzureResponsesVersion string `json:"azure_responses_version,omitempty"`
}

View File

@@ -244,6 +244,7 @@ func SetupContextForSelectedChannel(c *gin.Context, channel *model.Channel, mode
common.SetContextKey(c, constant.ContextKeyChannelType, channel.Type)
common.SetContextKey(c, constant.ContextKeyChannelCreateTime, channel.CreatedTime)
common.SetContextKey(c, constant.ContextKeyChannelSetting, channel.GetSetting())
common.SetContextKey(c, constant.ContextKeyChannelOtherSetting, channel.GetOtherSettings())
common.SetContextKey(c, constant.ContextKeyChannelParamOverride, channel.GetParamOverride())
if nil != channel.OpenAIOrganization && *channel.OpenAIOrganization != "" {
common.SetContextKey(c, constant.ContextKeyChannelOrganization, *channel.OpenAIOrganization)

View File

@@ -42,7 +42,7 @@ type Channel struct {
Priority *int64 `json:"priority" gorm:"bigint;default:0"`
AutoBan *int `json:"auto_ban" gorm:"default:1"`
OtherInfo string `json:"other_info"`
Settings string `json:"settings"`
OtherSettings string `json:"settings" gorm:"column:settings"` // 其他设置
Tag *string `json:"tag" gorm:"index"`
Setting *string `json:"setting" gorm:"type:text"` // 渠道额外设置
ParamOverride *string `json:"param_override" gorm:"type:text"`
@@ -838,6 +838,28 @@ func (channel *Channel) SetSetting(setting dto.ChannelSettings) {
channel.Setting = common.GetPointer[string](string(settingBytes))
}
func (channel *Channel) GetOtherSettings() dto.ChannelOtherSettings {
setting := dto.ChannelOtherSettings{}
if channel.OtherSettings != "" {
err := common.UnmarshalJsonStr(channel.OtherSettings, &setting)
if err != nil {
common.SysError("failed to unmarshal setting: " + err.Error())
channel.OtherSettings = "{}" // 清空设置以避免后续错误
_ = channel.Save() // 保存修改
}
}
return setting
}
func (channel *Channel) SetOtherSettings(setting dto.ChannelOtherSettings) {
settingBytes, err := common.Marshal(setting)
if err != nil {
common.SysError("failed to marshal setting: " + err.Error())
return
}
channel.OtherSettings = string(settingBytes)
}
func (channel *Channel) GetParamOverride() map[string]interface{} {
paramOverride := make(map[string]interface{})
if channel.ParamOverride != nil && *channel.ParamOverride != "" {

View File

@@ -128,7 +128,17 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
// 特殊处理 responses API
if info.RelayMode == relayconstant.RelayModeResponses {
requestURL = fmt.Sprintf("/openai/v1/responses?api-version=preview")
responsesApiVersion := "preview"
if info.ChannelOtherSettings.AzureResponsesVersion != "" {
responsesApiVersion = info.ChannelOtherSettings.AzureResponsesVersion
}
subUrl := "/openai/v1/responses"
if strings.Contains(info.BaseUrl, "cognitiveservices.azure.com") {
subUrl = "/openai/responses"
}
requestURL = fmt.Sprintf("%s?api-version=%s", subUrl, responsesApiVersion)
return relaycommon.GetFullRequestURL(info.BaseUrl, requestURL, info.ChannelType), nil
}

View File

@@ -102,6 +102,7 @@ type RelayInfo struct {
AudioUsage bool
ReasoningEffort string
ChannelSetting dto.ChannelSettings
ChannelOtherSettings dto.ChannelOtherSettings
ParamOverride map[string]interface{}
UserSetting dto.UserSetting
UserEmail string
@@ -292,6 +293,12 @@ func GenRelayInfo(c *gin.Context) *RelayInfo {
if ok {
info.ChannelSetting = channelSetting
}
channelOtherSettings, ok := common.GetContextKeyType[dto.ChannelOtherSettings](c, constant.ContextKeyChannelOtherSetting)
if ok {
info.ChannelOtherSettings = channelOtherSettings
}
userSetting, ok := common.GetContextKeyType[dto.UserSetting](c, constant.ContextKeyUserSetting)
if ok {
info.UserSetting = userSetting

View File

@@ -132,6 +132,7 @@ const EditChannelModal = (props) => {
pass_through_body_enabled: false,
system_prompt: '',
system_prompt_override: false,
settings: '',
};
const [batch, setBatch] = useState(false);
const [multiToSingle, setMultiToSingle] = useState(false);
@@ -187,38 +188,31 @@ const EditChannelModal = (props) => {
handleInputChange('setting', settingsJson);
};
// 解析渠道设置JSON为单独的状态
const parseChannelSettings = (settingJson) => {
try {
if (settingJson && settingJson.trim()) {
const parsed = JSON.parse(settingJson);
setChannelSettings({
force_format: parsed.force_format || false,
thinking_to_content: parsed.thinking_to_content || false,
proxy: parsed.proxy || '',
pass_through_body_enabled: parsed.pass_through_body_enabled || false,
system_prompt: parsed.system_prompt || '',
});
} else {
setChannelSettings({
force_format: false,
thinking_to_content: false,
proxy: '',
pass_through_body_enabled: false,
system_prompt: '',
});
}
} catch (error) {
console.error('解析渠道设置失败:', error);
setChannelSettings({
force_format: false,
thinking_to_content: false,
proxy: '',
pass_through_body_enabled: false,
system_prompt: '',
});
const handleChannelOtherSettingsChange = (key, value) => {
// 更新内部状态
setChannelSettings(prev => ({ ...prev, [key]: value }));
// 同步更新到表单字段
if (formApiRef.current) {
formApiRef.current.setValue(key, value);
}
};
// 同步更新inputs状态
setInputs(prev => ({ ...prev, [key]: value }));
// 需要更新settings是一个json例如{"azure_responses_version": "preview"}
let settings = {};
if (inputs.settings) {
try {
settings = JSON.parse(inputs.settings);
} catch (error) {
console.error('解析设置失败:', error);
}
}
settings[key] = value;
const settingsJson = JSON.stringify(settings);
handleInputChange('settings', settingsJson);
}
const handleInputChange = (name, value) => {
if (formApiRef.current) {
@@ -360,6 +354,17 @@ const EditChannelModal = (props) => {
data.system_prompt_override = false;
}
if (data.settings) {
try {
const parsedSettings = JSON.parse(data.settings);
data.azure_responses_version = parsedSettings.azure_responses_version || '';
} catch (error) {
console.error('解析其他设置失败:', error);
data.azure_responses_version = '';
data.region = '';
}
}
setInputs(data);
if (formApiRef.current) {
formApiRef.current.setValues(data);
@@ -1377,6 +1382,15 @@ const EditChannelModal = (props) => {
showClear
/>
</div>
<div>
<Form.Input
field='azure_responses_version'
label={t('默认 Responses API 版本,为空则使用上方版本')}
placeholder={t('例如preview')}
onChange={(value) => handleChannelOtherSettingsChange('azure_responses_version', value)}
showClear
/>
</div>
</>
)}