Merge branch 'staging' into gork-ai
| @@ -1975,7 +1975,7 @@ | |||
| 1975 | <span data-i18n="enable_functions_desc_3">Can be utilized by various extensions to provide additional functionality.</span> | 1975 | <span data-i18n="enable_functions_desc_3">Can be utilized by various extensions to provide additional functionality.</span> |
| 1976 | </div> | 1976 | </div> |
| 1977 | </div> | 1977 | </div> |
| 1978 | <div class="range-block" data-source="openai,openrouter,makersuite,claude,custom,01ai,xai"> | 1978 | <div class="range-block" data-source="openai,openrouter,mistralai,makersuite,claude,custom,01ai,xai"> |
| 1979 | <label for="openai_image_inlining" class="checkbox_label flexWrap widthFreeExpand"> | 1979 | <label for="openai_image_inlining" class="checkbox_label flexWrap widthFreeExpand"> |
| 1980 | <input id="openai_image_inlining" type="checkbox" /> | 1980 | <input id="openai_image_inlining" type="checkbox" /> |
| 1981 | <span data-i18n="Send inline images">Send inline images</span> | 1981 | <span data-i18n="Send inline images">Send inline images</span> |
| @@ -43,10 +43,12 @@ import EventSourceStream from './sse-stream.js'; | |||
| 43 | * @property {boolean?} [stream=false] - Whether to stream the response | 43 | * @property {boolean?} [stream=false] - Whether to stream the response |
| 44 | * @property {ChatCompletionMessage[]} messages - Array of chat messages | 44 | * @property {ChatCompletionMessage[]} messages - Array of chat messages |
| 45 | * @property {string} [model] - Optional model name to use for completion | 45 | * @property {string} [model] - Optional model name to use for completion |
| 46 | * @property {string} chat_completion_source - Source provider for chat completion | 46 | * @property {string} chat_completion_source - Source provider |
| 47 | * @property {number} max_tokens - Maximum number of tokens to generate | 47 | * @property {number} max_tokens - Maximum number of tokens to generate |
| 48 | * @property {number} [temperature] - Optional temperature parameter for response randomness | 48 | * @property {number} [temperature] - Optional temperature parameter for response randomness |
| 49 | * @property {string} [custom_url] - Optional custom URL for chat completion | 49 | * @property {string} [custom_url] - Optional custom URL |
| 50 | * @property {string} [reverse_proxy] - Optional reverse proxy URL | ||
| 51 | * @property {string} [proxy_password] - Optional proxy password | ||
| 50 | */ | 52 | */ |
| 51 | 53 | ||
| 52 | /** @typedef {Record<string, any> & ChatCompletionPayloadBase} ChatCompletionPayload */ | 54 | /** @typedef {Record<string, any> & ChatCompletionPayloadBase} ChatCompletionPayload */ |
| @@ -80,7 +82,6 @@ export class TextCompletionService { | |||
| 80 | */ | 82 | */ |
| 81 | static createRequestData({ stream = false, prompt, max_tokens, model, api_type, api_server, temperature, min_p, ...props }) { | 83 | static createRequestData({ stream = false, prompt, max_tokens, model, api_type, api_server, temperature, min_p, ...props }) { |
| 82 | const payload = { | 84 | const payload = { |
| 83 | ...props, | ||
| 84 | stream, | 85 | stream, |
| 85 | prompt, | 86 | prompt, |
| 86 | max_tokens, | 87 | max_tokens, |
| @@ -90,6 +91,7 @@ export class TextCompletionService { | |||
| 90 | api_server: api_server ?? getTextGenServer(api_type), | 91 | api_server: api_server ?? getTextGenServer(api_type), |
| 91 | temperature, | 92 | temperature, |
| 92 | min_p, | 93 | min_p, |
| 94 | ...props, | ||
| 93 | }; | 95 | }; |
| 94 | 96 | ||
| 95 | // Remove undefined values to avoid API errors | 97 | // Remove undefined values to avoid API errors |
| @@ -387,9 +389,8 @@ export class ChatCompletionService { | |||
| 387 | * @param {ChatCompletionPayload} custom | 389 | * @param {ChatCompletionPayload} custom |
| 388 | * @returns {ChatCompletionPayload} | 390 | * @returns {ChatCompletionPayload} |
| 389 | */ | 391 | */ |
| 390 | static createRequestData({ stream = false, messages, model, chat_completion_source, max_tokens, temperature, custom_url, ...props }) { | 392 | static createRequestData({ stream = false, messages, model, chat_completion_source, max_tokens, temperature, custom_url, reverse_proxy, proxy_password, ...props }) { |
| 391 | const payload = { | 393 | const payload = { |
| 392 | ...props, | ||
| 393 | stream, | 394 | stream, |
| 394 | messages, | 395 | messages, |
| 395 | model, | 396 | model, |
| @@ -397,6 +398,11 @@ export class ChatCompletionService { | |||
| 397 | max_tokens, | 398 | max_tokens, |
| 398 | temperature, | 399 | temperature, |
| 399 | custom_url, | 400 | custom_url, |
| 401 | reverse_proxy, | ||
| 402 | proxy_password, | ||
| 403 | use_makersuite_sysprompt: true, | ||
| 404 | claude_use_sysprompt: true, | ||
| 405 | ...props, | ||
| 400 | }; | 406 | }; |
| 401 | 407 | ||
| 402 | // Remove undefined values to avoid API errors | 408 | // Remove undefined values to avoid API errors |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { CONNECT_API_MAP, getRequestHeaders } from '../../script.js'; | 1 | import { CONNECT_API_MAP, getRequestHeaders } from '../../script.js'; |
| 2 | import { extension_settings, openThirdPartyExtensionMenu } from '../extensions.js'; | 2 | import { extension_settings, openThirdPartyExtensionMenu } from '../extensions.js'; |
| 3 | import { t } from '../i18n.js'; | 3 | import { t } from '../i18n.js'; |
| 4 | import { oai_settings } from '../openai.js'; | 4 | import { oai_settings, proxies } from '../openai.js'; |
| 5 | import { SECRET_KEYS, secret_state } from '../secrets.js'; | 5 | import { SECRET_KEYS, secret_state } from '../secrets.js'; |
| 6 | import { textgen_types, textgenerationwebui_settings } from '../textgen-settings.js'; | 6 | import { textgen_types, textgenerationwebui_settings } from '../textgen-settings.js'; |
| 7 | import { getTokenCountAsync } from '../tokenizers.js'; | 7 | import { getTokenCountAsync } from '../tokenizers.js'; |
| @@ -310,9 +310,10 @@ export class ConnectionManagerRequestService { | |||
| 310 | * @param {boolean?} [custom.includePreset=true] | 310 | * @param {boolean?} [custom.includePreset=true] |
| 311 | * @param {boolean?} [custom.includeInstruct=true] | 311 | * @param {boolean?} [custom.includeInstruct=true] |
| 312 | * @param {Partial<InstructSettings>?} [custom.instructSettings] Override instruct settings | 312 | * @param {Partial<InstructSettings>?} [custom.instructSettings] Override instruct settings |
| 313 | * @param {Record<string, any>} [overridePayload] - Override payload for the request | ||
| 313 | * @returns {Promise<import('../custom-request.js').ExtractedData | (() => AsyncGenerator<import('../custom-request.js').StreamResponse>)>} If not streaming, returns extracted data; if streaming, returns a function that creates an AsyncGenerator | 314 | * @returns {Promise<import('../custom-request.js').ExtractedData | (() => AsyncGenerator<import('../custom-request.js').StreamResponse>)>} If not streaming, returns extracted data; if streaming, returns a function that creates an AsyncGenerator |
| 314 | */ | 315 | */ |
| 315 | static async sendRequest(profileId, prompt, maxTokens, custom = this.defaultSendRequestParams) { | 316 | static async sendRequest(profileId, prompt, maxTokens, custom = this.defaultSendRequestParams, overridePayload = {}) { |
| 316 | const { stream, signal, extractData, includePreset, includeInstruct, instructSettings } = { ...this.defaultSendRequestParams, ...custom }; | 317 | const { stream, signal, extractData, includePreset, includeInstruct, instructSettings } = { ...this.defaultSendRequestParams, ...custom }; |
| 317 | 318 | ||
| 318 | const context = SillyTavern.getContext(); | 319 | const context = SillyTavern.getContext(); |
| @@ -330,6 +331,8 @@ export class ConnectionManagerRequestService { | |||
| 330 | throw new Error(`API type ${selectedApiMap.selected} does not support chat completions`); | 331 | throw new Error(`API type ${selectedApiMap.selected} does not support chat completions`); |
| 331 | } | 332 | } |
| 332 | 333 | ||
| 334 | const proxyPreset = proxies.find((p) => p.name === profile.proxy); | ||
| 335 | |||
| 333 | const messages = Array.isArray(prompt) ? prompt : [{ role: 'user', content: prompt }]; | 336 | const messages = Array.isArray(prompt) ? prompt : [{ role: 'user', content: prompt }]; |
| 334 | return await context.ChatCompletionService.processRequest({ | 337 | return await context.ChatCompletionService.processRequest({ |
| 335 | stream, | 338 | stream, |
| @@ -338,6 +341,9 @@ export class ConnectionManagerRequestService { | |||
| 338 | model: profile.model, | 341 | model: profile.model, |
| 339 | chat_completion_source: selectedApiMap.source, | 342 | chat_completion_source: selectedApiMap.source, |
| 340 | custom_url: profile['api-url'], | 343 | custom_url: profile['api-url'], |
| 344 | reverse_proxy: proxyPreset?.url, | ||
| 345 | proxy_password: proxyPreset?.password, | ||
| 346 | ...overridePayload, | ||
| 341 | }, { | 347 | }, { |
| 342 | presetName: includePreset ? profile.preset : undefined, | 348 | presetName: includePreset ? profile.preset : undefined, |
| 343 | }, extractData, signal); | 349 | }, extractData, signal); |
| @@ -354,6 +360,7 @@ export class ConnectionManagerRequestService { | |||
| 354 | model: profile.model, | 360 | model: profile.model, |
| 355 | api_type: selectedApiMap.type, | 361 | api_type: selectedApiMap.type, |
| 356 | api_server: profile['api-url'], | 362 | api_server: profile['api-url'], |
| 363 | ...overridePayload, | ||
| 357 | }, { | 364 | }, { |
| 358 | instructName: includeInstruct ? profile.instruct : undefined, | 365 | instructName: includeInstruct ? profile.instruct : undefined, |
| 359 | presetName: includePreset ? profile.preset : undefined, | 366 | presetName: includePreset ? profile.preset : undefined, |
| @@ -4193,6 +4193,80 @@ function getMaxContextWindowAI(value) { | |||
| 4193 | } | 4193 | } |
| 4194 | 4194 | ||
| 4195 | /** | 4195 | /** |
| 4196 | * Get the maximum context size for the Mistral model | ||
| 4197 | * @param {string} model Model identifier | ||
| 4198 | * @param {boolean} isUnlocked Whether context limits are unlocked | ||
| 4199 | * @returns {number} Maximum context size in tokens | ||
| 4200 | */ | ||
| 4201 | function getMistralMaxContext(model, isUnlocked) { | ||
| 4202 | if (isUnlocked) { | ||
| 4203 | return unlocked_max; | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | if (Array.isArray(model_list) && model_list.length > 0) { | ||
| 4207 | const contextLength = model_list.find((record) => record.id === model)?.max_context_length; | ||
| 4208 | if (contextLength) { | ||
| 4209 | return contextLength; | ||
| 4210 | } | ||
| 4211 | } | ||
| 4212 | |||
| 4213 | const contextMap = { | ||
| 4214 | 'codestral-2411-rc5': 262144, | ||
| 4215 | 'codestral-2412': 262144, | ||
| 4216 | 'codestral-2501': 262144, | ||
| 4217 | 'codestral-latest': 262144, | ||
| 4218 | 'codestral-mamba-2407': 262144, | ||
| 4219 | 'codestral-mamba-latest': 262144, | ||
| 4220 | 'open-codestral-mamba': 262144, | ||
| 4221 | 'ministral-3b-2410': 131072, | ||
| 4222 | 'ministral-3b-latest': 131072, | ||
| 4223 | 'ministral-8b-2410': 131072, | ||
| 4224 | 'ministral-8b-latest': 131072, | ||
| 4225 | 'mistral-large-2407': 131072, | ||
| 4226 | 'mistral-large-2411': 131072, | ||
| 4227 | 'mistral-large-latest': 131072, | ||
| 4228 | 'mistral-large-pixtral-2411': 131072, | ||
| 4229 | 'mistral-tiny-2407': 131072, | ||
| 4230 | 'mistral-tiny-latest': 131072, | ||
| 4231 | 'open-mistral-nemo': 131072, | ||
| 4232 | 'open-mistral-nemo-2407': 131072, | ||
| 4233 | 'pixtral-12b': 131072, | ||
| 4234 | 'pixtral-12b-2409': 131072, | ||
| 4235 | 'pixtral-12b-latest': 131072, | ||
| 4236 | 'pixtral-large-2411': 131072, | ||
| 4237 | 'pixtral-large-latest': 131072, | ||
| 4238 | 'open-mixtral-8x22b': 65536, | ||
| 4239 | 'open-mixtral-8x22b-2404': 65536, | ||
| 4240 | 'codestral-2405': 32768, | ||
| 4241 | 'mistral-embed': 32768, | ||
| 4242 | 'mistral-large-2402': 32768, | ||
| 4243 | 'mistral-medium': 32768, | ||
| 4244 | 'mistral-medium-2312': 32768, | ||
| 4245 | 'mistral-medium-latest': 32768, | ||
| 4246 | 'mistral-moderation-2411': 32768, | ||
| 4247 | 'mistral-moderation-latest': 32768, | ||
| 4248 | 'mistral-ocr-2503': 32768, | ||
| 4249 | 'mistral-ocr-latest': 32768, | ||
| 4250 | 'mistral-saba-2502': 32768, | ||
| 4251 | 'mistral-saba-latest': 32768, | ||
| 4252 | 'mistral-small': 32768, | ||
| 4253 | 'mistral-small-2312': 32768, | ||
| 4254 | 'mistral-small-2402': 32768, | ||
| 4255 | 'mistral-small-2409': 32768, | ||
| 4256 | 'mistral-small-2501': 32768, | ||
| 4257 | 'mistral-small-2503': 32768, | ||
| 4258 | 'mistral-small-latest': 32768, | ||
| 4259 | 'mistral-tiny': 32768, | ||
| 4260 | 'mistral-tiny-2312': 32768, | ||
| 4261 | 'open-mistral-7b': 32768, | ||
| 4262 | 'open-mixtral-8x7b': 32768, | ||
| 4263 | }; | ||
| 4264 | |||
| 4265 | // Return context size if model found, otherwise default to 32k | ||
| 4266 | return Object.entries(contextMap).find(([key]) => model.includes(key))?.[1] || 32768; | ||
| 4267 | } | ||
| 4268 | |||
| 4269 | /** | ||
| 4196 | * Get the maximum context size for the Groq model | 4270 | * Get the maximum context size for the Groq model |
| 4197 | * @param {string} model Model identifier | 4271 | * @param {string} model Model identifier |
| 4198 | * @param {boolean} isUnlocked Whether context limits are unlocked | 4272 | * @param {boolean} isUnlocked Whether context limits are unlocked |
| @@ -4460,27 +4534,10 @@ async function onModelChange() { | |||
| 4460 | } | 4534 | } |
| 4461 | 4535 | ||
| 4462 | if (oai_settings.chat_completion_source === chat_completion_sources.MISTRALAI) { | 4536 | if (oai_settings.chat_completion_source === chat_completion_sources.MISTRALAI) { |
| 4463 | if (oai_settings.max_context_unlocked) { | 4537 | const maxContext = getMistralMaxContext(oai_settings.mistralai_model, oai_settings.max_context_unlocked); |
| 4464 | $('#openai_max_context').attr('max', unlocked_max); | 4538 | $('#openai_max_context').attr('max', maxContext); |
| 4465 | } else if (['codestral-latest', 'codestral-mamba-2407', 'codestral-2411-rc5', 'codestral-2412', 'codestral-2501'].includes(oai_settings.mistralai_model)) { | ||
| 4466 | $('#openai_max_context').attr('max', max_256k); | ||
| 4467 | } else if (['mistral-large-2407', 'mistral-large-2411', 'mistral-large-pixtral-2411', 'mistral-large-latest'].includes(oai_settings.mistralai_model)) { | ||
| 4468 | $('#openai_max_context').attr('max', max_128k); | ||
| 4469 | } else if (oai_settings.mistralai_model.includes('mistral-nemo')) { | ||
| 4470 | $('#openai_max_context').attr('max', max_128k); | ||
| 4471 | } else if (oai_settings.mistralai_model.includes('mixtral-8x22b')) { | ||
| 4472 | $('#openai_max_context').attr('max', max_64k); | ||
| 4473 | } else if (oai_settings.mistralai_model.includes('pixtral')) { | ||
| 4474 | $('#openai_max_context').attr('max', max_128k); | ||
| 4475 | } else if (oai_settings.mistralai_model.includes('ministral')) { | ||
| 4476 | $('#openai_max_context').attr('max', max_32k); | ||
| 4477 | } else { | ||
| 4478 | $('#openai_max_context').attr('max', max_32k); | ||
| 4479 | } | ||
| 4480 | oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max'))); | 4539 | oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max'))); |
| 4481 | $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); | 4540 | $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); |
| 4482 | |||
| 4483 | //mistral also caps temp at 1.0 | ||
| 4484 | oai_settings.temp_openai = Math.min(claude_max_temp, oai_settings.temp_openai); | 4541 | oai_settings.temp_openai = Math.min(claude_max_temp, oai_settings.temp_openai); |
| 4485 | $('#temp_openai').attr('max', claude_max_temp).val(oai_settings.temp_openai).trigger('input'); | 4542 | $('#temp_openai').attr('max', claude_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4486 | } | 4543 | } |
| @@ -5070,7 +5127,9 @@ export function isImageInliningSupported() { | |||
| 5070 | 'o1-2024-12-17', | 5127 | 'o1-2024-12-17', |
| 5071 | 'chatgpt-4o-latest', | 5128 | 'chatgpt-4o-latest', |
| 5072 | 'yi-vision', | 5129 | 'yi-vision', |
| 5073 | 'pixtral-latest', | 5130 | 'mistral-large-pixtral-2411', |
| 5131 | 'mistral-small-2503', | ||
| 5132 | 'mistral-small-latest', | ||
| 5074 | 'pixtral-12b-latest', | 5133 | 'pixtral-12b-latest', |
| 5075 | 'pixtral-12b', | 5134 | 'pixtral-12b', |
| 5076 | 'pixtral-12b-2409', | 5135 | 'pixtral-12b-2409', |
| @@ -58,6 +58,8 @@ const OPENROUTER_PROVIDERS = [ | |||
| 58 | 'Minimax', | 58 | 'Minimax', |
| 59 | 'Nineteen', | 59 | 'Nineteen', |
| 60 | 'Liquid', | 60 | 'Liquid', |
| 61 | 'Stealth', | ||
| 62 | 'NCompass', | ||
| 61 | 'InferenceNet', | 63 | 'InferenceNet', |
| 62 | 'Friendli', | 64 | 'Friendli', |
| 63 | 'AionLabs', | 65 | 'AionLabs', |
| @@ -69,6 +71,9 @@ const OPENROUTER_PROVIDERS = [ | |||
| 69 | 'Targon', | 71 | 'Targon', |
| 70 | 'Ubicloud', | 72 | 'Ubicloud', |
| 71 | 'Parasail', | 73 | 'Parasail', |
| 74 | 'Phala', | ||
| 75 | 'Cent-ML', | ||
| 76 | 'Venice', | ||
| 72 | '01.AI', | 77 | '01.AI', |
| 73 | 'HuggingFace', | 78 | 'HuggingFace', |
| 74 | 'Mancer', | 79 | 'Mancer', |
| @@ -1166,7 +1166,8 @@ falai.post('/models', async (_request, response) => { | |||
| 1166 | const models = data | 1166 | const models = data |
| 1167 | .filter(x => !x.title.toLowerCase().includes('inpainting') && | 1167 | .filter(x => !x.title.toLowerCase().includes('inpainting') && |
| 1168 | !x.title.toLowerCase().includes('control') && | 1168 | !x.title.toLowerCase().includes('control') && |
| 1169 | !x.title.toLowerCase().includes('upscale')) | 1169 | !x.title.toLowerCase().includes('upscale') && |
| 1170 | !x.title.toLowerCase().includes('lora')) | ||
| 1170 | .sort((a, b) => a.title.localeCompare(b.title)) | 1171 | .sort((a, b) => a.title.localeCompare(b.title)) |
| 1171 | .map(x => ({ value: x.modelUrl.split('fal-ai/')[1], text: x.title })); | 1172 | .map(x => ({ value: x.modelUrl.split('fal-ai/')[1], text: x.title })); |
| 1172 | return response.send(models); | 1173 | return response.send(models); |