Skip to content

Commit

Permalink
Merge pull request #370 from ONLYOFFICE-PLUGINS/feature/AI
Browse files Browse the repository at this point in the history
Feature/ai
  • Loading branch information
K0R0L authored Dec 20, 2024
2 parents 80ae06e + 14d06e9 commit 9601134
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 54 deletions.
3 changes: 3 additions & 0 deletions sdkjs-plugins/content/ai/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@

## 2.1.0
* Bug fix.

## 2.1.1
* Bug fix.
2 changes: 1 addition & 1 deletion sdkjs-plugins/content/ai/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},

"guid" : "asc.{9DC93CDB-B576-4F0C-B55E-FCC9C48DD007}",
"version": "2.1.0",
"version": "2.1.1",
"minVersion" : "8.2.0",

"variations" : [
Expand Down
Binary file modified sdkjs-plugins/content/ai/deploy/ai.plugin
Binary file not shown.
7 changes: 7 additions & 0 deletions sdkjs-plugins/content/ai/scripts/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,24 @@ function onOpenSummarizationModal() {
return;
}

let isError = false;
requestEngine.setErrorHandler(function(data){
summarizationWindow && summarizationWindow.command("onSummarize", data);
isError = true;
});

let prompt = Asc.Prompts.getSummarizationPrompt(content.data, content.lang);
let result = await requestEngine.chatRequest(prompt);

if (isError)
return;

if (!result) {
summarizationWindow.command("onSummarize", {
error : 1,
message : "Empty result"
});
return;
}

summarizationWindow && summarizationWindow.command("onSummarize", {
Expand Down
76 changes: 40 additions & 36 deletions sdkjs-plugins/content/ai/scripts/engine/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,6 @@
window.AI = window.AI || {};
var AI = window.AI;

AI.isLocalDesktop = (function(){
if (window.navigator && window.navigator.userAgent.toLowerCase().indexOf("ascdesktopeditor") < 0)
return false;
if (window.location && window.location.protocol == "file:")
return true;
if (window.document && window.document.currentScript && 0 == window.document.currentScript.src.indexOf("file:///"))
return true;
return false;
})();

AI.isLocalUrl = function(url) {
let filter = ["localhost", "127.0.0.1"];
for (let i = 0, len = filter.length; i < len; i++) {
let pos = url.indexOf(filter[i]);
if (pos >= 0 && pos < 10)
return true;
}
return false;
};

if (!AI.isLocalDesktop)
return;

Expand Down Expand Up @@ -114,15 +94,37 @@
}

AI.TmpProviderForModels = null;

AI._getHeaders = function(_provider) {
let provider = _provider.createInstance ? _provider : AI.Storage.getProvider(_provider.name);
return provider.getRequestHeaderOptions(_provider.key);
};

AI._extendBody = function(_provider, body) {
let provider = _provider.createInstance ? _provider : AI.Storage.getProvider(_provider.name);

let bodyPr = provider.getRequestBodyOptions();

for (let i in bodyPr) {
if (!body[i])
body[i] = bodyPr[i];
}

return;
};

AI._getEndpointUrl = function(_provider, endpoint) {
let override = _provider.overrideEndpointUrl(endpoint);
if (undefined !== override)
return override;
return AI.Endpoints.getUrl(endpoint);
};

AI.getModels = async function(provider)
{
AI.TmpProviderForModels = null;
return new Promise(function (resolve, reject) {
let headers = {};
headers["Content-Type"] = "application/json";
if (provider.key)
headers["Authorization"] = "Bearer " + provider.key;

let headers = AI._getHeaders(provider);
requestWrapper({
url : provider.url + AI.Endpoints.getUrl(AI.Endpoints.Types.v1.Models),
headers : headers,
Expand All @@ -142,8 +144,7 @@
if (!model.id)
continue;

if (!model.name)
model.name = model.id;
model.name = model.id;
model.endpoints = [];
model.options = {};

Expand Down Expand Up @@ -282,10 +283,7 @@
if (max_input_tokens < header_footer_overhead)
max_input_tokens = header_footer_overhead + 1000;

let headers = {};
headers["Content-Type"] = "application/json";
if (provider.key)
headers["Authorization"] = "Bearer " + provider.key;
let headers = AI._getHeaders(provider);

let input_len = content.length;
let input_tokens = Asc.OpenAIEncode(content).length;
Expand Down Expand Up @@ -313,17 +311,23 @@
method : "POST"
};

if (!isUseCompletionsInsteadChat)
objRequest.url = provider.url + AI.Endpoints.getUrl(AI.Endpoints.Types.v1.Chat_Completions);
else
objRequest.url = provider.url + AI.Endpoints.getUrl(AI.Endpoints.Types.v1.Completions);
let endpointType = isUseCompletionsInsteadChat ? AI.Endpoints.Types.v1.Completions :
AI.Endpoints.Types.v1.Chat_Completions;
objRequest.url = provider.url + AI._getEndpointUrl(provider, endpointType);

objRequest.body = {
model : this.modelUI.id
};

AI._extendBody(provider, objRequest.body);

let processResult = function(data) {
let choice = data.data.choices[0];
let arrResult = data.data.choices || data.data.content;
if (!arrResult)
return "";
let choice = arrResult[0];
if (!choice)
return "";
let text = "";
if (choice.message)
text = choice.message.content;
Expand Down
71 changes: 70 additions & 1 deletion sdkjs-plugins/content/ai/scripts/engine/internal_providers.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
return new AI.ProviderOpenAI(name, url, key);
};

AI.Provider.prototype.checkExcludeModel = function(model) {
AI.ProviderOpenAI.prototype.checkExcludeModel = function(model) {
if (-1 !== model.id.indexOf("babbage-002") ||
-1 !== model.id.indexOf("davinci-002"))
return true;
Expand Down Expand Up @@ -162,6 +162,12 @@
return new AI.ProviderGpt4All(name, url, key);
};

AI.ProviderGpt4All.prototype.getRequestBodyOptions = function() {
return {
max_tokens : 4096
};
};

// Mistral
AI.ProviderMistral = function(name, url, key) {
AI.Provider.call(this, name || "Mistral", url || "https://api.mistral.ai", key || "");
Expand Down Expand Up @@ -216,16 +222,79 @@

model.options.max_input_tokens = AI.InputMaxTokens["128k"];
model.endpoints.push(AI.Endpoints.Types.v1.Chat_Completions);

let capUI = AI.CapabilitiesUI.Chat;
if (model.capabilities && model.capabilities.vision)
capUI = AI.CapabilitiesUI.Vision;
return capUI;
};

// Anthropic
AI.ProviderAnthropic = function(name, url, key) {
AI.Provider.call(this, name || "Anthropic", url || "https://api.anthropic.com", key || "");
};

AI.ProviderAnthropic.prototype = Object.create(AI.Provider.prototype);
AI.ProviderAnthropic.prototype.constructor = AI.ProviderAnthropic;

AI.ProviderAnthropic.prototype.createInstance = function(name, url, key) {
return new AI.ProviderAnthropic(name, url, key);
};

AI.ProviderAnthropic.prototype.checkModelCapability = function(model) {
if (0 == model.id.indexOf("claude-2"))
{
model.options.max_input_tokens = AI.InputMaxTokens["100k"];
model.endpoints.push(AI.Endpoints.Types.v1.Chat_Completions);
return AI.CapabilitiesUI.Chat;
}

if (0 == model.id.indexOf("claude-3-5-haiku"))
{
model.options.max_input_tokens = AI.InputMaxTokens["200k"];
model.endpoints.push(AI.Endpoints.Types.v1.Chat_Completions);
return AI.CapabilitiesUI.Chat;
}

model.options.max_input_tokens = AI.InputMaxTokens["200k"];
model.endpoints.push(AI.Endpoints.Types.v1.Chat_Completions);
return AI.CapabilitiesUI.Chat | AI.CapabilitiesUI.Vision;
};

AI.ProviderAnthropic.prototype.overrideEndpointUrl = function(endpoint) {
if (AI.Endpoints.Types.v1.Chat_Completions === endpoint)
return "/v1/messages";
return undefined;
};

AI.ProviderAnthropic.prototype.getRequestBodyOptions = function() {
return {
"max_tokens": 4096
};
};

AI.ProviderAnthropic.prototype.getRequestHeaderOptions = function(key) {
let headers = {
"Content-Type" : "application/json",
"anthropic-version" : "2023-06-01",
"anthropic-dangerous-direct-browser-access": "true"
};
if (key)
headers["x-api-key"] = key;
return headers;
};

// Register internal providers
AI.Storage.InternalProviders = [];

AI.Storage.InternalProviders.push(new AI.ProviderOpenAI());
AI.Storage.InternalProviders.push(new AI.ProviderTogetherAI());
AI.Storage.InternalProviders.push(new AI.ProviderMistral());

// bug in desktop with simple request
if (!AI.isLocalDesktop || AI.getDesktopLocalVersion() >= 8003000)
AI.Storage.InternalProviders.push(new AI.ProviderAnthropic());

if (window["AscDesktopEditor"])
AI.Storage.InternalProviders.push(new AI.ProviderGpt4All());

Expand Down
20 changes: 10 additions & 10 deletions sdkjs-plugins/content/ai/scripts/engine/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,25 @@
});
};

Library.prototype.InsertAsReview = async function(content, isHtml) {
Asc.scope.isHtml = !!isHtml;
Library.prototype.InsertAsReview = async function(content, isHtml)
{
let isTrackRevisions = await Editor.callCommand(function(){
let doc = Api.GetDocument();
let res = doc.IsTrackRevisions();
//doc.SetTrackRevisions(true);
let res = Api.asc_GetLocalTrackRevisions();
Api.asc_SetLocalTrackRevisions(true);
return res;
});

Asc.scope.localTrackRevisions = isTrackRevisions;

await Editor.callMethod(isHtml ? "PasteHtml" : "PasteText", [content.trim()]);

if (!isTrackRevisions) {

if (true !== isTrackRevisions)
{
await Editor.callCommand(function(){
//return Api.GetDocument().SetTrackRevisions(false);
Api.asc_SetLocalTrackRevisions(false);
Api.asc_SetLocalTrackRevisions(Asc.scope.localTrackRevisions);
});
}
}
};

Library.prototype.PasteText = async function(text)
{
Expand Down
54 changes: 54 additions & 0 deletions sdkjs-plugins/content/ai/scripts/engine/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@
AI.Storage = AI.Storage || {};
AI.Storage.Version = 2;

AI.isLocalDesktop = (function(){
if (window.navigator && window.navigator.userAgent.toLowerCase().indexOf("ascdesktopeditor") < 0)
return false;
if (window.location && window.location.protocol == "file:")
return true;
if (window.document && window.document.currentScript && 0 == window.document.currentScript.src.indexOf("file:///"))
return true;
return false;
})();

AI.isLocalUrl = function(url) {
let filter = ["localhost", "127.0.0.1"];
for (let i = 0, len = filter.length; i < len; i++) {
let pos = url.indexOf(filter[i]);
if (pos >= 0 && pos < 10)
return true;
}
return false;
};

AI.getDesktopLocalVersion = function() {
let ret = 99 * 1000000 + 99 * 1000 + 99;
if (!AI.isLocalDesktop)
return ret;
let pos = window.navigator.userAgent.indexOf("AscDesktopEditor/");
let pos2 = window.navigator.userAgent.indexOf(" ", pos);
if (pos === -1 || pos2 === -1)
return ret;
try {
let tokens = window.navigator.userAgent.substring(pos + 17, pos2).split(".");
return parseInt(tokens[0]) * 1000000 + parseInt(tokens[1]) * 1000 + parseInt(tokens[2]);
} catch (e) {
}

return ret;
};

AI.Endpoints = {

Types : {
Expand Down Expand Up @@ -155,13 +192,30 @@
}
};

AI.Provider.prototype.overrideEndpointUrl = function(endpoint) {
return undefined;
};

AI.Provider.prototype.getRequestBodyOptions = function() {
return {};
};
AI.Provider.prototype.getRequestHeaderOptions = function(key) {
let headers = {
"Content-Type" : "application/json"
};
if (key)
headers["Authorization"] = "Bearer " + key;
return headers;
};

AI.InputMaxTokens = {
"4k" : 4096,
"8k" : 8192,
"16k" : 16384,
"32k" : 32768,
"64k" : 65536,
"128k" : 131072,
"200k" : 204800,
"256k" : 262144
};

Expand Down
Loading

0 comments on commit 9601134

Please sign in to comment.