diff --git a/src/models/ai21.js b/src/models/ai21.js new file mode 100644 index 000000000..7097cc3c8 --- /dev/null +++ b/src/models/ai21.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class AI21 { + static prefix = 'ai21'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.ai21.com/studio/v1"; + + config.apiKey = getKey('AI21_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "jamba-1.5-large", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by AI21.'); + } +} \ No newline at end of file diff --git a/src/models/anyscale.js b/src/models/anyscale.js new file mode 100644 index 000000000..5de63b9f1 --- /dev/null +++ b/src/models/anyscale.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class Anyscale { + static prefix = 'anyscale'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.endpoints.anyscale.com/v1"; + + config.apiKey = getKey('ANYSCALE_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "meta-llama/Meta-Llama-3-70B-Instruct", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by Anyscale.'); + } +} \ No newline at end of file diff --git a/src/models/cohere.js b/src/models/cohere.js new file mode 100644 index 000000000..a77089e90 --- /dev/null +++ b/src/models/cohere.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class Cohere { + static prefix = 'cohere'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.cohere.com/v1"; + + config.apiKey = getKey('COHERE_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "command-r-plus", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by Cohere.'); + } +} \ No newline at end of file diff --git a/src/models/deepinfra.js b/src/models/deepinfra.js new file mode 100644 index 000000000..e1d6858a4 --- /dev/null +++ b/src/models/deepinfra.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class DeepInfra { + static prefix = 'deepinfra'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.deepinfra.com/v1/openai"; + + config.apiKey = getKey('DEEPINFRA_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "meta-llama/Meta-Llama-3-70B-Instruct", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by DeepInfra.'); + } +} \ No newline at end of file diff --git a/src/models/fireworks.js b/src/models/fireworks.js new file mode 100644 index 000000000..4367e286e --- /dev/null +++ b/src/models/fireworks.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class Fireworks { + static prefix = 'fireworks'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.fireworks.ai/inference/v1"; + + config.apiKey = getKey('FIREWORKS_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "accounts/fireworks/models/llama-v3p1-70b-instruct", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by Fireworks.'); + } +} \ No newline at end of file diff --git a/src/models/nvidia.js b/src/models/nvidia.js new file mode 100644 index 000000000..1f1785173 --- /dev/null +++ b/src/models/nvidia.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class Nvidia { + static prefix = 'nvidia'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://integrate.api.nvidia.com/v1"; + + config.apiKey = getKey('NVIDIA_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "meta/llama3-70b-instruct", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by Nvidia.'); + } +} \ No newline at end of file diff --git a/src/models/perplexity.js b/src/models/perplexity.js new file mode 100644 index 000000000..11beb89c3 --- /dev/null +++ b/src/models/perplexity.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class Perplexity { + static prefix = 'perplexity'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.perplexity.ai"; + + config.apiKey = getKey('PERPLEXITY_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "llama-3-sonar-large-32k-online", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by Perplexity.'); + } +} \ No newline at end of file diff --git a/src/models/together.js b/src/models/together.js new file mode 100644 index 000000000..ec3e37cc2 --- /dev/null +++ b/src/models/together.js @@ -0,0 +1,70 @@ +import OpenAIApi from 'openai'; +import { getKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class Together { + static prefix = 'together'; + constructor(model_name, url, params) { + this.model_name = model_name; + this.url = url; + this.params = params; + + let config = {}; + if (url) + config.baseURL = url; + else + config.baseURL = "https://api.together.xyz/v1"; + + config.apiKey = getKey('TOGETHER_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage) { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "meta-llama/Llama-3-70b-chat-hf", + messages, + ...(this.params || {}) + }; + + let res = null; + try { + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + return await this.sendRequest(turns.slice(1), systemMessage); + } else { + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async sendVisionRequest(messages, systemMessage, imageBuffer) { + const imageMessages = [...messages]; + imageMessages.push({ + role: "user", + content: [ + { type: "text", text: systemMessage }, + { + type: "image_url", + image_url: { + url: `data:image/jpeg;base64,${imageBuffer.toString('base64')}` + } + } + ] + }); + return this.sendRequest(imageMessages, systemMessage); + } + + async embed(text) { + throw new Error('Embeddings are not supported by Together.'); + } +} \ No newline at end of file