plugin-ai-api 1.0.21 → 1.0.23
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/dist/client/123.e6fe04c856ce6417.js +10 -0
- package/dist/client/index.js +1 -1
- package/dist/client-v2/123.05f1f649923f93eb.js +10 -0
- package/dist/client-v2/index.js +1 -1
- package/dist/constants.js +5 -2
- package/dist/locale/en-US.json +12 -1
- package/dist/locale/vi-VN.json +12 -1
- package/dist/locale/zh-CN.json +12 -1
- package/dist/server/collections/ai-api-user-permissions.js +67 -0
- package/dist/server/plugin.js +32 -0
- package/dist/server/resource/ai-api-user-permissions.js +75 -0
- package/dist/server/routes/agent-completions.js +5 -0
- package/dist/server/routes/chat-completions.js +29 -16
- package/dist/server/routes/completions.js +33 -20
- package/dist/server/routes/embeddings.js +6 -14
- package/dist/server/routes/models.js +24 -0
- package/dist/server/utils/openai-format.js +17 -3
- package/dist/server/utils/user-permissions.js +160 -0
- package/dist/swagger.js +4 -3
- package/package.json +2 -2
- package/src/client/__tests__/settings-registration.test.tsx +69 -0
- package/src/client/plugin.tsx +14 -3
- package/src/client-v2/__tests__/settings-registration.test.tsx +33 -4
- package/src/client-v2/pages/UserPermissionsPage.tsx +322 -0
- package/src/client-v2/plugin.tsx +12 -3
- package/src/constants.ts +7 -0
- package/src/locale/en-US.json +12 -1
- package/src/locale/vi-VN.json +12 -1
- package/src/locale/zh-CN.json +12 -1
- package/src/server/__tests__/models.test.ts +44 -2
- package/src/server/__tests__/openai-format.test.ts +52 -1
- package/src/server/__tests__/permission-sync.test.ts +109 -0
- package/src/server/__tests__/usage-route.test.ts +213 -0
- package/src/server/__tests__/user-permissions-resource.test.ts +66 -0
- package/src/server/__tests__/user-permissions.test.ts +284 -0
- package/src/server/collections/ai-api-user-permissions.ts +46 -0
- package/src/server/plugin.ts +42 -1
- package/src/server/resource/ai-api-user-permissions.ts +76 -0
- package/src/server/routes/agent-completions.ts +7 -0
- package/src/server/routes/chat-completions.ts +32 -16
- package/src/server/routes/completions.ts +40 -18
- package/src/server/routes/embeddings.ts +10 -15
- package/src/server/routes/models.ts +28 -0
- package/src/server/utils/openai-format.ts +26 -0
- package/src/server/utils/user-permissions.ts +218 -0
- package/src/swagger.ts +9 -3
|
@@ -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
|
+
"use strict";(self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).push([["123"],{46:function(e,t,r){r.r(t),r.d(t,{default:function(){return p}});var n=r(155),l=r.n(n),a=r(59),o=r(694),i=r(650),u=r(630);function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function c(e,t,r,n,l,a,o){try{var i=e[a](o),u=i.value}catch(e){r(e);return}i.done?t(u):Promise.resolve(u).then(n,l)}function d(e){return function(){var t=this,r=arguments;return new Promise(function(n,l){var a=e.apply(t,r);function o(e){c(a,n,l,o,i,"next",e)}function i(e){c(a,n,l,o,i,"throw",e)}o(void 0)})}}function m(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,l=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=l){var a=[],o=!0,i=!1;try{for(l=l.call(e);!(o=(r=l.next()).done)&&(a.push(r.value),!t||a.length!==t);o=!0);}catch(e){i=!0,n=e}finally{try{o||null==l.return||l.return()}finally{if(i)throw n}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return s(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return s(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function f(e,t){var r,n,l,a={label:0,sent:function(){if(1&l[0])throw l[1];return l[1]},trys:[],ops:[]},o=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(o,"next",{value:u(0)}),i(o,"throw",{value:u(1)}),i(o,"return",{value:u(2)}),"function"==typeof Symbol&&i(o,Symbol.iterator,{value:function(){return this}}),o;function u(i){return function(u){var s=[i,u];if(r)throw TypeError("Generator is already executing.");for(;o&&(o=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(l=2&s[0]?n.return:s[0]?n.throw||((l=n.return)&&l.call(n),0):n.next)&&!(l=l.call(n,s[1])).done)return l;switch(n=0,l&&(s=[2&s[0],l.value]),s[0]){case 0:case 1:l=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!(l=(l=a.trys).length>0&&l[l.length-1])&&(6===s[0]||2===s[0])){a=0;continue}if(3===s[0]&&(!l||s[1]>l[0]&&s[1]<l[3])){a.label=s[1];break}if(6===s[0]&&a.label<l[1]){a.label=l[1],l=s;break}if(l&&a.label<l[2]){a.label=l[2],a.ops.push(s);break}l[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=l=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}}}function p(){var e=(0,o.useFlowContext)(),t=(0,i.k)(),r=m(a.Form.useForm(),1)[0],s=a.Form.useWatch("allowedLlmServices",r),c=a.Form.useWatch("allowAllModels",r),p=m((0,n.useState)([]),2),v=p[0],h=p[1],b=m((0,n.useState)(0),2),y=b[0],w=b[1],S=m((0,n.useState)(1),2),g=S[0],E=S[1],k=m((0,n.useState)([]),2),A=k[0],M=k[1],I=m((0,n.useState)(""),2),F=I[0],C=I[1],U=m((0,n.useState)([]),2),x=U[0],L=U[1],P=m((0,n.useState)(!1),2),T=P[0],O=P[1],j=m((0,n.useState)(!1),2),z=j[0],q=j[1],B=m((0,n.useState)(),2),D=B[0],N=B[1],_=m((0,n.useState)(!1),2),G=_[0],V=_[1],W=(0,n.useCallback)(function(){return d(function(){var t,r,n,l,o,i,s;return f(this,function(c){switch(c.label){case 0:O(!0),c.label=1;case 1:return c.trys.push([1,3,4,5]),[4,Promise.all([e.api.request({url:"aiApiUserPermissions:list",method:"get",params:{page:g,pageSize:20,appends:["user"],sort:"-updatedAt"}}),e.api.request({url:"ai:listAllEnabledModels",method:"get"})])];case 2:return o=(l=m.apply(void 0,[c.sent(),2]))[0],i=l[1],h((0,u.m)(o,[])),w(null!=(t=null==o||null==(n=o.data)||null==(r=n.meta)?void 0:r.count)?t:0),L((0,u.m)(i,[])),[3,5];case 3:return s=c.sent(),a.message.error((0,u.g)(s)),[3,5];case 4:return O(!1),[7];case 5:return[2]}})})()},[e.api,g]);(0,n.useEffect)(function(){W()},[W]);var J=(0,n.useCallback)(function(t){return d(function(){var r,n;return f(this,function(l){switch(l.label){case 0:return l.trys.push([0,2,,3]),[4,e.api.request({url:"aiApiUserPermissions:listUsers",method:"get",params:{keyword:t,pageSize:50,excludeGranted:!D}})];case 1:return r=l.sent(),M((0,u.m)(r,[])),[3,3];case 2:return n=l.sent(),a.message.error((0,u.g)(n)),[3,3];case 3:return[2]}})})()},[e.api,D]);(0,n.useEffect)(function(){if(G){var e=setTimeout(function(){return J(F)},300);return function(){return clearTimeout(e)}}},[G,F,J]);var K=(0,n.useMemo)(function(){return x.map(function(e){return{label:e.llmServiceTitle||e.llmService,value:e.llmService}})},[x]),$=(0,n.useMemo)(function(){var e=new Set(s||[]);return x.filter(function(t){return e.has(t.llmService)}).flatMap(function(e){return(e.enabledModels||[]).map(function(t){return{label:"".concat(e.llmServiceTitle||e.llmService," / ").concat(t.label||t.value),value:"".concat(e.llmService,"/").concat(t.value)}})})},[x,s]),H=function(e){N(e),C(""),M(e.user?[e.user]:[]),r.setFieldsValue({userId:e.userId,enabled:e.enabled,allowAllModels:e.allowAllModels,allowedLlmServices:e.allowedLlmServices||[],allowedModels:e.allowedModels||[]}),V(!0)},Q=function(e){var t;return(null==e?void 0:e.nickname)||(null==e?void 0:e.username)||(null==e?void 0:e.email)||String(null!=(t=null==e?void 0:e.id)?t:"")},R=function(e){var t;return(null==(t=K.find(function(t){return t.value===e}))?void 0:t.label)||e},X=[{title:t("User"),key:"user",width:180,render:function(e,t){return Q(t.user)||String(t.userId)}},{title:t("Allowed LLM services"),dataIndex:"allowedLlmServices",key:"allowedLlmServices",render:function(e){return(null==e?void 0:e.length)?l().createElement(a.Space,{size:[0,4],wrap:!0},e.map(function(e){return l().createElement(a.Tag,{key:e},R(e))})):l().createElement(a.Tag,{color:"red"},t("No service allowed"))}},{title:t("Allowed models"),key:"allowedModels",width:220,render:function(e,r){return r.allowAllModels?l().createElement(a.Tag,{color:"blue"},t("All models of allowed services")):l().createElement(a.Space,{size:[0,4],wrap:!0},(r.allowedModels||[]).map(function(e){return l().createElement(a.Tag,{key:e},e)}))}},{title:t("Status"),dataIndex:"enabled",key:"enabled",width:100,render:function(e){return l().createElement(a.Tag,{color:e?"green":"default"},e?t("Enabled"):t("Disabled"))}},{title:t("Actions"),key:"actions",width:150,fixed:"right",render:function(r,n){return l().createElement(a.Space,{size:0},l().createElement(a.Button,{type:"link",onClick:function(){return H(n)}},t("Edit")),l().createElement(a.Popconfirm,{title:t("Delete this permission?"),onConfirm:function(){return d(function(){var r;return f(this,function(l){switch(l.label){case 0:return l.trys.push([0,3,,4]),[4,e.api.request({url:"aiApiUserPermissions:destroy/".concat(n.id),method:"post"})];case 1:return l.sent(),a.message.success(t("Deleted successfully")),[4,W()];case 2:return l.sent(),[3,4];case 3:return r=l.sent(),a.message.error((0,u.g)(r)),[3,4];case 4:return[2]}})})()}},l().createElement(a.Button,{type:"link",danger:!0},t("Delete"))))}}];return l().createElement(a.Card,{title:t("User LLM permissions"),extra:l().createElement(a.Button,{type:"primary",onClick:function(){N(void 0),C(""),r.setFieldsValue({enabled:!0,allowedLlmServices:[],allowAllModels:!0,allowedModels:[]}),V(!0)}},t("Add permission"))},l().createElement(a.Alert,{type:"info",showIcon:!0,style:{marginBottom:16},message:t("Users listed here are limited to the services selected below. Users without a record fall back to the general configuration.")}),l().createElement(a.Table,{rowKey:"id",columns:X,dataSource:v,loading:T,scroll:{x:1e3},pagination:{current:g,pageSize:20,total:y,showSizeChanger:!1,onChange:E}}),l().createElement(a.Modal,{title:D?t("Edit permission"):t("Add permission"),open:G,onCancel:function(){return V(!1)},onOk:function(){return d(function(){var n,l;return f(this,function(o){switch(o.label){case 0:return[4,r.validateFields()];case 1:n=o.sent(),q(!0),o.label=2;case 2:return o.trys.push([2,5,6,7]),[4,e.api.request({url:D?"aiApiUserPermissions:update/".concat(D.id):"aiApiUserPermissions:create",method:"post",data:n})];case 3:return o.sent(),a.message.success(t("Saved successfully")),V(!1),[4,W()];case 4:return o.sent(),[3,7];case 5:return l=o.sent(),a.message.error((0,u.g)(l)),[3,7];case 6:return q(!1),[7];case 7:return[2]}})})()},confirmLoading:z,destroyOnClose:!0},l().createElement(a.Form,{form:r,layout:"vertical",preserve:!1},l().createElement(a.Form.Item,{name:"userId",label:t("User"),rules:[{required:!0}]},l().createElement(a.Select,{disabled:!!D,showSearch:!0,filterOption:!1,onSearch:C,notFoundContent:null,options:A.map(function(e){return{label:Q(e),value:e.id}})})),l().createElement(a.Form.Item,{name:"allowedLlmServices",label:t("Allowed LLM services"),extra:t("Only services also enabled in the general configuration take effect.")},l().createElement(a.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:K})),l().createElement(a.Form.Item,{name:"allowAllModels",label:t("Allow all models"),valuePropName:"checked"},l().createElement(a.Switch,null)),!1===c&&l().createElement(a.Form.Item,{name:"allowedModels",label:t("Allowed models")},l().createElement(a.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:$})),l().createElement(a.Form.Item,{name:"enabled",label:t("Enabled"),valuePropName:"checked"},l().createElement(a.Switch,null)))))}},650:function(e,t,r){r.d(t,{k:function(){return a}});var n=r(694),l=JSON.parse('{"UU":"plugin-ai-api"}');function a(){var e=(0,n.useFlowEngine)();return function(t){return e.context.t(t,{ns:[l.UU,"client"]})}}},630:function(e,t,r){function n(e,t){var r,n;return e&&(void 0===e?"undefined":e&&"u">typeof Symbol&&e.constructor===Symbol?"symbol":typeof e)=="object"?null!=(r=null==(n=e.data)?void 0:n.data)?r:t:t}function l(e){var t;return(null!=(t=Error)&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t)?e.message:String(e)}r.d(t,{g:function(){return l},m:function(){return n}})}}]);
|
package/dist/client/index.js
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client"),require("@nocobase/flow-engine")):"function"==typeof define&&define.amd?define("plugin-ai-api",["@nocobase/client-v2","dayjs","react","antd","@nocobase/client","@nocobase/plugin-acl/client","@nocobase/flow-engine"],t):"object"==typeof exports?exports["plugin-ai-api"]=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client"),require("@nocobase/flow-engine")):e["plugin-ai-api"]=t(e["@nocobase/client-v2"],e.dayjs,e.react,e.antd,e["@nocobase/client"],e["@nocobase/plugin-acl/client"],e["@nocobase/flow-engine"])}(self,function(e,t,n,r,i,o,a){return function(){"use strict";var u,c,l,p={342:function(e){e.exports=i},485:function(t){t.exports=e},694:function(e){e.exports=a},79:function(e){e.exports=o},59:function(e){e.exports=r},185:function(e){e.exports=t},155:function(e){e.exports=n}},s={};function f(e){var t=s[e];if(void 0!==t)return t.exports;var n=s[e]={exports:{}};return p[e](n,n.exports,f),n.exports}f.m=p,f.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(t,{a:t}),t},f.d=function(e,t){for(var n in t)f.o(t,n)&&!f.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},f.f={},f.e=function(e){return Promise.all(Object.keys(f.f).reduce(function(t,n){return f.f[n](e,t),t},[]))},f.u=function(e){return""+e+"."+({286:"01c0e3c5fff3cccb",302:"fc3a3491b4ec2dfd",562:"17a0a299d2e5152c",757:"a01403fb7a1bea01",902:"92e1daaf1ab16ebf",97:"72979a11a067a7c9"})[e]+".js"},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},d={},f.l=function(e,t,n,r){if(d[e])return void d[e].push(t);if(void 0!==n)for(var i,o,a=document.getElementsByTagName("script"),u=0;u<a.length;u++){var c=a[u];if(c.getAttribute("src")==e||c.getAttribute("data-rspack")=="plugin-ai-api:"+n){i=c;break}}i||(o=!0,(i=document.createElement("script")).timeout=120,f.nc&&i.setAttribute("nonce",f.nc),i.setAttribute("data-rspack","plugin-ai-api:"+n),i.src=e),d[e]=[t];var l=function(t,n){i.onerror=i.onload=null,clearTimeout(p);var r=d[e];if(delete d[e],i.parentNode&&i.parentNode.removeChild(i),r&&r.forEach(function(e){return e(n)}),t)return t(n)},p=setTimeout(l.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=l.bind(null,i.onerror),i.onload=l.bind(null,i.onload),o&&document.head.appendChild(i)},f.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.g.importScripts&&(b=f.g.location+"");var d,b,g=f.g.document;if(!b&&g&&(g.currentScript&&"SCRIPT"===g.currentScript.tagName.toUpperCase()&&(b=g.currentScript.src),!b)){var h=g.getElementsByTagName("script");if(h.length)for(var y=h.length-1;y>-1&&(!b||!/^http(s?):/.test(b));)b=h[y--].src}if(!b)throw Error("Automatic publicPath is not supported in this browser");f.p=b.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),u={889:0},f.f.j=function(e,t){var n=f.o(u,e)?u[e]:void 0;if(0!==n)if(n)t.push(n[2]);else{var r=new Promise(function(t,r){n=u[e]=[t,r]});t.push(n[2]=r);var i=f.p+f.u(e),o=Error();f.l(i,function(t){if(f.o(u,e)&&(0!==(n=u[e])&&(u[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;o.message="Loading chunk "+e+" failed.\n("+r+": "+i+")",o.name="ChunkLoadError",o.type=r,o.request=i,n[1](o)}},"chunk-"+e,e)}},c=function(e,t){var n,r,i=t[0],o=t[1],a=t[2],c=0;if(i.some(function(e){return 0!==u[e]})){for(n in o)f.o(o,n)&&(f.m[n]=o[n]);a&&a(f)}for(e&&e(t);c<i.length;c++)r=i[c],f.o(u,r)&&u[r]&&u[r][0](),u[r]=0},(l=self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).forEach(c.bind(null,0)),l.push=c.bind(null,l.push.bind(l));var v={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src){var n=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"");n.indexOf("/static/plugins/plugin-ai-api/dist/client/")>=0&&(e=n.replace(/\/[^\/]+$/,"/"))}if(!e){var r=window.__webpack_public_path__||"";r&&("/"!==r.charAt(r.length-1)&&(r+="/"),e=r+"static/plugins/plugin-ai-api/dist/client/")}if(!e){var i=window.__nocobase_modern_client_prefix__||"v",o="/"+(i=String(i).replace(/^\/+|\/+$/g,"")||"v")+"/";if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var a=window.location.pathname||"/",u=a.indexOf(o);e=u>=0?a.slice(0,u+1):"/"}e&&(e=e.replace(RegExp("/"+i+"/?$"),"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/plugin-ai-api/dist/client/"}f.p=e}(),!function(){f.r(v),f.d(v,{default:function(){return w}});var e=f(342),t=f(79),n=f.n(t),r="pm.plugin-ai-api.configuration",i=f(155),o=f.n(i);function a(e,t,n,r,i,o,a){try{var u=e[o](a),c=u.value}catch(e){n(e);return}u.done?t(c):Promise.resolve(c).then(r,i)}function u(e,t,n){return(u=s()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&l(i,n.prototype),i}).apply(null,arguments)}function c(e){return(c=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function p(e){var t="function"==typeof Map?new Map:void 0;return(p=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 u(e,arguments,c(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),l(n,e)})(e)}function s(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(s=function(){return!!e})()}var d=o().lazy(function(){return f.e("302").then(f.bind(f,581))}),b=o().lazy(function(){return f.e("97").then(f.bind(f,760))}),g=o().lazy(function(){return f.e("562").then(f.bind(f,641))}),h=o().lazy(function(){return f.e("902").then(f.bind(f,77))}),y=o().lazy(function(){return f.e("757").then(f.bind(f,364))}),m=(0,e.lazy)(function(){return f.e("286").then(f.bind(f,421))},"AiApiRolePermissions").AiApiRolePermissions,w=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function i(){var e,t;if(!(this instanceof i))throw TypeError("Cannot call a class as a function");return e=i,t=arguments,e=c(e),function(e,t){var n;if(t&&("object"==((n=t)&&"u">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,s()?Reflect.construct(e,t||[],c(this).constructor):e.apply(this,t))}return i.prototype=Object.create(e&&e.prototype,{constructor:{value:i,writable:!0,configurable:!0}}),e&&l(i,e),t=[{key:"load",value:function(){var e;return(e=function(){var e;return function(e,t){var n,r,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(n)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&l[0]?r.return:l[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,l[1])).done)return i;switch(r=0,i&&(l=[2&l[0],i.value]),l[0]){case 0:case 1:i=l;break;case 4:return o.label++,{value:l[1],done:!1};case 5:o.label++,r=l[1],l=[0];continue;case 7:l=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===l[0]||2===l[0])){o=0;continue}if(3===l[0]&&(!i||l[1]>i[0]&&l[1]<i[3])){o.label=l[1];break}if(6===l[0]&&o.label<i[1]){o.label=i[1],i=l;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(l);break}i[2]&&o.ops.pop(),o.trys.pop();continue}l=t.call(e,o)}catch(e){l=[6,e],r=0}finally{n=i=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}(this,function(t){return this.app.pluginSettingsManager.add("ai-api",{icon:"ApiOutlined",title:this.t("AI API Gateway"),aclSnippet:r}),this.app.pluginSettingsManager.add("ai-api.config",{title:this.t("Configuration"),Component:d,aclSnippet:r,sort:1}),this.app.pluginSettingsManager.add("ai-api.model-pricing",{title:this.t("Model pricing"),Component:b,aclSnippet:r,sort:2}),this.app.pluginSettingsManager.add("ai-api.model-metadata",{title:this.t("Model metadata"),Component:g,aclSnippet:r,sort:3}),this.app.pluginSettingsManager.add("ai-api.user-quotas",{title:this.t("User quotas"),Component:h,aclSnippet:r,sort:4}),this.app.pluginSettingsManager.add("ai-api.usage",{title:this.t("Usage"),Component:y,aclSnippet:r,sort:5}),(null==(e=this.app.pm.get(n()))?void 0:e.settingsUI)&&e.settingsUI.addPermissionsTab(function(e){var t=e.t,n=e.TabLayout,r=e.activeRole;return{key:"aiApi",label:t("AI API",{ns:["plugin-ai-api","client"]}),sort:25,children:o().createElement(n,null,o().createElement(m,{role:r}))}}),[2]})},function(){var t=this,n=arguments;return new Promise(function(r,i){var o=e.apply(t,n);function u(e){a(o,r,i,u,c,"next",e)}function c(e){a(o,r,i,u,c,"throw",e)}u(void 0)})}).call(this)}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(i.prototype,t),i}(p(e.Plugin))}(),v}()});
|
|
10
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client"),require("@nocobase/flow-engine")):"function"==typeof define&&define.amd?define("plugin-ai-api",["@nocobase/client-v2","dayjs","react","antd","@nocobase/client","@nocobase/plugin-acl/client","@nocobase/flow-engine"],t):"object"==typeof exports?exports["plugin-ai-api"]=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client"),require("@nocobase/flow-engine")):e["plugin-ai-api"]=t(e["@nocobase/client-v2"],e.dayjs,e.react,e.antd,e["@nocobase/client"],e["@nocobase/plugin-acl/client"],e["@nocobase/flow-engine"])}(self,function(e,t,n,r,i,o,a){return function(){"use strict";var u,c,l,p={342:function(e){e.exports=i},485:function(t){t.exports=e},694:function(e){e.exports=a},79:function(e){e.exports=o},59:function(e){e.exports=r},185:function(e){e.exports=t},155:function(e){e.exports=n}},s={};function f(e){var t=s[e];if(void 0!==t)return t.exports;var n=s[e]={exports:{}};return p[e](n,n.exports,f),n.exports}f.m=p,f.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(t,{a:t}),t},f.d=function(e,t){for(var n in t)f.o(t,n)&&!f.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},f.f={},f.e=function(e){return Promise.all(Object.keys(f.f).reduce(function(t,n){return f.f[n](e,t),t},[]))},f.u=function(e){return""+e+"."+({123:"e6fe04c856ce6417",286:"01c0e3c5fff3cccb",302:"fc3a3491b4ec2dfd",562:"17a0a299d2e5152c",757:"a01403fb7a1bea01",902:"92e1daaf1ab16ebf",97:"72979a11a067a7c9"})[e]+".js"},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},d={},f.l=function(e,t,n,r){if(d[e])return void d[e].push(t);if(void 0!==n)for(var i,o,a=document.getElementsByTagName("script"),u=0;u<a.length;u++){var c=a[u];if(c.getAttribute("src")==e||c.getAttribute("data-rspack")=="plugin-ai-api:"+n){i=c;break}}i||(o=!0,(i=document.createElement("script")).timeout=120,f.nc&&i.setAttribute("nonce",f.nc),i.setAttribute("data-rspack","plugin-ai-api:"+n),i.src=e),d[e]=[t];var l=function(t,n){i.onerror=i.onload=null,clearTimeout(p);var r=d[e];if(delete d[e],i.parentNode&&i.parentNode.removeChild(i),r&&r.forEach(function(e){return e(n)}),t)return t(n)},p=setTimeout(l.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=l.bind(null,i.onerror),i.onload=l.bind(null,i.onload),o&&document.head.appendChild(i)},f.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.g.importScripts&&(b=f.g.location+"");var d,b,g=f.g.document;if(!b&&g&&(g.currentScript&&"SCRIPT"===g.currentScript.tagName.toUpperCase()&&(b=g.currentScript.src),!b)){var h=g.getElementsByTagName("script");if(h.length)for(var y=h.length-1;y>-1&&(!b||!/^http(s?):/.test(b));)b=h[y--].src}if(!b)throw Error("Automatic publicPath is not supported in this browser");f.p=b.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),u={889:0},f.f.j=function(e,t){var n=f.o(u,e)?u[e]:void 0;if(0!==n)if(n)t.push(n[2]);else{var r=new Promise(function(t,r){n=u[e]=[t,r]});t.push(n[2]=r);var i=f.p+f.u(e),o=Error();f.l(i,function(t){if(f.o(u,e)&&(0!==(n=u[e])&&(u[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;o.message="Loading chunk "+e+" failed.\n("+r+": "+i+")",o.name="ChunkLoadError",o.type=r,o.request=i,n[1](o)}},"chunk-"+e,e)}},c=function(e,t){var n,r,i=t[0],o=t[1],a=t[2],c=0;if(i.some(function(e){return 0!==u[e]})){for(n in o)f.o(o,n)&&(f.m[n]=o[n]);a&&a(f)}for(e&&e(t);c<i.length;c++)r=i[c],f.o(u,r)&&u[r]&&u[r][0](),u[r]=0},(l=self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).forEach(c.bind(null,0)),l.push=c.bind(null,l.push.bind(l));var v={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src){var n=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"");n.indexOf("/static/plugins/plugin-ai-api/dist/client/")>=0&&(e=n.replace(/\/[^\/]+$/,"/"))}if(!e){var r=window.__webpack_public_path__||"";r&&("/"!==r.charAt(r.length-1)&&(r+="/"),e=r+"static/plugins/plugin-ai-api/dist/client/")}if(!e){var i=window.__nocobase_modern_client_prefix__||"v",o="/"+(i=String(i).replace(/^\/+|\/+$/g,"")||"v")+"/";if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var a=window.location.pathname||"/",u=a.indexOf(o);e=u>=0?a.slice(0,u+1):"/"}e&&(e=e.replace(RegExp("/"+i+"/?$"),"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/plugin-ai-api/dist/client/"}f.p=e}(),!function(){f.r(v),f.d(v,{default:function(){return _}});var e=f(342),t=f(79),n=f.n(t),r="pm.plugin-ai-api.configuration",i=f(155),o=f.n(i);function a(e,t,n,r,i,o,a){try{var u=e[o](a),c=u.value}catch(e){n(e);return}u.done?t(c):Promise.resolve(c).then(r,i)}function u(e,t,n){return(u=s()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&l(i,n.prototype),i}).apply(null,arguments)}function c(e){return(c=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function p(e){var t="function"==typeof Map?new Map:void 0;return(p=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 u(e,arguments,c(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),l(n,e)})(e)}function s(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(s=function(){return!!e})()}var d=o().lazy(function(){return f.e("302").then(f.bind(f,581))}),b=o().lazy(function(){return f.e("97").then(f.bind(f,760))}),g=o().lazy(function(){return f.e("562").then(f.bind(f,641))}),h=o().lazy(function(){return f.e("123").then(f.bind(f,46))}),y=o().lazy(function(){return f.e("902").then(f.bind(f,77))}),m=o().lazy(function(){return f.e("757").then(f.bind(f,364))}),w=(0,e.lazy)(function(){return f.e("286").then(f.bind(f,421))},"AiApiRolePermissions").AiApiRolePermissions,_=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function i(){var e,t;if(!(this instanceof i))throw TypeError("Cannot call a class as a function");return e=i,t=arguments,e=c(e),function(e,t){var n;if(t&&("object"==((n=t)&&"u">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,s()?Reflect.construct(e,t||[],c(this).constructor):e.apply(this,t))}return i.prototype=Object.create(e&&e.prototype,{constructor:{value:i,writable:!0,configurable:!0}}),e&&l(i,e),t=[{key:"load",value:function(){var e;return(e=function(){var e;return function(e,t){var n,r,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(n)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&l[0]?r.return:l[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,l[1])).done)return i;switch(r=0,i&&(l=[2&l[0],i.value]),l[0]){case 0:case 1:i=l;break;case 4:return o.label++,{value:l[1],done:!1};case 5:o.label++,r=l[1],l=[0];continue;case 7:l=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===l[0]||2===l[0])){o=0;continue}if(3===l[0]&&(!i||l[1]>i[0]&&l[1]<i[3])){o.label=l[1];break}if(6===l[0]&&o.label<i[1]){o.label=i[1],i=l;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(l);break}i[2]&&o.ops.pop(),o.trys.pop();continue}l=t.call(e,o)}catch(e){l=[6,e],r=0}finally{n=i=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}(this,function(t){return this.app.pluginSettingsManager.add("ai-api",{icon:"ApiOutlined",title:this.t("AI API Gateway"),aclSnippet:r}),this.app.pluginSettingsManager.add("ai-api.config",{title:this.t("Configuration"),Component:d,aclSnippet:r,sort:1}),this.app.pluginSettingsManager.add("ai-api.model-pricing",{title:this.t("Model pricing"),Component:b,aclSnippet:r,sort:2}),this.app.pluginSettingsManager.add("ai-api.model-metadata",{title:this.t("Model metadata"),Component:g,aclSnippet:r,sort:3}),this.app.pluginSettingsManager.add("ai-api.user-permissions",{title:this.t("User LLM permissions"),Component:h,aclSnippet:"pm.plugin-ai-api.user-permissions",sort:4}),this.app.pluginSettingsManager.add("ai-api.user-quotas",{title:this.t("User quotas"),Component:y,aclSnippet:r,sort:5}),this.app.pluginSettingsManager.add("ai-api.usage",{title:this.t("Usage"),Component:m,aclSnippet:r,sort:6}),(null==(e=this.app.pm.get(n()))?void 0:e.settingsUI)&&e.settingsUI.addPermissionsTab(function(e){var t=e.t,n=e.TabLayout,r=e.activeRole;return{key:"aiApi",label:t("AI API",{ns:["plugin-ai-api","client"]}),sort:25,children:o().createElement(n,null,o().createElement(w,{role:r}))}}),[2]})},function(){var t=this,n=arguments;return new Promise(function(r,i){var o=e.apply(t,n);function u(e){a(o,r,i,u,c,"next",e)}function c(e){a(o,r,i,u,c,"throw",e)}u(void 0)})}).call(this)}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(i.prototype,t),i}(p(e.Plugin))}(),v}()});
|
|
@@ -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
|
+
"use strict";(self.webpackChunkplugin_ai_api_client_v2=self.webpackChunkplugin_ai_api_client_v2||[]).push([["123"],{46:function(e,t,r){r.r(t),r.d(t,{default:function(){return p}});var n=r(155),l=r.n(n),a=r(59),o=r(694),i=r(650),u=r(630);function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function c(e,t,r,n,l,a,o){try{var i=e[a](o),u=i.value}catch(e){r(e);return}i.done?t(u):Promise.resolve(u).then(n,l)}function d(e){return function(){var t=this,r=arguments;return new Promise(function(n,l){var a=e.apply(t,r);function o(e){c(a,n,l,o,i,"next",e)}function i(e){c(a,n,l,o,i,"throw",e)}o(void 0)})}}function m(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,l=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=l){var a=[],o=!0,i=!1;try{for(l=l.call(e);!(o=(r=l.next()).done)&&(a.push(r.value),!t||a.length!==t);o=!0);}catch(e){i=!0,n=e}finally{try{o||null==l.return||l.return()}finally{if(i)throw n}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return s(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return s(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function f(e,t){var r,n,l,a={label:0,sent:function(){if(1&l[0])throw l[1];return l[1]},trys:[],ops:[]},o=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(o,"next",{value:u(0)}),i(o,"throw",{value:u(1)}),i(o,"return",{value:u(2)}),"function"==typeof Symbol&&i(o,Symbol.iterator,{value:function(){return this}}),o;function u(i){return function(u){var s=[i,u];if(r)throw TypeError("Generator is already executing.");for(;o&&(o=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(l=2&s[0]?n.return:s[0]?n.throw||((l=n.return)&&l.call(n),0):n.next)&&!(l=l.call(n,s[1])).done)return l;switch(n=0,l&&(s=[2&s[0],l.value]),s[0]){case 0:case 1:l=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!(l=(l=a.trys).length>0&&l[l.length-1])&&(6===s[0]||2===s[0])){a=0;continue}if(3===s[0]&&(!l||s[1]>l[0]&&s[1]<l[3])){a.label=s[1];break}if(6===s[0]&&a.label<l[1]){a.label=l[1],l=s;break}if(l&&a.label<l[2]){a.label=l[2],a.ops.push(s);break}l[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=l=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}}}function p(){var e=(0,o.useFlowContext)(),t=(0,i.k)(),r=m(a.Form.useForm(),1)[0],s=a.Form.useWatch("allowedLlmServices",r),c=a.Form.useWatch("allowAllModels",r),p=m((0,n.useState)([]),2),v=p[0],h=p[1],b=m((0,n.useState)(0),2),y=b[0],w=b[1],S=m((0,n.useState)(1),2),g=S[0],E=S[1],k=m((0,n.useState)([]),2),A=k[0],M=k[1],I=m((0,n.useState)(""),2),F=I[0],C=I[1],U=m((0,n.useState)([]),2),x=U[0],L=U[1],P=m((0,n.useState)(!1),2),T=P[0],O=P[1],_=m((0,n.useState)(!1),2),j=_[0],z=_[1],q=m((0,n.useState)(),2),B=q[0],D=q[1],N=m((0,n.useState)(!1),2),G=N[0],V=N[1],W=(0,n.useCallback)(function(){return d(function(){var t,r,n,l,o,i,s;return f(this,function(c){switch(c.label){case 0:O(!0),c.label=1;case 1:return c.trys.push([1,3,4,5]),[4,Promise.all([e.api.request({url:"aiApiUserPermissions:list",method:"get",params:{page:g,pageSize:20,appends:["user"],sort:"-updatedAt"}}),e.api.request({url:"ai:listAllEnabledModels",method:"get"})])];case 2:return o=(l=m.apply(void 0,[c.sent(),2]))[0],i=l[1],h((0,u.m)(o,[])),w(null!=(t=null==o||null==(n=o.data)||null==(r=n.meta)?void 0:r.count)?t:0),L((0,u.m)(i,[])),[3,5];case 3:return s=c.sent(),a.message.error((0,u.g)(s)),[3,5];case 4:return O(!1),[7];case 5:return[2]}})})()},[e.api,g]);(0,n.useEffect)(function(){W()},[W]);var J=(0,n.useCallback)(function(t){return d(function(){var r,n;return f(this,function(l){switch(l.label){case 0:return l.trys.push([0,2,,3]),[4,e.api.request({url:"aiApiUserPermissions:listUsers",method:"get",params:{keyword:t,pageSize:50,excludeGranted:!B}})];case 1:return r=l.sent(),M((0,u.m)(r,[])),[3,3];case 2:return n=l.sent(),a.message.error((0,u.g)(n)),[3,3];case 3:return[2]}})})()},[e.api,B]);(0,n.useEffect)(function(){if(G){var e=setTimeout(function(){return J(F)},300);return function(){return clearTimeout(e)}}},[G,F,J]);var K=(0,n.useMemo)(function(){return x.map(function(e){return{label:e.llmServiceTitle||e.llmService,value:e.llmService}})},[x]),$=(0,n.useMemo)(function(){var e=new Set(s||[]);return x.filter(function(t){return e.has(t.llmService)}).flatMap(function(e){return(e.enabledModels||[]).map(function(t){return{label:"".concat(e.llmServiceTitle||e.llmService," / ").concat(t.label||t.value),value:"".concat(e.llmService,"/").concat(t.value)}})})},[x,s]),H=function(e){D(e),C(""),M(e.user?[e.user]:[]),r.setFieldsValue({userId:e.userId,enabled:e.enabled,allowAllModels:e.allowAllModels,allowedLlmServices:e.allowedLlmServices||[],allowedModels:e.allowedModels||[]}),V(!0)},Q=function(e){var t;return(null==e?void 0:e.nickname)||(null==e?void 0:e.username)||(null==e?void 0:e.email)||String(null!=(t=null==e?void 0:e.id)?t:"")},R=function(e){var t;return(null==(t=K.find(function(t){return t.value===e}))?void 0:t.label)||e},X=[{title:t("User"),key:"user",width:180,render:function(e,t){return Q(t.user)||String(t.userId)}},{title:t("Allowed LLM services"),dataIndex:"allowedLlmServices",key:"allowedLlmServices",render:function(e){return(null==e?void 0:e.length)?l().createElement(a.Space,{size:[0,4],wrap:!0},e.map(function(e){return l().createElement(a.Tag,{key:e},R(e))})):l().createElement(a.Tag,{color:"red"},t("No service allowed"))}},{title:t("Allowed models"),key:"allowedModels",width:220,render:function(e,r){return r.allowAllModels?l().createElement(a.Tag,{color:"blue"},t("All models of allowed services")):l().createElement(a.Space,{size:[0,4],wrap:!0},(r.allowedModels||[]).map(function(e){return l().createElement(a.Tag,{key:e},e)}))}},{title:t("Status"),dataIndex:"enabled",key:"enabled",width:100,render:function(e){return l().createElement(a.Tag,{color:e?"green":"default"},e?t("Enabled"):t("Disabled"))}},{title:t("Actions"),key:"actions",width:150,fixed:"right",render:function(r,n){return l().createElement(a.Space,{size:0},l().createElement(a.Button,{type:"link",onClick:function(){return H(n)}},t("Edit")),l().createElement(a.Popconfirm,{title:t("Delete this permission?"),onConfirm:function(){return d(function(){var r;return f(this,function(l){switch(l.label){case 0:return l.trys.push([0,3,,4]),[4,e.api.request({url:"aiApiUserPermissions:destroy/".concat(n.id),method:"post"})];case 1:return l.sent(),a.message.success(t("Deleted successfully")),[4,W()];case 2:return l.sent(),[3,4];case 3:return r=l.sent(),a.message.error((0,u.g)(r)),[3,4];case 4:return[2]}})})()}},l().createElement(a.Button,{type:"link",danger:!0},t("Delete"))))}}];return l().createElement(a.Card,{title:t("User LLM permissions"),extra:l().createElement(a.Button,{type:"primary",onClick:function(){D(void 0),C(""),r.setFieldsValue({enabled:!0,allowedLlmServices:[],allowAllModels:!0,allowedModels:[]}),V(!0)}},t("Add permission"))},l().createElement(a.Alert,{type:"info",showIcon:!0,style:{marginBottom:16},message:t("Users listed here are limited to the services selected below. Users without a record fall back to the general configuration.")}),l().createElement(a.Table,{rowKey:"id",columns:X,dataSource:v,loading:T,scroll:{x:1e3},pagination:{current:g,pageSize:20,total:y,showSizeChanger:!1,onChange:E}}),l().createElement(a.Modal,{title:B?t("Edit permission"):t("Add permission"),open:G,onCancel:function(){return V(!1)},onOk:function(){return d(function(){var n,l;return f(this,function(o){switch(o.label){case 0:return[4,r.validateFields()];case 1:n=o.sent(),z(!0),o.label=2;case 2:return o.trys.push([2,5,6,7]),[4,e.api.request({url:B?"aiApiUserPermissions:update/".concat(B.id):"aiApiUserPermissions:create",method:"post",data:n})];case 3:return o.sent(),a.message.success(t("Saved successfully")),V(!1),[4,W()];case 4:return o.sent(),[3,7];case 5:return l=o.sent(),a.message.error((0,u.g)(l)),[3,7];case 6:return z(!1),[7];case 7:return[2]}})})()},confirmLoading:j,destroyOnClose:!0},l().createElement(a.Form,{form:r,layout:"vertical",preserve:!1},l().createElement(a.Form.Item,{name:"userId",label:t("User"),rules:[{required:!0}]},l().createElement(a.Select,{disabled:!!B,showSearch:!0,filterOption:!1,onSearch:C,notFoundContent:null,options:A.map(function(e){return{label:Q(e),value:e.id}})})),l().createElement(a.Form.Item,{name:"allowedLlmServices",label:t("Allowed LLM services"),extra:t("Only services also enabled in the general configuration take effect.")},l().createElement(a.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:K})),l().createElement(a.Form.Item,{name:"allowAllModels",label:t("Allow all models"),valuePropName:"checked"},l().createElement(a.Switch,null)),!1===c&&l().createElement(a.Form.Item,{name:"allowedModels",label:t("Allowed models")},l().createElement(a.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:$})),l().createElement(a.Form.Item,{name:"enabled",label:t("Enabled"),valuePropName:"checked"},l().createElement(a.Switch,null)))))}},650:function(e,t,r){r.d(t,{k:function(){return a}});var n=r(694),l=JSON.parse('{"UU":"plugin-ai-api"}');function a(){var e=(0,n.useFlowEngine)();return function(t){return e.context.t(t,{ns:[l.UU,"client"]})}}},630:function(e,t,r){function n(e,t){var r,n;return e&&(void 0===e?"undefined":e&&"u">typeof Symbol&&e.constructor===Symbol?"symbol":typeof e)=="object"?null!=(r=null==(n=e.data)?void 0:n.data)?r:t:t}function l(e){var t;return(null!=(t=Error)&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t)?e.message:String(e)}r.d(t,{g:function(){return l},m:function(){return n}})}}]);
|
package/dist/client-v2/index.js
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/flow-engine")):"function"==typeof define&&define.amd?define("plugin-ai-api/client-v2",["@nocobase/client-v2","dayjs","react","antd","@nocobase/flow-engine"],t):"object"==typeof exports?exports["plugin-ai-api/client-v2"]=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/flow-engine")):e["plugin-ai-api/client-v2"]=t(e["@nocobase/client-v2"],e.dayjs,e.react,e.antd,e["@nocobase/flow-engine"])}(self,function(e,t,n,r,
|
|
10
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/flow-engine")):"function"==typeof define&&define.amd?define("plugin-ai-api/client-v2",["@nocobase/client-v2","dayjs","react","antd","@nocobase/flow-engine"],t):"object"==typeof exports?exports["plugin-ai-api/client-v2"]=t(require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@nocobase/flow-engine")):e["plugin-ai-api/client-v2"]=t(e["@nocobase/client-v2"],e.dayjs,e.react,e.antd,e["@nocobase/flow-engine"])}(self,function(e,t,n,r,i){return function(){"use strict";var o,a,u,c={485:function(t){t.exports=e},694:function(e){e.exports=i},59:function(e){e.exports=r},185:function(e){e.exports=t},155:function(e){e.exports=n}},l={};function p(e){var t=l[e];if(void 0!==t)return t.exports;var n=l[e]={exports:{}};return c[e](n,n.exports,p),n.exports}p.m=c,p.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return p.d(t,{a:t}),t},p.d=function(e,t){for(var n in t)p.o(t,n)&&!p.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},p.f={},p.e=function(e){return Promise.all(Object.keys(p.f).reduce(function(t,n){return p.f[n](e,t),t},[]))},p.u=function(e){return""+e+"."+({123:"05f1f649923f93eb",302:"d27fe4ea9b0b3bf5",562:"fb2948ee6402de95",757:"a117ce1cf7119cea",902:"9054d990ddc223ac",952:"94100128b7757f56",97:"29c663318eebbd57"})[e]+".js"},p.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),p.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},s={},p.l=function(e,t,n,r){if(s[e])return void s[e].push(t);if(void 0!==n)for(var i,o,a=document.getElementsByTagName("script"),u=0;u<a.length;u++){var c=a[u];if(c.getAttribute("src")==e||c.getAttribute("data-rspack")=="plugin-ai-api/client-v2:"+n){i=c;break}}i||(o=!0,(i=document.createElement("script")).timeout=120,p.nc&&i.setAttribute("nonce",p.nc),i.setAttribute("data-rspack","plugin-ai-api/client-v2:"+n),i.src=e),s[e]=[t];var l=function(t,n){i.onerror=i.onload=null,clearTimeout(f);var r=s[e];if(delete s[e],i.parentNode&&i.parentNode.removeChild(i),r&&r.forEach(function(e){return e(n)}),t)return t(n)},f=setTimeout(l.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=l.bind(null,i.onerror),i.onload=l.bind(null,i.onload),o&&document.head.appendChild(i)},p.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},p.g.importScripts&&(f=p.g.location+"");var s,f,d=p.g.document;if(!f&&d&&(d.currentScript&&"SCRIPT"===d.currentScript.tagName.toUpperCase()&&(f=d.currentScript.src),!f)){var b=d.getElementsByTagName("script");if(b.length)for(var g=b.length-1;g>-1&&(!f||!/^http(s?):/.test(f));)f=b[g--].src}if(!f)throw Error("Automatic publicPath is not supported in this browser");p.p=f.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o={889:0},p.f.j=function(e,t){var n=p.o(o,e)?o[e]:void 0;if(0!==n)if(n)t.push(n[2]);else{var r=new Promise(function(t,r){n=o[e]=[t,r]});t.push(n[2]=r);var i=p.p+p.u(e),a=Error();p.l(i,function(t){if(p.o(o,e)&&(0!==(n=o[e])&&(o[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;a.message="Loading chunk "+e+" failed.\n("+r+": "+i+")",a.name="ChunkLoadError",a.type=r,a.request=i,n[1](a)}},"chunk-"+e,e)}},a=function(e,t){var n,r,i=t[0],a=t[1],u=t[2],c=0;if(i.some(function(e){return 0!==o[e]})){for(n in a)p.o(a,n)&&(p.m[n]=a[n]);u&&u(p)}for(e&&e(t);c<i.length;c++)r=i[c],p.o(o,r)&&o[r]&&o[r][0](),o[r]=0},(u=self.webpackChunkplugin_ai_api_client_v2=self.webpackChunkplugin_ai_api_client_v2||[]).forEach(a.bind(null,0)),u.push=a.bind(null,u.push.bind(u));var h={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src){var n=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"");n.indexOf("/static/plugins/plugin-ai-api/dist/client-v2/")>=0&&(e=n.replace(/\/[^\/]+$/,"/"))}if(!e){var r=window.__webpack_public_path__||"";r&&("/"!==r.charAt(r.length-1)&&(r+="/"),e=r+"static/plugins/plugin-ai-api/dist/client-v2/")}if(!e){var i=window.__nocobase_modern_client_prefix__||"v",o="/"+(i=String(i).replace(/^\/+|\/+$/g,"")||"v")+"/";if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var a=window.location.pathname||"/",u=a.indexOf(o);e=u>=0?a.slice(0,u+1):"/"}e&&(e=e.replace(RegExp("/"+i+"/?$"),"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/plugin-ai-api/dist/client-v2/"}p.p=e}(),!function(){p.r(h),p.d(h,{default:function(){return c}}),p(155);var e=p(485),t="pm.plugin-ai-api.configuration";function n(e,t,n,r,i,o,a){try{var u=e[o](a),c=u.value}catch(e){n(e);return}u.done?t(c):Promise.resolve(c).then(r,i)}function r(e,t,n){return(r=u()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&o(i,n.prototype),i}).apply(null,arguments)}function i(e){return(i=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function o(e,t){return(o=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function a(e){var t="function"==typeof Map?new Map:void 0;return(a=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 r(e,arguments,i(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),o(n,e)})(e)}function u(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(u=function(){return!!e})()}var c=function(e){var r;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function a(){var e,t;if(!(this instanceof a))throw TypeError("Cannot call a class as a function");return e=a,t=arguments,e=i(e),function(e,t){var n;if(t&&("object"==((n=t)&&"u">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,u()?Reflect.construct(e,t||[],i(this).constructor):e.apply(this,t))}return a.prototype=Object.create(e&&e.prototype,{constructor:{value:a,writable:!0,configurable:!0}}),e&&o(a,e),r=[{key:"load",value:function(){var e;return(e=function(){var e,n,r;return function(e,t){var n,r,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(a,"next",{value:c(0)}),u(a,"throw",{value:c(1)}),u(a,"return",{value:c(2)}),"function"==typeof Symbol&&u(a,Symbol.iterator,{value:function(){return this}}),a;function c(u){return function(c){var l=[u,c];if(n)throw TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&l[0]?r.return:l[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,l[1])).done)return i;switch(r=0,i&&(l=[2&l[0],i.value]),l[0]){case 0:case 1:i=l;break;case 4:return o.label++,{value:l[1],done:!1};case 5:o.label++,r=l[1],l=[0];continue;case 7:l=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===l[0]||2===l[0])){o=0;continue}if(3===l[0]&&(!i||l[1]>i[0]&&l[1]<i[3])){o.label=l[1];break}if(6===l[0]&&o.label<i[1]){o.label=i[1],i=l;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(l);break}i[2]&&o.ops.pop(),o.trys.pop();continue}l=t.call(e,o)}catch(e){l=[6,e],r=0}finally{n=i=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}(this,function(i){return this.pluginSettingsManager.addMenuItem({key:"ai-api",title:this.t("AI API Gateway"),icon:"ApiOutlined",aclSnippet:t}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"index",title:this.t("Configuration"),aclSnippet:t,sort:1,componentLoader:function(){return p.e("302").then(p.bind(p,581))}}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"model-pricing",title:this.t("Model pricing"),aclSnippet:t,sort:2,componentLoader:function(){return p.e("97").then(p.bind(p,760))}}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"model-metadata",title:this.t("Model metadata"),aclSnippet:t,sort:3,componentLoader:function(){return p.e("562").then(p.bind(p,641))}}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"user-permissions",title:this.t("User LLM permissions"),aclSnippet:"pm.plugin-ai-api.user-permissions",sort:4,componentLoader:function(){return p.e("123").then(p.bind(p,46))}}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"user-quotas",title:this.t("User quotas"),aclSnippet:t,sort:5,componentLoader:function(){return p.e("902").then(p.bind(p,77))}}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"usage",title:this.t("Usage"),aclSnippet:t,sort:6,componentLoader:function(){return p.e("757").then(p.bind(p,364))}}),null==(r=this.app.pm.get("@nocobase/plugin-acl"))||null==(n=r.settingsUI)||null==(e=n.addPermissionsTab)||e.call(n,{key:"aiApi",label:this.t("AI API"),sort:25,componentLoader:function(){return p.e("952").then(p.bind(p,699))}}),[2]})},function(){var t=this,r=arguments;return new Promise(function(i,o){var a=e.apply(t,r);function u(e){n(a,i,o,u,c,"next",e)}function c(e){n(a,i,o,u,c,"throw",e)}u(void 0)})}).call(this)}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(a.prototype,r),a}(a(e.Plugin))}(),h}()});
|
package/dist/constants.js
CHANGED
|
@@ -26,11 +26,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
26
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
27
|
var constants_exports = {};
|
|
28
28
|
__export(constants_exports, {
|
|
29
|
-
AI_API_ACL_SNIPPET: () => AI_API_ACL_SNIPPET
|
|
29
|
+
AI_API_ACL_SNIPPET: () => AI_API_ACL_SNIPPET,
|
|
30
|
+
AI_API_USER_PERMISSIONS_SNIPPET: () => AI_API_USER_PERMISSIONS_SNIPPET
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(constants_exports);
|
|
32
33
|
const AI_API_ACL_SNIPPET = "pm.plugin-ai-api.configuration";
|
|
34
|
+
const AI_API_USER_PERMISSIONS_SNIPPET = "pm.plugin-ai-api.user-permissions";
|
|
33
35
|
// Annotate the CommonJS export names for ESM import in node:
|
|
34
36
|
0 && (module.exports = {
|
|
35
|
-
AI_API_ACL_SNIPPET
|
|
37
|
+
AI_API_ACL_SNIPPET,
|
|
38
|
+
AI_API_USER_PERMISSIONS_SNIPPET
|
|
36
39
|
});
|
package/dist/locale/en-US.json
CHANGED
|
@@ -101,5 +101,16 @@
|
|
|
101
101
|
"Select which AI Employees this role may use:": "Select which AI Employees this role may use:",
|
|
102
102
|
"Select allowed AI Employees": "Select allowed AI Employees",
|
|
103
103
|
"Max request body size (MB)": "Max request body size (MB)",
|
|
104
|
-
"Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.": "Raise this to accept inline base64 images. Base64 adds about 33% to the original file size."
|
|
104
|
+
"Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.": "Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.",
|
|
105
|
+
"User LLM permissions": "User LLM permissions",
|
|
106
|
+
"Add permission": "Add permission",
|
|
107
|
+
"Edit permission": "Edit permission",
|
|
108
|
+
"Delete this permission?": "Delete this permission?",
|
|
109
|
+
"Allowed LLM services": "Allowed LLM services",
|
|
110
|
+
"Allow all models": "Allow all models",
|
|
111
|
+
"Allowed models": "Allowed models",
|
|
112
|
+
"No service allowed": "No service allowed",
|
|
113
|
+
"All models of allowed services": "All models of allowed services",
|
|
114
|
+
"Users listed here are limited to the services selected below. Users without a record fall back to the general configuration.": "Users listed here are limited to the services selected below. Users without a record fall back to the general configuration.",
|
|
115
|
+
"Only services also enabled in the general configuration take effect.": "Only services also enabled in the general configuration take effect."
|
|
105
116
|
}
|
package/dist/locale/vi-VN.json
CHANGED
|
@@ -101,5 +101,16 @@
|
|
|
101
101
|
"Select which AI Employees this role may use:": "Chọn AI Employee mà vai trò này được dùng:",
|
|
102
102
|
"Select allowed AI Employees": "Chọn AI Employee được phép",
|
|
103
103
|
"Max request body size (MB)": "Giới hạn kích thước request body (MB)",
|
|
104
|
-
"Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.": "Tăng giá trị này để nhận ảnh base64 gửi trực tiếp. Base64 làm tăng khoảng 33% so với kích thước tệp gốc."
|
|
104
|
+
"Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.": "Tăng giá trị này để nhận ảnh base64 gửi trực tiếp. Base64 làm tăng khoảng 33% so với kích thước tệp gốc.",
|
|
105
|
+
"User LLM permissions": "Phân quyền LLM theo người dùng",
|
|
106
|
+
"Add permission": "Thêm phân quyền",
|
|
107
|
+
"Edit permission": "Sửa phân quyền",
|
|
108
|
+
"Delete this permission?": "Xoá phân quyền này?",
|
|
109
|
+
"Allowed LLM services": "Dịch vụ LLM được phép",
|
|
110
|
+
"Allow all models": "Cho phép tất cả model",
|
|
111
|
+
"Allowed models": "Model được phép",
|
|
112
|
+
"No service allowed": "Không được phép dịch vụ nào",
|
|
113
|
+
"All models of allowed services": "Tất cả model của các dịch vụ được phép",
|
|
114
|
+
"Users listed here are limited to the services selected below. Users without a record fall back to the general configuration.": "Người dùng có trong danh sách này chỉ được dùng các dịch vụ được chọn bên dưới. Người dùng không có bản ghi sẽ dùng theo cấu hình chung.",
|
|
115
|
+
"Only services also enabled in the general configuration take effect.": "Chỉ những dịch vụ đồng thời được bật trong cấu hình chung mới có hiệu lực."
|
|
105
116
|
}
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -101,5 +101,16 @@
|
|
|
101
101
|
"Select which AI Employees this role may use:": "选择此角色可使用的 AI 员工:",
|
|
102
102
|
"Select allowed AI Employees": "选择允许的 AI 员工",
|
|
103
103
|
"Max request body size (MB)": "请求体大小上限(MB)",
|
|
104
|
-
"Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.": "调高此值以接收内联 base64 图片。base64 编码会使体积增加约 33%。"
|
|
104
|
+
"Raise this to accept inline base64 images. Base64 adds about 33% to the original file size.": "调高此值以接收内联 base64 图片。base64 编码会使体积增加约 33%。",
|
|
105
|
+
"User LLM permissions": "用户 LLM 权限",
|
|
106
|
+
"Add permission": "添加权限",
|
|
107
|
+
"Edit permission": "编辑权限",
|
|
108
|
+
"Delete this permission?": "确定删除此权限?",
|
|
109
|
+
"Allowed LLM services": "允许的 LLM 服务",
|
|
110
|
+
"Allow all models": "允许所有模型",
|
|
111
|
+
"Allowed models": "允许的模型",
|
|
112
|
+
"No service allowed": "未允许任何服务",
|
|
113
|
+
"All models of allowed services": "允许服务下的所有模型",
|
|
114
|
+
"Users listed here are limited to the services selected below. Users without a record fall back to the general configuration.": "此处列出的用户仅能使用下方所选的服务;没有记录的用户按通用配置处理。",
|
|
115
|
+
"Only services also enabled in the general configuration take effect.": "仅当服务同时在通用配置中启用时才会生效。"
|
|
105
116
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
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 ai_api_user_permissions_exports = {};
|
|
28
|
+
__export(ai_api_user_permissions_exports, {
|
|
29
|
+
default: () => ai_api_user_permissions_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(ai_api_user_permissions_exports);
|
|
32
|
+
var import_database = require("@nocobase/database");
|
|
33
|
+
var ai_api_user_permissions_default = (0, import_database.defineCollection)({
|
|
34
|
+
name: "aiApiUserPermissions",
|
|
35
|
+
autoGenId: true,
|
|
36
|
+
fields: [
|
|
37
|
+
{ name: "userId", type: "bigInt", allowNull: false, index: true },
|
|
38
|
+
{
|
|
39
|
+
name: "user",
|
|
40
|
+
type: "belongsTo",
|
|
41
|
+
target: "users",
|
|
42
|
+
targetKey: "id",
|
|
43
|
+
foreignKey: "userId",
|
|
44
|
+
constraints: false
|
|
45
|
+
},
|
|
46
|
+
{ name: "enabled", type: "boolean", defaultValue: true, index: true },
|
|
47
|
+
{
|
|
48
|
+
name: "allowedLlmServices",
|
|
49
|
+
type: "json",
|
|
50
|
+
defaultValue: [],
|
|
51
|
+
comment: "LLM service names/titles this user may use. Empty means the user is denied every service."
|
|
52
|
+
},
|
|
53
|
+
{ name: "allowAllModels", type: "boolean", defaultValue: true },
|
|
54
|
+
{
|
|
55
|
+
name: "allowedModels",
|
|
56
|
+
type: "json",
|
|
57
|
+
defaultValue: [],
|
|
58
|
+
comment: 'Array of "serviceName/modelId" this user may use (when allowAllModels=false)'
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
indexes: [
|
|
62
|
+
{
|
|
63
|
+
fields: ["userId"],
|
|
64
|
+
unique: true
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
});
|
package/dist/server/plugin.js
CHANGED
|
@@ -44,8 +44,10 @@ var import_server = require("@nocobase/server");
|
|
|
44
44
|
var import_router = require("./routes/router");
|
|
45
45
|
var import_ai_api_config = __toESM(require("./resource/ai-api-config"));
|
|
46
46
|
var import_ai_api_usage_monitor = __toESM(require("./resource/ai-api-usage-monitor"));
|
|
47
|
+
var import_ai_api_user_permissions = __toESM(require("./resource/ai-api-user-permissions"));
|
|
47
48
|
var import_rate_limiter = require("./utils/rate-limiter");
|
|
48
49
|
var import_role_permission = require("./middleware/role-permission");
|
|
50
|
+
var import_user_permissions = require("./utils/user-permissions");
|
|
49
51
|
var import_validation = require("./validation");
|
|
50
52
|
var import_constants = require("../constants");
|
|
51
53
|
var import_dayjs = __toESM(require("dayjs"));
|
|
@@ -84,12 +86,19 @@ class PluginAiApiServer extends import_server.Plugin {
|
|
|
84
86
|
this.app.use((0, import_router.createAiLlmRouter)(this), { after: "idp-oauth-resource-auth", before: "resourcer" });
|
|
85
87
|
this.app.resourceManager.define(import_ai_api_config.default);
|
|
86
88
|
this.app.resourceManager.define(import_ai_api_usage_monitor.default);
|
|
89
|
+
this.app.resourceManager.define(import_ai_api_user_permissions.default);
|
|
87
90
|
this.app.db.on("aiApiRolePermissions.afterSave", (model) => {
|
|
88
91
|
(0, import_role_permission.invalidateRolePermissionCache)(model.get("roleName"));
|
|
89
92
|
});
|
|
90
93
|
this.app.db.on("aiApiRolePermissions.afterDestroy", (model) => {
|
|
91
94
|
(0, import_role_permission.invalidateRolePermissionCache)(model.get("roleName"));
|
|
92
95
|
});
|
|
96
|
+
this.app.db.on("aiApiUserPermissions.afterSave", (model, options) => {
|
|
97
|
+
this.revokeUserPermissions(model.get("userId"), options == null ? void 0 : options.transaction);
|
|
98
|
+
});
|
|
99
|
+
this.app.db.on("aiApiUserPermissions.afterDestroy", (model, options) => {
|
|
100
|
+
this.revokeUserPermissions(model.get("userId"), options == null ? void 0 : options.transaction);
|
|
101
|
+
});
|
|
93
102
|
this.app.acl.registerSnippet({
|
|
94
103
|
name: import_constants.AI_API_ACL_SNIPPET,
|
|
95
104
|
actions: [
|
|
@@ -105,9 +114,32 @@ class PluginAiApiServer extends import_server.Plugin {
|
|
|
105
114
|
"aiApiUsageMonitor:summary"
|
|
106
115
|
]
|
|
107
116
|
});
|
|
117
|
+
this.app.acl.registerSnippet({
|
|
118
|
+
name: import_constants.AI_API_USER_PERMISSIONS_SNIPPET,
|
|
119
|
+
actions: ["aiApiUserPermissions:*"]
|
|
120
|
+
});
|
|
108
121
|
this.gcInterval = setInterval(() => this.rateLimiter.gc(), 5 * 60 * 1e3);
|
|
109
122
|
this.gcInterval.unref();
|
|
110
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Drop a user's cached LLM scope on every node.
|
|
126
|
+
*
|
|
127
|
+
* The local call is not redundant: syncMessageManager hardcodes skipSelf, so the publishing
|
|
128
|
+
* node never receives its own message. Passing the transaction defers the broadcast until
|
|
129
|
+
* the write commits, so other nodes cannot re-read the old row and re-cache it.
|
|
130
|
+
*/
|
|
131
|
+
revokeUserPermissions(userId, transaction) {
|
|
132
|
+
(0, import_user_permissions.invalidateUserPermissionCache)(userId);
|
|
133
|
+
this.sendSyncMessage({ type: "invalidateUserPermissions", userId }, { transaction });
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Received only on the *other* nodes (skipSelf), so this must not re-broadcast.
|
|
137
|
+
*/
|
|
138
|
+
async handleSyncMessage(message) {
|
|
139
|
+
if ((message == null ? void 0 : message.type) === "invalidateUserPermissions") {
|
|
140
|
+
(0, import_user_permissions.invalidateUserPermissionCache)(message.userId);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
111
143
|
async install() {
|
|
112
144
|
const existing = await this.db.getRepository("aiApiConfig").findOne();
|
|
113
145
|
if (!existing) {
|
|
@@ -0,0 +1,75 @@
|
|
|
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 ai_api_user_permissions_exports = {};
|
|
28
|
+
__export(ai_api_user_permissions_exports, {
|
|
29
|
+
default: () => ai_api_user_permissions_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(ai_api_user_permissions_exports);
|
|
32
|
+
const MAX_PAGE_SIZE = 100;
|
|
33
|
+
const aiApiUserPermissionsResource = {
|
|
34
|
+
name: "aiApiUserPermissions",
|
|
35
|
+
actions: {
|
|
36
|
+
async listUsers(ctx, next) {
|
|
37
|
+
const params = ctx.action.params || {};
|
|
38
|
+
const keyword = typeof params.keyword === "string" ? params.keyword.trim() : "";
|
|
39
|
+
const page = Math.max(1, Number(params.page) || 1);
|
|
40
|
+
const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, Number(params.pageSize) || 50));
|
|
41
|
+
const filter = keyword ? {
|
|
42
|
+
$or: [
|
|
43
|
+
{ nickname: { $includes: keyword } },
|
|
44
|
+
{ username: { $includes: keyword } },
|
|
45
|
+
{ email: { $includes: keyword } }
|
|
46
|
+
]
|
|
47
|
+
} : {};
|
|
48
|
+
if (params.excludeGranted) {
|
|
49
|
+
const granted = await ctx.db.getRepository("aiApiUserPermissions").find({ fields: ["userId"] });
|
|
50
|
+
const ids = granted.map((row) => row.get("userId")).filter((id) => id !== null && id !== void 0);
|
|
51
|
+
if (ids.length) filter.id = { $notIn: ids };
|
|
52
|
+
}
|
|
53
|
+
const [rows, count] = await ctx.db.getRepository("users").findAndCount({
|
|
54
|
+
filter,
|
|
55
|
+
fields: ["id", "nickname", "username", "email"],
|
|
56
|
+
sort: ["nickname", "id"],
|
|
57
|
+
offset: (page - 1) * pageSize,
|
|
58
|
+
limit: pageSize
|
|
59
|
+
});
|
|
60
|
+
ctx.body = {
|
|
61
|
+
rows: rows.map((row) => ({
|
|
62
|
+
id: row.get("id"),
|
|
63
|
+
nickname: row.get("nickname"),
|
|
64
|
+
username: row.get("username"),
|
|
65
|
+
email: row.get("email")
|
|
66
|
+
})),
|
|
67
|
+
count,
|
|
68
|
+
page,
|
|
69
|
+
pageSize
|
|
70
|
+
};
|
|
71
|
+
await next();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var ai_api_user_permissions_default = aiApiUserPermissionsResource;
|
|
@@ -32,6 +32,7 @@ module.exports = __toCommonJS(agent_completions_exports);
|
|
|
32
32
|
var import_openai_format = require("../utils/openai-format");
|
|
33
33
|
var import_resolve_service = require("../utils/resolve-service");
|
|
34
34
|
var import_role_permission = require("../middleware/role-permission");
|
|
35
|
+
var import_user_permissions = require("../utils/user-permissions");
|
|
35
36
|
var import_streaming = require("../utils/streaming");
|
|
36
37
|
var import_ai_employee_runtime = require("../utils/ai-employee-runtime");
|
|
37
38
|
var import_usage = require("../usage");
|
|
@@ -88,6 +89,10 @@ async function handleAgentCompletions(ctx, plugin) {
|
|
|
88
89
|
ctx.body = (0, import_openai_format.toOpenAIError)(404, "LLM service is disabled", "invalid_request_error", "model_not_found");
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
92
|
+
const globalEnabledServices = config ? config.get("enabledLlmServices") || config.enabledLlmServices : [];
|
|
93
|
+
if (!await (0, import_user_permissions.enforceModelAccess)(ctx, globalEnabledServices, service, modelId)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
91
96
|
const employeeUsername = defaultAiEmployee;
|
|
92
97
|
if (!(0, import_role_permission.checkEmployeeAccess)(ctx, employeeUsername)) {
|
|
93
98
|
ctx.status = 403;
|
|
@@ -38,11 +38,11 @@ var import_openai_format = require("../utils/openai-format");
|
|
|
38
38
|
var import_resolve_service = require("../utils/resolve-service");
|
|
39
39
|
var import_streaming = require("../utils/streaming");
|
|
40
40
|
var import_role_permission = require("../middleware/role-permission");
|
|
41
|
+
var import_user_permissions = require("../utils/user-permissions");
|
|
41
42
|
var import_usage = require("../usage");
|
|
42
43
|
var import_billing = require("../billing");
|
|
43
44
|
var import_app_observability = require("../utils/app-observability");
|
|
44
45
|
async function handleChatCompletions(ctx, plugin) {
|
|
45
|
-
var _a;
|
|
46
46
|
const body = ctx.request.body;
|
|
47
47
|
if (!(body == null ? void 0 : body.model)) {
|
|
48
48
|
ctx.status = 400;
|
|
@@ -117,20 +117,8 @@ async function handleChatCompletions(ctx, plugin) {
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
const config = await ctx.db.getRepository("aiApiConfig").findOne();
|
|
120
|
-
if ((
|
|
121
|
-
|
|
122
|
-
const serviceTitle = service.title;
|
|
123
|
-
const isAllowed = config.enabledLlmServices.some((s) => s === serviceName || s === serviceTitle);
|
|
124
|
-
if (!isAllowed) {
|
|
125
|
-
ctx.status = 403;
|
|
126
|
-
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
127
|
-
403,
|
|
128
|
-
`LLM service '${service.title || service.name}' is not enabled for API access`,
|
|
129
|
-
"invalid_request_error",
|
|
130
|
-
"model_not_available"
|
|
131
|
-
);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
120
|
+
if (!await (0, import_user_permissions.enforceModelAccess)(ctx, config == null ? void 0 : config.enabledLlmServices, service, modelId)) {
|
|
121
|
+
return;
|
|
134
122
|
}
|
|
135
123
|
const providerMeta = aiPlugin.aiManager.llmProviders.get(service.provider);
|
|
136
124
|
if (!providerMeta) {
|
|
@@ -140,6 +128,13 @@ async function handleChatCompletions(ctx, plugin) {
|
|
|
140
128
|
}
|
|
141
129
|
await (0, import_billing.prepareLlmBilling)(ctx, resolved);
|
|
142
130
|
const providerRequestParameters = getProviderRequestParameters(body);
|
|
131
|
+
if (stream) {
|
|
132
|
+
const streamOptions = isRecord(body.stream_options) ? body.stream_options : {};
|
|
133
|
+
providerRequestParameters.stream_options = {
|
|
134
|
+
...streamOptions,
|
|
135
|
+
include_usage: true
|
|
136
|
+
};
|
|
137
|
+
}
|
|
143
138
|
const modelOptions = {
|
|
144
139
|
model: modelId,
|
|
145
140
|
llmService: service.name
|
|
@@ -312,7 +307,13 @@ async function handleStreamingCompletion(ctx, chatModel, messages, completionId,
|
|
|
312
307
|
finishReason = "tool_calls";
|
|
313
308
|
await (0, import_streaming.writeResponse)(
|
|
314
309
|
ctx,
|
|
315
|
-
(0, import_openai_format.formatSSE)(
|
|
310
|
+
(0, import_openai_format.formatSSE)(
|
|
311
|
+
(0, import_openai_format.toOpenAIStreamChunk)({
|
|
312
|
+
id: completionId,
|
|
313
|
+
model: modelName,
|
|
314
|
+
delta: { tool_calls: toolCallChunks }
|
|
315
|
+
})
|
|
316
|
+
)
|
|
316
317
|
);
|
|
317
318
|
}
|
|
318
319
|
if (chunk.usage_metadata) {
|
|
@@ -331,6 +332,18 @@ async function handleStreamingCompletion(ctx, chatModel, messages, completionId,
|
|
|
331
332
|
})
|
|
332
333
|
)
|
|
333
334
|
);
|
|
335
|
+
if (usage) {
|
|
336
|
+
await (0, import_streaming.writeResponse)(
|
|
337
|
+
ctx,
|
|
338
|
+
(0, import_openai_format.formatSSE)(
|
|
339
|
+
(0, import_openai_format.toOpenAIUsageChunk)({
|
|
340
|
+
id: completionId,
|
|
341
|
+
model: modelName,
|
|
342
|
+
usage
|
|
343
|
+
})
|
|
344
|
+
)
|
|
345
|
+
);
|
|
346
|
+
}
|
|
334
347
|
await (0, import_streaming.writeResponse)(ctx, (0, import_openai_format.formatSSEDone)());
|
|
335
348
|
(0, import_usage.setAiApiUsageResult)(ctx, usage, { gatewayResponseId: completionId, providerRequestId });
|
|
336
349
|
ctx.state.aiApiStreamResult = { succeeded: true, id: completionId };
|