@nocobase/plugin-ai 2.2.0-alpha.5 → 2.2.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/docs/nocobase/file-manager/storage/local.md +3 -1
- package/dist/ai/docs/nocobase/get-started/installation/docker-caddy.mdx +6 -1
- package/dist/ai/docs/nocobase/get-started/installation/docker-nginx.mdx +6 -2
- package/dist/ai/docs/nocobase/get-started/installation/docker.mdx +94 -1
- package/dist/ai/docs/nocobase/security/guide.md +23 -0
- package/dist/ai/tools/subAgentWebSearch.js +20 -15
- package/dist/client/index.js +1 -1
- package/dist/client-v2/ai-employees/tools/data-modeling/useFieldInterfaceOptions.d.ts +1 -0
- package/dist/client-v2/index.js +1 -1
- package/dist/client-v2/llm-providers/forms.d.ts +2 -0
- package/dist/client-v2/llm-providers/index.d.ts +1 -0
- package/dist/externalVersion.js +15 -15
- package/dist/locale/en-US.json +5 -0
- package/dist/locale/zh-CN.json +5 -0
- package/dist/node_modules/@langchain/mistralai/package.json +1 -1
- package/dist/node_modules/@langchain/xai/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/jsonrepair/package.json +1 -1
- package/dist/node_modules/just-bash/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-employee.js +2 -1
- package/dist/server/ai-employees/prompts.d.ts +2 -1
- package/dist/server/ai-employees/prompts.js +8 -2
- package/dist/server/collections/ai-usage-events.d.ts +10 -0
- package/dist/server/collections/ai-usage-events.js +183 -0
- package/dist/server/llm-providers/dashscope.d.ts +2 -1
- package/dist/server/llm-providers/dashscope.js +16 -1
- package/dist/server/llm-providers/deepseek.d.ts +2 -1
- package/dist/server/llm-providers/deepseek.js +33 -2
- package/dist/server/llm-providers/kimi/provider.d.ts +2 -1
- package/dist/server/llm-providers/kimi/provider.js +22 -2
- package/dist/server/llm-providers/mistral.d.ts +36 -2
- package/dist/server/llm-providers/mistral.js +62 -2
- package/dist/server/llm-providers/openai/completions.d.ts +2 -1
- package/dist/server/llm-providers/openai/completions.js +17 -1
- package/dist/server/llm-providers/openai/responses.d.ts +2 -1
- package/dist/server/llm-providers/openai/responses.js +17 -1
- package/dist/server/llm-providers/orcarouter.d.ts +35 -0
- package/dist/server/llm-providers/orcarouter.js +155 -0
- package/dist/server/llm-providers/provider.d.ts +7 -0
- package/dist/server/llm-providers/provider.js +7 -1
- package/dist/server/manager/ai-chat-conversation.js +2 -0
- package/dist/server/manager/ai-manager.d.ts +2 -1
- package/dist/server/manager/ai-manager.js +4 -1
- package/dist/server/manager/ai-usage-events.d.ts +49 -0
- package/dist/server/manager/ai-usage-events.js +195 -0
- package/dist/server/plugin.js +2 -0
- package/package.json +2 -2
|
@@ -9,6 +9,8 @@ Local Storage does not support private access. After a file is uploaded, NocoBas
|
|
|
9
9
|
|
|
10
10
|
If you need to store contracts, identity documents, internal materials, or other files that should not be public, use [S3 Pro](./s3-pro). If historical files already exist, see [Migrate to S3 Pro](./migrate-to-s3-pro.md).
|
|
11
11
|
|
|
12
|
+
If you are not using Docker or the official nginx configuration and access local uploaded files through a custom proxy, make sure the `/storage/uploads/` path sets `X-Content-Type-Options: nosniff` and returns active content files such as `html`, `svg`, `xhtml`, and `pdf` as attachments. For details, see [Security guide: File storage](../../security/guide.md#file-storage).
|
|
13
|
+
|
|
12
14
|
:::
|
|
13
15
|
|
|
14
16
|
## Configuration Parameters
|
|
@@ -26,4 +28,4 @@ This section only introduces parameters specific to the local storage engine. Fo
|
|
|
26
28
|
Represents both the relative path for file storage on the server and the URL access path. For example, "`user/avatar`" (without leading or trailing slashes) represents:
|
|
27
29
|
|
|
28
30
|
1. The relative path on the server where uploaded files are stored: `/path/to/nocobase-app/storage/uploads/user/avatar`.
|
|
29
|
-
2. The URL prefix for accessing the files: `http://localhost:13000/storage/uploads/user/avatar`.
|
|
31
|
+
2. The URL prefix for accessing the files: `http://localhost:13000/storage/uploads/user/avatar`.
|
|
@@ -18,6 +18,7 @@ In this setup, the NocoBase app container and the Caddy container run separately
|
|
|
18
18
|
|
|
19
19
|
If you need the `full` image, replace `latest-no-nginx` with `latest-full-no-nginx`.
|
|
20
20
|
|
|
21
|
+
The `13000:80` mapping is only for convenient local testing, so it does not occupy the standard host ports directly. In production, you usually do not keep using `13000:80`; instead, let the external Caddy container map directly to the host `80` and `443` ports.
|
|
21
22
|
```yml
|
|
22
23
|
networks:
|
|
23
24
|
nocobase:
|
|
@@ -66,7 +67,11 @@ services:
|
|
|
66
67
|
caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
|
|
67
68
|
'
|
|
68
69
|
ports:
|
|
70
|
+
# This is only a local testing example.
|
|
69
71
|
- "13000:80"
|
|
72
|
+
# In production, usually change it to:
|
|
73
|
+
# - "80:80"
|
|
74
|
+
# - "443:443"
|
|
70
75
|
|
|
71
76
|
postgres:
|
|
72
77
|
image: postgres:16
|
|
@@ -89,7 +94,7 @@ services:
|
|
|
89
94
|
- `NOCOBASE_PROXY_UPSTREAM_HOST=app` lets the Caddy container reach the `app` service through the Compose network
|
|
90
95
|
- `./storage` must be mounted into both the `app` and `caddy` containers so they can share proxy config, static assets, and uploaded files
|
|
91
96
|
- The `caddy` container should wait until `nocobase.caddy` is generated, then link it to `/etc/caddy/Caddyfile` with `ln -sf`
|
|
92
|
-
- Expose only the Caddy container port to the host.
|
|
97
|
+
- Expose only the Caddy container port to the host. For testing, you can start with `13000:80`; in production, you usually expose the host `80` and `443` ports directly, while the `app` service does not need to expose its port to the host
|
|
93
98
|
|
|
94
99
|
## If you use a local host Caddy
|
|
95
100
|
|
|
@@ -18,6 +18,7 @@ In this setup, the NocoBase app container and the Nginx container run separately
|
|
|
18
18
|
|
|
19
19
|
If you need the `full` image, replace `latest-no-nginx` with `latest-full-no-nginx`.
|
|
20
20
|
|
|
21
|
+
The `13000:80` mapping is only for convenient local testing, so it does not occupy the standard host ports directly. In production, you usually do not keep using `13000:80`; instead, let the external Nginx container map directly to the host `80` and `443` ports.
|
|
21
22
|
```yml
|
|
22
23
|
networks:
|
|
23
24
|
nocobase:
|
|
@@ -67,7 +68,11 @@ services:
|
|
|
67
68
|
nginx -g "daemon off;"
|
|
68
69
|
'
|
|
69
70
|
ports:
|
|
71
|
+
# This is only a local testing example.
|
|
70
72
|
- "13000:80"
|
|
73
|
+
# In production, usually change it to:
|
|
74
|
+
# - "80:80"
|
|
75
|
+
# - "443:443"
|
|
71
76
|
|
|
72
77
|
postgres:
|
|
73
78
|
image: postgres:16
|
|
@@ -90,8 +95,7 @@ services:
|
|
|
90
95
|
- `NOCOBASE_PROXY_UPSTREAM_HOST=app` lets the Nginx container reach the `app` service through the Compose network
|
|
91
96
|
- `./storage` must be mounted into both the `app` and `nginx` containers so they can share proxy config, static assets, and uploaded files
|
|
92
97
|
- The `nginx` container should wait until `nocobase.conf` is generated, then link it to `/etc/nginx/conf.d/default.conf` with `ln -sf`
|
|
93
|
-
- If you use
|
|
94
|
-
- If you use an external Nginx container, let the `nginx` container handle the host port mapping, and do not expose the `app` service port to the host
|
|
98
|
+
- If you use an external Nginx container, let the `nginx` container handle the host port mapping. For testing, you can start with `13000:80`; in production, you usually expose the host `80` and `443` ports directly, while the `app` service does not need to expose its port to the host
|
|
95
99
|
|
|
96
100
|
## If you use a local host Nginx
|
|
97
101
|
|
|
@@ -617,4 +617,97 @@ Open [http://localhost:13000](http://localhost:13000) in your browser. The initi
|
|
|
617
617
|
|
|
618
618
|
After logging in for the first time, please change the default password promptly to ensure system security.
|
|
619
619
|
|
|
620
|
-
:::
|
|
620
|
+
:::
|
|
621
|
+
|
|
622
|
+
## 5. Production deployment
|
|
623
|
+
|
|
624
|
+
If you use the built-in Nginx image, it is usually better not to expose `13000` directly to the public internet. A more common setup is to keep the container port available only on the host and let the host Nginx handle the domain, HTTPS, and reverse proxy.
|
|
625
|
+
|
|
626
|
+
### Proxy the root path with Nginx
|
|
627
|
+
|
|
628
|
+
The following config proxies domain requests to `http://127.0.0.1:13000/`:
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
server {
|
|
632
|
+
listen 80;
|
|
633
|
+
server_name your_domain.com; # Replace your_domain.com with your domain
|
|
634
|
+
|
|
635
|
+
location / {
|
|
636
|
+
proxy_pass http://127.0.0.1:13000/;
|
|
637
|
+
proxy_http_version 1.1;
|
|
638
|
+
|
|
639
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
640
|
+
proxy_set_header Connection $connection_upgrade;
|
|
641
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
642
|
+
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
|
|
643
|
+
proxy_set_header Host $final_host;
|
|
644
|
+
proxy_set_header Referer $http_referer;
|
|
645
|
+
proxy_set_header User-Agent $http_user_agent;
|
|
646
|
+
|
|
647
|
+
add_header Cache-Control "no-cache, no-store" always;
|
|
648
|
+
proxy_cache_bypass $http_upgrade;
|
|
649
|
+
|
|
650
|
+
proxy_connect_timeout 600;
|
|
651
|
+
proxy_send_timeout 600;
|
|
652
|
+
proxy_read_timeout 600;
|
|
653
|
+
send_timeout 600;
|
|
654
|
+
proxy_buffering off;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
If you also want to enable HTTPS, configure `443` and the certificate on the host Nginx. The NocoBase container does not need to handle certificates separately.
|
|
660
|
+
|
|
661
|
+
### Subpath deployment
|
|
662
|
+
|
|
663
|
+
If you want to deploy the app under a subpath, such as `https://your_domain.com/nocobase/`, configure the `APP_PUBLIC_PATH` environment variable first:
|
|
664
|
+
|
|
665
|
+
```diff
|
|
666
|
+
services:
|
|
667
|
+
app:
|
|
668
|
+
image: nocobase/nocobase:latest
|
|
669
|
+
environment:
|
|
670
|
+
+ - APP_PUBLIC_PATH=/nocobase/
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
Keep the leading and trailing `/` in the path. After this is configured, the app URL becomes `http://127.0.0.1:13000/nocobase/`.
|
|
674
|
+
|
|
675
|
+
Then configure the host Nginx with the same subpath proxy:
|
|
676
|
+
|
|
677
|
+
```bash
|
|
678
|
+
server {
|
|
679
|
+
listen 80;
|
|
680
|
+
server_name your_domain.com; # Replace your_domain.com with your domain
|
|
681
|
+
|
|
682
|
+
location /nocobase/ {
|
|
683
|
+
proxy_pass http://127.0.0.1:13000/nocobase/;
|
|
684
|
+
proxy_http_version 1.1;
|
|
685
|
+
|
|
686
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
687
|
+
proxy_set_header Connection $connection_upgrade;
|
|
688
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
689
|
+
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
|
|
690
|
+
proxy_set_header Host $final_host;
|
|
691
|
+
proxy_set_header Referer $http_referer;
|
|
692
|
+
proxy_set_header User-Agent $http_user_agent;
|
|
693
|
+
|
|
694
|
+
add_header Cache-Control "no-cache, no-store" always;
|
|
695
|
+
proxy_cache_bypass $http_upgrade;
|
|
696
|
+
|
|
697
|
+
proxy_connect_timeout 600;
|
|
698
|
+
proxy_send_timeout 600;
|
|
699
|
+
proxy_read_timeout 600;
|
|
700
|
+
send_timeout 600;
|
|
701
|
+
proxy_buffering off;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
The key point is that `APP_PUBLIC_PATH` and the path in `proxy_pass` must stay consistent. If either side misses `/nocobase/`, static assets and routing will usually not work correctly.
|
|
707
|
+
|
|
708
|
+
### Other options
|
|
709
|
+
|
|
710
|
+
If you do not want to use the built-in Nginx, you can also use one of these separate proxy setups:
|
|
711
|
+
|
|
712
|
+
- [Docker Installation (External Nginx)](./docker-nginx.mdx)
|
|
713
|
+
- [Docker Installation (External Caddy)](./docker-caddy.mdx)
|
|
@@ -215,6 +215,29 @@ If you need to store sensitive files, it is recommended to use a cloud storage s
|
|
|
215
215
|
|
|
216
216
|
For local storage or other public storage that can be accessed directly through same-origin application URLs, you should also pay extra attention to the risks introduced by active content files. Files such as `html`, `xhtml`, and `svg` may be parsed and executed directly by the browser. If an attacker can upload such a file and trick a user into opening it, the attacker may use your trusted application domain to host a malicious page or script.
|
|
217
217
|
|
|
218
|
+
NocoBase upload validation does not trust the `Content-Type` sent by the request. It prefers the MIME type detected on the server side. A file extension only represents the filename and should not be treated as the authoritative file content type. Therefore, when serving public uploaded files, you also need to make sure the file access path has proper security response headers.
|
|
219
|
+
|
|
220
|
+
If you deploy with Docker or use the nginx configuration generated by NocoBase, the upload directory already includes this protection: all uploaded files return `X-Content-Type-Options: nosniff`, and active content files such as `html`, `xhtml`, `svg`, `svgz`, and `pdf` are returned as downloads through `Content-Disposition: attachment`.
|
|
221
|
+
|
|
222
|
+
If you use a custom proxy, CDN, object storage, or expose the local upload directory directly, make sure these rules are not bypassed. You can use the following nginx configuration as a reference:
|
|
223
|
+
|
|
224
|
+
```nginx
|
|
225
|
+
location ~* ^/storage/uploads/(.*\.(?:htm|html|svg|svgz|xhtml|pdf))$ {
|
|
226
|
+
alias /path/to/nocobase/storage/uploads/$1;
|
|
227
|
+
add_header Content-Disposition "attachment" always;
|
|
228
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
229
|
+
autoindex off;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
location /storage/uploads/ {
|
|
233
|
+
alias /path/to/nocobase/storage/uploads/;
|
|
234
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
235
|
+
autoindex off;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
If your NocoBase app uses `APP_PUBLIC_PATH`, replace `/storage/uploads/` with the actual access prefix, such as `/nocobase/storage/uploads/`.
|
|
240
|
+
|
|
218
241
|
In most cases, we recommend that administrators:
|
|
219
242
|
|
|
220
243
|
- Prefer private storage, signed URLs, or a separate file domain, so that user-uploaded files are not served directly from the same origin as the main application.
|
|
@@ -40,9 +40,12 @@ var subAgentWebSearch_default = (0, import_ai.defineTools)({
|
|
|
40
40
|
},
|
|
41
41
|
definition: {
|
|
42
42
|
name: "subAgentWebSearch",
|
|
43
|
-
description: "
|
|
43
|
+
description: "Search the web for current information. Put all independent search queries needed for this turn into one call so they can run in parallel. Do not call this tool repeatedly with similar queries unless the previous results are clearly insufficient for a critical missing fact.",
|
|
44
44
|
schema: import_zod.z.object({
|
|
45
|
-
query: import_zod.z.array(
|
|
45
|
+
query: import_zod.z.array(
|
|
46
|
+
import_zod.z.string(),
|
|
47
|
+
"A list of clear, specific, non-overlapping web search queries. Include all independent queries needed for this answer in a single tool call so they can run in parallel."
|
|
48
|
+
)
|
|
46
49
|
})
|
|
47
50
|
},
|
|
48
51
|
invoke: async (ctx, args, id) => {
|
|
@@ -51,7 +54,8 @@ var subAgentWebSearch_default = (0, import_ai.defineTools)({
|
|
|
51
54
|
const { model } = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) ?? {};
|
|
52
55
|
const { provider } = await pluginAI.aiManager.getLLMService({
|
|
53
56
|
...model,
|
|
54
|
-
webSearch: true
|
|
57
|
+
webSearch: true,
|
|
58
|
+
reasoning: { mode: "off" }
|
|
55
59
|
});
|
|
56
60
|
if (!((_c = args.query) == null ? void 0 : _c.length)) {
|
|
57
61
|
return {
|
|
@@ -85,19 +89,20 @@ var subAgentWebSearch_default = (0, import_ai.defineTools)({
|
|
|
85
89
|
};
|
|
86
90
|
}
|
|
87
91
|
});
|
|
88
|
-
const WEB_SEARCH_SYSTEM_PROMPT = `You are a web search assistant.
|
|
92
|
+
const WEB_SEARCH_SYSTEM_PROMPT = `You are a web search retrieval assistant.
|
|
89
93
|
|
|
90
|
-
Your
|
|
94
|
+
Your output is for another AI model, not the final user-facing answer.
|
|
91
95
|
|
|
92
96
|
Requirements:
|
|
93
|
-
1.
|
|
94
|
-
2.
|
|
95
|
-
3.
|
|
96
|
-
4.
|
|
97
|
-
5.
|
|
98
|
-
6.
|
|
97
|
+
1. Retrieve current, relevant information for the query.
|
|
98
|
+
2. Return concise findings only. Do not write a polished final answer.
|
|
99
|
+
3. Include source title, publisher/site, URL, and publication or update date when available.
|
|
100
|
+
4. Prefer authoritative and recent sources.
|
|
101
|
+
5. Distinguish confirmed facts from uncertain or incomplete information.
|
|
102
|
+
6. Do not fabricate results, sources, dates, or URLs.
|
|
103
|
+
7. If results are weak, say exactly what is missing instead of broadening the search yourself.
|
|
99
104
|
|
|
100
|
-
Output
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
105
|
+
Output format:
|
|
106
|
+
- Findings: 3-6 concise bullet points.
|
|
107
|
+
- Sources: numbered list with title, site, URL, and date when available.
|
|
108
|
+
- Gaps: one short sentence if important information could not be verified.`;
|