feat: add siliconflow chat provider (#4764)

* feat: add siliconflow chat provider

* fix: remove siliconflow seed handling

* fix: enable SiliconFlow image inlining from shared vision list

* fix: handle SiliconFlow model context limits and sizing

* fix: drop SiliconFlow reasoning effort handling since controls are hidden

* fix: parse SiliconFlow reasoning in streaming and non-streaming

* fix: add missing comma in supported models list

* Remove seed from HTML template

* Combine streamed reasoning parsing blocks

* Update logo image

* Unhide image inlining controls

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
QiyuanChen
2025-11-20 04:10:29 +08:00
committed by GitHub
parent 05a963a637
commit 5c974bd148
11 changed files with 166 additions and 8 deletions
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="142.22" height="68.010002" viewBox="0 0 142.22 68.010002" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<path d="M 136.05,0 H 74.21 c -3.42,0 -6.18,2.77 -6.18,6.18 v 18.55 c 0,3.42 -2.77,6.18 -6.18,6.18 H 6.18 C 2.76,30.91 0,33.68 0,37.09 v 24.74 c 0,3.42 2.77,6.18 6.18,6.18 h 61.84 c 3.42,0 6.18,-2.77 6.18,-6.18 V 43.28 c 0,-3.42 2.77,-6.18 6.18,-6.18 h 55.66 c 3.42,0 6.18,-2.77 6.18,-6.18 V 6.18 C 142.22,2.76 139.45,0 136.04,0 Z" />
</svg>

After

Width:  |  Height:  |  Size: 560 B

+22 -7
View File
@@ -693,7 +693,7 @@
</span>
</div>
</div>
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai,zai">
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,siliconflow,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai,zai">
<div class="range-block-title" data-i18n="Temperature">
Temperature
</div>
@@ -706,7 +706,7 @@
</div>
</div>
</div>
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai">
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,siliconflow,mistralai,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai">
<div class="range-block-title" data-i18n="Frequency Penalty">
Frequency Penalty
</div>
@@ -719,7 +719,7 @@
</div>
</div>
</div>
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai">
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,siliconflow,mistralai,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai">
<div class="range-block-title" data-i18n="Presence Penalty">
Presence Penalty
</div>
@@ -745,7 +745,7 @@
</div>
</div>
</div>
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai,zai">
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,siliconflow,electronhub,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi,azure_openai,zai">
<div class="range-block-title" data-i18n="Top P">
Top P
</div>
@@ -1965,7 +1965,7 @@
</b>
</div>
</div>
<div class="range-block" data-source="openai,cohere,mistralai,custom,claude,aimlapi,openrouter,groq,deepseek,makersuite,vertexai,ai21,xai,pollinations,moonshot,fireworks,cometapi,electronhub,azure_openai,zai">
<div class="range-block" data-source="openai,cohere,mistralai,custom,claude,aimlapi,openrouter,groq,siliconflow,deepseek,makersuite,vertexai,ai21,xai,pollinations,moonshot,fireworks,cometapi,electronhub,azure_openai,zai">
<label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand">
<input id="openai_function_calling" type="checkbox" />
<span data-i18n="Enable function calling">Enable function calling</span>
@@ -1980,7 +1980,7 @@
<strong data-i18n="enable_functions_desc_4">Not supported when Prompt Post-Processing with "no tools" is used!</strong>
</div>
</div>
<div class="range-block" data-source="openai,aimlapi,openrouter,mistralai,makersuite,vertexai,claude,custom,xai,pollinations,moonshot,cohere,cometapi,nanogpt,electronhub,azure_openai,zai">
<div class="range-block" data-source="openai,aimlapi,openrouter,mistralai,makersuite,vertexai,claude,custom,xai,pollinations,moonshot,cohere,cometapi,nanogpt,electronhub,azure_openai,zai,siliconflow">
<label for="openai_image_inlining" class="checkbox_label flexWrap widthFreeExpand">
<input id="openai_image_inlining" type="checkbox" />
<span data-i18n="Send inline images">Send inline images</span>
@@ -1992,7 +1992,7 @@
<div id="image_inlining_hint" class="flexBasis100p toggle-description justifyLeft">
<span data-i18n="image_inlining_hint_1">Sends images in prompts if the model supports it.</span>
</div>
<div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,xai,pollinations,cohere,cometapi,nanogpt,moonshot,aimlapi,openrouter,mistralai,electronhub,azure_openai,zai">
<div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,xai,pollinations,cohere,cometapi,nanogpt,moonshot,aimlapi,openrouter,mistralai,electronhub,azure_openai,zai,siliconflow">
<div class="flex-container oneline-dropdown">
<label for="openai_inline_image_quality" data-i18n="Inline Image Quality">
Inline Image Quality
@@ -2806,6 +2806,7 @@
<option value="openrouter">OpenRouter</option>
<option value="perplexity">Perplexity</option>
<option value="pollinations">Pollinations</option>
<option value="siliconflow">SiliconFlow</option>
<option value="xai">xAI (Grok)</option>
<option value="zai">Z.AI (GLM)</option>
</optgroup>
@@ -3397,6 +3398,20 @@
<option value="mistral-saba-24b">mistral-saba-24b</option>
</select>
</div>
<div id="siliconflow_form" data-source="siliconflow">
<h4>SiliconFlow API Key</h4>
<div class="flex-container">
<input id="api_key_siliconflow" name="api_key_siliconflow" class="text_pole flex1" value="" type="text" autocomplete="off">
<div title="Manage API keys" data-i18n="[title]Manage API keys" class="menu_button fa-solid fa-key fa-fw manage-api-keys" data-key="api_key_siliconflow"></div>
</div>
<div data-for="api_key_siliconflow" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you click 'Connect'.">
For privacy reasons, your API key will be hidden after you click 'Connect'.
</div>
<h4>SiliconFlow Model</h4>
<select id="model_siliconflow_select">
<option value="" data-i18n="-- Connect to the API --">-- Connect to the API --</option>
</select>
</div>
<div id="electronhub_form" data-source="electronhub">
<h4 data-i18n="Electron Hub API Key">Electron Hub API Key</h4>
<div>
+1
View File
@@ -403,6 +403,7 @@ function RA_autoconnect(PrevApi) {
|| (secret_state[SECRET_KEYS.COHERE] && oai_settings.chat_completion_source == chat_completion_sources.COHERE)
|| (secret_state[SECRET_KEYS.PERPLEXITY] && oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY)
|| (secret_state[SECRET_KEYS.GROQ] && oai_settings.chat_completion_source == chat_completion_sources.GROQ)
|| (secret_state[SECRET_KEYS.SILICONFLOW] && oai_settings.chat_completion_source == chat_completion_sources.SILICONFLOW)
|| (secret_state[SECRET_KEYS.ELECTRONHUB] && oai_settings.chat_completion_source == chat_completion_sources.ELECTRONHUB)
|| (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT)
|| (secret_state[SECRET_KEYS.DEEPSEEK] && oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK)
+118 -1
View File
@@ -194,6 +194,7 @@ export const chat_completion_sources = {
COMETAPI: 'cometapi',
AZURE_OPENAI: 'azure_openai',
ZAI: 'zai',
SILICONFLOW: 'siliconflow',
};
const character_names_behavior = {
@@ -280,6 +281,7 @@ export const settingsToUpdate = {
cohere_model: ['#model_cohere_select', 'cohere_model', false, true],
perplexity_model: ['#model_perplexity_select', 'perplexity_model', false, true],
groq_model: ['#model_groq_select', 'groq_model', false, true],
siliconflow_model: ['#model_siliconflow_select', 'siliconflow_model', false, true],
electronhub_model: ['#model_electronhub_select', 'electronhub_model', false, true],
electronhub_sort_models: ['#electronhub_sort_models', 'electronhub_sort_models', false, true],
electronhub_group_models: ['#electronhub_group_models', 'electronhub_group_models', false, true],
@@ -387,6 +389,7 @@ const default_settings = {
cohere_model: 'command-r-plus',
perplexity_model: 'sonar-pro',
groq_model: 'llama-3.3-70b-versatile',
siliconflow_model: 'deepseek-ai/DeepSeek-V3',
electronhub_model: 'gpt-4o-mini',
electronhub_sort_models: 'alphabetically',
electronhub_group_models: false,
@@ -1587,6 +1590,8 @@ export function getChatCompletionModel(source = null) {
return oai_settings.perplexity_model;
case chat_completion_sources.GROQ:
return oai_settings.groq_model;
case chat_completion_sources.SILICONFLOW:
return oai_settings.siliconflow_model;
case chat_completion_sources.ELECTRONHUB:
return oai_settings.electronhub_model;
case chat_completion_sources.NANOGPT:
@@ -1920,6 +1925,24 @@ function saveModelList(data) {
$('#model_groq_select').val(oai_settings.groq_model).trigger('change');
}
if (oai_settings.chat_completion_source === chat_completion_sources.SILICONFLOW) {
$('#model_siliconflow_select').empty();
model_list.forEach((model) => {
$('#model_siliconflow_select').append(
$('<option>', {
value: model.id,
text: model.id,
}));
});
const selectedModel = model_list.find(model => model.id === oai_settings.siliconflow_model);
if (model_list.length > 0 && (!selectedModel || !oai_settings.siliconflow_model)) {
oai_settings.siliconflow_model = model_list[0].id;
}
$('#model_siliconflow_select').val(oai_settings.siliconflow_model).trigger('change');
}
if (oai_settings.chat_completion_source === chat_completion_sources.FIREWORKS) {
$('#model_fireworks_select').empty();
model_list.forEach((model) => {
@@ -2654,7 +2677,7 @@ export function getStreamingReply(data, state, { chatCompletionSource = null, ov
state.reasoning += (data.choices?.filter(x => x?.delta?.reasoning)?.[0]?.delta?.reasoning || '');
}
return data.choices?.[0]?.delta?.content ?? data.choices?.[0]?.message?.content ?? data.choices?.[0]?.text ?? '';
} else if ([chat_completion_sources.CUSTOM, chat_completion_sources.POLLINATIONS, chat_completion_sources.AIMLAPI, chat_completion_sources.MOONSHOT, chat_completion_sources.COMETAPI, chat_completion_sources.ELECTRONHUB, chat_completion_sources.NANOGPT, chat_completion_sources.ZAI].includes(chat_completion_source)) {
} else if ([chat_completion_sources.CUSTOM, chat_completion_sources.POLLINATIONS, chat_completion_sources.AIMLAPI, chat_completion_sources.MOONSHOT, chat_completion_sources.COMETAPI, chat_completion_sources.ELECTRONHUB, chat_completion_sources.NANOGPT, chat_completion_sources.ZAI, chat_completion_sources.SILICONFLOW].includes(chat_completion_source)) {
if (show_thoughts) {
state.reasoning +=
data.choices?.filter(x => x?.delta?.reasoning_content)?.[0]?.delta?.reasoning_content ??
@@ -3665,6 +3688,7 @@ function loadOpenAISettings(data, settings) {
oai_settings.cohere_model = settings.cohere_model ?? default_settings.cohere_model;
oai_settings.perplexity_model = settings.perplexity_model ?? default_settings.perplexity_model;
oai_settings.groq_model = settings.groq_model ?? default_settings.groq_model;
oai_settings.siliconflow_model = settings.siliconflow_model ?? default_settings.siliconflow_model;
oai_settings.electronhub_model = settings.electronhub_model ?? default_settings.electronhub_model;
oai_settings.electronhub_sort_models = settings.electronhub_sort_models ?? default_settings.electronhub_sort_models;
oai_settings.electronhub_group_models = settings.electronhub_group_models ?? default_settings.electronhub_group_models;
@@ -3770,6 +3794,8 @@ function loadOpenAISettings(data, settings) {
$(`#model_perplexity_select option[value="${oai_settings.perplexity_model}"`).prop('selected', true);
$('#model_groq_select').val(oai_settings.groq_model);
$(`#model_groq_select option[value="${oai_settings.groq_model}"`).prop('selected', true);
$('#model_siliconflow_select').val(oai_settings.siliconflow_model);
$(`#model_siliconflow_select option[value="${oai_settings.siliconflow_model}"`).prop('selected', true);
$('#model_electronhub_select').val(oai_settings.electronhub_model);
$(`#model_electronhub_select option[value="${oai_settings.electronhub_model}"`).prop('selected', true);
$('#model_nanogpt_select').val(oai_settings.nanogpt_model);
@@ -4077,6 +4103,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
cohere_model: settings.cohere_model,
perplexity_model: settings.perplexity_model,
groq_model: settings.groq_model,
siliconflow_model: settings.siliconflow_model,
xai_model: settings.xai_model,
pollinations_model: settings.pollinations_model,
aimlapi_model: settings.aimlapi_model,
@@ -4765,6 +4792,65 @@ function getZaiMaxContext(model, isUnlocked) {
return Object.entries(contextMap).find(([key]) => model.includes(key))?.[1] || max_128k;
}
/**
* Get the maximum context size for the SiliconFlow model
* @param {string} model Model identifier
* @param {boolean} isUnlocked Whether context limits are unlocked
* @returns {number} Maximum context size in tokens
*/
function getSiliconflowMaxContext(model, isUnlocked) {
if (isUnlocked) {
return unlocked_max;
}
const contextMap = {
'baidu/ERNIE-4.5-300B-A47B': max_128k,
'ByteDance-Seed/Seed-OSS-36B-Instruct': max_256k,
'deepseek-ai/DeepSeek-R1': max_128k,
'deepseek-ai/DeepSeek-V3': max_128k,
'deepseek-ai/DeepSeek-V3.1': max_128k,
'deepseek-ai/DeepSeek-V3.1-Terminus': max_128k,
'deepseek-ai/DeepSeek-V3.2-Exp': max_128k,
'deepseek-ai/deepseek-vl2': max_4k,
'inclusionAI/Ling-1T': max_128k,
'inclusionAI/Ling-flash-2.0': max_128k,
'inclusionAI/Ling-mini-2.0': max_128k,
'inclusionAI/Ring-1T': max_128k,
'inclusionAI/Ring-flash-2.0': max_128k,
'meta-llama/Llama-3.3-70B-Instruct': max_32k,
'meta-llama/Meta-Llama-3.1-8B-Instruct': max_32k,
'MiniMaxAI/MiniMax-M1-80k': max_128k,
'MiniMaxAI/MiniMax-M2': max_128k,
'moonshotai/Kimi-K2-Instruct': max_128k,
'moonshotai/Kimi-K2-Instruct-0905': max_256k,
'moonshotai/Kimi-K2-Thinking': max_256k,
'openai/gpt-oss-120b': max_128k,
'openai/gpt-oss-20b': max_128k,
'Qwen/Qwen3-235B-A22B-Instruct-2507': max_256k,
'Qwen/Qwen3-235B-A22B-Thinking-2507': max_256k,
'Qwen/Qwen3-30B-A3B-Instruct-2507': max_256k,
'Qwen/Qwen3-30B-A3B-Thinking-2507': max_256k,
'Qwen/Qwen3-VL-235B-A22B-Instruct': max_256k,
'Qwen/Qwen3-VL-235B-A22B-Thinking': max_256k,
'Qwen/Qwen3-VL-30B-A3B-Instruct': max_256k,
'Qwen/Qwen3-VL-30B-A3B-Thinking': max_256k,
'Qwen/Qwen3-VL-32B-Instruct': max_256k,
'Qwen/Qwen3-VL-32B-Thinking': max_256k,
'Qwen/Qwen3-VL-8B-Instruct': max_256k,
'Qwen/Qwen3-VL-8B-Thinking': max_256k,
'stepfun-ai/step3': max_64k,
'tencent/Hunyuan-A13B-Instruct': max_128k,
'zai-org/GLM-4.5': max_128k,
'zai-org/GLM-4.5-Air': max_128k,
'zai-org/GLM-4.5V': max_64k,
'zai-org/GLM-4.6': max_200k,
};
// Return context size if model found, otherwise default to 32k
return Object.entries(contextMap).find(([key]) => model.includes(key))?.[1] || max_32k;
}
/**
* Get the maximum context size for the Moonshot model
* @param {string} model Model identifier
@@ -4956,6 +5042,15 @@ async function onModelChange() {
oai_settings.groq_model = value;
}
if ($(this).is('#model_siliconflow_select')) {
if (!value) {
console.debug('Null SiliconFlow model selected. Ignoring.');
return;
}
console.log('SiliconFlow model changed to', value);
oai_settings.siliconflow_model = value;
}
if ($(this).is('#model_electronhub_select')) {
if (!value) {
console.debug('Null ElectronHub model selected. Ignoring.');
@@ -5356,6 +5451,15 @@ async function onModelChange() {
$('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
}
if (oai_settings.chat_completion_source === chat_completion_sources.SILICONFLOW) {
const maxContext = getSiliconflowMaxContext(oai_settings.siliconflow_model, oai_settings.max_context_unlocked);
$('#openai_max_context').attr('max', maxContext);
oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context);
$('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
oai_settings.temp_openai = Math.min(oai_max_temp, oai_settings.temp_openai);
$('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
}
if (oai_settings.chat_completion_source == chat_completion_sources.ZAI) {
const maxContext = getZaiMaxContext(oai_settings.zai_model, oai_settings.max_context_unlocked);
$('#openai_max_context').attr('max', maxContext);
@@ -5411,6 +5515,7 @@ async function onConnectButtonClick(e) {
[chat_completion_sources.COHERE]: { key: SECRET_KEYS.COHERE, selector: '#api_key_cohere', proxy: false },
[chat_completion_sources.PERPLEXITY]: { key: SECRET_KEYS.PERPLEXITY, selector: '#api_key_perplexity', proxy: false },
[chat_completion_sources.GROQ]: { key: SECRET_KEYS.GROQ, selector: '#api_key_groq', proxy: false },
[chat_completion_sources.SILICONFLOW]: { key: SECRET_KEYS.SILICONFLOW, selector: '#api_key_siliconflow', proxy: false },
[chat_completion_sources.ELECTRONHUB]: { key: SECRET_KEYS.ELECTRONHUB, selector: '#api_key_electronhub', proxy: false },
[chat_completion_sources.NANOGPT]: { key: SECRET_KEYS.NANOGPT, selector: '#api_key_nanogpt', proxy: false },
[chat_completion_sources.DEEPSEEK]: { key: SECRET_KEYS.DEEPSEEK, selector: '#api_key_deepseek', proxy: true },
@@ -5493,6 +5598,9 @@ function toggleChatCompletionForms() {
else if (oai_settings.chat_completion_source == chat_completion_sources.GROQ) {
$('#model_groq_select').trigger('change');
}
else if (oai_settings.chat_completion_source == chat_completion_sources.SILICONFLOW) {
$('#model_siliconflow_select').trigger('change');
}
else if (oai_settings.chat_completion_source == chat_completion_sources.ELECTRONHUB) {
$('#model_electronhub_select').trigger('change');
}
@@ -5647,6 +5755,12 @@ export function isImageInliningSupported() {
'moonshot-v1-128k-vision-preview',
// Z.AI (GLM)
'glm-4.5v',
// SiliconFlow
'Qwen/Qwen3-VL-32B-Instruct',
'Qwen/Qwen3-VL-8B-Instruct',
'Qwen/Qwen3-VL-235B-A22B-Instruct',
'Qwen/Qwen3-VL-30B-A3B-Instruct',
'zai-org/GLM-4.5V',
];
switch (oai_settings.chat_completion_source) {
@@ -5691,6 +5805,8 @@ export function isImageInliningSupported() {
return (Array.isArray(model_list) && model_list.find(m => m.id === oai_settings.nanogpt_model)?.capabilities?.vision);
case chat_completion_sources.ZAI:
return visionSupportedModels.some(model => oai_settings.zai_model.includes(model));
case chat_completion_sources.SILICONFLOW:
return visionSupportedModels.some(model => oai_settings.siliconflow_model.includes(model));
default:
return false;
}
@@ -6571,6 +6687,7 @@ export function initOpenAI() {
$('#model_cohere_select').on('change', onModelChange);
$('#model_perplexity_select').on('change', onModelChange);
$('#model_groq_select').on('change', onModelChange);
$('#model_siliconflow_select').on('change', onModelChange);
$('#model_electronhub_select').on('change', onModelChange);
$('#model_nanogpt_select').on('change', onModelChange);
$('#model_deepseek_select').on('change', onModelChange);
+1
View File
@@ -127,6 +127,7 @@ export function extractReasoningFromData(data, {
case chat_completion_sources.COMETAPI:
case chat_completion_sources.ELECTRONHUB:
case chat_completion_sources.NANOGPT:
case chat_completion_sources.SILICONFLOW:
case chat_completion_sources.ZAI:
case chat_completion_sources.CUSTOM: {
return data?.choices?.[0]?.message?.reasoning_content
+3
View File
@@ -69,6 +69,7 @@ export const SECRET_KEYS = {
MOONSHOT: 'api_key_moonshot',
COMETAPI: 'api_key_cometapi',
ZAI: 'api_key_zai',
SILICONFLOW: 'api_key_siliconflow',
};
const FRIENDLY_NAMES = {
@@ -126,6 +127,7 @@ const FRIENDLY_NAMES = {
[SECRET_KEYS.COMETAPI]: 'CometAPI',
[SECRET_KEYS.AZURE_OPENAI]: 'Azure OpenAI',
[SECRET_KEYS.ZAI]: 'Z.AI',
[SECRET_KEYS.SILICONFLOW]: 'SiliconFlow',
};
const INPUT_MAP = {
@@ -166,6 +168,7 @@ const INPUT_MAP = {
[SECRET_KEYS.COMETAPI]: '#api_key_cometapi',
[SECRET_KEYS.AZURE_OPENAI]: '#api_key_azure_openai',
[SECRET_KEYS.ZAI]: '#api_key_zai',
[SECRET_KEYS.SILICONFLOW]: '#api_key_siliconflow',
};
const getLabel = () => moment().format('L LT');
+1
View File
@@ -4844,6 +4844,7 @@ function getModelOptions(quiet) {
{ id: 'model_cohere_select', api: 'openai', type: chat_completion_sources.COHERE },
{ id: 'model_perplexity_select', api: 'openai', type: chat_completion_sources.PERPLEXITY },
{ id: 'model_groq_select', api: 'openai', type: chat_completion_sources.GROQ },
{ id: 'model_siliconflow_select', api: 'openai', type: chat_completion_sources.SILICONFLOW },
{ id: 'model_electronhub_select', api: 'openai', type: chat_completion_sources.ELECTRONHUB },
{ id: 'model_nanogpt_select', api: 'openai', type: chat_completion_sources.NANOGPT },
{ id: 'model_deepseek_select', api: 'openai', type: chat_completion_sources.DEEPSEEK },
+1
View File
@@ -662,6 +662,7 @@ export class ToolManager {
chat_completion_sources.ELECTRONHUB,
chat_completion_sources.AZURE_OPENAI,
chat_completion_sources.ZAI,
chat_completion_sources.SILICONFLOW,
];
return supportedSources.includes(oai_settings.chat_completion_source);
}
+1
View File
@@ -207,6 +207,7 @@ export const CHAT_COMPLETION_SOURCES = {
COMETAPI: 'cometapi',
AZURE_OPENAI: 'azure_openai',
ZAI: 'zai',
SILICONFLOW: 'siliconflow',
};
/**
@@ -76,6 +76,7 @@ const API_MOONSHOT = 'https://api.moonshot.ai/v1';
const API_FIREWORKS = 'https://api.fireworks.ai/inference/v1';
const API_COMETAPI = 'https://api.cometapi.com/v1';
const API_ZAI = 'https://api.z.ai/api/paas/v4';
const API_SILICONFLOW = 'https://api.siliconflow.com/v1';
/**
* Gets OpenRouter transforms based on the request.
@@ -1570,6 +1571,10 @@ router.post('/status', async function (request, statusResponse) {
console.error('Azure OpenAI status check connection error:', error);
return statusResponse.status(500).send({ error: true, message: 'Failed to connect to the Azure endpoint.' });
}
} else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.SILICONFLOW) {
apiUrl = API_SILICONFLOW;
apiKey = readSecret(request.user.directories, SECRET_KEYS.SILICONFLOW);
headers = {};
} else {
console.warn('This chat completion source is not supported yet.');
return statusResponse.status(400).send({ error: true });
@@ -1980,6 +1985,14 @@ router.post('/generate', function (request, response) {
if (request.body.json_schema) {
setJsonObjectFormat(bodyParams, request.body.messages, request.body.json_schema);
}
} else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.SILICONFLOW) {
apiUrl = API_SILICONFLOW;
apiKey = readSecret(request.user.directories, SECRET_KEYS.SILICONFLOW);
headers = {};
bodyParams = {};
if (request.body.json_schema) {
setJsonObjectFormat(bodyParams, request.body.messages, request.body.json_schema);
}
} else {
console.warn('This chat completion source is not supported yet.');
return response.status(400).send({ error: true });
+1
View File
@@ -62,6 +62,7 @@ export const SECRET_KEYS = {
COMETAPI: 'api_key_cometapi',
AZURE_OPENAI: 'api_key_azure_openai',
ZAI: 'api_key_zai',
SILICONFLOW: 'api_key_siliconflow',
};
/**