@nocobase/plugin-ai 2.1.17 → 2.1.18

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.
@@ -51,6 +51,33 @@ API_BASE_PATH=/api/
51
51
 
52
52
  ## API_BASE_URL
53
53
 
54
+ ## SERVER_REQUEST_WHITELIST
55
+
56
+ Whitelist for outbound HTTP requests initiated by the server. It applies to server-side requests from features such as workflow request nodes, custom requests, and AI services.
57
+
58
+ When this variable is not configured, NocoBase still allows `http` / `https` requests to keep existing deployments compatible. However, if the target is a loopback, private, link-local, or metadata address, or if a domain resolves to one of these addresses, the server logs a warning. Future versions may gradually tighten the default behavior. If your deployment needs to access internal services, configure an explicit whitelist in advance.
59
+
60
+ Supported entries include:
61
+
62
+ - Exact IPv4 address, such as `192.168.1.10`
63
+ - IPv4 CIDR range, such as `10.0.0.0/8`
64
+ - Exact IPv6 address, such as `::1`
65
+ - IPv6 CIDR range, such as `fc00::/7`
66
+ - Exact domain, such as `api.example.com`
67
+ - Single-level wildcard subdomain, such as `*.example.com`
68
+
69
+ Use `,` to separate multiple targets:
70
+
71
+ ```bash
72
+ SERVER_REQUEST_WHITELIST=api.example.com,*.trusted.com,10.0.0.0/8,127.0.0.1
73
+ ```
74
+
75
+ :::warning Note
76
+
77
+ If a domain is configured in the whitelist, the whitelist check uses the host in the request URL. In other words, after `internal.example.com` is configured, it is treated as explicitly allowed even if the domain resolves to `127.0.0.1` or a private address.
78
+
79
+ :::
80
+
54
81
  ## CLUSTER_MODE
55
82
 
56
83
  > `v1.6.0+`
@@ -285,4 +312,4 @@ Enabled trace data processors, defaults to `console`. Other values should refer
285
312
 
286
313
  ```bash
287
314
  TELEMETRY_TRACE_PROCESSOR=console
288
- ```
315
+ ```
@@ -12,17 +12,8 @@ Currently, NocoBase provides the following file preview plugins:
12
12
 
13
13
  ## PDF preview with external storage
14
14
 
15
- PDF preview uses PDF.js to render files in the browser. The browser must first read the PDF file content and then pass it to PDF.js for rendering. Therefore, when files are stored in external storage such as OSS, S3, COS, or a CDN, and the file access domain is different from the NocoBase site domain, the external storage must allow the NocoBase site to read files across origins.
15
+ NocoBase previews PDFs through a browser iframe. Some browsers or PDF readers may support scripts, forms, or other interactive content inside PDF files. If the previewed file comes from an untrusted source, pay attention to the security boundary for script execution.
16
16
 
17
- If CORS is not configured, PDF downloads can still work normally, but preview may fail with a file loading error.
17
+ We recommend isolating the file access domain from the NocoBase site and API domains. For example, serve files from OSS, S3, COS, or a CDN through a dedicated domain, instead of sharing the same origin with the NocoBase frontend or API.
18
18
 
19
- The CORS configuration for external storage or CDN should include:
20
-
21
- ```http
22
- Access-Control-Allow-Origin: https://your-nocobase-domain
23
- Access-Control-Allow-Methods: GET, HEAD
24
- Access-Control-Allow-Headers: *
25
- Access-Control-Expose-Headers: Content-Length, Content-Range, Accept-Ranges, Content-Disposition, Content-Type
26
- ```
27
-
28
- `Access-Control-Allow-Origin` should be set to the actual domain used to access NocoBase. Avoid using `*` for non-public files over the long term, because it expands the range of sites that can read the files.
19
+ If the file domain is different from the API domain, and the API does not enable CORS access for the file domain, scripts running in the PDF preview environment are usually restricted by the browser's same-origin policy. They cannot directly read the NocoBase page, browser storage, or API responses.
@@ -349,15 +349,17 @@ TELEMETRY_TRACE_PROCESSOR=console
349
349
 
350
350
  ### SERVER_REQUEST_WHITELIST
351
351
 
352
- Whitelist of allowed targets for server-initiated outbound HTTP requests, used to prevent SSRF (Server-Side Request Forgery) attacks. Accepts a comma-separated list of exact IPs, CIDR ranges, exact hostnames, and single-level wildcard subdomains.
352
+ Whitelist of allowed targets for outbound HTTP requests initiated by the NocoBase server. Accepts a comma-separated list of exact IPs, CIDR ranges, exact hostnames, and single-level wildcard subdomains.
353
353
 
354
354
  ```bash
