plugin-ai-api 1.0.4 → 1.0.6

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.
@@ -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(485),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.useApp)().apiClient,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],S=null==t?void 0:t.name;(0,n.useEffect)(function(){S&&P()},[S]);var P=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:S},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:S,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 a=n(155),r=n.n(a),l=n(59),o=n(485);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}function c(e,t,n,a,r,l,o){try{var i=e[l](o),c=i.value}catch(e){n(e);return}i.done?t(c):Promise.resolve(c).then(a,r)}function u(e){return function(){var t=this,n=arguments;return new Promise(function(a,r){var l=e.apply(t,n);function o(e){c(l,a,r,o,i,"next",e)}function i(e){c(l,a,r,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,a,r=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var l=[],o=!0,i=!1;try{for(r=r.call(e);!(o=(n=r.next()).done)&&(l.push(n.value),!t||l.length!==t);o=!0);}catch(e){i=!0,a=e}finally{try{o||null==r.return||r.return()}finally{if(i)throw a}}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,a,r,l={label:0,sent:function(){if(1&r[0])throw r[1];return r[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,a&&(r=2&u[0]?a.return:u[0]?a.throw||((r=a.return)&&r.call(a),0):a.next)&&!(r=r.call(a,u[1])).done)return r;switch(a=0,r&&(u=[2&u[0],r.value]),u[0]){case 0:case 1:r=u;break;case 4:return l.label++,{value:u[1],done:!1};case 5:l.label++,a=u[1],u=[0];continue;case 7:u=l.ops.pop(),l.trys.pop();continue;default:if(!(r=(r=l.trys).length>0&&r[r.length-1])&&(6===u[0]||2===u[0])){l=0;continue}if(3===u[0]&&(!r||u[1]>r[0]&&u[1]<r[3])){l.label=u[1];break}if(6===u[0]&&l.label<r[1]){l.label=r[1],r=u;break}if(r&&l.label<r[2]){l.label=r[2],l.ops.push(u);break}r[2]&&l.ops.pop(),l.trys.pop();continue}u=t.call(e,l)}catch(e){u=[6,e],a=0}finally{n=r=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.useApp)().apiClient,t=s(l.Form.useForm(),1)[0],n=s((0,a.useState)(!0),2),i=n[0],c=n[1],y=s((0,a.useState)(!1),2),v=y[0],h=y[1],b=s((0,a.useState)([]),2),g=b[0],E=b[1],A=s((0,a.useState)([]),2),S=A[0],w=A[1],I=s((0,a.useState)(""),2),L=I[0],k=I[1];(0,a.useEffect)(function(){C(),k("".concat(window.location.origin,"/api/ai-llm/v1"))},[]);var C=function(){return u(function(){var n,a,r,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==(a=i.data)?void 0:a.data)||[]).map(function(e){return{username:e.username,nickname:e.nickname||e.username}})),[4,e.request({url:"ai:listLLMServices"})];case 4:return w(((null==(u=s.sent())||null==(r=u.data)?void 0:r.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?r().createElement("div",{style:{display:"flex",justifyContent:"center",padding:60}},r().createElement(l.Spin,{size:"large"})):r().createElement("div",{style:{maxWidth:800,margin:"0 auto",padding:"24px 0"}},r().createElement(p,{level:3},"AI API Gateway Configuration"),r().createElement(f,{type:"secondary"},"Configure the OpenAI-compatible API endpoint. External applications can connect using the base URL and a NocoBase API key."),r().createElement(l.Card,{style:{marginBottom:24}},r().createElement(l.Alert,{type:"info",showIcon:!0,message:"API Endpoint",description:r().createElement(l.Space,{direction:"vertical",size:4},r().createElement(d,null,"Base URL:"," ",r().createElement(d,{code:!0,copyable:!0},L)),r().createElement(d,{type:"secondary"},"Use this as the base URL in any OpenAI-compatible client (Cursor, Continue.dev, n8n, etc.)")),style:{marginBottom:16}}),r().createElement(l.Alert,{type:"warning",showIcon:!0,message:"Authentication",description:r().createElement(d,null,"Clients must include a NocoBase API key as a Bearer token:",r().createElement("br",null),r().createElement(d,{code:!0},"Authorization: Bearer ","<your-nocobase-api-key>"),r().createElement("br",null),r().createElement(d,{type:"secondary"},"API keys can be created in Settings → API keys."))})),r().createElement(l.Card,{title:"Configuration"},r().createElement(l.Form,{form:t,layout:"vertical",onFinish:function(){return u(function(){var n;return m(this,function(a){switch(a.label){case 0:h(!0),a.label=1;case 1:return a.trys.push([1,3,4,5]),n=t.getFieldsValue(),[4,e.request({url:"aiApiConfig:save",method:"post",data:n})];case 2:return a.sent(),l.message.success("Configuration saved"),[3,5];case 3:return a.sent(),l.message.error("Failed to save configuration"),[3,5];case 4:return h(!1),[7];case 5:return[2]}})})()},initialValues:{mode:"llm"}},r().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."},r().createElement(l.Radio.Group,null,r().createElement(l.Radio.Button,{value:"llm"},"LLM Proxy"),r().createElement(l.Radio.Button,{value:"agent"},"AI Employee Agent"))),r().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)"},r().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}})})),r().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"}]},r().createElement(l.Select,{allowClear:!0,placeholder:"Select an LLM Service",options:S.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),r().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."},r().createElement(l.Select,{mode:"multiple",allowClear:!0,placeholder:"All enabled services (default)",options:S.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),r().createElement(l.Form.Item,{name:"rateLimitPerMinute",label:"Rate Limit (requests/minute)",tooltip:"Maximum API requests per user per minute. Set 0 for unlimited."},r().createElement(l.InputNumber,{min:0,max:1e4,style:{width:200}})),r().createElement(l.Form.Item,null,r().createElement(l.Button,{type:"primary",htmlType:"submit",loading:v},"Save Configuration")))),r().createElement(l.Card,{title:"Quick Start",style:{marginTop:24}},r().createElement(p,{level:5},"cURL Example"),r().createElement(f,null,r().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 }\''))),r().createElement(p,{level:5},"Python (OpenAI SDK)"),r().createElement(f,null,r().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)'))),r().createElement(p,{level:5},"List Available Models"),r().createElement(f,null,r().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}}]);
@@ -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("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}()});
10
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@nocobase/client-v2"),require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client")):"function"==typeof define&&define.amd?define("plugin-ai-api",["@nocobase/client-v2","react","antd","@nocobase/client","@nocobase/plugin-acl/client"],t):"object"==typeof exports?exports["plugin-ai-api"]=t(require("@nocobase/client-v2"),require("react"),require("antd"),require("@nocobase/client"),require("@nocobase/plugin-acl/client")):e["plugin-ai-api"]=t(e["@nocobase/client-v2"],e.react,e.antd,e["@nocobase/client"],e["@nocobase/plugin-acl/client"])}(self,function(e,t,n,r,o){return function(){"use strict";var i,a,u,c={342:function(e){e.exports=r},485:function(t){t.exports=e},79:function(e){e.exports=o},59:function(e){e.exports=n},155:function(e){e.exports=t}},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+"."+({778:"5c452944cb747975",950:"83390c5f1d5a97fb"})[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)},f={},p.l=function(e,t,n,r){if(f[e])return void f[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,p.nc&&o.setAttribute("nonce",p.nc),o.setAttribute("data-rspack","plugin-ai-api:"+n),o.src=e),f[e]=[t];var l=function(t,n){o.onerror=o.onload=null,clearTimeout(s);var r=f[e];if(delete f[e],o.parentNode&&o.parentNode.removeChild(o),r&&r.forEach(function(e){return e(n)}),t)return t(n)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=l.bind(null,o.onerror),o.onload=l.bind(null,o.onload),i&&document.head.appendChild(o)},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&&(s=p.g.location+"");var f,s,d=p.g.document;if(!s&&d&&(d.currentScript&&"SCRIPT"===d.currentScript.tagName.toUpperCase()&&(s=d.currentScript.src),!s)){var b=d.getElementsByTagName("script");if(b.length)for(var h=b.length-1;h>-1&&(!s||!/^http(s?):/.test(s));)s=b[h--].src}if(!s)throw Error("Automatic publicPath is not supported in this browser");p.p=s.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),i={889:0},p.f.j=function(e,t){var n=p.o(i,e)?i[e]:void 0;if(0!==n)if(n)t.push(n[2]);else{var r=new Promise(function(t,r){n=i[e]=[t,r]});t.push(n[2]=r);var o=p.p+p.u(e),a=Error();p.l(o,function(t){if(p.o(i,e)&&(0!==(n=i[e])&&(i[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;a.message="Loading chunk "+e+" failed.\n("+r+": "+o+")",a.name="ChunkLoadError",a.type=r,a.request=o,n[1](a)}},"chunk-"+e,e)}},a=function(e,t){var n,r,o=t[0],a=t[1],u=t[2],c=0;if(o.some(function(e){return 0!==i[e]})){for(n in a)p.o(a,n)&&(p.m[n]=a[n]);u&&u(p)}for(e&&e(t);c<o.length;c++)r=o[c],p.o(i,r)&&i[r]&&i[r][0](),i[r]=0},(u=self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).forEach(a.bind(null,0)),u.push=a.bind(null,u.push.bind(u));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/")}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/"}p.p=e}(),!function(){p.r(v),p.d(v,{default:function(){return b}});var e=p(342),t=p(79),n=p.n(t),r=p(155),o=p.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 l(e){var t="function"==typeof Map?new Map:void 0;return(l=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 p.e("950").then(p.bind(p,693))}),d=(0,e.lazy)(function(){return p.e("778").then(p.bind(p,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}(l(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([["950"],{693:function(e,t,n){n.r(t),n.d(t,{AiApiConfigPage:function(){return y}});var a=n(155),r=n.n(a),l=n(59),o=n(485);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}function c(e,t,n,a,r,l,o){try{var i=e[l](o),c=i.value}catch(e){n(e);return}i.done?t(c):Promise.resolve(c).then(a,r)}function u(e){return function(){var t=this,n=arguments;return new Promise(function(a,r){var l=e.apply(t,n);function o(e){c(l,a,r,o,i,"next",e)}function i(e){c(l,a,r,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,a,r=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var l=[],o=!0,i=!1;try{for(r=r.call(e);!(o=(n=r.next()).done)&&(l.push(n.value),!t||l.length!==t);o=!0);}catch(e){i=!0,a=e}finally{try{o||null==r.return||r.return()}finally{if(i)throw a}}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,a,r,l={label:0,sent:function(){if(1&r[0])throw r[1];return r[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,a&&(r=2&u[0]?a.return:u[0]?a.throw||((r=a.return)&&r.call(a),0):a.next)&&!(r=r.call(a,u[1])).done)return r;switch(a=0,r&&(u=[2&u[0],r.value]),u[0]){case 0:case 1:r=u;break;case 4:return l.label++,{value:u[1],done:!1};case 5:l.label++,a=u[1],u=[0];continue;case 7:u=l.ops.pop(),l.trys.pop();continue;default:if(!(r=(r=l.trys).length>0&&r[r.length-1])&&(6===u[0]||2===u[0])){l=0;continue}if(3===u[0]&&(!r||u[1]>r[0]&&u[1]<r[3])){l.label=u[1];break}if(6===u[0]&&l.label<r[1]){l.label=r[1],r=u;break}if(r&&l.label<r[2]){l.label=r[2],l.ops.push(u);break}r[2]&&l.ops.pop(),l.trys.pop();continue}u=t.call(e,l)}catch(e){u=[6,e],a=0}finally{n=r=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.useApp)().apiClient,t=s(l.Form.useForm(),1)[0],n=s((0,a.useState)(!0),2),i=n[0],c=n[1],y=s((0,a.useState)(!1),2),v=y[0],h=y[1],b=s((0,a.useState)([]),2),g=b[0],E=b[1],A=s((0,a.useState)([]),2),S=A[0],w=A[1],I=s((0,a.useState)(""),2),L=I[0],k=I[1];(0,a.useEffect)(function(){C(),k("".concat(window.location.origin,"/api/ai-llm/v1"))},[]);var C=function(){return u(function(){var n,a,r,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==(a=i.data)?void 0:a.data)||[]).map(function(e){return{username:e.username,nickname:e.nickname||e.username}})),[4,e.request({url:"ai:listLLMServices"})];case 4:return w(((null==(u=s.sent())||null==(r=u.data)?void 0:r.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?r().createElement("div",{style:{display:"flex",justifyContent:"center",padding:60}},r().createElement(l.Spin,{size:"large"})):r().createElement("div",{style:{maxWidth:800,margin:"0 auto",padding:"24px 0"}},r().createElement(p,{level:3},"AI API Gateway Configuration"),r().createElement(f,{type:"secondary"},"Configure the OpenAI-compatible API endpoint. External applications can connect using the base URL and a NocoBase API key."),r().createElement(l.Card,{style:{marginBottom:24}},r().createElement(l.Alert,{type:"info",showIcon:!0,message:"API Endpoint",description:r().createElement(l.Space,{direction:"vertical",size:4},r().createElement(d,null,"Base URL:"," ",r().createElement(d,{code:!0,copyable:!0},L)),r().createElement(d,{type:"secondary"},"Use this as the base URL in any OpenAI-compatible client (Cursor, Continue.dev, n8n, etc.)")),style:{marginBottom:16}}),r().createElement(l.Alert,{type:"warning",showIcon:!0,message:"Authentication",description:r().createElement(d,null,"Clients must include a NocoBase API key as a Bearer token:",r().createElement("br",null),r().createElement(d,{code:!0},"Authorization: Bearer ","<your-nocobase-api-key>"),r().createElement("br",null),r().createElement(d,{type:"secondary"},"API keys can be created in Settings → API keys."))})),r().createElement(l.Card,{title:"Configuration"},r().createElement(l.Form,{form:t,layout:"vertical",onFinish:function(){return u(function(){var n;return m(this,function(a){switch(a.label){case 0:h(!0),a.label=1;case 1:return a.trys.push([1,3,4,5]),n=t.getFieldsValue(),[4,e.request({url:"aiApiConfig:save",method:"post",data:n})];case 2:return a.sent(),l.message.success("Configuration saved"),[3,5];case 3:return a.sent(),l.message.error("Failed to save configuration"),[3,5];case 4:return h(!1),[7];case 5:return[2]}})})()},initialValues:{mode:"llm"}},r().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."},r().createElement(l.Radio.Group,null,r().createElement(l.Radio.Button,{value:"llm"},"LLM Proxy"),r().createElement(l.Radio.Button,{value:"agent"},"AI Employee Agent"))),r().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)"},r().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}})})),r().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"}]},r().createElement(l.Select,{allowClear:!0,placeholder:"Select an LLM Service",options:S.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),r().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."},r().createElement(l.Select,{mode:"multiple",allowClear:!0,placeholder:"All enabled services (default)",options:S.map(function(e){return{label:"".concat(e.title," (").concat(e.provider,")"),value:e.name}})})),r().createElement(l.Form.Item,{name:"rateLimitPerMinute",label:"Rate Limit (requests/minute)",tooltip:"Maximum API requests per user per minute. Set 0 for unlimited."},r().createElement(l.InputNumber,{min:0,max:1e4,style:{width:200}})),r().createElement(l.Form.Item,null,r().createElement(l.Button,{type:"primary",htmlType:"submit",loading:v},"Save Configuration")))),r().createElement(l.Card,{title:"Quick Start",style:{marginTop:24}},r().createElement(p,{level:5},"cURL Example"),r().createElement(f,null,r().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 }\''))),r().createElement(p,{level:5},"Python (OpenAI SDK)"),r().createElement(f,null,r().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)'))),r().createElement(p,{level:5},"List Available Models"),r().createElement(f,null,r().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}}]);
@@ -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("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}()});
10
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@nocobase/client-v2"),require("react"),require("antd")):"function"==typeof define&&define.amd?define("plugin-ai-api/client-v2",["@nocobase/client-v2","react","antd"],t):"object"==typeof exports?exports["plugin-ai-api/client-v2"]=t(require("@nocobase/client-v2"),require("react"),require("antd")):e["plugin-ai-api/client-v2"]=t(e["@nocobase/client-v2"],e.react,e.antd)}(self,function(e,t,n){return function(){"use strict";var r,o,i,a={485:function(t){t.exports=e},59:function(e){e.exports=n},155:function(e){e.exports=t}},u={};function c(e){var t=u[e];if(void 0!==t)return t.exports;var n=u[e]={exports:{}};return a[e](n,n.exports,c),n.exports}c.m=a,c.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(t,{a:t}),t},c.d=function(e,t){for(var n in t)c.o(t,n)&&!c.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},c.f={},c.e=function(e){return Promise.all(Object.keys(c.f).reduce(function(t,n){return c.f[n](e,t),t},[]))},c.u=function(e){return""+e+".42b30b5cc9e32b8f.js"},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l={},c.l=function(e,t,n,r){if(l[e])return void l[e].push(t);if(void 0!==n)for(var o,i,a=document.getElementsByTagName("script"),u=0;u<a.length;u++){var p=a[u];if(p.getAttribute("src")==e||p.getAttribute("data-rspack")=="plugin-ai-api/client-v2:"+n){o=p;break}}o||(i=!0,(o=document.createElement("script")).timeout=120,c.nc&&o.setAttribute("nonce",c.nc),o.setAttribute("data-rspack","plugin-ai-api/client-v2:"+n),o.src=e),l[e]=[t];var f=function(t,n){o.onerror=o.onload=null,clearTimeout(s);var r=l[e];if(delete l[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)},c.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.g.importScripts&&(p=c.g.location+"");var l,p,f=c.g.document;if(!p&&f&&(f.currentScript&&"SCRIPT"===f.currentScript.tagName.toUpperCase()&&(p=f.currentScript.src),!p)){var s=f.getElementsByTagName("script");if(s.length)for(var d=s.length-1;d>-1&&(!p||!/^http(s?):/.test(p));)p=s[d--].src}if(!p)throw Error("Automatic publicPath is not supported in this browser");c.p=p.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r={889:0},c.f.j=function(e,t){var n=c.o(r,e)?r[e]:void 0;if(0!==n)if(n)t.push(n[2]);else{var o=new Promise(function(t,o){n=r[e]=[t,o]});t.push(n[2]=o);var i=c.p+c.u(e),a=Error();c.l(i,function(t){if(c.o(r,e)&&(0!==(n=r[e])&&(r[e]=void 0),n)){var o=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;a.message="Loading chunk "+e+" failed.\n("+o+": "+i+")",a.name="ChunkLoadError",a.type=o,a.request=i,n[1](a)}},"chunk-"+e,e)}},o=function(e,t){var n,o,i=t[0],a=t[1],u=t[2],l=0;if(i.some(function(e){return 0!==r[e]})){for(n in a)c.o(a,n)&&(c.m[n]=a[n]);u&&u(c)}for(e&&e(t);l<i.length;l++)o=i[l],c.o(r,o)&&r[o]&&r[o][0](),r[o]=0},(i=self.webpackChunkplugin_ai_api_client_v2=self.webpackChunkplugin_ai_api_client_v2||[]).forEach(o.bind(null,0)),i.push=o.bind(null,i.push.bind(i));var b={};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/"}c.p=e}(),!function(){c.r(b),c.d(b,{default:function(){return u}});var e=c(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)}c(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 c.e("950").then(c.bind(c,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))}(),b}()});
@@ -10,10 +10,10 @@
10
10
  module.exports = {
11
11
  "react": "18.2.0",
12
12
  "antd": "5.24.2",
13
- "@nocobase/client": "2.1.6",
13
+ "@nocobase/client-v2": "2.1.6",
14
14
  "@nocobase/flow-engine": "2.1.6",
15
+ "@nocobase/client": "2.1.6",
15
16
  "@nocobase/plugin-acl": "2.1.6",
16
- "@nocobase/client-v2": "2.1.6",
17
17
  "@nocobase/server": "2.1.6",
18
18
  "dayjs": "1.11.13",
19
19
  "@nocobase/database": "2.1.6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plugin-ai-api",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "dist/server/index.js",
5
5
  "dependencies": {},
6
6
  "peerDependencies": {
@@ -9,7 +9,7 @@
9
9
 
10
10
  import React, { useEffect, useState } from 'react';
11
11
  import { Card, Form, Select, InputNumber, Button, message, Typography, Space, Alert, Divider, Spin, Radio } from 'antd';
12
- import { useAPIClient } from '@nocobase/client';
12
+ import { useApp } from '@nocobase/client-v2';
13
13
 
14
14
  const { Title, Text, Paragraph } = Typography;
15
15
 
@@ -34,7 +34,7 @@ interface LlmService {
34
34
  }
35
35
 
36
36
  export function AiApiConfigPage() {
37
- const api = useAPIClient();
37
+ const api = useApp().apiClient;
38
38
  const [form] = Form.useForm();
39
39
  const [loading, setLoading] = useState(true);
40
40
  const [saving, setSaving] = useState(false);
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import React, { useEffect, useState } from 'react';
11
- import { useAPIClient } from '@nocobase/client';
11
+ import { useApp } from '@nocobase/client-v2';
12
12
  import { Card, Switch, Select, Space, Typography, Spin, Divider } from 'antd';
13
13
 
14
14
  const { Text } = Typography;
@@ -31,7 +31,7 @@ interface RolePermRecord {
31
31
  * Lets admins control whether a role can use the AI API and which AI Employees it may access.
32
32
  */
33
33
  export function AiApiRolePermissions({ role }: { role: any }) {
34
- const api = useAPIClient();
34
+ const api = useApp().apiClient;
35
35
  const [loading, setLoading] = useState(true);
36
36
  const [saving, setSaving] = useState(false);
37
37
  const [employees, setEmployees] = useState<AiEmployee[]>([]);
@@ -1,10 +0,0 @@
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})))))}}}]);
@@ -1,10 +0,0 @@
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}}]);
@@ -1,10 +0,0 @@
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}}]);