plugin-ai-api 1.0.2 → 1.0.4
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 +15 -1
- package/client-v2.d.ts +2 -0
- package/client-v2.js +1 -0
- package/dist/client/778.180aac1b13a38702.js +10 -0
- package/dist/client/950.2797862732563625.js +10 -0
- package/dist/client/index.js +10 -1
- package/dist/client-v2/950.8991b849cd7c1351.js +10 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/externalVersion.js +19 -8
- package/dist/index.js +9 -0
- package/dist/locale/en-US.json +10 -10
- package/dist/locale/zh-CN.json +10 -10
- package/dist/server/collections/ai-api-config.js +9 -0
- package/dist/server/collections/ai-api-role-permissions.js +9 -0
- package/dist/server/index.js +9 -0
- package/dist/server/middleware/rate-limit.js +9 -0
- package/dist/server/middleware/role-permission.js +9 -0
- package/dist/server/plugin.js +14 -0
- package/dist/server/resource/ai-api-config.js +9 -0
- package/dist/server/routes/agent-completions.js +21 -4
- package/dist/server/routes/auth.js +11 -12
- package/dist/server/routes/chat-completions.js +16 -4
- package/dist/server/routes/completions.js +16 -4
- package/dist/server/routes/embeddings.js +10 -3
- package/dist/server/routes/models.js +11 -8
- package/dist/server/routes/router.js +20 -4
- package/dist/server/utils/openai-format.js +9 -0
- package/dist/server/utils/rate-limiter.js +9 -0
- package/dist/server/utils/resolve-service.js +9 -0
- package/dist/swagger.js +10 -4
- package/package.json +21 -3
- package/src/client/AiApiConfigPage.tsx +309 -0
- package/src/client/client.d.ts +258 -0
- package/src/client/components/AiApiRolePermissions.tsx +169 -0
- package/{dist/client/models/index.d.ts → src/client/index.tsx} +10 -10
- package/src/client/locale.ts +21 -0
- package/src/client/models/index.ts +12 -0
- package/src/client/plugin.tsx +48 -0
- package/src/client-v2/plugin.tsx +24 -0
- package/{dist/client/locale.d.ts → src/index.ts} +11 -10
- package/src/locale/en-US.json +10 -0
- package/src/locale/zh-CN.json +10 -0
- package/src/server/collections/.gitkeep +0 -0
- package/src/server/collections/ai-api-config.ts +51 -0
- package/src/server/collections/ai-api-role-permissions.ts +41 -0
- package/src/server/index.ts +10 -0
- package/src/server/middleware/rate-limit.ts +70 -0
- package/src/server/middleware/role-permission.ts +66 -0
- package/src/server/plugin.ts +89 -0
- package/src/server/resource/ai-api-config.ts +74 -0
- package/src/server/routes/agent-completions.ts +428 -0
- package/src/server/routes/auth.ts +111 -0
- package/src/server/routes/chat-completions.ts +318 -0
- package/src/server/routes/completions.ts +299 -0
- package/src/server/routes/embeddings.ts +191 -0
- package/src/server/routes/models.ts +195 -0
- package/src/server/routes/router.ts +283 -0
- package/src/server/utils/openai-format.ts +142 -0
- package/src/server/utils/rate-limiter.ts +83 -0
- package/src/server/utils/resolve-service.ts +82 -0
- package/src/swagger.ts +325 -0
- package/dist/client/2c126424a58bcb27.js +0 -1
- package/dist/client/824c2f7487ee05fd.js +0 -1
- package/dist/client/AiApiConfigPage.d.ts +0 -3
- package/dist/client/components/AiApiRolePermissions.d.ts +0 -8
- package/dist/client/plugin.d.ts +0 -6
- package/dist/index.d.ts +0 -2
- package/dist/server/collections/ai-api-config.d.ts +0 -2
- package/dist/server/collections/ai-api-role-permissions.d.ts +0 -2
- package/dist/server/index.d.ts +0 -1
- package/dist/server/middleware/rate-limit.d.ts +0 -18
- package/dist/server/middleware/role-permission.d.ts +0 -21
- package/dist/server/plugin.d.ts +0 -18
- package/dist/server/resource/ai-api-config.d.ts +0 -10
- package/dist/server/routes/agent-completions.d.ts +0 -34
- package/dist/server/routes/auth.d.ts +0 -8
- package/dist/server/routes/chat-completions.d.ts +0 -9
- package/dist/server/routes/completions.d.ts +0 -10
- package/dist/server/routes/embeddings.d.ts +0 -22
- package/dist/server/routes/models.d.ts +0 -21
- package/dist/server/routes/router.d.ts +0 -25
- package/dist/server/utils/openai-format.d.ts +0 -99
- package/dist/server/utils/rate-limiter.d.ts +0 -35
- package/dist/server/utils/resolve-service.d.ts +0 -19
- package/dist/swagger.d.ts +0 -472
- package/plugin-ai-api-1.0.1.tgz +0 -0
- package/plugin-ai-api-1.0.2.tgz +0 -0
- /package/{dist/client/index.d.ts → src/client-v2/index.tsx} +0 -0
package/README.md
CHANGED
|
@@ -1 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# plugin-ai-api
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Provides an internal API layer for routing and managing AI model interactions in NocoBase.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
- **Centralized AI Routing**: Acts as the middleware for all AI-related requests.
|
|
8
|
+
- **Provider Abstraction**: Normalizes requests and responses across different LLM providers (OpenAI, Anthropic, Custom LLMs).
|
|
9
|
+
- **Rate Limiting & Logging**: Internal mechanisms to track token usage and API limits.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
*This is primarily an internal system plugin.*
|
|
13
|
+
1. Enable the plugin via the Plugin Manager.
|
|
14
|
+
2. Developers can use the exported API services in their custom plugins by importing `@nocobase/plugin-ai-api`.
|
|
15
|
+
3. Configure default AI models in the global NocoBase Settings under "AI API Provider".
|
package/client-v2.d.ts
ADDED
package/client-v2.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/client-v2/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
|
+
"use strict";(self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).push([["778"],{905:function(e,t,r){r.r(t),r.d(t,{AiApiRolePermissions:function(){return d}});var n=r(155),l=r.n(n),a=r(342),o=r(59);function i(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 u(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 c(e){return function(){var t=this,r=arguments;return new Promise(function(n,l){var a=e.apply(t,r);function o(e){u(a,n,l,o,i,"next",e)}function i(e){u(a,n,l,o,i,"throw",e)}o(void 0)})}}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){var n;n=r[t],t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n})}return e}function p(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 i(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 i(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 c=[i,u];if(r)throw TypeError("Generator is already executing.");for(;o&&(o=0,c[0]&&(a=0)),a;)try{if(r=1,n&&(l=2&c[0]?n.return:c[0]?n.throw||((l=n.return)&&l.call(n),0):n.next)&&!(l=l.call(n,c[1])).done)return l;switch(n=0,l&&(c=[2&c[0],l.value]),c[0]){case 0:case 1:l=c;break;case 4:return a.label++,{value:c[1],done:!1};case 5:a.label++,n=c[1],c=[0];continue;case 7:c=a.ops.pop(),a.trys.pop();continue;default:if(!(l=(l=a.trys).length>0&&l[l.length-1])&&(6===c[0]||2===c[0])){a=0;continue}if(3===c[0]&&(!l||c[1]>l[0]&&c[1]<l[3])){a.label=c[1];break}if(6===c[0]&&a.label<l[1]){a.label=l[1],l=c;break}if(l&&a.label<l[2]){a.label=l[2],a.ops.push(c);break}l[2]&&a.ops.pop(),a.trys.pop();continue}c=t.call(e,a)}catch(e){c=[6,e],n=0}finally{r=l=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}}}var m=o.Typography.Text;function d(e){var t=e.role,r=(0,a.useAPIClient)(),i=p((0,n.useState)(!0),2),u=i[0],d=i[1],y=p((0,n.useState)(!1),2),b=y[0],h=y[1],v=p((0,n.useState)([]),2),w=v[0],E=v[1],g=p((0,n.useState)(null),2),A=g[0],O=g[1],P=null==t?void 0:t.name;(0,n.useEffect)(function(){P&&S()},[P]);var S=function(){return c(function(){var e,t,n,l,a,o,i;return f(this,function(u){switch(u.label){case 0:d(!0),u.label=1;case 1:return u.trys.push([1,3,4,5]),[4,Promise.all([r.request({url:"aiApiRolePermissions",params:{filter:{roleName:P},paginate:!1}}),r.request({url:"aiEmployees:list",params:{paginate:!1}})])];case 2:return a=(l=p.apply(void 0,[u.sent(),2]))[0],o=l[1],O((i=null==a||null==(t=a.data)||null==(e=t.data)?void 0:e[0])?{id:i.id,roleName:i.roleName,enabled:!!i.enabled,allowAllEmployees:!1!==i.allowAllEmployees,allowedEmployees:i.allowedEmployees||[]}:{roleName:P,enabled:!1,allowAllEmployees:!0,allowedEmployees:[]}),E(((null==o||null==(n=o.data)?void 0:n.data)||[]).map(function(e){return{username:e.username,nickname:e.nickname||e.username}})),[3,5];case 3:return console.error("Failed to load AI API role permissions:",u.sent()),[3,5];case 4:return d(!1),[7];case 5:return[2]}})})()},j=function(e){return c(function(){var t,n,l,a;return f(this,function(o){switch(o.label){case 0:if(!A)return[2];O(t=s({},A,e)),h(!0),o.label=1;case 1:if(o.trys.push([1,6,7,8]),!t.id)return[3,3];return[4,r.request({url:"aiApiRolePermissions/".concat(t.id),method:"PUT",data:t})];case 2:return o.sent(),[3,5];case 3:return[4,r.request({url:"aiApiRolePermissions",method:"POST",data:t})];case 4:var i,u;(null==(a=null==(l=o.sent())||null==(n=l.data)?void 0:n.data)?void 0:a.id)&&O((i=s({},t),u=u={id:a.id},Object.getOwnPropertyDescriptors?Object.defineProperties(i,Object.getOwnPropertyDescriptors(u)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t})(Object(u)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(u,e))}),i)),o.label=5;case 5:return[3,8];case 6:return console.error("Failed to save AI API role permissions:",o.sent()),O(A),[3,8];case 7:return h(!1),[7];case 8:return[2]}})})()};return u?l().createElement(o.Spin,null):l().createElement(o.Card,{bordered:!1},l().createElement(o.Space,{direction:"vertical",style:{width:"100%"},size:"middle"},l().createElement(o.Space,null,l().createElement(o.Switch,{checked:!!(null==A?void 0:A.enabled),loading:b,onChange:function(e){return j({enabled:e})}}),l().createElement(m,{strong:!0},"Allow this role to use the AI API")),(null==A?void 0:A.enabled)&&l().createElement(l().Fragment,null,l().createElement(o.Divider,{style:{margin:"8px 0"}}),l().createElement(o.Space,null,l().createElement(o.Switch,{checked:!!(null==A?void 0:A.allowAllEmployees),loading:b,onChange:function(e){return j({allowAllEmployees:e})}}),l().createElement(m,null,"Allow all AI Employees")),!(null==A?void 0:A.allowAllEmployees)&&l().createElement("div",null,l().createElement(m,{type:"secondary",style:{display:"block",marginBottom:8}},"Select which AI Employees this role may use:"),l().createElement(o.Select,{mode:"multiple",allowClear:!0,style:{width:"100%",maxWidth:480},placeholder:"Select allowed AI Employees",value:(null==A?void 0:A.allowedEmployees)||[],options:w.map(function(e){return{label:"".concat(e.nickname," (").concat(e.username,")"),value:e.username}}),onChange:function(e){return j({allowedEmployees:e})},disabled:b})))))}}}]);
|
|
@@ -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([["950"],{693:function(e,t,n){n.r(t),n.d(t,{AiApiConfigPage:function(){return y}});var r=n(155),a=n.n(r),l=n(59),o=n(342);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function c(e,t,n,r,a,l,o){try{var i=e[l](o),c=i.value}catch(e){n(e);return}i.done?t(c):Promise.resolve(c).then(r,a)}function u(e){return function(){var t=this,n=arguments;return new Promise(function(r,a){var l=e.apply(t,n);function o(e){c(l,r,a,o,i,"next",e)}function i(e){c(l,r,a,o,i,"throw",e)}o(void 0)})}}function s(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,r,a=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var l=[],o=!0,i=!1;try{for(a=a.call(e);!(o=(n=a.next()).done)&&(l.push(n.value),!t||l.length!==t);o=!0);}catch(e){i=!0,r=e}finally{try{o||null==a.return||a.return()}finally{if(i)throw r}}return l}}(e,t)||function(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return i(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 m(e,t){var n,r,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},o=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(o,"next",{value:c(0)}),i(o,"throw",{value:c(1)}),i(o,"return",{value:c(2)}),"function"==typeof Symbol&&i(o,Symbol.iterator,{value:function(){return this}}),o;function c(i){return function(c){var u=[i,c];if(n)throw TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(l=0)),l;)try{if(n=1,r&&(a=2&u[0]?r.return:u[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,u[1])).done)return a;switch(r=0,a&&(u=[2&u[0],a.value]),u[0]){case 0:case 1:a=u;break;case 4:return l.label++,{value:u[1],done:!1};case 5:l.label++,r=u[1],u=[0];continue;case 7:u=l.ops.pop(),l.trys.pop();continue;default:if(!(a=(a=l.trys).length>0&&a[a.length-1])&&(6===u[0]||2===u[0])){l=0;continue}if(3===u[0]&&(!a||u[1]>a[0]&&u[1]<a[3])){l.label=u[1];break}if(6===u[0]&&l.label<a[1]){l.label=a[1],a=u;break}if(a&&l.label<a[2]){l.label=a[2],l.ops.push(u);break}a[2]&&l.ops.pop(),l.trys.pop();continue}u=t.call(e,l)}catch(e){u=[6,e],r=0}finally{n=a=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}}}var p=l.Typography.Title,d=l.Typography.Text,f=l.Typography.Paragraph;function y(){var e=(0,o.useAPIClient)(),t=s(l.Form.useForm(),1)[0],n=s((0,r.useState)(!0),2),i=n[0],c=n[1],y=s((0,r.useState)(!1),2),v=y[0],h=y[1],b=s((0,r.useState)([]),2),g=b[0],E=b[1],A=s((0,r.useState)([]),2),I=A[0],S=A[1],w=s((0,r.useState)(""),2),L=w[0],k=w[1];(0,r.useEffect)(function(){P(),k("".concat(window.location.origin,"/api/ai-llm/v1"))},[]);var P=function(){return u(function(){var n,r,a,l,o,i,u;return m(this,function(s){switch(s.label){case 0:c(!0),s.label=1;case 1:return s.trys.push([1,5,6,7]),[4,e.request({url:"aiApiConfig:get"})];case 2:return(o=null==(l=s.sent())||null==(n=l.data)?void 0:n.data)&&t.setFieldsValue({mode:o.mode||"llm",defaultAiEmployee:o.defaultAiEmployee||void 0,defaultLlmService:o.defaultLlmService||void 0,enabledLlmServices:o.enabledLlmServices||[],rateLimitPerMinute:o.rateLimitPerMinute||60}),[4,e.request({url:"aiEmployees:list",params:{paginate:!1}})];case 3:return E(((null==(i=s.sent())||null==(r=i.data)?void 0:r.data)||[]).map(function(e){return{username:e.username,nickname:e.nickname||e.username}})),[4,e.request({url:"ai:listLLMServices"})];case 4:return S(((null==(u=s.sent())||null==(a=u.data)?void 0:a.data)||[]).map(function(e){return{name:e.name,title:e.title||e.name,provider:e.provider,enabled:!1!==e.enabled}})),[3,7];case 5:return console.error("Failed to load config:",s.sent()),[3,7];case 6:return c(!1),[7];case 7:return[2]}})})()};return i?a().createElement("div",{style:{display:"flex",justifyContent:"center",padding:60}},a().createElement(l.Spin,{size:"large"})):a().createElement("div",{style:{maxWidth:800,margin:"0 auto",padding:"24px 0"}},a().createElement(p,{level:3},"AI API Gateway Configuration"),a().createElement(f,{type:"secondary"},"Configure the OpenAI-compatible API endpoint. External applications can connect using the base URL and a NocoBase API key."),a().createElement(l.Card,{style:{marginBottom:24}},a().createElement(l.Alert,{type:"info",showIcon:!0,message:"API Endpoint",description:a().createElement(l.Space,{direction:"vertical",size:4},a().createElement(d,null,"Base URL:"," ",a().createElement(d,{code:!0,copyable:!0},L)),a().createElement(d,{type:"secondary"},"Use this as the base URL in any OpenAI-compatible client (Cursor, Continue.dev, n8n, etc.)")),style:{marginBottom:16}}),a().createElement(l.Alert,{type:"warning",showIcon:!0,message:"Authentication",description:a().createElement(d,null,"Clients must include a NocoBase API key as a Bearer token:",a().createElement("br",null),a().createElement(d,{code:!0},"Authorization: Bearer ","<your-nocobase-api-key>"),a().createElement("br",null),a().createElement(d,{type:"secondary"},"API keys can be created in Settings → API keys."))})),a().createElement(l.Card,{title:"Configuration"},a().createElement(l.Form,{form:t,layout:"vertical",onFinish:function(){return u(function(){var n;return m(this,function(r){switch(r.label){case 0:h(!0),r.label=1;case 1:return r.trys.push([1,3,4,5]),n=t.getFieldsValue(),[4,e.request({url:"aiApiConfig:save",method:"post",data:n})];case 2:return r.sent(),l.message.success("Configuration saved"),[3,5];case 3:return r.sent(),l.message.error("Failed to save configuration"),[3,5];case 4:return h(!1),[7];case 5:return[2]}})})()},initialValues:{mode:"llm"}},a().createElement(l.Form.Item,{name:"mode",label:"API Mode",tooltip:"LLM Proxy: Direct access to the LLM model. Agent: Full AI Employee with tools, knowledge base, and agent capabilities."},a().createElement(l.Radio.Group,null,a().createElement(l.Radio.Button,{value:"llm"},"LLM Proxy"),a().createElement(l.Radio.Button,{value:"agent"},"AI Employee Agent"))),a().createElement(l.Form.Item,{name:"defaultAiEmployee",label:"Default AI Employee",tooltip:"The AI Employee whose system prompt will be injected into chat completions (when client doesn't provide a system message)"},a().createElement(l.Select,{allowClear:!0,placeholder:"Select an AI Employee (optional)",options:g.map(function(e){return{label:"".concat(e.nickname," (").concat(e.username,")"),value:e.username}})})),a().createElement(l.Form.Item,{name:"defaultLlmService",label:"Default LLM Service",tooltip:"The LLM service used when clients send only a model name (e.g. 'gpt-4o') without a service prefix. This is the main service that powers the API.",rules:[{required:!0,message:"Please select a default LLM service"}]},a().createElement(l.Select,{allowClear:!0,placeholder:"Select an LLM Service",options:I.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),a().createElement(l.Form.Item,{name:"enabledLlmServices",label:"Enabled LLM Services",tooltip:"Only these services will be exposed via the API. Leave empty to expose all enabled services."},a().createElement(l.Select,{mode:"multiple",allowClear:!0,placeholder:"All enabled services (default)",options:I.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),a().createElement(l.Form.Item,{name:"rateLimitPerMinute",label:"Rate Limit (requests/minute)",tooltip:"Maximum API requests per user per minute. Set 0 for unlimited."},a().createElement(l.InputNumber,{min:0,max:1e4,style:{width:200}})),a().createElement(l.Form.Item,null,a().createElement(l.Button,{type:"primary",htmlType:"submit",loading:v},"Save Configuration")))),a().createElement(l.Card,{title:"Quick Start",style:{marginTop:24}},a().createElement(p,{level:5},"cURL Example"),a().createElement(f,null,a().createElement("pre",{style:{background:"#1a1a2e",color:"#e0e0e0",padding:16,borderRadius:8,fontSize:13,overflow:"auto"}},"curl ".concat(L,'/chat/completions \\\n -H "Authorization: Bearer <your-api-key>" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "model": "<service-name>/<model-id>",\n "messages": [\n {"role": "user", "content": "Hello!"}\n ]\n }\''))),a().createElement(p,{level:5},"Python (OpenAI SDK)"),a().createElement(f,null,a().createElement("pre",{style:{background:"#1a1a2e",color:"#e0e0e0",padding:16,borderRadius:8,fontSize:13,overflow:"auto"}},'from openai import OpenAI\n\nclient = OpenAI(\n base_url="'.concat(L,'",\n api_key="<your-nocobase-api-key>"\n)\n\nresponse = client.chat.completions.create(\n model="<service-name>/<model-id>",\n messages=[{"role": "user", "content": "Hello!"}]\n)'))),a().createElement(p,{level:5},"List Available Models"),a().createElement(f,null,a().createElement("pre",{style:{background:"#1a1a2e",color:"#e0e0e0",padding:16,borderRadius:8,fontSize:13,overflow:"auto"}},"curl ".concat(L,'/models \\\n -H "Authorization: Bearer <your-api-key>"')))))}t.default=y}}]);
|
package/dist/client/index.js
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
-
|
|
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("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client")):"function"==typeof define&&define.amd?define("plugin-ai-api",["react","antd","@nocobase/client","@nocobase/plugin-acl/client"],t):"object"==typeof exports?exports["plugin-ai-api"]=t(require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client")):e["plugin-ai-api"]=t(e.react,e.antd,e["@nocobase/client"],e["@nocobase/plugin-acl/client"])}(self,function(e,t,n,r){return function(){"use strict";var o,i,a,u={342:function(e){e.exports=n},79:function(e){e.exports=r},59:function(e){e.exports=t},155:function(t){t.exports=e}},c={};function l(e){var t=c[e];if(void 0!==t)return t.exports;var n=c[e]={exports:{}};return u[e](n,n.exports,l),n.exports}l.m=u,l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,{a:t}),t},l.d=function(e,t){for(var n in t)l.o(t,n)&&!l.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},l.f={},l.e=function(e){return Promise.all(Object.keys(l.f).reduce(function(t,n){return l.f[n](e,t),t},[]))},l.u=function(e){return""+e+"."+({778:"180aac1b13a38702",950:"2797862732563625"})[e]+".js"},l.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},p={},l.l=function(e,t,n,r){if(p[e])return void p[e].push(t);if(void 0!==n)for(var o,i,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){o=c;break}}o||(i=!0,(o=document.createElement("script")).timeout=120,l.nc&&o.setAttribute("nonce",l.nc),o.setAttribute("data-rspack","plugin-ai-api:"+n),o.src=e),p[e]=[t];var f=function(t,n){o.onerror=o.onload=null,clearTimeout(s);var r=p[e];if(delete p[e],o.parentNode&&o.parentNode.removeChild(o),r&&r.forEach(function(e){return e(n)}),t)return t(n)},s=setTimeout(f.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=f.bind(null,o.onerror),o.onload=f.bind(null,o.onload),i&&document.head.appendChild(o)},l.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.g.importScripts&&(f=l.g.location+"");var p,f,s=l.g.document;if(!f&&s&&(s.currentScript&&"SCRIPT"===s.currentScript.tagName.toUpperCase()&&(f=s.currentScript.src),!f)){var d=s.getElementsByTagName("script");if(d.length)for(var b=d.length-1;b>-1&&(!f||!/^http(s?):/.test(f));)f=d[b--].src}if(!f)throw Error("Automatic publicPath is not supported in this browser");l.p=f.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o={889:0},l.f.j=function(e,t){var n=l.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=l.p+l.u(e),a=Error();l.l(i,function(t){if(l.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)}},i=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)l.o(a,n)&&(l.m[n]=a[n]);u&&u(l)}for(e&&e(t);c<i.length;c++)r=i[c],l.o(o,r)&&o[r]&&o[r][0](),o[r]=0},(a=self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).forEach(i.bind(null,0)),a.push=i.bind(null,a.push.bind(a));var h={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src&&(e=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/")),!e){var n=window.__webpack_public_path__||"";n&&("/"!==n.charAt(n.length-1)&&(n+="/"),e=n+"static/plugins/plugin-ai-api/dist/client/")}if(!e){var r=window.__nocobase_modern_client_prefix__||"v",o="/"+(r=String(r).replace(/^\/+|\/+$/g,"")||"v")+"/";if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var i=window.location.pathname||"/",a=i.indexOf(o);e=a>=0?i.slice(0,a+1):"/"}e&&(e=e.replace(RegExp("/"+r+"/?$"),"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/plugin-ai-api/dist/client/"}l.p=e}(),!function(){l.r(h),l.d(h,{default:function(){return b}});var e=l(342),t=l(79),n=l.n(t),r=l(155),o=l.n(r);function i(e,t,n,r,o,i,a){try{var u=e[i](a),c=u.value}catch(e){n(e);return}u.done?t(c):Promise.resolve(c).then(r,o)}function a(e,t,n){return(a=f()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&c(o,n.prototype),o}).apply(null,arguments)}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function c(e,t){return(c=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 a(e,arguments,u(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),c(n,e)})(e)}function f(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(f=function(){return!!e})()}var s=o().lazy(function(){return l.e("950").then(l.bind(l,693))}),d=(0,e.lazy)(function(){return l.e("778").then(l.bind(l,905))},"AiApiRolePermissions").AiApiRolePermissions,b=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function r(){var e,t;if(!(this instanceof r))throw TypeError("Cannot call a class as a function");return e=r,t=arguments,e=u(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,f()?Reflect.construct(e,t||[],u(this).constructor):e.apply(this,t))}return r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),e&&c(r,e),t=[{key:"load",value:function(){var e;return(e=function(){var e;return function(e,t){var n,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[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]&&(i=0)),i;)try{if(n=1,r&&(o=2&l[0]?r.return:l[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,l[1])).done)return o;switch(r=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,r=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===l[0]||2===l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=t.call(e,i)}catch(e){l=[6,e],r=0}finally{n=o=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:"pm.ai-api.configuration"}),this.app.pluginSettingsManager.add("ai-api.config",{title:this.t("Configuration"),Component:s}),(null==(e=this.app.pm.get(n()))?void 0:e.settingsUI)&&e.settingsUI.addPermissionsTab(function(e){e.t;var t=e.TabLayout,n=e.activeRole;return{key:"aiApi",label:"AI API",sort:25,children:o().createElement(t,null,o().createElement(d,{role:n}))}}),[2]})},function(){var t=this,n=arguments;return new Promise(function(r,o){var a=e.apply(t,n);function u(e){i(a,r,o,u,c,"next",e)}function c(e){i(a,r,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)}}(r.prototype,t),r}(p(e.Plugin))}(),h}()});
|
|
@@ -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([["950"],{693:function(e,t,n){n.r(t),n.d(t,{AiApiConfigPage:function(){return y}});var r=n(155),a=n.n(r),l=n(59),o=n(342);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function c(e,t,n,r,a,l,o){try{var i=e[l](o),c=i.value}catch(e){n(e);return}i.done?t(c):Promise.resolve(c).then(r,a)}function u(e){return function(){var t=this,n=arguments;return new Promise(function(r,a){var l=e.apply(t,n);function o(e){c(l,r,a,o,i,"next",e)}function i(e){c(l,r,a,o,i,"throw",e)}o(void 0)})}}function s(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,r,a=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var l=[],o=!0,i=!1;try{for(a=a.call(e);!(o=(n=a.next()).done)&&(l.push(n.value),!t||l.length!==t);o=!0);}catch(e){i=!0,r=e}finally{try{o||null==a.return||a.return()}finally{if(i)throw r}}return l}}(e,t)||function(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return i(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 m(e,t){var n,r,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},o=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(o,"next",{value:c(0)}),i(o,"throw",{value:c(1)}),i(o,"return",{value:c(2)}),"function"==typeof Symbol&&i(o,Symbol.iterator,{value:function(){return this}}),o;function c(i){return function(c){var u=[i,c];if(n)throw TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(l=0)),l;)try{if(n=1,r&&(a=2&u[0]?r.return:u[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,u[1])).done)return a;switch(r=0,a&&(u=[2&u[0],a.value]),u[0]){case 0:case 1:a=u;break;case 4:return l.label++,{value:u[1],done:!1};case 5:l.label++,r=u[1],u=[0];continue;case 7:u=l.ops.pop(),l.trys.pop();continue;default:if(!(a=(a=l.trys).length>0&&a[a.length-1])&&(6===u[0]||2===u[0])){l=0;continue}if(3===u[0]&&(!a||u[1]>a[0]&&u[1]<a[3])){l.label=u[1];break}if(6===u[0]&&l.label<a[1]){l.label=a[1],a=u;break}if(a&&l.label<a[2]){l.label=a[2],l.ops.push(u);break}a[2]&&l.ops.pop(),l.trys.pop();continue}u=t.call(e,l)}catch(e){u=[6,e],r=0}finally{n=a=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}}}var p=l.Typography.Title,d=l.Typography.Text,f=l.Typography.Paragraph;function y(){var e=(0,o.useAPIClient)(),t=s(l.Form.useForm(),1)[0],n=s((0,r.useState)(!0),2),i=n[0],c=n[1],y=s((0,r.useState)(!1),2),v=y[0],h=y[1],b=s((0,r.useState)([]),2),g=b[0],E=b[1],A=s((0,r.useState)([]),2),I=A[0],S=A[1],w=s((0,r.useState)(""),2),L=w[0],k=w[1];(0,r.useEffect)(function(){P(),k("".concat(window.location.origin,"/api/ai-llm/v1"))},[]);var P=function(){return u(function(){var n,r,a,l,o,i,u;return m(this,function(s){switch(s.label){case 0:c(!0),s.label=1;case 1:return s.trys.push([1,5,6,7]),[4,e.request({url:"aiApiConfig:get"})];case 2:return(o=null==(l=s.sent())||null==(n=l.data)?void 0:n.data)&&t.setFieldsValue({mode:o.mode||"llm",defaultAiEmployee:o.defaultAiEmployee||void 0,defaultLlmService:o.defaultLlmService||void 0,enabledLlmServices:o.enabledLlmServices||[],rateLimitPerMinute:o.rateLimitPerMinute||60}),[4,e.request({url:"aiEmployees:list",params:{paginate:!1}})];case 3:return E(((null==(i=s.sent())||null==(r=i.data)?void 0:r.data)||[]).map(function(e){return{username:e.username,nickname:e.nickname||e.username}})),[4,e.request({url:"ai:listLLMServices"})];case 4:return S(((null==(u=s.sent())||null==(a=u.data)?void 0:a.data)||[]).map(function(e){return{name:e.name,title:e.title||e.name,provider:e.provider,enabled:!1!==e.enabled}})),[3,7];case 5:return console.error("Failed to load config:",s.sent()),[3,7];case 6:return c(!1),[7];case 7:return[2]}})})()};return i?a().createElement("div",{style:{display:"flex",justifyContent:"center",padding:60}},a().createElement(l.Spin,{size:"large"})):a().createElement("div",{style:{maxWidth:800,margin:"0 auto",padding:"24px 0"}},a().createElement(p,{level:3},"AI API Gateway Configuration"),a().createElement(f,{type:"secondary"},"Configure the OpenAI-compatible API endpoint. External applications can connect using the base URL and a NocoBase API key."),a().createElement(l.Card,{style:{marginBottom:24}},a().createElement(l.Alert,{type:"info",showIcon:!0,message:"API Endpoint",description:a().createElement(l.Space,{direction:"vertical",size:4},a().createElement(d,null,"Base URL:"," ",a().createElement(d,{code:!0,copyable:!0},L)),a().createElement(d,{type:"secondary"},"Use this as the base URL in any OpenAI-compatible client (Cursor, Continue.dev, n8n, etc.)")),style:{marginBottom:16}}),a().createElement(l.Alert,{type:"warning",showIcon:!0,message:"Authentication",description:a().createElement(d,null,"Clients must include a NocoBase API key as a Bearer token:",a().createElement("br",null),a().createElement(d,{code:!0},"Authorization: Bearer ","<your-nocobase-api-key>"),a().createElement("br",null),a().createElement(d,{type:"secondary"},"API keys can be created in Settings → API keys."))})),a().createElement(l.Card,{title:"Configuration"},a().createElement(l.Form,{form:t,layout:"vertical",onFinish:function(){return u(function(){var n;return m(this,function(r){switch(r.label){case 0:h(!0),r.label=1;case 1:return r.trys.push([1,3,4,5]),n=t.getFieldsValue(),[4,e.request({url:"aiApiConfig:save",method:"post",data:n})];case 2:return r.sent(),l.message.success("Configuration saved"),[3,5];case 3:return r.sent(),l.message.error("Failed to save configuration"),[3,5];case 4:return h(!1),[7];case 5:return[2]}})})()},initialValues:{mode:"llm"}},a().createElement(l.Form.Item,{name:"mode",label:"API Mode",tooltip:"LLM Proxy: Direct access to the LLM model. Agent: Full AI Employee with tools, knowledge base, and agent capabilities."},a().createElement(l.Radio.Group,null,a().createElement(l.Radio.Button,{value:"llm"},"LLM Proxy"),a().createElement(l.Radio.Button,{value:"agent"},"AI Employee Agent"))),a().createElement(l.Form.Item,{name:"defaultAiEmployee",label:"Default AI Employee",tooltip:"The AI Employee whose system prompt will be injected into chat completions (when client doesn't provide a system message)"},a().createElement(l.Select,{allowClear:!0,placeholder:"Select an AI Employee (optional)",options:g.map(function(e){return{label:"".concat(e.nickname," (").concat(e.username,")"),value:e.username}})})),a().createElement(l.Form.Item,{name:"defaultLlmService",label:"Default LLM Service",tooltip:"The LLM service used when clients send only a model name (e.g. 'gpt-4o') without a service prefix. This is the main service that powers the API.",rules:[{required:!0,message:"Please select a default LLM service"}]},a().createElement(l.Select,{allowClear:!0,placeholder:"Select an LLM Service",options:I.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),a().createElement(l.Form.Item,{name:"enabledLlmServices",label:"Enabled LLM Services",tooltip:"Only these services will be exposed via the API. Leave empty to expose all enabled services."},a().createElement(l.Select,{mode:"multiple",allowClear:!0,placeholder:"All enabled services (default)",options:I.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),a().createElement(l.Form.Item,{name:"rateLimitPerMinute",label:"Rate Limit (requests/minute)",tooltip:"Maximum API requests per user per minute. Set 0 for unlimited."},a().createElement(l.InputNumber,{min:0,max:1e4,style:{width:200}})),a().createElement(l.Form.Item,null,a().createElement(l.Button,{type:"primary",htmlType:"submit",loading:v},"Save Configuration")))),a().createElement(l.Card,{title:"Quick Start",style:{marginTop:24}},a().createElement(p,{level:5},"cURL Example"),a().createElement(f,null,a().createElement("pre",{style:{background:"#1a1a2e",color:"#e0e0e0",padding:16,borderRadius:8,fontSize:13,overflow:"auto"}},"curl ".concat(L,'/chat/completions \\\n -H "Authorization: Bearer <your-api-key>" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "model": "<service-name>/<model-id>",\n "messages": [\n {"role": "user", "content": "Hello!"}\n ]\n }\''))),a().createElement(p,{level:5},"Python (OpenAI SDK)"),a().createElement(f,null,a().createElement("pre",{style:{background:"#1a1a2e",color:"#e0e0e0",padding:16,borderRadius:8,fontSize:13,overflow:"auto"}},'from openai import OpenAI\n\nclient = OpenAI(\n base_url="'.concat(L,'",\n api_key="<your-nocobase-api-key>"\n)\n\nresponse = client.chat.completions.create(\n model="<service-name>/<model-id>",\n messages=[{"role": "user", "content": "Hello!"}]\n)'))),a().createElement(p,{level:5},"List Available Models"),a().createElement(f,null,a().createElement("pre",{style:{background:"#1a1a2e",color:"#e0e0e0",padding:16,borderRadius:8,fontSize:13,overflow:"auto"}},"curl ".concat(L,'/models \\\n -H "Authorization: Bearer <your-api-key>"')))))}t.default=y}}]);
|
|
@@ -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("@nocobase/client-v2"),require("react"),require("antd"),require("@nocobase/client")):"function"==typeof define&&define.amd?define("plugin-ai-api/client-v2",["@nocobase/client-v2","react","antd","@nocobase/client"],t):"object"==typeof exports?exports["plugin-ai-api/client-v2"]=t(require("@nocobase/client-v2"),require("react"),require("antd"),require("@nocobase/client")):e["plugin-ai-api/client-v2"]=t(e["@nocobase/client-v2"],e.react,e.antd,e["@nocobase/client"])}(self,function(e,t,n,r){return function(){"use strict";var o,i,a,u={342:function(e){e.exports=r},485:function(t){t.exports=e},59:function(e){e.exports=n},155:function(e){e.exports=t}},c={};function l(e){var t=c[e];if(void 0!==t)return t.exports;var n=c[e]={exports:{}};return u[e](n,n.exports,l),n.exports}l.m=u,l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,{a:t}),t},l.d=function(e,t){for(var n in t)l.o(t,n)&&!l.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},l.f={},l.e=function(e){return Promise.all(Object.keys(l.f).reduce(function(t,n){return l.f[n](e,t),t},[]))},l.u=function(e){return""+e+".8991b849cd7c1351.js"},l.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},p={},l.l=function(e,t,n,r){if(p[e])return void p[e].push(t);if(void 0!==n)for(var o,i,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){o=c;break}}o||(i=!0,(o=document.createElement("script")).timeout=120,l.nc&&o.setAttribute("nonce",l.nc),o.setAttribute("data-rspack","plugin-ai-api/client-v2:"+n),o.src=e),p[e]=[t];var f=function(t,n){o.onerror=o.onload=null,clearTimeout(s);var r=p[e];if(delete p[e],o.parentNode&&o.parentNode.removeChild(o),r&&r.forEach(function(e){return e(n)}),t)return t(n)},s=setTimeout(f.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=f.bind(null,o.onerror),o.onload=f.bind(null,o.onload),i&&document.head.appendChild(o)},l.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.g.importScripts&&(f=l.g.location+"");var p,f,s=l.g.document;if(!f&&s&&(s.currentScript&&"SCRIPT"===s.currentScript.tagName.toUpperCase()&&(f=s.currentScript.src),!f)){var d=s.getElementsByTagName("script");if(d.length)for(var b=d.length-1;b>-1&&(!f||!/^http(s?):/.test(f));)f=d[b--].src}if(!f)throw Error("Automatic publicPath is not supported in this browser");l.p=f.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o={889:0},l.f.j=function(e,t){var n=l.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=l.p+l.u(e),a=Error();l.l(i,function(t){if(l.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)}},i=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)l.o(a,n)&&(l.m[n]=a[n]);u&&u(l)}for(e&&e(t);c<i.length;c++)r=i[c],l.o(o,r)&&o[r]&&o[r][0](),o[r]=0},(a=self.webpackChunkplugin_ai_api_client_v2=self.webpackChunkplugin_ai_api_client_v2||[]).forEach(i.bind(null,0)),a.push=i.bind(null,a.push.bind(a));var v={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src&&(e=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/")),!e){var n=window.__webpack_public_path__||"";n&&("/"!==n.charAt(n.length-1)&&(n+="/"),e=n+"static/plugins/plugin-ai-api/dist/client-v2/")}if(!e){var r=window.__nocobase_modern_client_prefix__||"v",o="/"+(r=String(r).replace(/^\/+|\/+$/g,"")||"v")+"/";if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var i=window.location.pathname||"/",a=i.indexOf(o);e=a>=0?i.slice(0,a+1):"/"}e&&(e=e.replace(RegExp("/"+r+"/?$"),"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/plugin-ai-api/dist/client-v2/"}l.p=e}(),!function(){l.r(v),l.d(v,{default:function(){return u}});var e=l(485);function t(e,t,n,r,o,i,a){try{var u=e[i](a),c=u.value}catch(e){n(e);return}u.done?t(c):Promise.resolve(c).then(r,o)}function n(e,t,r){return(n=a()?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)}l(155);function r(e){return(r=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 i(e){var t="function"==typeof Map?new Map:void 0;return(i=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,i)}function i(){return n(e,arguments,r(this).constructor)}return i.prototype=Object.create(e.prototype,{constructor:{value:i,enumerable:!1,writable:!0,configurable:!0}}),o(i,e)})(e)}function a(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(a=function(){return!!e})()}var u=function(e){var n;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=r(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,a()?Reflect.construct(e,t||[],r(this).constructor):e.apply(this,t))}return i.prototype=Object.create(e&&e.prototype,{constructor:{value:i,writable:!0,configurable:!0}}),e&&o(i,e),n=[{key:"load",value:function(){var e;return(e=function(){return function(e,t){var n,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[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]&&(i=0)),i;)try{if(n=1,r&&(o=2&l[0]?r.return:l[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,l[1])).done)return o;switch(r=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,r=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===l[0]||2===l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=t.call(e,i)}catch(e){l=[6,e],r=0}finally{n=o=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}}}(this,function(e){return this.pluginSettingsManager.addMenuItem({key:"ai-api",title:this.t("AI API Gateway"),icon:"ApiOutlined",aclSnippet:"pm.ai-api.configuration"}),this.pluginSettingsManager.addPageTabItem({menuKey:"ai-api",key:"index",title:this.t("Configuration"),componentLoader:function(){return l.e("950").then(l.bind(l,693))}}),[2]})},function(){var n=this,r=arguments;return new Promise(function(o,i){var a=e.apply(n,r);function u(e){t(a,o,i,u,c,"next",e)}function c(e){t(a,o,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,n),i}(i(e.Plugin))}(),v}()});
|
package/dist/externalVersion.js
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
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
|
+
|
|
1
10
|
module.exports = {
|
|
2
11
|
"react": "18.2.0",
|
|
3
12
|
"antd": "5.24.2",
|
|
4
|
-
"@nocobase/client": "2.
|
|
5
|
-
"@nocobase/flow-engine": "2.
|
|
6
|
-
"@nocobase/plugin-acl": "2.
|
|
7
|
-
"@nocobase/
|
|
8
|
-
"@nocobase/
|
|
9
|
-
"
|
|
10
|
-
"@nocobase/
|
|
11
|
-
"@nocobase/
|
|
13
|
+
"@nocobase/client": "2.1.6",
|
|
14
|
+
"@nocobase/flow-engine": "2.1.6",
|
|
15
|
+
"@nocobase/plugin-acl": "2.1.6",
|
|
16
|
+
"@nocobase/client-v2": "2.1.6",
|
|
17
|
+
"@nocobase/server": "2.1.6",
|
|
18
|
+
"dayjs": "1.11.13",
|
|
19
|
+
"@nocobase/database": "2.1.6",
|
|
20
|
+
"@nocobase/actions": "2.1.6",
|
|
21
|
+
"@nocobase/resourcer": "2.1.6",
|
|
22
|
+
"@nocobase/plugin-ai": "2.1.6"
|
|
12
23
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
package/dist/locale/en-US.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
{
|
|
2
|
-
"AI API Gateway": "AI API Gateway",
|
|
3
|
-
"Configuration": "Configuration",
|
|
4
|
-
"Default AI Employee": "Default AI Employee",
|
|
5
|
-
"Enabled LLM Services": "Enabled LLM Services",
|
|
6
|
-
"Rate Limit": "Rate Limit",
|
|
7
|
-
"Save Configuration": "Save Configuration",
|
|
8
|
-
"Configuration saved": "Configuration saved",
|
|
9
|
-
"Failed to save configuration": "Failed to save configuration"
|
|
10
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"AI API Gateway": "AI API Gateway",
|
|
3
|
+
"Configuration": "Configuration",
|
|
4
|
+
"Default AI Employee": "Default AI Employee",
|
|
5
|
+
"Enabled LLM Services": "Enabled LLM Services",
|
|
6
|
+
"Rate Limit": "Rate Limit",
|
|
7
|
+
"Save Configuration": "Save Configuration",
|
|
8
|
+
"Configuration saved": "Configuration saved",
|
|
9
|
+
"Failed to save configuration": "Failed to save configuration"
|
|
10
|
+
}
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
{
|
|
2
|
-
"AI API Gateway": "AI API 网关",
|
|
3
|
-
"Configuration": "配置",
|
|
4
|
-
"Default AI Employee": "默认 AI 员工",
|
|
5
|
-
"Enabled LLM Services": "已启用 LLM 服务",
|
|
6
|
-
"Rate Limit": "速率限制",
|
|
7
|
-
"Save Configuration": "保存配置",
|
|
8
|
-
"Configuration saved": "配置已保存",
|
|
9
|
-
"Failed to save configuration": "保存配置失败"
|
|
10
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"AI API Gateway": "AI API 网关",
|
|
3
|
+
"Configuration": "配置",
|
|
4
|
+
"Default AI Employee": "默认 AI 员工",
|
|
5
|
+
"Enabled LLM Services": "已启用 LLM 服务",
|
|
6
|
+
"Rate Limit": "速率限制",
|
|
7
|
+
"Save Configuration": "保存配置",
|
|
8
|
+
"Configuration saved": "配置已保存",
|
|
9
|
+
"Failed to save configuration": "保存配置失败"
|
|
10
|
+
}
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
package/dist/server/plugin.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -35,6 +44,11 @@ var import_server = require("@nocobase/server");
|
|
|
35
44
|
var import_router = require("./routes/router");
|
|
36
45
|
var import_ai_api_config = __toESM(require("./resource/ai-api-config"));
|
|
37
46
|
var import_rate_limiter = require("./utils/rate-limiter");
|
|
47
|
+
var import_dayjs = __toESM(require("dayjs"));
|
|
48
|
+
var import_utc = __toESM(require("dayjs/plugin/utc"));
|
|
49
|
+
var import_timezone = __toESM(require("dayjs/plugin/timezone"));
|
|
50
|
+
import_dayjs.default.extend(import_utc.default);
|
|
51
|
+
import_dayjs.default.extend(import_timezone.default);
|
|
38
52
|
class PluginAiApiServer extends import_server.Plugin {
|
|
39
53
|
/**
|
|
40
54
|
* Singleton rate limiter — lives for the entire plugin lifetime, shared across all requests.
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __create = Object.create;
|
|
2
11
|
var __defProp = Object.defineProperty;
|
|
3
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -57,7 +66,8 @@ async function handleAgentCompletions(ctx, plugin) {
|
|
|
57
66
|
return;
|
|
58
67
|
}
|
|
59
68
|
const config = await ctx.db.getRepository("aiApiConfig").findOne();
|
|
60
|
-
|
|
69
|
+
const defaultAiEmployee = config ? config.get("defaultAiEmployee") || config.defaultAiEmployee : null;
|
|
70
|
+
if (!defaultAiEmployee) {
|
|
61
71
|
ctx.status = 400;
|
|
62
72
|
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
63
73
|
400,
|
|
@@ -84,7 +94,7 @@ async function handleAgentCompletions(ctx, plugin) {
|
|
|
84
94
|
ctx.body = (0, import_openai_format.toOpenAIError)(404, "LLM service is disabled", "invalid_request_error", "model_not_found");
|
|
85
95
|
return;
|
|
86
96
|
}
|
|
87
|
-
const employeeUsername =
|
|
97
|
+
const employeeUsername = defaultAiEmployee;
|
|
88
98
|
if (!(0, import_role_permission.checkEmployeeAccess)(ctx, employeeUsername)) {
|
|
89
99
|
ctx.status = 403;
|
|
90
100
|
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
@@ -137,14 +147,21 @@ async function handleAgentCompletions(ctx, plugin) {
|
|
|
137
147
|
);
|
|
138
148
|
AIEmployee = mod.AIEmployee;
|
|
139
149
|
} catch (importErr) {
|
|
140
|
-
ctx.log.error(
|
|
150
|
+
ctx.log.error(
|
|
151
|
+
"AI API: Failed to import AIEmployee from plugin-ai. Ensure plugin-ai is installed and built.",
|
|
152
|
+
importErr
|
|
153
|
+
);
|
|
141
154
|
ctx.status = 500;
|
|
142
155
|
ctx.body = (0, import_openai_format.toOpenAIError)(500, "Agent mode unavailable: plugin-ai not found or not built", "server_error");
|
|
143
156
|
return;
|
|
144
157
|
}
|
|
145
158
|
if (!AIEmployee) {
|
|
146
159
|
ctx.status = 500;
|
|
147
|
-
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
160
|
+
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
161
|
+
500,
|
|
162
|
+
"Agent mode unavailable: AIEmployee class not exported by plugin-ai",
|
|
163
|
+
"server_error"
|
|
164
|
+
);
|
|
148
165
|
return;
|
|
149
166
|
}
|
|
150
167
|
if (!ctx.get("x-timezone")) {
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -58,22 +67,12 @@ async function authenticateBearer(ctx) {
|
|
|
58
67
|
decoded = await jwt.decode(token);
|
|
59
68
|
} catch (e) {
|
|
60
69
|
ctx.status = 401;
|
|
61
|
-
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
62
|
-
401,
|
|
63
|
-
"Incorrect API key provided",
|
|
64
|
-
"invalid_request_error",
|
|
65
|
-
"invalid_api_key"
|
|
66
|
-
);
|
|
70
|
+
ctx.body = (0, import_openai_format.toOpenAIError)(401, "Incorrect API key provided", "invalid_request_error", "invalid_api_key");
|
|
67
71
|
return false;
|
|
68
72
|
}
|
|
69
73
|
if (!decoded || !decoded.userId) {
|
|
70
74
|
ctx.status = 401;
|
|
71
|
-
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
72
|
-
401,
|
|
73
|
-
"Invalid or expired API key",
|
|
74
|
-
"invalid_request_error",
|
|
75
|
-
"invalid_api_key"
|
|
76
|
-
);
|
|
75
|
+
ctx.body = (0, import_openai_format.toOpenAIError)(401, "Invalid or expired API key", "invalid_request_error", "invalid_api_key");
|
|
77
76
|
return false;
|
|
78
77
|
}
|
|
79
78
|
const user = await ctx.db.getRepository("users").findOne({
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -68,16 +77,19 @@ async function handleChatCompletions(ctx, plugin) {
|
|
|
68
77
|
}
|
|
69
78
|
if (service.enabled === false) {
|
|
70
79
|
ctx.status = 404;
|
|
71
|
-
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
80
|
+
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
81
|
+
404,
|
|
82
|
+
`LLM service '${service.title || service.name}' is disabled`,
|
|
83
|
+
"invalid_request_error",
|
|
84
|
+
"model_not_found"
|
|
85
|
+
);
|
|
72
86
|
return;
|
|
73
87
|
}
|
|
74
88
|
const config = await ctx.db.getRepository("aiApiConfig").findOne();
|
|
75
89
|
if ((_a = config == null ? void 0 : config.enabledLlmServices) == null ? void 0 : _a.length) {
|
|
76
90
|
const serviceName = service.name;
|
|
77
91
|
const serviceTitle = service.title;
|
|
78
|
-
const isAllowed = config.enabledLlmServices.some(
|
|
79
|
-
(s) => s === serviceName || s === serviceTitle
|
|
80
|
-
);
|
|
92
|
+
const isAllowed = config.enabledLlmServices.some((s) => s === serviceName || s === serviceTitle);
|
|
81
93
|
if (!isAllowed) {
|
|
82
94
|
ctx.status = 403;
|
|
83
95
|
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -67,16 +76,19 @@ async function handleCompletions(ctx, plugin) {
|
|
|
67
76
|
}
|
|
68
77
|
if (service.enabled === false) {
|
|
69
78
|
ctx.status = 404;
|
|
70
|
-
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
79
|
+
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
80
|
+
404,
|
|
81
|
+
`LLM service '${service.title || service.name}' is disabled`,
|
|
82
|
+
"invalid_request_error",
|
|
83
|
+
"model_not_found"
|
|
84
|
+
);
|
|
71
85
|
return;
|
|
72
86
|
}
|
|
73
87
|
const config = await ctx.db.getRepository("aiApiConfig").findOne();
|
|
74
88
|
if ((_a = config == null ? void 0 : config.enabledLlmServices) == null ? void 0 : _a.length) {
|
|
75
89
|
const serviceName = service.name;
|
|
76
90
|
const serviceTitle = service.title;
|
|
77
|
-
const isAllowed = config.enabledLlmServices.some(
|
|
78
|
-
(s) => s === serviceName || s === serviceTitle
|
|
79
|
-
);
|
|
91
|
+
const isAllowed = config.enabledLlmServices.some((s) => s === serviceName || s === serviceTitle);
|
|
80
92
|
if (!isAllowed) {
|
|
81
93
|
ctx.status = 403;
|
|
82
94
|
ctx.body = (0, import_openai_format.toOpenAIError)(
|
|
@@ -1,3 +1,12 @@
|
|
|
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
|
+
|
|
1
10
|
var __defProp = Object.defineProperty;
|
|
2
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -95,9 +104,7 @@ async function handleEmbeddings(ctx, plugin) {
|
|
|
95
104
|
try {
|
|
96
105
|
const config = await ctx.db.getRepository("aiApiConfig").findOne();
|
|
97
106
|
if ((_a = config == null ? void 0 : config.enabledLlmServices) == null ? void 0 : _a.length) {
|
|
98
|
-
const allowed = config.enabledLlmServices.some(
|
|
99
|
-
(s) => s === service.name || s === service.title
|
|
100
|
-
);
|
|
107
|
+
const allowed = config.enabledLlmServices.some((s) => s === service.name || s === service.title);
|
|
101
108
|
if (!allowed) {
|
|
102
109
|
ctx.status = 403;
|
|
103
110
|
ctx.body = (0, import_openai_format.toOpenAIError)(
|