diff --git a/sdkjs-plugins/content/ai/aiModelEdit.html b/sdkjs-plugins/content/ai/aiModelEdit.html index dc5e7941..bc2fe764 100644 --- a/sdkjs-plugins/content/ai/aiModelEdit.html +++ b/sdkjs-plugins/content/ai/aiModelEdit.html @@ -22,10 +22,9 @@ + - - - + diff --git a/sdkjs-plugins/content/ai/aiModelsList.html b/sdkjs-plugins/content/ai/aiModelsList.html index c108c339..654c9cc9 100644 --- a/sdkjs-plugins/content/ai/aiModelsList.html +++ b/sdkjs-plugins/content/ai/aiModelsList.html @@ -22,8 +22,7 @@ - - + diff --git a/sdkjs-plugins/content/ai/scripts/engine/engine.js b/sdkjs-plugins/content/ai/scripts/engine/engine.js index 18c10210..4bf8d73e 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/engine.js +++ b/sdkjs-plugins/content/ai/scripts/engine/engine.js @@ -114,7 +114,7 @@ AI._getHeaders = function(_provider) { let provider = _provider.createInstance ? _provider : AI.Storage.getProvider(_provider.name); if (!provider) provider = new AI.Provider(); - return provider.getRequestHeaderOptions(_provider.key); + return provider.getRequestHeaderOptions(); }; AI._extendBody = function(_provider, body) { @@ -133,10 +133,13 @@ return provider.isUseProxy(); }; - AI._getEndpointUrl = function(_provider, endpoint) { + AI._getEndpointUrl = function(_provider, endpoint, model) { let provider = _provider.createInstance ? _provider : AI.Storage.getProvider(_provider.name); if (!provider) provider = new AI.Provider(_provider.name, _provider.url, _provider.key); + if (_provider.key && !provider.key) + provider.key = _provider.key; + let url = provider.url; if (url.endsWith("/")) url = url.substring(0, url.length - 1); @@ -148,10 +151,7 @@ url += plus; } - let override = provider.overrideEndpointUrl(endpoint); - if (undefined !== override) - return override; - return url + AI.Endpoints.getUrl(endpoint); + return url + provider.getEndpointUrl(endpoint, model); }; AI.getModels = async function(provider) @@ -171,16 +171,20 @@ models : [] }); else { - AI.TmpProviderForModels = AI.Provider.createInstance(provider.name, provider.url, provider.key); - for (let i = 0, len = data.data.length; i < len; i++) + AI.TmpProviderForModels = AI.createProviderInstance(provider.name, provider.url, provider.key); + let models = data.data; + if (data.data.models) + models = data.data.models; + for (let i = 0, len = models.length; i < len; i++) { - let model = data.data[i]; + let model = models[i]; + AI.TmpProviderForModels.correctModelInfo(model); + if (!model.id) continue; - model.name = model.id; model.endpoints = []; - model.options = {}; + model.options = {}; if (AI.TmpProviderForModels.checkExcludeModel(model)) continue; @@ -357,7 +361,7 @@ let endpointType = isUseCompletionsInsteadChat ? AI.Endpoints.Types.v1.Completions : AI.Endpoints.Types.v1.Chat_Completions; - objRequest.url = AI._getEndpointUrl(provider, endpointType); + objRequest.url = AI._getEndpointUrl(provider, endpointType, this.model); objRequest.body = { model : this.modelUI.id diff --git a/sdkjs-plugins/content/ai/scripts/engine/local_storage.js b/sdkjs-plugins/content/ai/scripts/engine/local_storage.js index 86781d80..ec763bc3 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/local_storage.js +++ b/sdkjs-plugins/content/ai/scripts/engine/local_storage.js @@ -78,11 +78,11 @@ for (let i in obj.providers) { let pr = obj.providers[i]; - AI.Providers[i] = AI.Provider.createInstance(pr.name, pr.url, pr.key); + AI.Providers[i] = AI.createProviderInstance(pr.name, pr.url, pr.key); AI.Providers[i].models = pr.models || []; if (fixVersion2) { - if (!AI.Storage.isInternalProvider(pr.name)) + if (!AI.isInternalProvider(pr.name)) AI.Providers[i].addon = "v1"; } } @@ -111,7 +111,7 @@ AI.Providers[model.provider.name].key = model.provider.key; } else { AI.Providers[model.provider.name] = - AI.Provider.createInstance(model.provider.name, model.provider.url, model.provider.key); + AI.createProviderInstance(model.provider.name, model.provider.url, model.provider.key); } if (AI.TmpProviderForModels && diff --git a/sdkjs-plugins/content/ai/scripts/engine/providers/base.js b/sdkjs-plugins/content/ai/scripts/engine/providers/base.js index ae224642..e5466d74 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/providers/base.js +++ b/sdkjs-plugins/content/ai/scripts/engine/providers/base.js @@ -119,7 +119,7 @@ AI.createProviderInstance = function(name, url, key) { for (let i = 0, len = window.AI.InternalProviders.length; i < len; i++) { if (name === AI.InternalProviders[i].name) - return AI.InternalProviders[i].createInstance(name, url, key); + return AI.InternalProviders[i].createInstance(name, url, key, AI.InternalProviders[i].addon); } return new Provider(name, url, key); }; diff --git a/sdkjs-plugins/content/ai/scripts/engine/providers/internal/anthropic.js b/sdkjs-plugins/content/ai/scripts/engine/providers/internal/anthropic.js index b393668d..473f933a 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/providers/internal/anthropic.js +++ b/sdkjs-plugins/content/ai/scripts/engine/providers/internal/anthropic.js @@ -26,20 +26,20 @@ class Provider extends AI.Provider { return AI.CapabilitiesUI.Chat | AI.CapabilitiesUI.Vision; } - getEndpointUrl(endpoint) { + getEndpointUrl(endpoint, model) { if (AI.Endpoints.Types.v1.Chat_Completions === endpoint) return "/messages"; return super.getEndpointUrl(); } - getRequestHeaderOptions(key) { + getRequestHeaderOptions() { let headers = { "Content-Type" : "application/json", "anthropic-version" : "2023-06-01", "anthropic-dangerous-direct-browser-access": "true" }; - if (key) - headers["x-api-key"] = key; + if (this.key) + headers["x-api-key"] = this.key; return headers; } diff --git a/sdkjs-plugins/content/ai/scripts/engine/providers/internal/google-gemini.js b/sdkjs-plugins/content/ai/scripts/engine/providers/internal/google-gemini.js index 188d2f56..68eac057 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/providers/internal/google-gemini.js +++ b/sdkjs-plugins/content/ai/scripts/engine/providers/internal/google-gemini.js @@ -3,7 +3,74 @@ class Provider extends AI.Provider { constructor() { - super("Google-Gemini", "https://generativelanguage.googleapis.com/v1beta", "", ""); + super("Google-Gemini", "https://generativelanguage.googleapis.com", "", "v1beta"); + } + + correctModelInfo(model) { + model.id = model.name; + let index = model.name.indexOf("models/"); + if (index === 0) + model.name = model.name.substring(7); + } + + checkExcludeModel(model) { + if (model.id === "models/chat-bison-001" || + model.id === "models/text-bison-001") + return true; + + if (-1 !== model.id.indexOf("gemini-1.0")) + return true; + + return false; + } + + checkModelCapability(model) { + if (model.inputTokenLimit) + model.options.max_input_tokens = model.inputTokenLimit; + + if (Array.isArray(model.supportedGenerationMethods) && + model.supportedGenerationMethods.includes("generateContent")) + { + model.endpoints.push(AI.Endpoints.Types.v1.Chat_Completions); + let caps = AI.CapabilitiesUI.Chat; + if (-1 !== model.id.indexOf("vision")) + caps |= AI.CapabilitiesUI.Vision; + + return AI.CapabilitiesUI.Chat | AI.CapabilitiesUI.Vision; + } + + if (Array.isArray(model.supportedGenerationMethods) && + model.supportedGenerationMethods.includes("embedContent")) + { + model.endpoints.push(AI.Endpoints.Types.v1.Embeddings); + return AI.CapabilitiesUI.Embeddings; + } + + return AI.CapabilitiesUI.All; + } + + getEndpointUrl(endpoint, model) { + let Types = AI.Endpoints.Types; + let url = ""; + switch (endpoint) + { + case Types.v1.Models: + url = "/models"; + break; + default: + url = "/" + model.id + ":generateContent"; + break; + } + if (this.key) + url += "?key=" + this.key; + return url; + } + + getRequestHeaderOptions() { + let headers = { + "Content-Type" : "application/json" + }; + return headers; } } diff --git a/sdkjs-plugins/content/ai/scripts/engine/providers/internal/ollama.js b/sdkjs-plugins/content/ai/scripts/engine/providers/internal/ollama.js index 970dfe1a..643a15f8 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/providers/internal/ollama.js +++ b/sdkjs-plugins/content/ai/scripts/engine/providers/internal/ollama.js @@ -6,4 +6,22 @@ class Provider extends AI.Provider { super("Ollama", "http://localhost:11434/api", "", ""); } + getEndpointUrl(endpoint, model) { + let Types = AI.Endpoints.Types; + switch (endpoint) + { + case Types.v1.Models: + return "/tags"; + + case Types.v1.Chat_Completions: + return "/chat"; + case Types.v1.Completions: + return "/generate"; + + default: + break; + } + + return super.getEndpointUrl(); + } } diff --git a/sdkjs-plugins/content/ai/scripts/engine/providers/provider.js b/sdkjs-plugins/content/ai/scripts/engine/providers/provider.js index 49595d1d..e9a5ede2 100644 --- a/sdkjs-plugins/content/ai/scripts/engine/providers/provider.js +++ b/sdkjs-plugins/content/ai/scripts/engine/providers/provider.js @@ -19,6 +19,13 @@ this.models = []; this.modelsUI = []; } + + /** + * Correct received (*models* endpoint) model object. + */ + correctModelInfo(model) { + model.name = model.id; + } /** * Return *true* if you do not want to work with a specific model (model.id). @@ -42,7 +49,7 @@ * Url for a specific endpoint. * @returns {string} */ - getEndpointUrl(endpoint) { + getEndpointUrl(endpoint, model) { let Types = AI.Endpoints.Types; switch (endpoint) { @@ -94,7 +101,7 @@ * Don't override this method unless you know what you're doing. * @returns {Object} */ - getRequestBodyOptions = function() { + getRequestBodyOptions() { return {}; } @@ -102,12 +109,12 @@ * The returned object is an enumeration of all the headers for the requests. * @returns {Object} */ - getRequestHeaderOptions = function(key) { + getRequestHeaderOptions() { let headers = { "Content-Type" : "application/json" }; - if (key) - headers["Authorization"] = "Bearer " + key; + if (this.key) + headers["Authorization"] = "Bearer " + this.key; return headers; } @@ -135,11 +142,12 @@ * ======================================================================================== */ createInstance(name, url, key, addon) { - let inst = Object.create(Object.getPrototypeOf(this)); + //let inst = Object.create(Object.getPrototypeOf(this)); + let inst = new this.constructor(); inst.name = name; inst.url = url; inst.key = key; - inst.addon = addon; + inst.addon = addon || ""; return inst; } diff --git a/sdkjs-plugins/content/ai/settings.html b/sdkjs-plugins/content/ai/settings.html index 1b826bc8..914194c1 100644 --- a/sdkjs-plugins/content/ai/settings.html +++ b/sdkjs-plugins/content/ai/settings.html @@ -24,7 +24,7 @@ - +