Add CometAPI as a model provider in "Chat Completion" (#4402) * feat: Add support for CometAPI, including API key management and model selection features. * Some code fixes * Fix loading model from presets * Add logo image * Enable tool calling, reasoning effort, reasoning display, structured generation --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>

41c74fd142eda6d4ed43987dad19c01459ce711d

TensorNull <129579691+TensorNull@users.noreply.github.com>

Signed
12 files changed, +132 -10Showing whitespace changes
public/img/cometapi.svg+1 -0
@@ -0,0 +1 @@
1+<svg version="1.0" width="274.67" height="309.33" viewBox="0 0 206 232" xmlns="http://www.w3.org/2000/svg"><path d="M127.3.98c-7 0-14 .67-19.3 2.02a77.68 77.68 0 0 0-50 40.5C53.2 53 0 200.9 0 204.5c0 1.4.6 2.5 1.3 2.5 1.5 0 10.1-8.7 23.1-23.7 10.1-11.6 14.2-15.1 15.7-13.6 1.4 1.4-.7 7.2-10.1 29.3-9.7 22.6-11.5 27.9-10 29.4 1.8 1.8 4.6-.3 29.1-22.2 15.6-14 21.9-17.9 21.9-13.5 0 .9-2.9 7.8-6.4 15.4-7.5 16-9.4 21.5-7.9 23 2.6 2.6 3.3 2.1 71.9-52.7 27-21.5 51.4-41.5 54.2-44.3 9.8-9.8 17.2-22.8 20.8-36.6 2.6-10.4 2.5-28.6-.4-38.8-8-28.1-28.7-48.5-56.6-55.7-5.3-1.35-12.3-2.02-19.3-2.02zm-.74 14.13c5.77-.1 11.5.48 16.64 1.79a64.64 64.64 0 0 1 46.3 46.2c2.2 8.3 2.3 22.5.1 30.9-4.5 17.9-17.4 34-33.6 41.9-11 5.4-20.9 7.5-32.1 6.8-22.9-1.4-44.1-15.5-53.8-35.9-5-10.6-6.5-17.1-6.4-28.3.1-24.7 13.5-46 36.1-57.4 7.37-3.75 17.13-5.82 26.76-6zm.61 16.05c-4.6.02-9.17.44-12.17 1.24-24.2 6.8-39.6 31.4-34.6 55.3 4 19.5 18.5 34.2 37.4 38.2 36.7 7.6 67.3-28.2 54.7-64-4.9-13.8-18-25.5-33-29.5-3.1-.85-7.73-1.25-12.33-1.24zM132 42.41c3.9.05 7.81.87 11.5 2.49a29 29 0 0 1 17.3 24.9c.5 7.6-1.1 14-4.9 19.2-5.1 7.1-10.8 8.5-19.9 5.1-6.9-2.6-26.9-16.1-29.9-20.1-4.6-6.4-3.7-13.9 2.8-21.3A30.28 30.28 0 0 1 132 42.41z"/></svg>
1 \ No newline at end of file
public/index.html+27 -8
@@ -691,7 +691,7 @@
691691 </span>
692692 </div>
693693 </div>
694694 <div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi">
695695 <div class="range-block-title" data-i18n="Temperature">
696696 Temperature
697697 </div>
@@ -704,7 +704,7 @@
704704 </div>
705705 </div>
706706 </div>
707707 <div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi">
708708 <div class="range-block-title" data-i18n="Frequency Penalty">
709709 Frequency Penalty
710710 </div>
@@ -717,7 +717,7 @@
717717 </div>
718718 </div>
719719 </div>
720720 <div class="range-block" data-source="openai,aimlapi,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi">
721721 <div class="range-block-title" data-i18n="Presence Penalty">
722722 Presence Penalty
723723 </div>
@@ -743,7 +743,7 @@
743743 </div>
744744 </div>
745745 </div>
746746 <div class="range-block" data-source="openai,claude,aimlapi,openrouter,ai21,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,nanogpt,deepseek,xai,pollinations,moonshot,fireworks,cometapi">
747747 <div class="range-block-title" data-i18n="Top P">
748748 Top P
749749 </div>
@@ -1984,7 +1984,7 @@
19841984 </b>
19851985 </div>
19861986 </div>
19871987 <div class="range-block" data-source="openai,cohere,mistralai,custom,claude,aimlapi,openrouter,groq,deepseek,makersuite,vertexai,ai21,xai,pollinations,moonshot,fireworks,cometapi">
19881988 <label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand">
19891989 <input id="openai_function_calling" type="checkbox" />
19901990 <span data-i18n="Enable function calling">Enable function calling</span>
@@ -1999,7 +1999,7 @@
19991999 <strong data-i18n="enable_functions_desc_4">Not supported when Prompt Post-Processing with "no tools" is used!</strong>
20002000 </div>
20012001 </div>
20022002 <div class="range-block" data-source="openai,aimlapi,openrouter,mistralai,makersuite,vertexai,claude,custom,xai,pollinations,moonshot,cohere,cometapi">
20032003 <label for="openai_image_inlining" class="checkbox_label flexWrap widthFreeExpand">
20042004 <input id="openai_image_inlining" type="checkbox" />
20052005 <span data-i18n="Send inline images">Send inline images</span>
@@ -2077,7 +2077,7 @@
20772077 </span>
20782078 </div>
20792079 </div>
20802080 <div class="range-block" data-source="deepseek,aimlapi,openrouter,custom,claude,xai,makersuite,vertexai,pollinations,moonshot,mistralai,fireworks,cometapi">
20812081 <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand">
20822082 <input id="openai_show_thoughts" type="checkbox" />
20832083 <span data-i18n="Request model reasoning">Request model reasoning</span>
@@ -2091,7 +2091,7 @@
20912091 </span>
20922092 </div>
20932093 </div>
20942094 <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai,makersuite,vertexai,aimlapi,openrouter,pollinations,perplexity,cometapi">
20952095 <div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models.&#10;Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models.">
20962096 <label for="openai_reasoning_effort">
20972097 <span data-i18n="Reasoning Effort">Reasoning Effort</span>
@@ -2804,6 +2804,7 @@
28042804 <option value="aimlapi">AI/ML API</option>
28052805 <option value="claude">Claude</option>
28062806 <option value="cohere">Cohere</option>
2807+ <option value="cometapi">CometAPI</option>
28072808 <option value="deepseek">DeepSeek</option>
28082809 <option value="fireworks">Fireworks AI</option>
28092810 <option value="groq">Groq</option>
@@ -3515,6 +3516,24 @@
35153516 </select>
35163517 </div>
35173518 </div>
3519+ <div id="cometapi_form" data-source="cometapi">
3520+ <h4><a href="https://api.cometapi.com/" target="_blank" rel="noopener noreferrer" data-i18n="CometAPI API Key">CometAPI API Key</a></h4>
3521+ <div class="flex-container">
3522+ <input id="api_key_cometapi" name="api_key_cometapi" class="text_pole flex1" value="" type="text" autocomplete="off">
3523+ <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_cometapi"></div>
3524+ </div>
3525+ <div data-for="api_key_cometapi" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you click 'Connect'.">
3526+ For privacy reasons, your API key will be hidden after you click 'Connect'.
3527+ </div>
3528+ <div>
3529+ <h4 data-i18n="CometAPI Model">CometAPI Model</h4>
3530+ <div class="flex-container">
3531+ <select id="model_cometapi_select" class="flex1">
3532+ <option value="" data-i18n="-- Connect to the API --">-- Connect to the API --</option>
3533+ </select>
3534+ </div>
3535+ </div>
3536+ </div>
35183537 <div id="perplexity_form" data-source="perplexity">
35193538 <h4 data-i18n="Perplexity API Key">Perplexity API Key</h4>
35203539 <div class="flex-container">
public/scripts/RossAscends-mods.js+1 -0
@@ -408,6 +408,7 @@ function RA_autoconnect(PrevApi) {
408408 || (secret_state[SECRET_KEYS.AIMLAPI] && oai_settings.chat_completion_source == chat_completion_sources.AIMLAPI)
409409 || (secret_state[SECRET_KEYS.MOONSHOT] && oai_settings.chat_completion_source == chat_completion_sources.MOONSHOT)
410410 || (secret_state[SECRET_KEYS.FIREWORKS] && oai_settings.chat_completion_source == chat_completion_sources.FIREWORKS)
411+ || (secret_state[SECRET_KEYS.COMETAPI] && oai_settings.chat_completion_source == chat_completion_sources.COMETAPI)
411412 || (oai_settings.chat_completion_source === chat_completion_sources.POLLINATIONS)
412413 || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM)
413414 ) {
public/scripts/constants.js+13 -0
@@ -52,3 +52,16 @@ export const inject_ids = {
5252 CUSTOM_WI_DEPTH: 'customDepthWI',
5353 CUSTOM_WI_DEPTH_ROLE: (depth, role) => `customDepthWI_${depth}_${role}`,
5454};
55+
56+export const COMETAPI_IGNORE_PATTERNS = [
57+ // Image generation models
58+ 'dall-e', 'dalle', 'midjourney', 'mj_', 'stable-diffusion', 'sd-',
59+ 'flux-', 'playground-v', 'ideogram', 'recraft-', 'black-forest-labs',
60+ '/recraft-v3', 'recraftv3', 'stability-ai/', 'sdxl',
61+ // Audio generation models
62+ 'suno_', 'tts', 'whisper',
63+ // Video generation models
64+ 'runway', 'luma_', 'luma-', 'veo', 'kling_', 'minimax_video', 'hunyuan-t1',
65+ // Utility models
66+ 'embedding', 'search-gpts', 'files_retrieve', 'moderation',
67+];
public/scripts/openai.js+70 -2
@@ -74,7 +74,7 @@ import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
7474import { t } from './i18n.js';
7575import { ToolManager } from './tool-calling.js';
7676import { accountStorage } from './util/AccountStorage.js';
7777import { COMETAPI_IGNORE_PATTERNS, IGNORE_SYMBOL } from './constants.js';
7878
7979export {
8080 openai_messages_count,
@@ -186,6 +186,7 @@ export const chat_completion_sources = {
186186 POLLINATIONS: 'pollinations',
187187 MOONSHOT: 'moonshot',
188188 FIREWORKS: 'fireworks',
189+ COMETAPI: 'cometapi',
189190};
190191
191192const character_names_behavior = {
@@ -277,6 +278,7 @@ export const settingsToUpdate = {
277278 pollinations_model: ['#model_pollinations_select', 'pollinations_model', false, true],
278279 moonshot_model: ['#model_moonshot_select', 'moonshot_model', false, true],
279280 fireworks_model: ['#model_fireworks_select', 'fireworks_model', false, true],
281+ cometapi_model: ['#model_cometapi_select', 'cometapi_model', false, true],
280282 custom_model: ['#custom_model_id', 'custom_model', false, true],
281283 custom_url: ['#custom_api_url_text', 'custom_url', false, true],
282284 custom_include_body: ['#custom_include_body', 'custom_include_body', false, true],
@@ -372,6 +374,7 @@ const default_settings = {
372374 aimlapi_model: 'gpt-4o-mini-2024-07-18',
373375 xai_model: 'grok-3-beta',
374376 pollinations_model: 'openai',
377+ cometapi_model: 'gpt-4o',
375378 moonshot_model: 'kimi-latest',
376379 fireworks_model: 'accounts/fireworks/models/kimi-k2-instruct',
377380 custom_model: '',
@@ -460,6 +463,7 @@ const oai_settings = {
460463 aimlapi_model: 'gpt-4-turbo',
461464 xai_model: 'grok-3-beta',
462465 pollinations_model: 'openai',
466+ cometapi_model: 'gpt-4o',
463467 moonshot_model: 'kimi-latest',
464468 fireworks_model: 'accounts/fireworks/models/kimi-k2-instruct',
465469 custom_model: '',
@@ -1622,6 +1626,8 @@ export function getChatCompletionModel(source = null) {
16221626 return oai_settings.xai_model;
16231627 case chat_completion_sources.POLLINATIONS:
16241628 return oai_settings.pollinations_model;
1629+ case chat_completion_sources.COMETAPI:
1630+ return oai_settings.cometapi_model;
16251631 case chat_completion_sources.MOONSHOT:
16261632 return oai_settings.moonshot_model;
16271633 case chat_completion_sources.FIREWORKS:
@@ -1899,6 +1905,29 @@ function saveModelList(data) {
18991905
19001906 $('#model_fireworks_select').val(oai_settings.fireworks_model).trigger('change');
19011907 }
1908+
1909+ if (oai_settings.chat_completion_source === chat_completion_sources.COMETAPI) {
1910+ $('#model_cometapi_select').empty();
1911+
1912+ model_list.forEach((model) => {
1913+ const modelId = model.id.toLowerCase();
1914+ const isIgnoredModel = COMETAPI_IGNORE_PATTERNS.some(pattern => modelId.includes(pattern));
1915+
1916+ if (isIgnoredModel) {
1917+ return;
1918+ }
1919+
1920+ $('#model_cometapi_select').append(new Option(model.id, model.id));
1921+ });
1922+
1923+ const selectedModel = model_list.find(model => model.id === oai_settings.cometapi_model);
1924+ if (model_list.length > 0 && (!selectedModel || !oai_settings.cometapi_model)) {
1925+ oai_settings.cometapi_model = model_list[0].id;
1926+ saveSettingsDebounced();
1927+ }
1928+
1929+ $('#model_cometapi_select').val(oai_settings.cometapi_model).trigger('change');
1930+ }
19021931}
19031932
19041933function appendOpenRouterOptions(model_list, groupModels = false, sort = false) {
@@ -2016,6 +2045,7 @@ function getReasoningEffort() {
20162045 chat_completion_sources.OPENROUTER,
20172046 chat_completion_sources.POLLINATIONS,
20182047 chat_completion_sources.PERPLEXITY,
2048+ chat_completion_sources.COMETAPI,
20192049 ];
20202050
20212051 if (!reasoningEffortSources.includes(oai_settings.chat_completion_source)) {
@@ -2439,7 +2469,7 @@ export function getStreamingReply(data, state, { chatCompletionSource = null, ov
24392469 state.reasoning += (data.choices?.filter(x => x?.delta?.reasoning)?.[0]?.delta?.reasoning || '');
24402470 }
24412471 return data.choices?.[0]?.delta?.content ?? data.choices?.[0]?.message?.content ?? data.choices?.[0]?.text ?? '';
24422472 } else if ([chat_completion_sources.CUSTOM, chat_completion_sources.POLLINATIONS, chat_completion_sources.AIMLAPI, chat_completion_sources.MOONSHOT, chat_completion_sources.COMETAPI].includes(chat_completion_source)) {
24432473 if (show_thoughts) {
24442474 state.reasoning +=
24452475 data.choices?.filter(x => x?.delta?.reasoning_content)?.[0]?.delta?.reasoning_content ??
@@ -3406,6 +3436,7 @@ function loadOpenAISettings(data, settings) {
34063436 oai_settings.aimlapi_model = settings.aimlapi_model ?? default_settings.aimlapi_model;
34073437 oai_settings.xai_model = settings.xai_model ?? default_settings.xai_model;
34083438 oai_settings.pollinations_model = settings.pollinations_model ?? default_settings.pollinations_model;
3439+ oai_settings.cometapi_model = settings.cometapi_model ?? default_settings.cometapi_model;
34093440 oai_settings.moonshot_model = settings.moonshot_model ?? default_settings.moonshot_model;
34103441 oai_settings.fireworks_model = settings.fireworks_model ?? default_settings.fireworks_model;
34113442 oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model;
@@ -3783,6 +3814,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
37833814 aimlapi_model: settings.aimlapi_model,
37843815 moonshot_model: settings.moonshot_model,
37853816 fireworks_model: settings.fireworks_model,
3817+ cometapi_model: settings.cometapi_model,
37863818 custom_model: settings.custom_model,
37873819 custom_url: settings.custom_url,
37883820 custom_include_body: settings.custom_include_body,
@@ -4694,6 +4726,15 @@ async function onModelChange() {
46944726 oai_settings.fireworks_model = value;
46954727 }
46964728
4729+ if ($(this).is('#model_cometapi_select')) {
4730+ if (!value) {
4731+ console.debug('Null CometAPI model selected. Ignoring.');
4732+ return;
4733+ }
4734+ console.log('CometAPI model changed to', value);
4735+ oai_settings.cometapi_model = value;
4736+ }
4737+
46974738 if ([chat_completion_sources.MAKERSUITE, chat_completion_sources.VERTEXAI].includes(oai_settings.chat_completion_source)) {
46984739 if (oai_settings.max_context_unlocked) {
46994740 $('#openai_max_context').attr('max', max_2mil);
@@ -4905,6 +4946,13 @@ async function onModelChange() {
49054946 $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
49064947 }
49074948
4949+ if (oai_settings.chat_completion_source === chat_completion_sources.COMETAPI) {
4950+ $('#openai_max_context').attr('max', oai_settings.max_context_unlocked ? unlocked_max : max_128k);
4951+ oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context);
4952+ $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
4953+ $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
4954+ }
4955+
49084956 if (oai_settings.chat_completion_source === chat_completion_sources.XAI) {
49094957 if (oai_settings.max_context_unlocked) {
49104958 $('#openai_max_context').attr('max', unlocked_max);
@@ -5233,6 +5281,19 @@ async function onConnectButtonClick(e) {
52335281 }
52345282 }
52355283
5284+ if (oai_settings.chat_completion_source == chat_completion_sources.COMETAPI) {
5285+ const api_key_cometapi = String($('#api_key_cometapi').val()).trim();
5286+
5287+ if (api_key_cometapi.length) {
5288+ await writeSecret(SECRET_KEYS.COMETAPI, api_key_cometapi);
5289+ }
5290+
5291+ if (!api_key_cometapi && !secret_state[SECRET_KEYS.COMETAPI]) {
5292+ console.log('No secret key saved for CometAPI');
5293+ return;
5294+ }
5295+ }
5296+
52365297 startStatusLoading();
52375298 saveSettingsDebounced();
52385299 await getStatusOpen();
@@ -5300,6 +5361,10 @@ function toggleChatCompletionForms() {
53005361 else if (oai_settings.chat_completion_source == chat_completion_sources.FIREWORKS) {
53015362 $('#model_fireworks_select').trigger('change');
53025363 }
5364+ else if (oai_settings.chat_completion_source == chat_completion_sources.COMETAPI) {
5365+ $('#model_cometapi_select').trigger('change');
5366+ }
5367+
53035368 $('[data-source]').each(function () {
53045369 const validSources = $(this).data('source').split(',');
53055370 $(this).toggle(validSources.includes(oai_settings.chat_completion_source));
@@ -5442,6 +5507,8 @@ export function isImageInliningSupported() {
54425507 return (Array.isArray(model_list) && model_list.find(m => m.id === oai_settings.aimlapi_model)?.features?.includes('openai/chat-completion.vision'));
54435508 case chat_completion_sources.POLLINATIONS:
54445509 return (Array.isArray(model_list) && model_list.find(m => m.id === oai_settings.pollinations_model)?.vision);
5510+ case chat_completion_sources.COMETAPI:
5511+ return true;
54455512 case chat_completion_sources.MOONSHOT:
54465513 return visionSupportedModels.some(model => oai_settings.moonshot_model.includes(model));
54475514 default:
@@ -6250,6 +6317,7 @@ export function initOpenAI() {
62506317 $('#model_custom_select').on('change', onModelChange);
62516318 $('#model_xai_select').on('change', onModelChange);
62526319 $('#model_pollinations_select').on('change', onModelChange);
6320+ $('#model_cometapi_select').on('change', onModelChange);
62536321 $('#model_moonshot_select').on('change', onModelChange);
62546322 $('#model_fireworks_select').on('change', onModelChange);
62556323 $('#settings_preset_openai').on('change', onSettingsPresetChange);
public/scripts/reasoning.js+1 -0
@@ -123,6 +123,7 @@ export function extractReasoningFromData(data, {
123123 case chat_completion_sources.AIMLAPI:
124124 case chat_completion_sources.POLLINATIONS:
125125 case chat_completion_sources.MOONSHOT:
126+ case chat_completion_sources.COMETAPI:
126127 case chat_completion_sources.CUSTOM: {
127128 return data?.choices?.[0]?.message?.reasoning_content
128129 ?? data?.choices?.[0]?.message?.reasoning
public/scripts/secrets.js+3 -0
@@ -65,6 +65,7 @@ export const SECRET_KEYS = {
6565 MINIMAX: 'api_key_minimax',
6666 MINIMAX_GROUP_ID: 'minimax_group_id',
6767 MOONSHOT: 'api_key_moonshot',
68+ COMETAPI: 'api_key_cometapi',
6869};
6970
7071const FRIENDLY_NAMES = {
@@ -118,6 +119,7 @@ const FRIENDLY_NAMES = {
118119 [SECRET_KEYS.MINIMAX]: 'MiniMax TTS',
119120 [SECRET_KEYS.MINIMAX_GROUP_ID]: 'MiniMax Group ID',
120121 [SECRET_KEYS.MOONSHOT]: 'Moonshot AI',
122+ [SECRET_KEYS.COMETAPI]: 'CometAPI',
121123};
122124
123125const INPUT_MAP = {
@@ -154,6 +156,7 @@ const INPUT_MAP = {
154156 [SECRET_KEYS.VERTEXAI_SERVICE_ACCOUNT]: '#vertexai_service_account_json',
155157 [SECRET_KEYS.MOONSHOT]: '#api_key_moonshot',
156158 [SECRET_KEYS.FIREWORKS]: '#api_key_fireworks',
159+ [SECRET_KEYS.COMETAPI]: '#api_key_cometapi',
157160};
158161
159162const getLabel = () => moment().format('L LT');
public/scripts/slash-commands.js+1 -0
@@ -4857,6 +4857,7 @@ function getModelOptions(quiet) {
48574857 { id: 'model_pollinations_select', api: 'openai', type: chat_completion_sources.POLLINATIONS },
48584858 { id: 'model_moonshot_select', api: 'openai', type: chat_completion_sources.MOONSHOT },
48594859 { id: 'model_fireworks_select', api: 'openai', type: chat_completion_sources.FIREWORKS },
4860+ { id: 'model_cometapi_select', api: 'openai', type: chat_completion_sources.COMETAPI },
48604861 { id: 'model_novel_select', api: 'novel', type: null },
48614862 { id: 'horde_model', api: 'koboldhorde', type: null },
48624863 ];
public/scripts/tool-calling.js+1 -0
@@ -650,6 +650,7 @@ export class ToolManager {
650650 chat_completion_sources.POLLINATIONS,
651651 chat_completion_sources.MOONSHOT,
652652 chat_completion_sources.FIREWORKS,
653+ chat_completion_sources.COMETAPI,
653654 ];
654655 return supportedSources.includes(oai_settings.chat_completion_source);
655656 }
src/constants.js+1 -0
@@ -180,6 +180,7 @@ export const CHAT_COMPLETION_SOURCES = {
180180 POLLINATIONS: 'pollinations',
181181 MOONSHOT: 'moonshot',
182182 FIREWORKS: 'fireworks',
183+ COMETAPI: 'cometapi',
183184};
184185
185186/**
src/endpoints/backends/chat-completions.js+12 -0
@@ -67,6 +67,7 @@ const API_AIMLAPI = 'https://api.aimlapi.com/v1';
6767const API_POLLINATIONS = 'https://text.pollinations.ai/openai';
6868const API_MOONSHOT = 'https://api.moonshot.ai/v1';
6969const API_FIREWORKS = 'https://api.fireworks.ai/inference/v1';
70+const API_COMETAPI = 'https://api.cometapi.com/v1';
7071
7172/**
7273 * Gets OpenRouter transforms based on the request.
@@ -1248,6 +1249,10 @@ router.post('/status', async function (request, statusResponse) {
12481249 apiUrl = API_GROQ;
12491250 apiKey = readSecret(request.user.directories, SECRET_KEYS.GROQ);
12501251 headers = {};
1252+ } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.COMETAPI) {
1253+ apiUrl = API_COMETAPI;
1254+ apiKey = readSecret(request.user.directories, SECRET_KEYS.COMETAPI);
1255+ headers = {};
12511256 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.MOONSHOT) {
12521257 apiUrl = API_MOONSHOT;
12531258 apiKey = readSecret(request.user.directories, SECRET_KEYS.MOONSHOT);
@@ -1661,6 +1666,13 @@ router.post('/generate', function (request, response) {
16611666 request.body.json_schema
16621667 ? setJsonObjectFormat(bodyParams, request.body.messages, request.body.json_schema)
16631668 : addAssistantPrefix(request.body.messages, [], 'partial');
1669+ } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.COMETAPI) {
1670+ apiUrl = API_COMETAPI;
1671+ apiKey = readSecret(request.user.directories, SECRET_KEYS.COMETAPI);
1672+ headers = {};
1673+ bodyParams = {
1674+ reasoning_effort: request.body.reasoning_effort,
1675+ };
16641676 } else {
16651677 console.warn('This chat completion source is not supported yet.');
16661678 return response.status(400).send({ error: true });
src/endpoints/secrets.js+1 -0
@@ -58,6 +58,7 @@ export const SECRET_KEYS = {
5858 MINIMAX: 'api_key_minimax',
5959 MINIMAX_GROUP_ID: 'minimax_group_id',
6060 MOONSHOT: 'api_key_moonshot',
61+ COMETAPI: 'api_key_cometapi',
6162};
6263
6364/**