355
- SERVER_REQUEST_WHITELIST=1.2.3.4,10.0.0.0/8,api.example.com,*.trusted.com
355
+ SERVER_REQUEST_WHITELIST=api.example.com,*.trusted.com,10.0.0.0/8,127.0.0.1
356
356
  ```
357
357
 
358
- **Applies to**: Workflow "HTTP Request" nodes and Custom Request action buttons. Relative-path requests (calls to the NocoBase API itself) are not affected.
358
+ **Applies to**: Workflow "HTTP Request" nodes, Custom Request action buttons, AI services, and other server-side requests. Relative-path requests (calls to the NocoBase API itself) are not affected.
359
359
 
360
- **When not set**: All `http`/`https` outbound requests are allowed (existing behaviour). **When set**: Only requests whose host matches a whitelist entry are permitted; non-matching requests will raise an error.
360
+ **When not set**: All `http` / `https` outbound requests are allowed to keep existing behavior. However, if the target is a loopback, private, link-local, or metadata address, or if a domain resolves to one of these addresses, the server logs a warning.
361
+
362
+ **When set**: Only requests whose host matches a whitelist entry are permitted; non-matching requests will raise an error. Future versions may gradually tighten the default behavior. If your deployment needs to access internal services, configure an explicit whitelist in advance.
361
363
 
362
364
  Supported formats:
363
365
 
@@ -365,9 +367,17 @@ Supported formats:
365
367
  | --- | --- | --- |
366
368
  | Exact IPv4 | `1.2.3.4` | That IP only |
367
369
  | IPv4 CIDR | `10.0.0.0/8` | All IPs in the subnet |
370
+ | Exact IPv6 | `::1` | That IP only |
371
+ | IPv6 CIDR | `fc00::/7` | All IPs in the subnet |
368
372
  | Exact hostname | `api.example.com` | That hostname only |
369
373
  | Wildcard subdomain | `*.example.com` | One subdomain level, e.g. `foo.example.com`; does **not** match `example.com` or `a.b.example.com` |
370
374
 
375
+ :::warning Note
376
+
377
+ If a domain is configured in the whitelist, the whitelist check uses the host in the request URL. In other words, after `internal.example.com` is configured, it is treated as explicitly allowed even if the domain resolves to `127.0.0.1` or a private address.
378
+
379
+ :::
380
+
371
381
  ## Experimental Environment Variables
372
382
 
373
383
  ### APPEND_PRESET_LOCAL_PLUGINS
@@ -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.webpackChunk_nocobase_plugin_ai=self.webpackChunk_nocobase_plugin_ai||[]).push([["559"],{6482:function(e,t,r){r.r(t),r.d(t,{Settings:function(){return z},useProviderSettingsForm:function(){return _},LLMServices:function(){return H},ProviderSelect:function(){return K}});var n=r(3342),o=r(9155),i=r.n(o),l=r(4442),a=r(3079),c=r(2059),s=r(7375),u={name:"llmServices",fields:[{name:"name",type:"uid",primaryKey:!0},{name:"title",type:"string",interface:"input",uiSchema:{title:'{{t("Title")}}',"x-component":"Input"}},{name:"provider",type:"string",interface:"select",uiSchema:{title:'{{t("Provider")}}',"x-component":"Select"}},{name:"options",type:"jsonb"},{name:"enabledModels",type:"json",defaultValue:{mode:"recommended",models:[]}},{name:"enabled",type:"boolean",defaultValue:!0},{name:"modelOptions",type:"jsonb",defaultValue:{temperature:1,topP:1,frequencyPenalty:0,presencePenalty:0}}]},p={type:"void",properties:{drawer:{type:"void",title:'{{ t("Add new") }}',"x-component":"Action.Drawer","x-decorator":"FormV2","x-use-decorator-props":"useCreateFormProps",properties:{provider:{type:"string","x-decorator":"FormItem",title:'{{ t("Provider") }}',"x-component":"ProviderSelect",required:!0},title:{type:"string","x-decorator":"FormItem",title:'{{ t("Title") }}',"x-component":"Input","x-reactions":{dependencies:["provider"],when:"{{!$self.modified}}",fulfill:{state:{value:"{{$getProviderLabel($deps[0])}}"},schema:{"x-visible":"{{!!$deps[0]}}"}}}},options:{type:"object","x-component":"Settings","x-reactions":{dependencies:["provider"],fulfill:{schema:{"x-visible":"{{!!$deps[0]}}"}}}},"options.baseURL":{type:"string","x-decorator":"FormItem",title:'{{ t("Base URL") }}',"x-component":"TextAreaWithGlobalScope","x-component-props":{placeholder:'{{ t("Base URL is optional, leave blank to use default (recommended)") }}'},"x-reactions":{dependencies:["provider"],fulfill:{schema:{"x-visible":"{{!!$deps[0]}}"}}}},enabledModels:{type:"object","x-decorator":"FormItem",title:'{{ t("Enabled Models") }}',"x-component":"EnabledModelsSelect","x-reactions":{dependencies:["provider"],fulfill:{schema:{"x-visible":"{{!!$deps[0]}}"}}}},footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{testFlight:{type:"void","x-component":"LLMTestFlight","x-reactions":{dependencies:["provider"],fulfill:{schema:{"x-visible":"{{!!$deps[0]}}"}}}},cancel:{title:'{{ t("Cancel") }}',"x-component":"Action","x-use-component-props":"useCancelActionProps"},submit:{title:'{{ t("Submit") }}',"x-component":"Action","x-component-props":{type:"primary"},"x-use-component-props":"useCreateActionProps"}}}}}}},d={type:"void",name:"llm-services",properties:{card:{type:"void","x-component":"CardItem","x-component-props":{heightMode:"fullHeight"},"x-decorator":"TableBlockProvider","x-decorator-props":{collection:"llmServices",action:"list",rowKey:"name",dragSort:!0,dragSortBy:"sort"},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{style:{marginBottom:20}},properties:{refresh:{title:"{{t('Refresh')}}","x-component":"Action","x-use-component-props":"useRefreshActionProps","x-component-props":{icon:"ReloadOutlined"}},bulkDelete:{title:"{{t('Delete')}}","x-action":"destroy","x-component":"Action","x-use-component-props":"useBulkDestroyActionProps","x-component-props":{icon:"DeleteOutlined",confirm:{title:"{{t('Delete record')}}",content:"{{t('Are you sure you want to delete it?')}}"}}},add:{type:"void","x-component":"AddNew",title:"{{t('Add new')}}","x-align":"right"}}},table:{type:"array","x-component":"TableV2","x-use-component-props":"useTableBlockProps","x-component-props":{rowKey:"name",rowSelection:{type:"checkbox"}},properties:{column1:{type:"void",title:'{{ t("UID") }}',"x-component":"TableV2.Column",properties:{name:{type:"string","x-component":"Input","x-read-pretty":!0}}},column2:{type:"void",title:'{{ t("Title") }}',"x-component":"TableV2.Column",properties:{title:{type:"string","x-component":"Input","x-read-pretty":!0}}},column3:{type:"void",title:'{{ t("Provider") }}',"x-component":"TableV2.Column",properties:{provider:{type:"string","x-component":"Select","x-read-pretty":!0,enum:"{{ providers }}"}}},column4:{type:"void",title:'{{ t("Enabled") }}',"x-component":"TableV2.Column",properties:{enabled:{type:"boolean","x-component":"EnabledSwitch"}}},column5:{type:"void",title:'{{ t("Actions") }}',"x-decorator":"TableV2.Column.ActionBar","x-component":"TableV2.Column",properties:{actions:{type:"void","x-component":"Space","x-component-props":{split:"|"},properties:{edit:{type:"void",title:'{{ t("Edit") }}',"x-action":"update","x-component":"Action.Link","x-component-props":{openMode:"drawer"},properties:{drawer:{type:"void",title:'{{ t("Edit record") }}',"x-component":"Action.Drawer","x-decorator":"FormV2","x-use-decorator-props":"useEditFormProps",properties:{provider:{type:"string","x-decorator":"FormItem",title:'{{ t("Provider") }}',"x-component":"ProviderDisplay"},title:{type:"string","x-decorator":"FormItem",title:'{{ t("Title") }}',"x-component":"Input"},options:{type:"object","x-component":"Settings"},"options.baseURL":{type:"string","x-decorator":"FormItem",title:'{{ t("Base URL") }}',"x-component":"TextAreaWithGlobalScope","x-component-props":{placeholder:'{{ t("Base URL is optional, leave blank to use default (recommended)") }}'}},enabledModels:{type:"object","x-decorator":"FormItem",title:'{{ t("Enabled Models") }}',"x-component":"EnabledModelsSelect"},footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{testFlight:{type:"void","x-component":"LLMTestFlight"},cancel:{title:'{{ t("Cancel") }}',"x-component":"Action","x-use-component-props":"useCancelActionProps"},submit:{title:'{{ t("Submit") }}',"x-component":"Action","x-component-props":{type:"primary"},"x-use-component-props":"useEditActionProps"}}}}}}},destroy:{type:"void",title:'{{ t("Delete") }}',"x-action":"destroy","x-component":"Action.Link","x-use-component-props":"useDestroyActionProps","x-component-props":{confirm:{title:"{{t('Delete record')}}",content:"{{t('Are you sure you want to delete it?')}}"}}}}}}}}}}}}},m=r(284),f=r(5230),y=r(9452),v=r(166),b=r(6759),x=r(5555),h={type:"object",properties:{temperature:{type:"number",title:'{{t("Temperature")}}',description:'{{t("Temperature description")}}',"x-decorator":"FormItem","x-component":"Slider","x-component-props":{min:0,max:2,step:.1},default:1},maxTokens:{type:"number",title:'{{t("Max tokens")}}',description:'{{t("Max completion tokens description")}}',"x-decorator":"FormItem","x-component":"InputNumber","x-component-props":{min:1,max:128e3,placeholder:'{{t("Leave empty for no limit")}}'}},topP:{type:"number",title:'{{t("Top P")}}',description:'{{t("Top P description")}}',"x-decorator":"FormItem","x-component":"Slider","x-component-props":{min:0,max:1,step:.1},default:1},frequencyPenalty:{type:"number",title:'{{t("Frequency penalty")}}',description:'{{t("Frequency penalty description")}}',"x-decorator":"FormItem","x-component":"Slider","x-component-props":{min:-2,max:2,step:.1},default:0},presencePenalty:{type:"number",title:'{{t("Presence penalty")}}',description:'{{t("Presence penalty description")}}',"x-decorator":"FormItem","x-component":"Slider","x-component-props":{min:-2,max:2,step:.1},default:0}}},g=function(){var e=(0,a.kj)();return i().createElement(c.Collapse,{bordered:!1,size:"small",style:{marginTop:16},items:[{key:"modelOptions",label:e("Model options"),forceRender:!0,children:i().createElement(n.SchemaComponent,{schema:h,scope:{t:e}})}]})},P=r(7330),S=r(1285);function A(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 w(e,t,r,n,o,i,l){try{var a=e[i](l),c=a.value}catch(e){r(e);return}a.done?t(c):Promise.resolve(c).then(n,o)}function k(e){return function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function l(e){w(i,n,o,l,a,"next",e)}function a(e){w(i,n,o,l,a,"throw",e)}l(void 0)})}}function C(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 E(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t})(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}),e}function M(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,o=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var i=[],l=!0,a=!1;try{for(o=o.call(e);!(l=(r=o.next()).done)&&(i.push(r.value),!t||i.length!==t);l=!0);}catch(e){a=!0,n=e}finally{try{l||null==o.return||o.return()}finally{if(a)throw n}}return i}}(e,t)||O(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 O(e,t){if(e){if("string"==typeof e)return A(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 A(e,t)}}function L(e,t){var r,n,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},l=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),a=Object.defineProperty;return a(l,"next",{value:c(0)}),a(l,"throw",{value:c(1)}),a(l,"return",{value:c(2)}),"function"==typeof Symbol&&a(l,Symbol.iterator,{value:function(){return this}}),l;function c(a){return function(c){var s=[a,c];if(r)throw TypeError("Generator is already executing.");for(;l&&(l=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===s[0]||2===s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}}}var I=(0,o.createContext)({autoOpen:!1,setAutoOpen:function(){}}),F=function(){return{form:(0,o.useMemo)(function(){return(0,y.createForm)({initialValues:{name:"v_".concat((0,v.uid)())}})},[])}},T=function(){var e=(0,n.useCollectionRecordData)();return{form:(0,o.useMemo)(function(){return(0,y.createForm)({initialValues:e})},[e])}},j=function(){var e=(0,n.useActionContext)().setVisible;return{type:"default",onClick:function(){e(!1)}}},D=function(){var e=(0,n.useActionContext)().setVisible,t=c.App.useApp().message,r=(0,f.useForm)(),o=(0,n.useDataBlockResource)(),i=(0,n.useDataBlockRequest)().refresh,l=(0,a.kj)(),s=(0,P.M)();return{type:"primary",onClick:function(){return k(function(){var n;return L(this,function(a){switch(a.label){case 0:return[4,r.submit()];case 1:return a.sent(),n=(0,S.Kr)(r.values),[4,o.create({values:n})];case 2:return a.sent(),i(),s.refreshLLMServices(),t.success(l("Saved successfully")),e(!1),[2]}})})()}}},B=function(){var e=(0,n.useActionContext)().setVisible,t=c.App.useApp().message,r=(0,f.useForm)(),o=(0,n.useDataBlockResource)(),i=(0,n.useDataBlockRequest)().refresh,l=(0,n.useCollection)().getFilterTargetKey(),s=(0,a.kj)(),u=(0,P.M)();return{type:"primary",onClick:function(){return k(function(){var n;return L(this,function(a){switch(a.label){case 0:return[4,r.submit()];case 1:return a.sent(),n=(0,S.Kr)(r.values),[4,o.update({values:n,filterByTk:n[l]})];case 2:return a.sent(),i(),u.refreshLLMServices(),t.success(s("Saved successfully")),e(!1),r.reset(),[2]}})})()}}},R={"google-genai":"Gemini",openai:"GPT","openai-completions":"Recommended for third-party OpenAI-compatible APIs (OpenRouter, Groq, Together AI, etc.)",anthropic:"Claude",deepseek:"DeepSeek",dashscope:"Qwen (Tongyi)",kimi:"Kimi",xai:"Grok models by xAI",ollama:"Local models",mimo:"Xiaomi MIMO",mistral:"Mistral models"},V=["google-genai","openai","anthropic","deepseek","dashscope","kimi","mistral","openai-completions","ollama"],q=function(){var e=(0,f.useField)(),t=(0,m.Pq)().find(function(t){return t.value===e.value});return i().createElement("span",null,(null==t?void 0:t.label)||e.value)},K=function(){var e=c.theme.useToken().token,t=(0,f.useField)(),r=(0,m.Pq)(),n=(0,a.kj)(),o=((function(e){if(Array.isArray(e))return A(e)})(r)||function(e){if("u">typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(r)||O(r)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()).sort(function(e,t){var r=V.indexOf(e.value),n=V.indexOf(t.value);return(r<0?1/0:r)-(n<0?1/0:n)}).map(function(t){var r=R[t.value],o=r?n(r):"",l=t.supportedModel||[],a=[l.includes("LLM")?"LLM":null,l.includes("EMBEDDING")?"EMBEDDING":null].filter(Boolean);return{value:t.value,label:i().createElement("div",null,i().createElement("div",{style:{fontWeight:500}},t.label),i().createElement("div",{style:{fontSize:e.fontSizeSM,color:e.colorTextTertiary,lineHeight:1.4,display:"flex",alignItems:"center",justifyContent:"space-between",gap:e.marginXS}},i().createElement("span",null,o),i().createElement("span",{style:{display:"inline-flex",alignItems:"center",gap:e.marginXXS,flexWrap:"wrap"}},a.map(function(e){return i().createElement(c.Tag,{key:e,bordered:!1,color:"default",style:{marginInlineEnd:0,paddingInline:6,lineHeight:"18px",height:18,fontSize:11}},e)})))),selectedLabel:t.label}});return i().createElement(c.Select,{value:t.value,onChange:function(e){return t.value=e},options:o,optionLabelProp:"selectedLabel",style:{width:"100%"},listHeight:400})},N=(0,f.observer)(function(){var e=(0,f.useField)(),t=(0,n.useCollectionRecordData)(),r=(0,n.useDataBlockResource)(),o=(0,n.useDataBlockRequest)().refresh,l=(0,n.useCollection)().getFilterTargetKey(),a=!1!==e.value,s=(0,P.M)();return i().createElement(c.Switch,{size:"small",checked:a,onChange:function(n){return k(function(){return L(this,function(i){switch(i.label){case 0:return e.value=n,[4,r.update({values:{enabled:n},filterByTk:t[l]})];case 1:return i.sent(),o(),s.refreshLLMServices(),[2]}})})()}})},{displayName:"EnabledSwitch"}),$=function(){var e=(0,n.useDestroyActionProps)(),t=(0,P.M)();return E(C({},e),{onClick:function(r,n){return k(function(){return L(this,function(o){switch(o.label){case 0:return[4,e.onClick(r,n)];case 1:return o.sent(),t.refreshLLMServices(),[2]}})})()}})},G=function(){var e=(0,n.useBulkDestroyActionProps)(),t=(0,P.M)();return E(C({},e),{onClick:function(r,n){return k(function(){return L(this,function(o){switch(o.label){case 0:return[4,e.onClick(r,n)];case 1:return o.sent(),t.refreshLLMServices(),[2]}})})()}})},U=function(){var e=(0,a.kj)(),t=M((0,o.useState)(!1),2),r=t[0],l=t[1],u=M((0,o.useState)(0),2),d=u[0],f=u[1],y=(0,m.Pq)(),v=(0,o.useContext)(I),h=v.autoOpen,P=v.setAutoOpen;return(0,o.useEffect)(function(){h&&(f(function(e){return e+1}),l(!0),P(!1),window.history.replaceState({},document.title))},[h,P]),i().createElement(n.ActionContextProvider,{value:{visible:r,setVisible:l}},i().createElement(c.Button,{icon:i().createElement(s.PlusOutlined,null),type:"primary",onClick:function(){f(function(e){return e+1}),l(!0)}},e("Add new")),i().createElement(n.SchemaComponent,{key:d,components:{LLMTestFlight:b.e,EnabledModelsSelect:x.uQ,ProviderSelect:K,ModelOptionsSettings:g},scope:{useCreateFormProps:F,providers:y,$getProviderLabel:function(e){var t=y.find(function(t){return t.value===e});return(null==t?void 0:t.label)||e}},schema:p}))},_=function(e){var t,r=(0,n.usePlugin)("ai").aiManager.llmProviders.get(e);return null==r||null==(t=r.components)?void 0:t.ProviderSettingsForm},z=(0,f.observer)(function(){var e=(0,f.useForm)(),t=(0,n.useCollectionRecordData)(),r=_(e.values.provider||t.provider);return r?i().createElement(r,null):null},{displayName:"LLMProviderSettings"}),H=function(){var e=(0,a.kj)(),t=M((0,o.useState)([]),2),r=t[0],c=t[1],s=(0,n.useAPIClient)(),p=(0,l.useLocation)(),y=M((0,o.useState)(!1),2),v=y[0],h=y[1];return(0,o.useEffect)(function(){var e=p.state;(null==e?void 0:e.autoOpenAddNew)&&h(!0)},[p.state]),(0,n.useRequest)(function(){return s.resource("ai").listLLMProviders().then(function(t){var r;return((null==t||null==(r=t.data)?void 0:r.data)||[]).map(function(t){return{key:t.name,label:f.Schema.compile(t.title||t.name,{t:e}),value:t.name,supportedModel:t.supportedModel}})})},{onSuccess:function(e){c(e)}}),i().createElement(I.Provider,{value:{autoOpen:v,setAutoOpen:h}},i().createElement(m.PL.Provider,{value:{providers:r}},i().createElement(n.ExtendCollectionsProvider,{collections:[u]},i().createElement(n.SchemaComponent,{schema:d,components:{AddNew:U,Settings:z,LLMTestFlight:b.e,EnabledModelsSelect:x.uQ,ProviderDisplay:q,ModelOptionsSettings:g,EnabledSwitch:N},scope:{t:e,providers:r,useEditFormProps:T,useCancelActionProps:j,useCreateActionProps:D,useEditActionProps:B,useDestroyActionProps:$,useBulkDestroyActionProps:G}}))))}},6759:function(e,t,r){r.d(t,{e:function(){return y}});var n=r(5230),o=r(3342),i=r(9155),l=r.n(i),a=r(2059),c=r(7375),s=r(1931),u=r(5555),p=r(3079),d=r(1285);function m(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 f(e,t,r,n,o,i,l){try{var a=e[i](l),c=a.value}catch(e){r(e);return}a.done?t(c):Promise.resolve(c).then(n,o)}var y=(0,n.observer)(function(){var e,t=(0,p.kj)(),r=(0,n.useForm)(),y=(0,o.useAPIClient)(),v=a.App.useApp().message,b=function(e){if(Array.isArray(e))return e}(e=(0,i.useState)(!1))||function(e){var t,r,n=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var o=[],i=!0,l=!1;try{for(n=n.call(e);!(i=(t=n.next()).done)&&(o.push(t.value),2!==o.length);i=!0);}catch(e){l=!0,r=e}finally{try{i||null==n.return||n.return()}finally{if(l)throw r}}return o}}(e)||function(e){if(e){if("string"==typeof e)return m(e,2);var t=Object.prototype.toString.call(e).slice(8,-1);if("Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t)return Array.from(t);if("Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return m(e,2)}}(e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),x=b[0],h=b[1];return l().createElement(a.Tooltip,{title:t("Test connection with the configured API Key")},l().createElement(a.Button,{icon:l().createElement(c.RocketOutlined,null),loading:x,onClick:function(){var e;return(e=function(){var e,n,o,i,l,a,c,p,m;return function(e,t){var r,n,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},l=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),a=Object.defineProperty;return a(l,"next",{value:c(0)}),a(l,"throw",{value:c(1)}),a(l,"return",{value:c(2)}),"function"==typeof Symbol&&a(l,Symbol.iterator,{value:function(){return this}}),l;function c(a){return function(c){var s=[a,c];if(r)throw TypeError("Generator is already executing.");for(;l&&(l=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===s[0]||2===s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}}}(this,function(f){switch(f.label){case 0:if(n=(e=r.values).provider,o=e.options,i=e.enabledModels,"ollama"!==n&&!(null==o?void 0:o.apiKey))return v.warning(t("Please fill in the API Key first")),[2];if("recommended"===(l=(0,u.lf)(i)).mode){if(0===(c=(0,s.sN)(n)).length)return v.warning(t("Please configure enabled models first")),[2];a=c[0].value}else{if(0===l.models.length)return v.warning(t("Please configure enabled models first")),[2];a=l.models[0].value}h(!0),f.label=1;case 1:return f.trys.push([1,3,4,5]),[4,y.resource("ai").testFlight({values:{provider:n,options:(0,d.ot)(o),model:a}})];case 2:return 0!==(p=f.sent()).data.data.code?v.error(p.data.data.message||t("Failure")):v.success(t("Successful")),[3,5];case 3:return m=f.sent(),v.error(m.message||t("Failure")),[3,5];case 4:return h(!1),[7];case 5:return[2]}})},function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function l(e){f(i,n,o,l,a,"next",e)}function a(e){f(i,n,o,l,a,"throw",e)}l(void 0)})})()}},t("Test flight")))})},284:function(e,t,r){r.d(t,{PL:function(){return o},Pq:function(){return i}});var n=r(9155);(0,n.createContext)({provider:""}).displayName="LLMProvidersContext";var o=(0,n.createContext)({providers:[]});o.displayName="LLMProviderssContext";var i=function(){return(0,n.useContext)(o).providers}}}]);