Add Fireworks AI Provider Support (#4374)
* add fireworks provider * fix * add context length * Fireworks fixes * Add logo image --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
659930d5ba
commit
e9be0f1c64
@@ -0,0 +1 @@
|
||||
<svg preserveAspectRatio="xMinYMid meet" class="h-5" viewBox="0 0 638 315" xmlns="http://www.w3.org/2000/svg"><path d="M318.563 221.755C300.863 221.755 284.979 211.247 278.206 194.978L196.549 0H244.342L318.842 178.361L393.273 0H441.066L358.92 195.048C352.112 211.247 336.263 221.755 318.563 221.755Z"></path><path d="M425.111 314.933C407.481 314.933 391.667 304.494 384.824 288.366C377.947 272.097 381.507 253.524 393.936 240.921L542.657 90.2803L561.229 134.094L425.076 271.748L619.147 270.666L637.72 314.479L425.146 315.003L425.076 314.933H425.111Z"></path><path d="M0 314.408L18.5727 270.595L212.643 271.677L76.525 133.988L95.0977 90.1748L243.819 240.816C256.247 253.384 259.843 272.026 252.93 288.26C246.088 304.424 230.203 314.827 212.643 314.827L0.0698221 314.339L0 314.408Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 795 B |
+23
-6
@@ -691,7 +691,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,nanogpt,deepseek,xai,pollinations,moonshot">
|
||||
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,nanogpt,deepseek,xai,pollinations,moonshot,fireworks">
|
||||
<div class="range-block-title" data-i18n="Temperature">
|
||||
Temperature
|
||||
</div>
|
||||
@@ -704,7 +704,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek,xai,pollinations,moonshot">
|
||||
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek,xai,pollinations,moonshot,fireworks">
|
||||
<div class="range-block-title" data-i18n="Frequency Penalty">
|
||||
Frequency Penalty
|
||||
</div>
|
||||
@@ -717,7 +717,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek,xai,pollinations,moonshot">
|
||||
<div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek,xai,pollinations,moonshot,fireworks">
|
||||
<div class="range-block-title" data-i18n="Presence Penalty">
|
||||
Presence Penalty
|
||||
</div>
|
||||
@@ -743,7 +743,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,nanogpt,deepseek,xai,pollinations,moonshot">
|
||||
<div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,nanogpt,deepseek,xai,pollinations,moonshot,fireworks">
|
||||
<div class="range-block-title" data-i18n="Top P">
|
||||
Top P
|
||||
</div>
|
||||
@@ -1984,7 +1984,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">
|
||||
<div class="range-block" data-source="openai,cohere,mistralai,custom,claude,aimlapi,openrouter,groq,deepseek,makersuite,vertexai,ai21,xai,pollinations,moonshot,fireworks">
|
||||
<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>
|
||||
@@ -2065,7 +2065,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="deepseek,aimlapi,openrouter,custom,claude,xai,makersuite,vertexai,pollinations,moonshot,mistralai">
|
||||
<div class="range-block" data-source="deepseek,aimlapi,openrouter,custom,claude,xai,makersuite,vertexai,pollinations,moonshot,mistralai,fireworks">
|
||||
<label for="openai_show_thoughts" class="checkbox_label widthFreeExpand">
|
||||
<input id="openai_show_thoughts" type="checkbox" />
|
||||
<span data-i18n="Request model reasoning">Request model reasoning</span>
|
||||
@@ -2793,6 +2793,7 @@
|
||||
<option value="claude">Claude</option>
|
||||
<option value="cohere">Cohere</option>
|
||||
<option value="deepseek">DeepSeek</option>
|
||||
<option value="fireworks">Fireworks AI</option>
|
||||
<option value="groq">Groq</option>
|
||||
<option value="makersuite">Google AI Studio</option>
|
||||
<option value="vertexai">Google Vertex AI</option>
|
||||
@@ -3484,6 +3485,22 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fireworks_form" data-source="fireworks">
|
||||
<h4 data-i18n="Fireworks AI API Key">Fireworks AI API Key</h4>
|
||||
<div class="flex-container">
|
||||
<input id="api_key_fireworks" name="api_key_fireworks" 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_fireworks"></div>
|
||||
</div>
|
||||
<div data-for="api_key_fireworks" 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>
|
||||
<div>
|
||||
<h4 data-i18n="Fireworks AI Model">Fireworks AI Model</h4>
|
||||
<select id="model_fireworks_select">
|
||||
<option value="" data-i18n="-- Connect to the API --">-- Connect to the API --</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="perplexity_form" data-source="perplexity">
|
||||
<h4 data-i18n="Perplexity API Key">Perplexity API Key</h4>
|
||||
<div class="flex-container">
|
||||
|
||||
@@ -407,6 +407,7 @@ function RA_autoconnect(PrevApi) {
|
||||
|| (secret_state[SECRET_KEYS.XAI] && oai_settings.chat_completion_source == chat_completion_sources.XAI)
|
||||
|| (secret_state[SECRET_KEYS.AIMLAPI] && oai_settings.chat_completion_source == chat_completion_sources.AIMLAPI)
|
||||
|| (secret_state[SECRET_KEYS.MOONSHOT] && oai_settings.chat_completion_source == chat_completion_sources.MOONSHOT)
|
||||
|| (secret_state[SECRET_KEYS.FIREWORKS] && oai_settings.chat_completion_source == chat_completion_sources.FIREWORKS)
|
||||
|| (oai_settings.chat_completion_source === chat_completion_sources.POLLINATIONS)
|
||||
|| (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM)
|
||||
) {
|
||||
|
||||
@@ -185,6 +185,7 @@ export const chat_completion_sources = {
|
||||
XAI: 'xai',
|
||||
POLLINATIONS: 'pollinations',
|
||||
MOONSHOT: 'moonshot',
|
||||
FIREWORKS: 'fireworks',
|
||||
};
|
||||
|
||||
const character_names_behavior = {
|
||||
@@ -458,6 +459,7 @@ const oai_settings = {
|
||||
xai_model: 'grok-3-beta',
|
||||
pollinations_model: 'openai',
|
||||
moonshot_model: 'kimi-latest',
|
||||
fireworks_model: 'accounts/fireworks/models/kimi-k2-instruct',
|
||||
custom_model: '',
|
||||
custom_url: '',
|
||||
custom_include_body: '',
|
||||
@@ -1620,6 +1622,8 @@ export function getChatCompletionModel(source = null) {
|
||||
return oai_settings.pollinations_model;
|
||||
case chat_completion_sources.MOONSHOT:
|
||||
return oai_settings.moonshot_model;
|
||||
case chat_completion_sources.FIREWORKS:
|
||||
return oai_settings.fireworks_model;
|
||||
default:
|
||||
console.error(`Unknown chat completion source: ${activeSource}`);
|
||||
return '';
|
||||
@@ -1872,6 +1876,27 @@ function saveModelList(data) {
|
||||
|
||||
$('#model_groq_select').val(oai_settings.groq_model).trigger('change');
|
||||
}
|
||||
|
||||
if (oai_settings.chat_completion_source === chat_completion_sources.FIREWORKS) {
|
||||
$('#model_fireworks_select').empty();
|
||||
model_list.forEach((model) => {
|
||||
if (!model?.supports_chat) {
|
||||
return;
|
||||
}
|
||||
$('#model_fireworks_select').append(
|
||||
$('<option>', {
|
||||
value: model.id,
|
||||
text: model.id,
|
||||
}));
|
||||
});
|
||||
|
||||
const selectedModel = model_list.find(model => model.id === oai_settings.fireworks_model);
|
||||
if (model_list.length > 0 && (!selectedModel || !oai_settings.fireworks_model)) {
|
||||
oai_settings.fireworks_model = model_list[0].id;
|
||||
}
|
||||
|
||||
$('#model_fireworks_select').val(oai_settings.fireworks_model).trigger('change');
|
||||
}
|
||||
}
|
||||
|
||||
function appendOpenRouterOptions(model_list, groupModels = false, sort = false) {
|
||||
@@ -4487,6 +4512,31 @@ function getMoonshotMaxContext(model, isUnlocked) {
|
||||
return Object.entries(contextMap).find(([key]) => model.includes(key))?.[1] || max_32k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum context size for the Fireworks model
|
||||
* @param {string} model Model identifier
|
||||
* @param {boolean} isUnlocked Whether context limits are unlocked
|
||||
* @returns {number} Maximum context size in tokens
|
||||
*/
|
||||
function getFireworksMaxContext(model, isUnlocked) {
|
||||
if (isUnlocked) {
|
||||
return unlocked_max;
|
||||
}
|
||||
|
||||
// First check if model info is available from model_list
|
||||
if (Array.isArray(model_list) && model_list.length > 0) {
|
||||
const modelInfo = model_list.find((record) => record.id === model);
|
||||
if (modelInfo?.context_length) {
|
||||
return modelInfo.context_length;
|
||||
}
|
||||
if (modelInfo?.context_window) {
|
||||
return modelInfo.context_window;
|
||||
}
|
||||
}
|
||||
|
||||
return max_32k;
|
||||
}
|
||||
|
||||
async function onModelChange() {
|
||||
biasCache = undefined;
|
||||
let value = String($(this).val() || '');
|
||||
@@ -4627,6 +4677,15 @@ async function onModelChange() {
|
||||
oai_settings.moonshot_model = value;
|
||||
}
|
||||
|
||||
if ($(this).is('#model_fireworks_select')) {
|
||||
if (!value) {
|
||||
console.debug('Null Fireworks model selected. Ignoring.');
|
||||
return;
|
||||
}
|
||||
console.log('Fireworks model changed to', value);
|
||||
oai_settings.fireworks_model = value;
|
||||
}
|
||||
|
||||
if ([chat_completion_sources.MAKERSUITE, chat_completion_sources.VERTEXAI].includes(oai_settings.chat_completion_source)) {
|
||||
if (oai_settings.max_context_unlocked) {
|
||||
$('#openai_max_context').attr('max', max_2mil);
|
||||
@@ -4899,6 +4958,15 @@ async function onModelChange() {
|
||||
$('#temp_openai').attr('max', claude_max_temp).val(oai_settings.temp_openai).trigger('input');
|
||||
}
|
||||
|
||||
if (oai_settings.chat_completion_source === chat_completion_sources.FIREWORKS) {
|
||||
const maxContext = getFireworksMaxContext(oai_settings.fireworks_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');
|
||||
}
|
||||
|
||||
$('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max')));
|
||||
|
||||
saveSettingsDebounced();
|
||||
@@ -5143,6 +5211,19 @@ async function onConnectButtonClick(e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.FIREWORKS) {
|
||||
const api_key_fireworks = String($('#api_key_fireworks').val()).trim();
|
||||
|
||||
if (api_key_fireworks.length) {
|
||||
await writeSecret(SECRET_KEYS.FIREWORKS, api_key_fireworks);
|
||||
}
|
||||
|
||||
if (!secret_state[SECRET_KEYS.FIREWORKS]) {
|
||||
console.log('No secret key saved for Fireworks');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
startStatusLoading();
|
||||
saveSettingsDebounced();
|
||||
await getStatusOpen();
|
||||
@@ -5207,6 +5288,9 @@ function toggleChatCompletionForms() {
|
||||
else if (oai_settings.chat_completion_source == chat_completion_sources.MOONSHOT) {
|
||||
$('#model_moonshot_select').trigger('change');
|
||||
}
|
||||
else if (oai_settings.chat_completion_source == chat_completion_sources.FIREWORKS) {
|
||||
$('#model_fireworks_select').trigger('change');
|
||||
}
|
||||
$('[data-source]').each(function () {
|
||||
const validSources = $(this).data('source').split(',');
|
||||
$(this).toggle(validSources.includes(oai_settings.chat_completion_source));
|
||||
@@ -6139,6 +6223,7 @@ export function initOpenAI() {
|
||||
$('#model_xai_select').on('change', onModelChange);
|
||||
$('#model_pollinations_select').on('change', onModelChange);
|
||||
$('#model_moonshot_select').on('change', onModelChange);
|
||||
$('#model_fireworks_select').on('change', onModelChange);
|
||||
$('#settings_preset_openai').on('change', onSettingsPresetChange);
|
||||
$('#new_oai_preset').on('click', onNewPresetClick);
|
||||
$('#delete_oai_preset').on('click', onDeletePresetClick);
|
||||
|
||||
@@ -60,6 +60,7 @@ export const SECRET_KEYS = {
|
||||
AIMLAPI: 'api_key_aimlapi',
|
||||
FALAI: 'api_key_falai',
|
||||
XAI: 'api_key_xai',
|
||||
FIREWORKS: 'api_key_fireworks',
|
||||
VERTEXAI_SERVICE_ACCOUNT: 'vertexai_service_account_json',
|
||||
MINIMAX: 'api_key_minimax',
|
||||
MINIMAX_GROUP_ID: 'minimax_group_id',
|
||||
@@ -107,6 +108,7 @@ const FRIENDLY_NAMES = {
|
||||
[SECRET_KEYS.FALAI]: 'FAL.AI',
|
||||
[SECRET_KEYS.AZURE_TTS]: 'Azure TTS',
|
||||
[SECRET_KEYS.AIMLAPI]: 'AI/ML API',
|
||||
[SECRET_KEYS.FIREWORKS]: 'Fireworks AI',
|
||||
[SECRET_KEYS.DEEPL]: 'DeepL',
|
||||
[SECRET_KEYS.LIBRE]: 'LibreTranslate',
|
||||
[SECRET_KEYS.LIBRE_URL]: 'LibreTranslate Endpoint (e.g. http://127.0.0.1:5000/translate)',
|
||||
@@ -151,6 +153,7 @@ const INPUT_MAP = {
|
||||
[SECRET_KEYS.XAI]: '#api_key_xai',
|
||||
[SECRET_KEYS.VERTEXAI_SERVICE_ACCOUNT]: '#vertexai_service_account_json',
|
||||
[SECRET_KEYS.MOONSHOT]: '#api_key_moonshot',
|
||||
[SECRET_KEYS.FIREWORKS]: '#api_key_fireworks',
|
||||
};
|
||||
|
||||
const getLabel = () => moment().format('L LT');
|
||||
|
||||
@@ -4855,6 +4855,7 @@ function getModelOptions(quiet) {
|
||||
{ id: 'model_xai_select', api: 'openai', type: chat_completion_sources.XAI },
|
||||
{ id: 'model_pollinations_select', api: 'openai', type: chat_completion_sources.POLLINATIONS },
|
||||
{ id: 'model_moonshot_select', api: 'openai', type: chat_completion_sources.MOONSHOT },
|
||||
{ id: 'model_fireworks_select', api: 'openai', type: chat_completion_sources.FIREWORKS },
|
||||
{ id: 'model_novel_select', api: 'novel', type: null },
|
||||
{ id: 'horde_model', api: 'koboldhorde', type: null },
|
||||
];
|
||||
|
||||
@@ -605,6 +605,13 @@ export class ToolManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (oai_settings.chat_completion_source === chat_completion_sources.FIREWORKS && Array.isArray(model_list)) {
|
||||
const currentModel = model_list.find(model => model.id === oai_settings.fireworks_model);
|
||||
if (currentModel) {
|
||||
return currentModel.supports_tools;
|
||||
}
|
||||
}
|
||||
|
||||
const supportedSources = [
|
||||
chat_completion_sources.OPENAI,
|
||||
chat_completion_sources.CUSTOM,
|
||||
@@ -621,6 +628,7 @@ export class ToolManager {
|
||||
chat_completion_sources.XAI,
|
||||
chat_completion_sources.POLLINATIONS,
|
||||
chat_completion_sources.MOONSHOT,
|
||||
chat_completion_sources.FIREWORKS,
|
||||
];
|
||||
return supportedSources.includes(oai_settings.chat_completion_source);
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ export const CHAT_COMPLETION_SOURCES = {
|
||||
XAI: 'xai',
|
||||
POLLINATIONS: 'pollinations',
|
||||
MOONSHOT: 'moonshot',
|
||||
FIREWORKS: 'fireworks',
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,6 +66,7 @@ const API_XAI = 'https://api.x.ai/v1';
|
||||
const API_AIMLAPI = 'https://api.aimlapi.com/v1';
|
||||
const API_POLLINATIONS = 'https://text.pollinations.ai/openai';
|
||||
const API_MOONSHOT = 'https://api.moonshot.ai/v1';
|
||||
const API_FIREWORKS = 'https://api.fireworks.ai/inference/v1';
|
||||
|
||||
/**
|
||||
* Gets OpenRouter transforms based on the request.
|
||||
@@ -1251,6 +1252,10 @@ router.post('/status', async function (request, statusResponse) {
|
||||
apiUrl = API_MOONSHOT;
|
||||
apiKey = readSecret(request.user.directories, SECRET_KEYS.MOONSHOT);
|
||||
headers = {};
|
||||
} else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.FIREWORKS) {
|
||||
apiUrl = API_FIREWORKS;
|
||||
apiKey = readSecret(request.user.directories, SECRET_KEYS.FIREWORKS);
|
||||
headers = {};
|
||||
} else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.MAKERSUITE) {
|
||||
apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);
|
||||
apiUrl = trimTrailingSlash(request.body.reverse_proxy || API_MAKERSUITE);
|
||||
@@ -1609,6 +1614,22 @@ router.post('/generate', function (request, response) {
|
||||
},
|
||||
};
|
||||
}
|
||||
} else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.FIREWORKS) {
|
||||
apiUrl = API_FIREWORKS;
|
||||
apiKey = readSecret(request.user.directories, SECRET_KEYS.FIREWORKS);
|
||||
headers = {};
|
||||
bodyParams = {};
|
||||
if (request.body.json_schema) {
|
||||
bodyParams['response_format'] = {
|
||||
type: 'json_schema',
|
||||
json_schema: {
|
||||
name: request.body.json_schema.name,
|
||||
description: request.body.json_schema.description,
|
||||
schema: request.body.json_schema.value,
|
||||
strict: request.body.json_schema.strict ?? true,
|
||||
},
|
||||
};
|
||||
}
|
||||
} else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.NANOGPT) {
|
||||
apiUrl = API_NANOGPT;
|
||||
apiKey = readSecret(request.user.directories, SECRET_KEYS.NANOGPT);
|
||||
|
||||
@@ -53,6 +53,7 @@ export const SECRET_KEYS = {
|
||||
SERPER: 'api_key_serper',
|
||||
AIMLAPI: 'api_key_aimlapi',
|
||||
XAI: 'api_key_xai',
|
||||
FIREWORKS: 'api_key_fireworks',
|
||||
VERTEXAI_SERVICE_ACCOUNT: 'vertexai_service_account_json',
|
||||
MINIMAX: 'api_key_minimax',
|
||||
MINIMAX_GROUP_ID: 'minimax_group_id',
|
||||
|
||||
Reference in New Issue
Block a user