plugin-custom-llm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.js +10 -0
- package/dist/externalVersion.js +20 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +20 -0
- package/dist/locale/vi-VN.json +20 -0
- package/dist/locale/zh-CN.json +16 -0
- package/dist/server/index.js +42 -0
- package/dist/server/llm-providers/custom-llm.js +201 -0
- package/dist/server/plugin.js +59 -0
- package/package.json +28 -0
- package/plugin-custom-llm-1.0.0.tgz +0 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @nocobase/plugin-custom-llm
|
package/client.d.ts
ADDED
package/client.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/client/index.js');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("@nocobase/plugin-ai/client"),require("@nocobase/client"),require("@nocobase/utils/client"),require("antd"),require("react-i18next")):"function"==typeof define&&define.amd?define("plugin-custom-llm",["react","@nocobase/plugin-ai/client","@nocobase/client","@nocobase/utils/client","antd","react-i18next"],t):"object"==typeof exports?exports["plugin-custom-llm"]=t(require("react"),require("@nocobase/plugin-ai/client"),require("@nocobase/client"),require("@nocobase/utils/client"),require("antd"),require("react-i18next")):e["plugin-custom-llm"]=t(e.react,e["@nocobase/plugin-ai/client"],e["@nocobase/client"],e["@nocobase/utils/client"],e.antd,e["react-i18next"])}(self,function(e,t,n,o,r,i){return function(){"use strict";var u={772:function(e){e.exports=n},645:function(e){e.exports=t},584:function(e){e.exports=o},721:function(e){e.exports=r},156:function(t){t.exports=e},238:function(e){e.exports=i}},c={};function a(e){var t=c[e];if(void 0!==t)return t.exports;var n=c[e]={exports:{}};return u[e](n,n.exports,a),n.exports}a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,{a:t}),t},a.d=function(e,t){for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var l={};return!function(){a.r(l),a.d(l,{PluginCustomLLMClient:function(){return g},default:function(){return S}});var e=a(772),t=a(156),n=a.n(t),o=a(584),r=a(238),i="@nocobase/plugin-custom-llm",u=a(721),c=a(645),p=function(){var t=(0,r.useTranslation)(i,{nsMode:"fallback"}).t;return n().createElement("div",{style:{marginBottom:24}},n().createElement(u.Collapse,{bordered:!1,size:"small",items:[{key:"options",label:t("Options"),forceRender:!0,children:n().createElement(e.SchemaComponent,{schema:{type:"void",name:"custom-llm",properties:{temperature:{title:(0,o.tval)("Temperature",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:.7,"x-component-props":{step:.1,min:0,max:2}},maxCompletionTokens:{title:(0,o.tval)("Max completion tokens",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:-1},topP:{title:(0,o.tval)("Top P",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:1,"x-component-props":{step:.1,min:0,max:1}},frequencyPenalty:{title:(0,o.tval)("Frequency penalty",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:0,"x-component-props":{step:.1,min:-2,max:2}},presencePenalty:{title:(0,o.tval)("Presence penalty",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:0,"x-component-props":{step:.1,min:-2,max:2}},responseFormat:{title:(0,o.tval)("Response format",{ns:i}),type:"string","x-decorator":"FormItem","x-component":"Select",enum:[{label:t("Text"),value:"text"},{label:t("JSON"),value:"json_object"}],default:"text"},timeout:{title:(0,o.tval)("Timeout (ms)",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:6e4},maxRetries:{title:(0,o.tval)("Max retries",{ns:i}),type:"number","x-decorator":"FormItem","x-component":"InputNumber",default:1}}}})}]}))},s={components:{ProviderSettingsForm:function(){return n().createElement(e.SchemaComponent,{schema:{type:"void",properties:{baseURL:{title:(0,o.tval)("Base URL",{ns:i}),type:"string",required:!0,"x-decorator":"FormItem","x-component":"TextAreaWithGlobalScope","x-component-props":{placeholder:"https://your-llm-server.com/v1"}},apiKey:{title:(0,o.tval)("API Key",{ns:i}),type:"string",required:!0,"x-decorator":"FormItem","x-component":"TextAreaWithGlobalScope"},requestConfig:{title:(0,o.tval)("Request config (JSON)",{ns:i}),type:"string","x-decorator":"FormItem","x-component":"Input.TextArea","x-component-props":{placeholder:JSON.stringify({extraHeaders:{},extraBody:{},modelKwargs:{}},null,2),rows:6,style:{fontFamily:"monospace",fontSize:12}},description:(0,o.tval)("Request config description",{ns:i})},responseConfig:{title:(0,o.tval)("Response config (JSON)",{ns:i}),type:"string","x-decorator":"FormItem","x-component":"Input.TextArea","x-component-props":{placeholder:JSON.stringify({contentPath:"auto",reasoningKey:"reasoning_content"},null,2),rows:4,style:{fontFamily:"monospace",fontSize:12}},description:(0,o.tval)("Response config description",{ns:i})}}}})},ModelSettingsForm:function(){return n().createElement(e.SchemaComponent,{components:{Options:p,ModelSelect:c.ModelSelect},schema:{type:"void",properties:{model:{title:(0,o.tval)("Model",{ns:i}),type:"string",required:!0,"x-decorator":"FormItem","x-component":"ModelSelect"},options:{type:"void","x-component":"Options"}}}})}}};function f(e,t,n,o,r,i,u){try{var c=e[i](u),a=c.value}catch(e){n(e);return}c.done?t(a):Promise.resolve(a).then(o,r)}function m(e){return function(){var t=this,n=arguments;return new Promise(function(o,r){var i=e.apply(t,n);function u(e){f(i,o,r,u,c,"next",e)}function c(e){f(i,o,r,u,c,"throw",e)}u(void 0)})}}function d(e,t,n){return(d=v()?Reflect.construct:function(e,t,n){var o=[null];o.push.apply(o,t);var r=new(Function.bind.apply(e,o));return n&&b(r,n.prototype),r}).apply(null,arguments)}function y(e){return(y=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function b(e,t){return(b=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function x(e){var t="function"==typeof Map?new Map:void 0;return(x=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return d(e,arguments,y(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),b(n,e)})(e)}function v(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(v=function(){return!!e})()}function h(e,t){var n,o,r,i,u={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function c(i){return function(c){var a=[i,c];if(n)throw TypeError("Generator is already executing.");for(;u;)try{if(n=1,o&&(r=2&a[0]?o.return:a[0]?o.throw||((r=o.return)&&r.call(o),0):o.next)&&!(r=r.call(o,a[1])).done)return r;switch(o=0,r&&(a=[2&a[0],r.value]),a[0]){case 0:case 1:r=a;break;case 4:return u.label++,{value:a[1],done:!1};case 5:u.label++,o=a[1],a=[0];continue;case 7:a=u.ops.pop(),u.trys.pop();continue;default:if(!(r=(r=u.trys).length>0&&r[r.length-1])&&(6===a[0]||2===a[0])){u=0;continue}if(3===a[0]&&(!r||a[1]>r[0]&&a[1]<r[3])){u.label=a[1];break}if(6===a[0]&&u.label<r[1]){u.label=r[1],r=a;break}if(r&&u.label<r[2]){u.label=r[2],u.ops.push(a);break}r[2]&&u.ops.pop(),u.trys.pop();continue}a=t.call(e,u)}catch(e){a=[6,e],o=0}finally{n=r=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}}}var g=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function n(){var e,t;if(!(this instanceof n))throw TypeError("Cannot call a class as a function");return e=n,t=arguments,e=y(e),function(e,t){var n;if(t&&("object"==((n=t)&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,v()?Reflect.construct(e,t||[],y(this).constructor):e.apply(this,t))}return n.prototype=Object.create(e&&e.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),e&&b(n,e),t=[{key:"afterAdd",value:function(){return m(function(){return h(this,function(e){return[2]})})()}},{key:"beforeLoad",value:function(){return m(function(){return h(this,function(e){return[2]})})()}},{key:"load",value:function(){var e=this;return m(function(){return h(this,function(t){return e.aiPlugin.aiManager.registerLLMProvider("custom-llm",s),[2]})})()}},{key:"aiPlugin",get:function(){return this.app.pm.get("ai")}}],function(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}(n.prototype,t),n}(x(e.Plugin)),S=g}(),l}()});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
"@nocobase/client": "2.0.15",
|
|
12
|
+
"@nocobase/plugin-ai": "2.0.15",
|
|
13
|
+
"react-i18next": "11.18.6",
|
|
14
|
+
"@nocobase/server": "2.0.15",
|
|
15
|
+
"@nocobase/flow-engine": "2.0.15",
|
|
16
|
+
"@nocobase/database": "2.0.15",
|
|
17
|
+
"react": "18.2.0",
|
|
18
|
+
"@nocobase/utils": "2.0.15",
|
|
19
|
+
"antd": "5.24.2"
|
|
20
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
29
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
32
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
33
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
34
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
35
|
+
mod
|
|
36
|
+
));
|
|
37
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
|
+
var src_exports = {};
|
|
39
|
+
__export(src_exports, {
|
|
40
|
+
default: () => import_server.default
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(src_exports);
|
|
43
|
+
__reExport(src_exports, require("./server"), module.exports);
|
|
44
|
+
var import_server = __toESM(require("./server"));
|
|
45
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
+
0 && (module.exports = {
|
|
47
|
+
...require("./server")
|
|
48
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Base URL": "Base URL",
|
|
3
|
+
"API Key": "API Key",
|
|
4
|
+
"Model": "Model",
|
|
5
|
+
"Options": "Options",
|
|
6
|
+
"Temperature": "Temperature",
|
|
7
|
+
"Max completion tokens": "Max completion tokens",
|
|
8
|
+
"Top P": "Top P",
|
|
9
|
+
"Frequency penalty": "Frequency penalty",
|
|
10
|
+
"Presence penalty": "Presence penalty",
|
|
11
|
+
"Response format": "Response format",
|
|
12
|
+
"Text": "Text",
|
|
13
|
+
"JSON": "JSON",
|
|
14
|
+
"Timeout (ms)": "Timeout (ms)",
|
|
15
|
+
"Max retries": "Max retries",
|
|
16
|
+
"Request config (JSON)": "Request config (JSON)",
|
|
17
|
+
"Request config description": "Extra configuration for LLM requests. Supported keys: extraHeaders (custom HTTP headers), extraBody (extra request body fields), modelKwargs (LangChain model kwargs).",
|
|
18
|
+
"Response config (JSON)": "Response config (JSON)",
|
|
19
|
+
"Response config description": "Configure response parsing. contentPath: 'auto' (default) or dot-path like '0.text'. reasoningKey: key name for reasoning content (default: 'reasoning_content')."
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Base URL": "URL cơ sở",
|
|
3
|
+
"API Key": "API Key",
|
|
4
|
+
"Model": "Mô hình",
|
|
5
|
+
"Options": "Tùy chọn",
|
|
6
|
+
"Temperature": "Nhiệt độ",
|
|
7
|
+
"Max completion tokens": "Số token tối đa",
|
|
8
|
+
"Top P": "Top P",
|
|
9
|
+
"Frequency penalty": "Hình phạt tần suất",
|
|
10
|
+
"Presence penalty": "Hình phạt sự hiện diện",
|
|
11
|
+
"Response format": "Định dạng phản hồi",
|
|
12
|
+
"Text": "Văn bản",
|
|
13
|
+
"JSON": "JSON",
|
|
14
|
+
"Timeout (ms)": "Thời gian chờ (ms)",
|
|
15
|
+
"Max retries": "Số lần thử lại tối đa",
|
|
16
|
+
"Request config (JSON)": "Cấu hình request (JSON)",
|
|
17
|
+
"Request config description": "Cấu hình bổ sung cho request LLM. Các key hỗ trợ: extraHeaders (HTTP headers tùy chỉnh), extraBody (thêm trường vào request body), modelKwargs (tham số model LangChain).",
|
|
18
|
+
"Response config (JSON)": "Cấu hình response (JSON)",
|
|
19
|
+
"Response config description": "Cấu hình cách parse response. contentPath: 'auto' (mặc định) hoặc dot-path như '0.text'. reasoningKey: tên key cho reasoning content (mặc định: 'reasoning_content')."
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Base URL": "基础 URL",
|
|
3
|
+
"API Key": "API 密钥",
|
|
4
|
+
"Model": "模型",
|
|
5
|
+
"Options": "选项",
|
|
6
|
+
"Temperature": "温度",
|
|
7
|
+
"Max completion tokens": "最大完成令牌数",
|
|
8
|
+
"Top P": "Top P",
|
|
9
|
+
"Frequency penalty": "频率惩罚",
|
|
10
|
+
"Presence penalty": "存在惩罚",
|
|
11
|
+
"Response format": "响应格式",
|
|
12
|
+
"Text": "文本",
|
|
13
|
+
"JSON": "JSON",
|
|
14
|
+
"Timeout (ms)": "超时 (毫秒)",
|
|
15
|
+
"Max retries": "最大重试次数"
|
|
16
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var server_exports = {};
|
|
38
|
+
__export(server_exports, {
|
|
39
|
+
default: () => import_plugin.default
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(server_exports);
|
|
42
|
+
var import_plugin = __toESM(require("./plugin"));
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var custom_llm_exports = {};
|
|
38
|
+
__export(custom_llm_exports, {
|
|
39
|
+
CustomLLMProvider: () => CustomLLMProvider,
|
|
40
|
+
customLLMProviderOptions: () => customLLMProviderOptions
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(custom_llm_exports);
|
|
43
|
+
var import_plugin_ai = require("@nocobase/plugin-ai");
|
|
44
|
+
var import_node_path = __toESM(require("node:path"));
|
|
45
|
+
function requireFromApp(moduleName) {
|
|
46
|
+
const appNodeModules = process.env.NODE_MODULES_PATH || import_node_path.default.join(process.cwd(), "node_modules");
|
|
47
|
+
const resolved = require.resolve(moduleName, { paths: [appNodeModules] });
|
|
48
|
+
return require(resolved);
|
|
49
|
+
}
|
|
50
|
+
let _ChatOpenAI = null;
|
|
51
|
+
function getChatOpenAI() {
|
|
52
|
+
if (!_ChatOpenAI) {
|
|
53
|
+
const mod = requireFromApp("@langchain/openai");
|
|
54
|
+
_ChatOpenAI = mod.ChatOpenAI;
|
|
55
|
+
}
|
|
56
|
+
return _ChatOpenAI;
|
|
57
|
+
}
|
|
58
|
+
function stripToolCallTags(content) {
|
|
59
|
+
if (typeof content !== "string") {
|
|
60
|
+
return content;
|
|
61
|
+
}
|
|
62
|
+
return content.replace(/<[||]tool▁(?:calls▁begin|calls▁end|call▁begin|call▁end|sep)[||]>/g, "");
|
|
63
|
+
}
|
|
64
|
+
function extractTextContent(content, contentPath) {
|
|
65
|
+
if (contentPath && contentPath !== "auto") {
|
|
66
|
+
try {
|
|
67
|
+
const keys = contentPath.split(".");
|
|
68
|
+
let result = content;
|
|
69
|
+
for (const key of keys) {
|
|
70
|
+
if (result == null) break;
|
|
71
|
+
result = result[key];
|
|
72
|
+
}
|
|
73
|
+
if (typeof result === "string") return result;
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (typeof content === "string") {
|
|
78
|
+
return content;
|
|
79
|
+
}
|
|
80
|
+
if (Array.isArray(content)) {
|
|
81
|
+
return content.filter((block) => block && block.type === "text").map((block) => block.text ?? "").join("");
|
|
82
|
+
}
|
|
83
|
+
if (content && typeof content === "object" && content.text) {
|
|
84
|
+
return String(content.text);
|
|
85
|
+
}
|
|
86
|
+
return "";
|
|
87
|
+
}
|
|
88
|
+
function safeParseJSON(str) {
|
|
89
|
+
if (!str || typeof str !== "string") return {};
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(str);
|
|
92
|
+
} catch {
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
class CustomLLMProvider extends import_plugin_ai.LLMProvider {
|
|
97
|
+
get baseURL() {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
get requestConfig() {
|
|
101
|
+
var _a;
|
|
102
|
+
return safeParseJSON((_a = this.serviceOptions) == null ? void 0 : _a.requestConfig);
|
|
103
|
+
}
|
|
104
|
+
get responseConfig() {
|
|
105
|
+
var _a;
|
|
106
|
+
return safeParseJSON((_a = this.serviceOptions) == null ? void 0 : _a.responseConfig);
|
|
107
|
+
}
|
|
108
|
+
createModel() {
|
|
109
|
+
const { baseURL, apiKey } = this.serviceOptions || {};
|
|
110
|
+
const { responseFormat } = this.modelOptions || {};
|
|
111
|
+
const reqConfig = this.requestConfig;
|
|
112
|
+
const responseFormatOptions = {
|
|
113
|
+
type: responseFormat ?? "text"
|
|
114
|
+
};
|
|
115
|
+
const modelKwargs = {
|
|
116
|
+
response_format: responseFormatOptions,
|
|
117
|
+
...reqConfig.modelKwargs || {}
|
|
118
|
+
};
|
|
119
|
+
if (reqConfig.extraBody && typeof reqConfig.extraBody === "object") {
|
|
120
|
+
Object.assign(modelKwargs, reqConfig.extraBody);
|
|
121
|
+
}
|
|
122
|
+
const ChatOpenAI = getChatOpenAI();
|
|
123
|
+
const config = {
|
|
124
|
+
apiKey,
|
|
125
|
+
...this.modelOptions,
|
|
126
|
+
modelKwargs,
|
|
127
|
+
configuration: {
|
|
128
|
+
baseURL
|
|
129
|
+
},
|
|
130
|
+
verbose: false
|
|
131
|
+
};
|
|
132
|
+
if (reqConfig.extraHeaders && typeof reqConfig.extraHeaders === "object") {
|
|
133
|
+
config.configuration.defaultHeaders = reqConfig.extraHeaders;
|
|
134
|
+
}
|
|
135
|
+
return new ChatOpenAI(config);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Handle streaming chunks — normalize content format using responseConfig.
|
|
139
|
+
*/
|
|
140
|
+
parseResponseChunk(chunk) {
|
|
141
|
+
const resConfig = this.responseConfig;
|
|
142
|
+
const text = extractTextContent(chunk, resConfig.contentPath);
|
|
143
|
+
return stripToolCallTags(text);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Handle saved messages — normalize array content when loading from DB.
|
|
147
|
+
*/
|
|
148
|
+
parseResponseMessage(message) {
|
|
149
|
+
const { content: rawContent, messageId, metadata, role, toolCalls, attachments, workContext } = message;
|
|
150
|
+
const content = {
|
|
151
|
+
...rawContent ?? {},
|
|
152
|
+
messageId,
|
|
153
|
+
metadata,
|
|
154
|
+
attachments,
|
|
155
|
+
workContext
|
|
156
|
+
};
|
|
157
|
+
if (toolCalls) {
|
|
158
|
+
content.tool_calls = toolCalls;
|
|
159
|
+
}
|
|
160
|
+
if (Array.isArray(content.content)) {
|
|
161
|
+
const textBlocks = content.content.filter((block) => block.type === "text");
|
|
162
|
+
content.content = textBlocks.map((block) => block.text).join("") || "";
|
|
163
|
+
}
|
|
164
|
+
if (typeof content.content === "string") {
|
|
165
|
+
content.content = stripToolCallTags(content.content);
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
key: messageId,
|
|
169
|
+
content,
|
|
170
|
+
role
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Parse reasoning content using responseConfig.reasoningKey.
|
|
175
|
+
*/
|
|
176
|
+
parseReasoningContent(chunk) {
|
|
177
|
+
var _a;
|
|
178
|
+
const resConfig = this.responseConfig;
|
|
179
|
+
const reasoningKey = resConfig.reasoningKey || "reasoning_content";
|
|
180
|
+
const reasoning = (_a = chunk == null ? void 0 : chunk.additional_kwargs) == null ? void 0 : _a[reasoningKey];
|
|
181
|
+
if (reasoning && typeof reasoning === "string") {
|
|
182
|
+
return {
|
|
183
|
+
status: "streaming",
|
|
184
|
+
content: reasoning
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
parseResponseError(err) {
|
|
190
|
+
return (err == null ? void 0 : err.message) ?? "Unexpected LLM service error";
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const customLLMProviderOptions = {
|
|
194
|
+
title: "Custom LLM (OpenAI Compatible)",
|
|
195
|
+
provider: CustomLLMProvider
|
|
196
|
+
};
|
|
197
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
198
|
+
0 && (module.exports = {
|
|
199
|
+
CustomLLMProvider,
|
|
200
|
+
customLLMProviderOptions
|
|
201
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var plugin_exports = {};
|
|
28
|
+
__export(plugin_exports, {
|
|
29
|
+
PluginCustomLLMServer: () => PluginCustomLLMServer,
|
|
30
|
+
default: () => plugin_default
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(plugin_exports);
|
|
33
|
+
var import_server = require("@nocobase/server");
|
|
34
|
+
var import_custom_llm = require("./llm-providers/custom-llm");
|
|
35
|
+
class PluginCustomLLMServer extends import_server.Plugin {
|
|
36
|
+
async afterAdd() {
|
|
37
|
+
}
|
|
38
|
+
async beforeLoad() {
|
|
39
|
+
}
|
|
40
|
+
async load() {
|
|
41
|
+
this.aiPlugin.aiManager.registerLLMProvider("custom-llm", import_custom_llm.customLLMProviderOptions);
|
|
42
|
+
}
|
|
43
|
+
async install() {
|
|
44
|
+
}
|
|
45
|
+
async afterEnable() {
|
|
46
|
+
}
|
|
47
|
+
async afterDisable() {
|
|
48
|
+
}
|
|
49
|
+
async remove() {
|
|
50
|
+
}
|
|
51
|
+
get aiPlugin() {
|
|
52
|
+
return this.app.pm.get("ai");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
var plugin_default = PluginCustomLLMServer;
|
|
56
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
57
|
+
0 && (module.exports = {
|
|
58
|
+
PluginCustomLLMServer
|
|
59
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "plugin-custom-llm",
|
|
3
|
+
"displayName": "AI LLM: Custom (OpenAI Compatible)",
|
|
4
|
+
"displayName.zh-CN": "AI LLM:自定义(OpenAI 兼容)",
|
|
5
|
+
"description": "OpenAI-compatible LLM provider with auto response format detection for external LLM services.",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"main": "dist/server/index.js",
|
|
8
|
+
"nocobase": {
|
|
9
|
+
"supportedVersions": [
|
|
10
|
+
"2.x"
|
|
11
|
+
],
|
|
12
|
+
"editionLevel": 0
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@langchain/openai": "^1.0.0",
|
|
16
|
+
"@langchain/core": "^1.0.0"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@nocobase/client": "2.x",
|
|
20
|
+
"@nocobase/plugin-ai": "2.x",
|
|
21
|
+
"@nocobase/server": "2.x",
|
|
22
|
+
"@nocobase/test": "2.x"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"AI"
|
|
26
|
+
],
|
|
27
|
+
"license": "Apache-2.0"
|
|
28
|
+
}
|
|
Binary file
|
package/server.d.ts
ADDED
package/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/server/index.js');
|