@nocobase/plugin-ai 2.1.0-beta.32 → 2.1.0-beta.33
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/cluster-mode/index.md +5 -1
- package/dist/ai/docs/nocobase/cluster-mode/preparations.md +58 -3
- package/dist/externalVersion.js +16 -16
- 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/manager/llm-stream-manager.d.ts +16 -10
- package/dist/server/manager/llm-stream-manager.js +121 -27
- package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.js +1 -1
- package/dist/server/resource/aiConversations.d.ts +12 -13
- package/dist/server/resource/aiConversations.js +117 -113
- package/dist/server/utils.d.ts +4 -0
- package/dist/server/utils.js +9 -0
- package/package.json +2 -2
|
@@ -11,6 +11,10 @@ keywords: "cluster mode,multi-instance,load balancing,shared storage,Redis,Kuber
|
|
|
11
11
|
|
|
12
12
|
Starting from v1.6.0, NocoBase supports running applications in cluster mode. When an application runs in cluster mode, it can improve its performance in handling concurrent access by using multiple instances and a multi-core mode.
|
|
13
13
|
|
|
14
|
+
Based on cluster mode, you can achieve application-level high availability: traffic is distributed by a load balancer across multiple NocoBase instances within the same cluster, so if a single instance fails, restarts, or is being released, other instances can continue serving traffic. In practice, a single cluster should usually be deployed within the same low-latency network environment.
|
|
15
|
+
|
|
16
|
+
It is important to note that NocoBase cluster mode addresses horizontal scaling and high availability of application instances at the application layer. If you need warm standby or disaster recovery across availability zones or regions, you would typically deploy multiple independent clusters, and the operations team would be responsible for the data replication and switchover strategy for the database, shared storage, and other infrastructure.
|
|
17
|
+
|
|
14
18
|
## System Architecture
|
|
15
19
|
|
|
16
20
|
|
|
@@ -33,4 +37,4 @@ This document only introduces the basic concepts and components of NocoBase's cl
|
|
|
33
37
|
- [Operations](./operations)
|
|
34
38
|
- Advanced
|
|
35
39
|
- [Service Splitting](./services-splitting)
|
|
36
|
-
- [Development Reference](./development)
|
|
40
|
+
- [Development Reference](./development)
|
|
@@ -25,12 +25,14 @@ First, please ensure you have obtained licenses for the above plugins (you can p
|
|
|
25
25
|
|
|
26
26
|
## System Components
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
In addition to the application instances themselves, cluster deployment also requires system components such as the database, middleware, shared storage, and load balancing. Different teams can choose the specific implementation of these components based on their own operating model.
|
|
29
29
|
|
|
30
30
|
### Database
|
|
31
31
|
|
|
32
32
|
Since the current cluster mode only targets application instances, the database temporarily supports only a single node. If you have a database architecture like master-slave, you need to implement it yourself through middleware and ensure it is transparent to the NocoBase application.
|
|
33
33
|
|
|
34
|
+
If you need warm standby or disaster recovery across availability zones or regions, the database synchronization and switchover strategy must be designed and implemented by your operations team.
|
|
35
|
+
|
|
34
36
|
### Middleware
|
|
35
37
|
|
|
36
38
|
NocoBase's cluster mode relies on some middleware to achieve inter-cluster communication and coordination, including:
|
|
@@ -49,10 +51,37 @@ When all middleware components use Redis, you can start a single Redis service w
|
|
|
49
51
|
|
|
50
52
|
### Shared Storage
|
|
51
53
|
|
|
52
|
-
NocoBase needs to use the storage directory to store system-related files. In multi-node mode, you
|
|
54
|
+
NocoBase needs to use the `storage` directory to store system-related files, and shared storage is also a required component of cluster deployment. In multi-node mode, you can choose different implementations based on your infrastructure environment, such as cloud disks, NFS, or EFS, to support shared access across multiple nodes. Otherwise, system files will not be synchronized automatically and the application will not work properly.
|
|
53
55
|
|
|
54
56
|
When deploying with Kubernetes, please refer to the [Kubernetes Deployment: Shared Storage](./kubernetes#shared-storage) section.
|
|
55
57
|
|
|
58
|
+
#### What is typically stored in the `storage` directory
|
|
59
|
+
|
|
60
|
+
The contents of the `storage` directory vary depending on the enabled plugins and the deployment method. Based on the current implementation, common contents include:
|
|
61
|
+
|
|
62
|
+
| Path | Purpose | Usage recommendation |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `storage/uploads` | Uploaded files when using local storage mode | In production clusters, prefer object storage such as S3 / OSS / COS |
|
|
65
|
+
| `storage/plugins` | Local plugin packages installed, uploaded, or discovered at runtime | If you rely on local plugins, this directory must be shared; if plugins are built into the image, this dependency can be reduced |
|
|
66
|
+
| `storage/apps/<app>/jwt_secret.dat` | Default token secret generated automatically when `APP_KEY` is not explicitly configured | Do not rely on this file in production; explicitly configure `APP_KEY` instead |
|
|
67
|
+
| `storage/apps/<app>/aes_key.dat` | Default AES key generated automatically when `APP_AES_SECRET_KEY` is not explicitly configured | Do not rely on this file in production; explicitly configure `APP_AES_SECRET_KEY` instead |
|
|
68
|
+
| `storage/environment-variables/<app>/aes_key.dat` | AES key file used in environment-variable plugin scenarios | A read-only mounted key file is recommended |
|
|
69
|
+
| `storage/logs` | Default log directory and some migration logs | It is recommended to integrate with an external logging platform in the future |
|
|
70
|
+
| `storage/tmp` | Temporary files for import, export, migration, etc. | It can be temporary, but if it needs to be reused across nodes, it must be shared, or the operation should be fixed to a single management node |
|
|
71
|
+
| `storage/backups`, `storage/duplicator`, `storage/migration-manager` | Artifacts related to backup, restore, and migration | These should be treated as operations directories, stored persistently, and not modified concurrently across multiple nodes |
|
|
72
|
+
|
|
73
|
+
The table above is not exhaustive, but it illustrates an important point: `storage` mixes business files, secret files, plugin directories, logs, and operations-related temporary artifacts. Therefore, in cluster deployment, the baseline is usually to persist and share the entire `/app/nocobase/storage`.
|
|
74
|
+
|
|
75
|
+
#### Storage recommendations
|
|
76
|
+
|
|
77
|
+
Cluster consistency in NocoBase mainly relies on the database, Redis, message queues, and distributed locks, rather than treating shared file systems as a high-concurrency coordination medium.
|
|
78
|
+
|
|
79
|
+
Therefore, the following is recommended:
|
|
80
|
+
|
|
81
|
+
- For high-frequency business files such as attachments, prefer object storage. In production clusters, long-term reliance on local storage is not recommended.
|
|
82
|
+
- Shared storage should mainly be used to host the `storage` directory, rather than as a high-throughput file storage service.
|
|
83
|
+
- Operations such as plugin installation, plugin upgrade, backup, restore, and migration should be performed only after scaling the cluster down to a single node, and the cluster can be scaled out again after completion.
|
|
84
|
+
|
|
56
85
|
### Load Balancing
|
|
57
86
|
|
|
58
87
|
Cluster mode requires a load balancer to distribute requests, as well as for health checks and failover of application instances. This part should be selected and configured according to the team's operational needs.
|
|
@@ -61,7 +90,6 @@ Taking a self-hosted Nginx as an example, add the following content to the confi
|
|
|
61
90
|
|
|
62
91
|
```
|
|
63
92
|
upstream myapp {
|
|
64
|
-
# ip_hash; # Can be used for session persistence. When enabled, requests from the same client are always sent to the same backend server.
|
|
65
93
|
server 172.31.0.1:13000; # Internal node 1
|
|
66
94
|
server 172.31.0.2:13000; # Internal node 2
|
|
67
95
|
server 172.31.0.3:13000; # Internal node 3
|
|
@@ -82,10 +110,37 @@ This means that requests are reverse-proxied and distributed to different server
|
|
|
82
110
|
|
|
83
111
|
For load balancing middleware provided by other cloud service providers, please refer to the configuration documentation provided by the specific provider.
|
|
84
112
|
|
|
113
|
+
For high-availability deployments, the following is recommended:
|
|
114
|
+
|
|
115
|
+
- Run at least 2 application instances within the same cluster, and let the load balancer handle instance failover.
|
|
116
|
+
- The health check of the load balancer should reflect actual application availability, not just whether the port is open.
|
|
117
|
+
- If you need warm standby across availability zones or regions, you would typically deploy multiple independent clusters, and the operations team would be responsible for synchronizing and switching the database, shared storage, and other infrastructure.
|
|
118
|
+
|
|
85
119
|
## Environment Variable Configuration
|
|
86
120
|
|
|
87
121
|
All nodes in the cluster should use the same environment variable configuration. In addition to NocoBase's basic [environment variables](../api/app/env), the following middleware-related environment variables also need to be configured.
|
|
88
122
|
|
|
123
|
+
### Key Secrets
|
|
124
|
+
|
|
125
|
+
In addition to the middleware environment variables, all nodes in the cluster should also explicitly configure the same key secrets:
|
|
126
|
+
|
|
127
|
+
```ini
|
|
128
|
+
APP_KEY=
|
|
129
|
+
APP_AES_SECRET_KEY=
|
|
130
|
+
# Or use a read-only mounted key file
|
|
131
|
+
# APP_AES_SECRET_KEY_PATH=
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- `APP_KEY` is used for token / JWT signing. If it is not explicitly configured, the application falls back to the default secret file under `storage`.
|
|
135
|
+
- `APP_AES_SECRET_KEY` is used to decrypt sensitive fields in the database. If it is not explicitly configured, the application also falls back to the default secret file under `storage`.
|
|
136
|
+
- In ephemeral containers or multi-node deployments, relying on automatically generated local secret files can cause tokens to become invalid after restart, or historical encrypted data to become undecryptable.
|
|
137
|
+
|
|
138
|
+
:::info{title=Tip}
|
|
139
|
+
`APP_AES_SECRET_KEY` must be a 32-byte AES-256 key, represented by 64 hexadecimal characters.
|
|
140
|
+
|
|
141
|
+
In cloud environments, it is recommended to manage these values centrally through services such as Secrets Manager, SSM Parameter Store, Kubernetes Secret, or a read-only mounted key file.
|
|
142
|
+
:::
|
|
143
|
+
|
|
89
144
|
### Multi-core Mode
|
|
90
145
|
|
|
91
146
|
When the application runs on a multi-core node, you can enable the node's multi-core mode:
|
package/dist/externalVersion.js
CHANGED
|
@@ -8,22 +8,22 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
|
-
"@nocobase/plugin-acl": "2.1.0-beta.
|
|
12
|
-
"@nocobase/plugin-workflow": "2.1.0-beta.
|
|
13
|
-
"@nocobase/client": "2.1.0-beta.
|
|
14
|
-
"@nocobase/utils": "2.1.0-beta.
|
|
15
|
-
"@nocobase/client-v2": "2.1.0-beta.
|
|
16
|
-
"@nocobase/database": "2.1.0-beta.
|
|
17
|
-
"@nocobase/server": "2.1.0-beta.
|
|
18
|
-
"@nocobase/plugin-file-manager": "2.1.0-beta.
|
|
19
|
-
"@nocobase/actions": "2.1.0-beta.
|
|
20
|
-
"@nocobase/ai": "2.1.0-beta.
|
|
11
|
+
"@nocobase/plugin-acl": "2.1.0-beta.33",
|
|
12
|
+
"@nocobase/plugin-workflow": "2.1.0-beta.33",
|
|
13
|
+
"@nocobase/client": "2.1.0-beta.33",
|
|
14
|
+
"@nocobase/utils": "2.1.0-beta.33",
|
|
15
|
+
"@nocobase/client-v2": "2.1.0-beta.33",
|
|
16
|
+
"@nocobase/database": "2.1.0-beta.33",
|
|
17
|
+
"@nocobase/server": "2.1.0-beta.33",
|
|
18
|
+
"@nocobase/plugin-file-manager": "2.1.0-beta.33",
|
|
19
|
+
"@nocobase/actions": "2.1.0-beta.33",
|
|
20
|
+
"@nocobase/ai": "2.1.0-beta.33",
|
|
21
21
|
"langchain": "1.2.24",
|
|
22
22
|
"react": "18.2.0",
|
|
23
23
|
"antd": "5.24.2",
|
|
24
24
|
"@formily/core": "2.3.7",
|
|
25
25
|
"@formily/react": "2.3.7",
|
|
26
|
-
"@nocobase/flow-engine": "2.1.0-beta.
|
|
26
|
+
"@nocobase/flow-engine": "2.1.0-beta.33",
|
|
27
27
|
"@ant-design/icons": "5.6.1",
|
|
28
28
|
"@formily/antd-v5": "1.2.3",
|
|
29
29
|
"react-router-dom": "6.30.1",
|
|
@@ -39,14 +39,14 @@ module.exports = {
|
|
|
39
39
|
"@langchain/deepseek": "1.0.11",
|
|
40
40
|
"@langchain/google-genai": "2.1.18",
|
|
41
41
|
"@langchain/ollama": "1.2.2",
|
|
42
|
-
"@nocobase/acl": "2.1.0-beta.
|
|
43
|
-
"@nocobase/cache": "2.1.0-beta.
|
|
44
|
-
"@nocobase/resourcer": "2.1.0-beta.
|
|
42
|
+
"@nocobase/acl": "2.1.0-beta.33",
|
|
43
|
+
"@nocobase/cache": "2.1.0-beta.33",
|
|
44
|
+
"@nocobase/resourcer": "2.1.0-beta.33",
|
|
45
45
|
"@emotion/css": "11.13.0",
|
|
46
46
|
"dayjs": "1.11.13",
|
|
47
47
|
"react-i18next": "11.18.6",
|
|
48
|
-
"@nocobase/plugin-data-source-manager": "2.1.0-beta.
|
|
48
|
+
"@nocobase/plugin-data-source-manager": "2.1.0-beta.33",
|
|
49
49
|
"@langchain/langgraph-checkpoint": "1.0.0",
|
|
50
|
-
"@nocobase/data-source-manager": "2.1.0-beta.
|
|
50
|
+
"@nocobase/data-source-manager": "2.1.0-beta.33",
|
|
51
51
|
"react-dom": "18.2.0"
|
|
52
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@langchain/xai","version":"1.3.3","description":"xAI integration for LangChain.js","author":"LangChain","license":"MIT","type":"module","engines":{"node":">=20"},"repository":{"type":"git","url":"git@github.com:langchain-ai/langchainjs.git"},"homepage":"https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain-xai/","dependencies":{"@langchain/openai":"1.2.7"},"peerDependencies":{"@langchain/core":"^1.0.0"},"devDependencies":{"@tsconfig/recommended":"^1.0.3","@types/uuid":"^9","@vitest/coverage-v8":"^3.2.4","dotenv":"^16.3.1","dpdm":"^3.14.0","eslint":"^9.34.0","prettier":"^3.5.0","typescript":"~5.8.3","vitest":"^3.2.4","zod":"^3.25.76","@langchain/core":"^1.1.21","@langchain/eslint":"0.1.1","@langchain/openai":"^1.2.7","@langchain/tsconfig":"0.0.1","@langchain/standard-tests":"0.0.23"},"publishConfig":{"access":"public"},"main":"./dist/index.cjs","types":"./dist/index.d.cts","exports":{".":{"input":"./src/index.ts","require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"},"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./package.json":"./package.json"},"files":["dist/","CHANGELOG.md","README.md","LICENSE"],"module":"./dist/index.js","scripts":{"build":"turbo build:compile --filter @langchain/xai --output-logs new-only","build:compile":"tsdown","lint:eslint":"eslint --cache src/","lint:dpdm":"dpdm --skip-dynamic-imports circular --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts","lint":"pnpm lint:eslint && pnpm lint:dpdm","lint:fix":"pnpm lint:eslint --fix && pnpm lint:dpdm","clean":"rm -rf .turbo dist/","test":"vitest run","test:watch":"vitest --watch","test:int":"vitest --mode int","test:standard:unit":"vitest --mode standard-unit","test:standard:int":"vitest --mode standard-int","test:standard":"pnpm test:standard:unit && pnpm test:standard:int","format":"prettier --write \"src\"","format:check":"prettier --check \"src\"","typegen":"pnpm run typegen:profiles","typegen:profiles":"pnpm --filter @langchain/model-profiles make --config profiles.toml"},"_lastModified":"2026-05-
|
|
1
|
+
{"name":"@langchain/xai","version":"1.3.3","description":"xAI integration for LangChain.js","author":"LangChain","license":"MIT","type":"module","engines":{"node":">=20"},"repository":{"type":"git","url":"git@github.com:langchain-ai/langchainjs.git"},"homepage":"https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain-xai/","dependencies":{"@langchain/openai":"1.2.7"},"peerDependencies":{"@langchain/core":"^1.0.0"},"devDependencies":{"@tsconfig/recommended":"^1.0.3","@types/uuid":"^9","@vitest/coverage-v8":"^3.2.4","dotenv":"^16.3.1","dpdm":"^3.14.0","eslint":"^9.34.0","prettier":"^3.5.0","typescript":"~5.8.3","vitest":"^3.2.4","zod":"^3.25.76","@langchain/core":"^1.1.21","@langchain/eslint":"0.1.1","@langchain/openai":"^1.2.7","@langchain/tsconfig":"0.0.1","@langchain/standard-tests":"0.0.23"},"publishConfig":{"access":"public"},"main":"./dist/index.cjs","types":"./dist/index.d.cts","exports":{".":{"input":"./src/index.ts","require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"},"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./package.json":"./package.json"},"files":["dist/","CHANGELOG.md","README.md","LICENSE"],"module":"./dist/index.js","scripts":{"build":"turbo build:compile --filter @langchain/xai --output-logs new-only","build:compile":"tsdown","lint:eslint":"eslint --cache src/","lint:dpdm":"dpdm --skip-dynamic-imports circular --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts","lint":"pnpm lint:eslint && pnpm lint:dpdm","lint:fix":"pnpm lint:eslint --fix && pnpm lint:dpdm","clean":"rm -rf .turbo dist/","test":"vitest run","test:watch":"vitest --watch","test:int":"vitest --mode int","test:standard:unit":"vitest --mode standard-unit","test:standard:int":"vitest --mode standard-int","test:standard":"pnpm test:standard:unit && pnpm test:standard:int","format":"prettier --write \"src\"","format:check":"prettier --check \"src\"","typegen":"pnpm run typegen:profiles","typegen:profiles":"pnpm --filter @langchain/model-profiles make --config profiles.toml"},"_lastModified":"2026-05-15T15:54:57.807Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"fs-extra","version":"9.1.0","description":"fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as recursive mkdir, copy, and remove.","engines":{"node":">=10"},"homepage":"https://github.com/jprichardson/node-fs-extra","repository":{"type":"git","url":"https://github.com/jprichardson/node-fs-extra"},"keywords":["fs","file","file system","copy","directory","extra","mkdirp","mkdir","mkdirs","recursive","json","read","write","extra","delete","remove","touch","create","text","output","move","promise"],"author":"JP Richardson <jprichardson@gmail.com>","license":"MIT","dependencies":{"at-least-node":"^1.0.0","graceful-fs":"^4.2.0","jsonfile":"^6.0.1","universalify":"^2.0.0"},"devDependencies":{"coveralls":"^3.0.0","klaw":"^2.1.1","klaw-sync":"^3.0.2","minimist":"^1.1.1","mocha":"^5.0.5","nyc":"^15.0.0","proxyquire":"^2.0.1","read-dir-files":"^0.1.1","standard":"^14.1.0"},"main":"./lib/index.js","files":["lib/","!lib/**/__tests__/"],"scripts":{"full-ci":"npm run lint && npm run coverage","coverage":"nyc -r lcovonly npm run unit","coveralls":"coveralls < coverage/lcov.info","lint":"standard","test-find":"find ./lib/**/__tests__ -name *.test.js | xargs mocha","test":"npm run lint && npm run unit","unit":"node test.js"},"_lastModified":"2026-05-
|
|
1
|
+
{"name":"fs-extra","version":"9.1.0","description":"fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as recursive mkdir, copy, and remove.","engines":{"node":">=10"},"homepage":"https://github.com/jprichardson/node-fs-extra","repository":{"type":"git","url":"https://github.com/jprichardson/node-fs-extra"},"keywords":["fs","file","file system","copy","directory","extra","mkdirp","mkdir","mkdirs","recursive","json","read","write","extra","delete","remove","touch","create","text","output","move","promise"],"author":"JP Richardson <jprichardson@gmail.com>","license":"MIT","dependencies":{"at-least-node":"^1.0.0","graceful-fs":"^4.2.0","jsonfile":"^6.0.1","universalify":"^2.0.0"},"devDependencies":{"coveralls":"^3.0.0","klaw":"^2.1.1","klaw-sync":"^3.0.2","minimist":"^1.1.1","mocha":"^5.0.5","nyc":"^15.0.0","proxyquire":"^2.0.1","read-dir-files":"^0.1.1","standard":"^14.1.0"},"main":"./lib/index.js","files":["lib/","!lib/**/__tests__/"],"scripts":{"full-ci":"npm run lint && npm run coverage","coverage":"nyc -r lcovonly npm run unit","coveralls":"coveralls < coverage/lcov.info","lint":"standard","test-find":"find ./lib/**/__tests__ -name *.test.js | xargs mocha","test":"npm run lint && npm run unit","unit":"node test.js"},"_lastModified":"2026-05-15T15:54:57.963Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"jsonrepair","version":"3.13.1","description":"Repair broken JSON documents","repository":{"type":"git","url":"https://github.com/josdejong/jsonrepair.git"},"type":"module","main":"lib/cjs/index.js","module":"lib/esm/index.js","browser":"lib/umd/jsonrepair.min.js","types":"lib/types/index.d.ts","sideEffects":false,"exports":{".":{"import":"./lib/esm/index.js","require":"./lib/cjs/index.js","types":"./lib/types/index.d.ts"},"./stream":{"import":"./lib/esm/stream.js","require":"./lib/cjs/stream.js","types":"./lib/types/stream.d.ts"}},"keywords":["simple","json","repair","fix","invalid","stream","streaming"],"bin":{"jsonrepair":"./bin/cli.js"},"scripts":{"test":"vitest watch src","test:it":"vitest run src","build":"npm-run-all build:**","build:clean":"del-cli lib","build:esm":"babel src --out-dir lib/esm --extensions \".ts\" --source-maps --config-file ./babel.config.json","build:cjs":"babel src --out-dir lib/cjs --extensions \".ts\" --source-maps --config-file ./babel-cjs.config.json && cpy tools/cjs lib/cjs --flat","build:umd":"rollup lib/esm/index.js --format umd --name JSONRepair --sourcemap --output.file lib/umd/jsonrepair.js && cpy tools/cjs/package.json lib/umd --flat","build:umd:min":"uglifyjs --compress --mangle --source-map --comments --output lib/umd/jsonrepair.min.js -- lib/umd/jsonrepair.js","build:types":"tsc --project tsconfig-types.json","build:validate":"vitest run test-lib","lint":"biome check","format":"biome check --write","benchmark":"npm run build:esm && node tools/benchmark/run.mjs","build-and-test":"npm run lint && npm run test:it && npm run build","release":"npm-run-all release:**","release:build-and-test":"npm run build-and-test","release:version":"standard-version","release:push":"git push && git push --tag","release:publish":"npm publish","release-dry-run":"npm run build-and-test && standard-version --dry-run","prepare":"husky"},"files":["README.md","LICENSE.md","lib"],"author":"Jos de Jong","license":"ISC","devDependencies":{"@babel/cli":"7.28.3","@babel/core":"7.28.4","@babel/plugin-transform-typescript":"7.28.0","@babel/preset-env":"7.28.3","@babel/preset-typescript":"7.27.1","@biomejs/biome":"2.2.4","@commitlint/cli":"19.8.1","@commitlint/config-conventional":"19.8.1","@types/node":"24.5.2","cpy-cli":"6.0.0","del-cli":"7.0.0","husky":"9.1.7","npm-run-all":"4.1.5","rollup":"4.51.0","standard-version":"9.5.0","tinybench":"5.0.1","ts-node":"10.9.2","typescript":"5.9.2","uglify-js":"3.19.3","vitest":"3.2.4"},"_lastModified":"2026-05-
|
|
1
|
+
{"name":"jsonrepair","version":"3.13.1","description":"Repair broken JSON documents","repository":{"type":"git","url":"https://github.com/josdejong/jsonrepair.git"},"type":"module","main":"lib/cjs/index.js","module":"lib/esm/index.js","browser":"lib/umd/jsonrepair.min.js","types":"lib/types/index.d.ts","sideEffects":false,"exports":{".":{"import":"./lib/esm/index.js","require":"./lib/cjs/index.js","types":"./lib/types/index.d.ts"},"./stream":{"import":"./lib/esm/stream.js","require":"./lib/cjs/stream.js","types":"./lib/types/stream.d.ts"}},"keywords":["simple","json","repair","fix","invalid","stream","streaming"],"bin":{"jsonrepair":"./bin/cli.js"},"scripts":{"test":"vitest watch src","test:it":"vitest run src","build":"npm-run-all build:**","build:clean":"del-cli lib","build:esm":"babel src --out-dir lib/esm --extensions \".ts\" --source-maps --config-file ./babel.config.json","build:cjs":"babel src --out-dir lib/cjs --extensions \".ts\" --source-maps --config-file ./babel-cjs.config.json && cpy tools/cjs lib/cjs --flat","build:umd":"rollup lib/esm/index.js --format umd --name JSONRepair --sourcemap --output.file lib/umd/jsonrepair.js && cpy tools/cjs/package.json lib/umd --flat","build:umd:min":"uglifyjs --compress --mangle --source-map --comments --output lib/umd/jsonrepair.min.js -- lib/umd/jsonrepair.js","build:types":"tsc --project tsconfig-types.json","build:validate":"vitest run test-lib","lint":"biome check","format":"biome check --write","benchmark":"npm run build:esm && node tools/benchmark/run.mjs","build-and-test":"npm run lint && npm run test:it && npm run build","release":"npm-run-all release:**","release:build-and-test":"npm run build-and-test","release:version":"standard-version","release:push":"git push && git push --tag","release:publish":"npm publish","release-dry-run":"npm run build-and-test && standard-version --dry-run","prepare":"husky"},"files":["README.md","LICENSE.md","lib"],"author":"Jos de Jong","license":"ISC","devDependencies":{"@babel/cli":"7.28.3","@babel/core":"7.28.4","@babel/plugin-transform-typescript":"7.28.0","@babel/preset-env":"7.28.3","@babel/preset-typescript":"7.27.1","@biomejs/biome":"2.2.4","@commitlint/cli":"19.8.1","@commitlint/config-conventional":"19.8.1","@types/node":"24.5.2","cpy-cli":"6.0.0","del-cli":"7.0.0","husky":"9.1.7","npm-run-all":"4.1.5","rollup":"4.51.0","standard-version":"9.5.0","tinybench":"5.0.1","ts-node":"10.9.2","typescript":"5.9.2","uglify-js":"3.19.3","vitest":"3.2.4"},"_lastModified":"2026-05-15T15:55:04.228Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"just-bash","version":"2.14.3","description":"A simulated bash environment with virtual filesystem","repository":{"type":"git","url":"git+https://github.com/vercel-labs/just-bash.git"},"homepage":"https://github.com/vercel-labs/just-bash#readme","bugs":{"url":"https://github.com/vercel-labs/just-bash/issues"},"type":"module","main":"dist/bundle/index.js","types":"dist/index.d.ts","exports":{".":{"browser":"./dist/bundle/browser.js","require":{"types":"./dist/index.d.cts","default":"./dist/bundle/index.cjs"},"import":{"types":"./dist/index.d.ts","default":"./dist/bundle/index.js"}},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/bundle/browser.js"}},"files":["dist/bundle/","dist/bin/","dist/*.d.ts","dist/*.d.cts","dist/ast/*.d.ts","dist/commands/**/*.d.ts","dist/fs/**/*.d.ts","dist/interpreter/**/*.d.ts","dist/network/**/*.d.ts","dist/parser/*.d.ts","dist/sandbox/*.d.ts","dist/utils/*.d.ts","vendor/cpython-emscripten/","README.md","CHANGELOG.md","dist/AGENTS.md"],"bin":{"just-bash":"./dist/bin/just-bash.js","just-bash-shell":"./dist/bin/shell/shell.js"},"publishConfig":{"access":"public"},"keywords":[],"author":"Malte and Claude","license":"Apache-2.0","devDependencies":{"@types/ini":"^4.1.1","@types/node":"^25.0.3","@types/papaparse":"^5.5.2","@types/sprintf-js":"^1.1.4","@types/sql.js":"^1.4.9","@types/turndown":"^5.0.6","@vitest/coverage-v8":"^4.0.18","esbuild":"^0.27.2","fast-check":"^3.23.2","knip":"^5.41.1","typescript":"^5.9.3","vitest":"^4.0.16"},"dependencies":{"seek-bzip":"^2.0.0","diff":"^8.0.2","fast-xml-parser":"5.3.3","file-type":"^21.2.0","ini":"^6.0.0","minimatch":"^10.1.1","modern-tar":"^0.7.3","papaparse":"^5.5.3","quickjs-emscripten":"^0.32.0","re2js":"^1.2.1","smol-toml":"^1.6.0","sprintf-js":"^1.1.3","sql.js":"^1.13.0","turndown":"^7.2.2","yaml":"^2.8.2"},"optionalDependencies":{"@mongodb-js/zstd":"^7.0.0","node-liblzma":"^2.0.3"},"scripts":{"build":"rm -rf dist && tsc && pnpm build:lib && pnpm build:lib:cjs && pnpm build:browser && pnpm build:cli && pnpm build:shell && pnpm build:worker && pnpm build:clean && cp dist/index.d.ts dist/index.d.cts && sed '1,/^-->/d' AGENTS.npm.md > dist/AGENTS.md","build:clean":"find dist -name '*.test.js' -delete && find dist -name '*.test.d.ts' -delete","build:worker":"esbuild src/commands/python3/worker.ts --bundle --platform=node --format=esm --outfile=src/commands/python3/worker.js --external:../../../vendor/cpython-emscripten/* && cp src/commands/python3/worker.js dist/commands/python3/worker.js && mkdir -p dist/bin/chunks && cp src/commands/python3/worker.js dist/bin/chunks/worker.js && mkdir -p dist/bundle/chunks && cp src/commands/python3/worker.js dist/bundle/chunks/worker.js && esbuild src/commands/js-exec/js-exec-worker.ts --bundle --platform=node --format=esm --outfile=src/commands/js-exec/js-exec-worker.js --external:quickjs-emscripten && cp src/commands/js-exec/js-exec-worker.js dist/commands/js-exec/js-exec-worker.js && cp src/commands/js-exec/js-exec-worker.js dist/bin/chunks/js-exec-worker.js && cp src/commands/js-exec/js-exec-worker.js dist/bundle/chunks/js-exec-worker.js","build:lib":"esbuild dist/index.js --bundle --splitting --platform=node --format=esm --minify --outdir=dist/bundle --chunk-names=chunks/[name]-[hash] --external:diff --external:minimatch --external:sprintf-js --external:turndown --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","build:lib:cjs":"esbuild dist/index.js --bundle --platform=node --format=cjs --minify --outfile=dist/bundle/index.cjs --external:diff --external:minimatch --external:sprintf-js --external:turndown --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","build:browser":"esbuild dist/browser.js --bundle --platform=browser --format=esm --minify --outfile=dist/bundle/browser.js --external:diff --external:minimatch --external:sprintf-js --external:turndown --external:node:zlib --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip --define:__BROWSER__=true --alias:node:dns=./src/shims/browser-unsupported.js","build:cli":"esbuild dist/cli/just-bash.js --bundle --splitting --platform=node --format=esm --minify --outdir=dist/bin --entry-names=[name] --chunk-names=chunks/[name]-[hash] --banner:js='#!/usr/bin/env node' --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","build:shell":"esbuild dist/cli/shell.js --bundle --splitting --platform=node --format=esm --minify --outdir=dist/bin/shell --entry-names=[name] --chunk-names=chunks/[name]-[hash] --banner:js='#!/usr/bin/env node' --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","validate":"pnpm lint && pnpm knip && pnpm typecheck && pnpm build && pnpm check:worker-sync && pnpm test:run && pnpm test:wasm && pnpm test:dist","typecheck":"tsc --noEmit","lint":"pnpm lint:banned","check:worker-sync":"node scripts/check-worker-sync.js","lint:banned":"node scripts/check-banned-patterns.js","lint:fix":"pnpm --workspace-root lint:fix","knip":"knip","test":"vitest","test:run":"vitest run --exclude src/security/fuzzing/ --exclude src/commands/python3/ --exclude src/commands/sqlite3/ --exclude src/commands/js-exec/ --exclude src/agent-examples/python-scripting.test.ts","test:dist":"vitest run src/cli/just-bash.bundle.test.ts","test:unit":"vitest run --config vitest.unit.config.ts","test:wasm":"vitest run --config vitest.wasm.config.ts","test:comparison":"vitest run --config vitest.comparison.config.ts","test:comparison:record":"RECORD_FIXTURES=1 vitest run --config vitest.comparison.config.ts","test:coverage":"vitest run --coverage","test:coverage:unit":"vitest run --config vitest.unit.config.ts --coverage","test:fuzz":"vitest run src/security/fuzzing/","test:fuzz:long":"FUZZ_RUNS=10000 vitest run src/security/fuzzing/","shell":"npx tsx src/cli/shell.ts","dev:exec":"npx tsx src/cli/exec.ts"},"_lastModified":"2026-05-
|
|
1
|
+
{"name":"just-bash","version":"2.14.3","description":"A simulated bash environment with virtual filesystem","repository":{"type":"git","url":"git+https://github.com/vercel-labs/just-bash.git"},"homepage":"https://github.com/vercel-labs/just-bash#readme","bugs":{"url":"https://github.com/vercel-labs/just-bash/issues"},"type":"module","main":"dist/bundle/index.js","types":"dist/index.d.ts","exports":{".":{"browser":"./dist/bundle/browser.js","require":{"types":"./dist/index.d.cts","default":"./dist/bundle/index.cjs"},"import":{"types":"./dist/index.d.ts","default":"./dist/bundle/index.js"}},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/bundle/browser.js"}},"files":["dist/bundle/","dist/bin/","dist/*.d.ts","dist/*.d.cts","dist/ast/*.d.ts","dist/commands/**/*.d.ts","dist/fs/**/*.d.ts","dist/interpreter/**/*.d.ts","dist/network/**/*.d.ts","dist/parser/*.d.ts","dist/sandbox/*.d.ts","dist/utils/*.d.ts","vendor/cpython-emscripten/","README.md","CHANGELOG.md","dist/AGENTS.md"],"bin":{"just-bash":"./dist/bin/just-bash.js","just-bash-shell":"./dist/bin/shell/shell.js"},"publishConfig":{"access":"public"},"keywords":[],"author":"Malte and Claude","license":"Apache-2.0","devDependencies":{"@types/ini":"^4.1.1","@types/node":"^25.0.3","@types/papaparse":"^5.5.2","@types/sprintf-js":"^1.1.4","@types/sql.js":"^1.4.9","@types/turndown":"^5.0.6","@vitest/coverage-v8":"^4.0.18","esbuild":"^0.27.2","fast-check":"^3.23.2","knip":"^5.41.1","typescript":"^5.9.3","vitest":"^4.0.16"},"dependencies":{"seek-bzip":"^2.0.0","diff":"^8.0.2","fast-xml-parser":"5.3.3","file-type":"^21.2.0","ini":"^6.0.0","minimatch":"^10.1.1","modern-tar":"^0.7.3","papaparse":"^5.5.3","quickjs-emscripten":"^0.32.0","re2js":"^1.2.1","smol-toml":"^1.6.0","sprintf-js":"^1.1.3","sql.js":"^1.13.0","turndown":"^7.2.2","yaml":"^2.8.2"},"optionalDependencies":{"@mongodb-js/zstd":"^7.0.0","node-liblzma":"^2.0.3"},"scripts":{"build":"rm -rf dist && tsc && pnpm build:lib && pnpm build:lib:cjs && pnpm build:browser && pnpm build:cli && pnpm build:shell && pnpm build:worker && pnpm build:clean && cp dist/index.d.ts dist/index.d.cts && sed '1,/^-->/d' AGENTS.npm.md > dist/AGENTS.md","build:clean":"find dist -name '*.test.js' -delete && find dist -name '*.test.d.ts' -delete","build:worker":"esbuild src/commands/python3/worker.ts --bundle --platform=node --format=esm --outfile=src/commands/python3/worker.js --external:../../../vendor/cpython-emscripten/* && cp src/commands/python3/worker.js dist/commands/python3/worker.js && mkdir -p dist/bin/chunks && cp src/commands/python3/worker.js dist/bin/chunks/worker.js && mkdir -p dist/bundle/chunks && cp src/commands/python3/worker.js dist/bundle/chunks/worker.js && esbuild src/commands/js-exec/js-exec-worker.ts --bundle --platform=node --format=esm --outfile=src/commands/js-exec/js-exec-worker.js --external:quickjs-emscripten && cp src/commands/js-exec/js-exec-worker.js dist/commands/js-exec/js-exec-worker.js && cp src/commands/js-exec/js-exec-worker.js dist/bin/chunks/js-exec-worker.js && cp src/commands/js-exec/js-exec-worker.js dist/bundle/chunks/js-exec-worker.js","build:lib":"esbuild dist/index.js --bundle --splitting --platform=node --format=esm --minify --outdir=dist/bundle --chunk-names=chunks/[name]-[hash] --external:diff --external:minimatch --external:sprintf-js --external:turndown --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","build:lib:cjs":"esbuild dist/index.js --bundle --platform=node --format=cjs --minify --outfile=dist/bundle/index.cjs --external:diff --external:minimatch --external:sprintf-js --external:turndown --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","build:browser":"esbuild dist/browser.js --bundle --platform=browser --format=esm --minify --outfile=dist/bundle/browser.js --external:diff --external:minimatch --external:sprintf-js --external:turndown --external:node:zlib --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip --define:__BROWSER__=true --alias:node:dns=./src/shims/browser-unsupported.js","build:cli":"esbuild dist/cli/just-bash.js --bundle --splitting --platform=node --format=esm --minify --outdir=dist/bin --entry-names=[name] --chunk-names=chunks/[name]-[hash] --banner:js='#!/usr/bin/env node' --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","build:shell":"esbuild dist/cli/shell.js --bundle --splitting --platform=node --format=esm --minify --outdir=dist/bin/shell --entry-names=[name] --chunk-names=chunks/[name]-[hash] --banner:js='#!/usr/bin/env node' --external:sql.js --external:quickjs-emscripten --external:@mongodb-js/zstd --external:node-liblzma --external:seek-bzip","validate":"pnpm lint && pnpm knip && pnpm typecheck && pnpm build && pnpm check:worker-sync && pnpm test:run && pnpm test:wasm && pnpm test:dist","typecheck":"tsc --noEmit","lint":"pnpm lint:banned","check:worker-sync":"node scripts/check-worker-sync.js","lint:banned":"node scripts/check-banned-patterns.js","lint:fix":"pnpm --workspace-root lint:fix","knip":"knip","test":"vitest","test:run":"vitest run --exclude src/security/fuzzing/ --exclude src/commands/python3/ --exclude src/commands/sqlite3/ --exclude src/commands/js-exec/ --exclude src/agent-examples/python-scripting.test.ts","test:dist":"vitest run src/cli/just-bash.bundle.test.ts","test:unit":"vitest run --config vitest.unit.config.ts","test:wasm":"vitest run --config vitest.wasm.config.ts","test:comparison":"vitest run --config vitest.comparison.config.ts","test:comparison:record":"RECORD_FIXTURES=1 vitest run --config vitest.comparison.config.ts","test:coverage":"vitest run --coverage","test:coverage:unit":"vitest run --config vitest.unit.config.ts --coverage","test:fuzz":"vitest run src/security/fuzzing/","test:fuzz:long":"FUZZ_RUNS=10000 vitest run src/security/fuzzing/","shell":"npx tsx src/cli/shell.ts","dev:exec":"npx tsx src/cli/exec.ts"},"_lastModified":"2026-05-15T15:55:04.008Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"nodejs-snowflake","collaborators":["Utkarsh Srivastava <utkarsh@sagacious.dev>"],"description":"Generate time sortable 64 bits unique ids for distributed systems (inspired from twitter snowflake)","version":"2.0.1","license":"Apache 2.0","repository":{"type":"git","url":"https://github.com/utkarsh-pro/nodejs-snowflake.git"},"files":["nodejs_snowflake_bg.wasm","nodejs_snowflake.js","nodejs_snowflake.d.ts"],"main":"nodejs_snowflake.js","types":"nodejs_snowflake.d.ts","_lastModified":"2026-05-
|
|
1
|
+
{"name":"nodejs-snowflake","collaborators":["Utkarsh Srivastava <utkarsh@sagacious.dev>"],"description":"Generate time sortable 64 bits unique ids for distributed systems (inspired from twitter snowflake)","version":"2.0.1","license":"Apache 2.0","repository":{"type":"git","url":"https://github.com/utkarsh-pro/nodejs-snowflake.git"},"files":["nodejs_snowflake_bg.wasm","nodejs_snowflake.js","nodejs_snowflake.d.ts"],"main":"nodejs_snowflake.js","types":"nodejs_snowflake.d.ts","_lastModified":"2026-05-15T15:54:53.233Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"openai","version":"6.22.0","description":"The official TypeScript library for the OpenAI API","author":"OpenAI <support@openai.com>","types":"./index.d.ts","main":"./index.js","type":"commonjs","repository":"github:openai/openai-node","license":"Apache-2.0","packageManager":"yarn@1.22.22","files":["**/*"],"private":false,"publishConfig":{"access":"public"},"scripts":{"test":"./scripts/test","build":"./scripts/build","format":"./scripts/format","tsn":"ts-node -r tsconfig-paths/register","lint":"./scripts/lint","fix":"./scripts/format"},"dependencies":{},"bin":{"openai":"bin/cli"},"exports":{".":{"require":{"types":"./index.d.ts","default":"./index.js"},"types":"./index.d.mts","default":"./index.mjs"},"./_vendor/*.mjs":{"default":"./_vendor/*.mjs"},"./_vendor/*.js":{"default":"./_vendor/*.js"},"./_vendor/*":{"import":"./_vendor/*.mjs","require":"./_vendor/*.js"},"./api-promise":{"import":"./api-promise.mjs","require":"./api-promise.js"},"./api-promise.js":{"default":"./api-promise.js"},"./api-promise.mjs":{"default":"./api-promise.mjs"},"./azure":{"import":"./azure.mjs","require":"./azure.js"},"./azure.js":{"default":"./azure.js"},"./azure.mjs":{"default":"./azure.mjs"},"./beta/*.mjs":{"default":"./beta/*.mjs"},"./beta/*.js":{"default":"./beta/*.js"},"./beta/*":{"import":"./beta/*.mjs","require":"./beta/*.js"},"./client":{"import":"./client.mjs","require":"./client.js"},"./client.js":{"default":"./client.js"},"./client.mjs":{"default":"./client.mjs"},"./core/*.mjs":{"default":"./core/*.mjs"},"./core/*.js":{"default":"./core/*.js"},"./core/*":{"import":"./core/*.mjs","require":"./core/*.js"},"./error":{"import":"./error.mjs","require":"./error.js"},"./error.js":{"default":"./error.js"},"./error.mjs":{"default":"./error.mjs"},"./helpers/*.mjs":{"default":"./helpers/*.mjs"},"./helpers/*.js":{"default":"./helpers/*.js"},"./helpers/*":{"import":"./helpers/*.mjs","require":"./helpers/*.js"},"./index":{"import":"./index.mjs","require":"./index.js"},"./index.js":{"default":"./index.js"},"./index.mjs":{"default":"./index.mjs"},"./lib/*.mjs":{"default":"./lib/*.mjs"},"./lib/*.js":{"default":"./lib/*.js"},"./lib/*":{"import":"./lib/*.mjs","require":"./lib/*.js"},"./pagination":{"import":"./pagination.mjs","require":"./pagination.js"},"./pagination.js":{"default":"./pagination.js"},"./pagination.mjs":{"default":"./pagination.mjs"},"./realtime/*.mjs":{"default":"./realtime/*.mjs"},"./realtime/*.js":{"default":"./realtime/*.js"},"./realtime/*":{"import":"./realtime/*.mjs","require":"./realtime/*.js"},"./resource":{"import":"./resource.mjs","require":"./resource.js"},"./resource.js":{"default":"./resource.js"},"./resource.mjs":{"default":"./resource.mjs"},"./resources/*.mjs":{"default":"./resources/*.mjs"},"./resources/*.js":{"default":"./resources/*.js"},"./resources/*":{"import":"./resources/*.mjs","require":"./resources/*.js"},"./resources":{"import":"./resources.mjs","require":"./resources.js"},"./resources.js":{"default":"./resources.js"},"./resources.mjs":{"default":"./resources.mjs"},"./streaming":{"import":"./streaming.mjs","require":"./streaming.js"},"./streaming.js":{"default":"./streaming.js"},"./streaming.mjs":{"default":"./streaming.mjs"},"./uploads":{"import":"./uploads.mjs","require":"./uploads.js"},"./uploads.js":{"default":"./uploads.js"},"./uploads.mjs":{"default":"./uploads.mjs"},"./version":{"import":"./version.mjs","require":"./version.js"},"./version.js":{"default":"./version.js"},"./version.mjs":{"default":"./version.mjs"}},"peerDependencies":{"ws":"^8.18.0","zod":"^3.25 || ^4.0"},"peerDependenciesMeta":{"ws":{"optional":true},"zod":{"optional":true}},"_lastModified":"2026-05-
|
|
1
|
+
{"name":"openai","version":"6.22.0","description":"The official TypeScript library for the OpenAI API","author":"OpenAI <support@openai.com>","types":"./index.d.ts","main":"./index.js","type":"commonjs","repository":"github:openai/openai-node","license":"Apache-2.0","packageManager":"yarn@1.22.22","files":["**/*"],"private":false,"publishConfig":{"access":"public"},"scripts":{"test":"./scripts/test","build":"./scripts/build","format":"./scripts/format","tsn":"ts-node -r tsconfig-paths/register","lint":"./scripts/lint","fix":"./scripts/format"},"dependencies":{},"bin":{"openai":"bin/cli"},"exports":{".":{"require":{"types":"./index.d.ts","default":"./index.js"},"types":"./index.d.mts","default":"./index.mjs"},"./_vendor/*.mjs":{"default":"./_vendor/*.mjs"},"./_vendor/*.js":{"default":"./_vendor/*.js"},"./_vendor/*":{"import":"./_vendor/*.mjs","require":"./_vendor/*.js"},"./api-promise":{"import":"./api-promise.mjs","require":"./api-promise.js"},"./api-promise.js":{"default":"./api-promise.js"},"./api-promise.mjs":{"default":"./api-promise.mjs"},"./azure":{"import":"./azure.mjs","require":"./azure.js"},"./azure.js":{"default":"./azure.js"},"./azure.mjs":{"default":"./azure.mjs"},"./beta/*.mjs":{"default":"./beta/*.mjs"},"./beta/*.js":{"default":"./beta/*.js"},"./beta/*":{"import":"./beta/*.mjs","require":"./beta/*.js"},"./client":{"import":"./client.mjs","require":"./client.js"},"./client.js":{"default":"./client.js"},"./client.mjs":{"default":"./client.mjs"},"./core/*.mjs":{"default":"./core/*.mjs"},"./core/*.js":{"default":"./core/*.js"},"./core/*":{"import":"./core/*.mjs","require":"./core/*.js"},"./error":{"import":"./error.mjs","require":"./error.js"},"./error.js":{"default":"./error.js"},"./error.mjs":{"default":"./error.mjs"},"./helpers/*.mjs":{"default":"./helpers/*.mjs"},"./helpers/*.js":{"default":"./helpers/*.js"},"./helpers/*":{"import":"./helpers/*.mjs","require":"./helpers/*.js"},"./index":{"import":"./index.mjs","require":"./index.js"},"./index.js":{"default":"./index.js"},"./index.mjs":{"default":"./index.mjs"},"./lib/*.mjs":{"default":"./lib/*.mjs"},"./lib/*.js":{"default":"./lib/*.js"},"./lib/*":{"import":"./lib/*.mjs","require":"./lib/*.js"},"./pagination":{"import":"./pagination.mjs","require":"./pagination.js"},"./pagination.js":{"default":"./pagination.js"},"./pagination.mjs":{"default":"./pagination.mjs"},"./realtime/*.mjs":{"default":"./realtime/*.mjs"},"./realtime/*.js":{"default":"./realtime/*.js"},"./realtime/*":{"import":"./realtime/*.mjs","require":"./realtime/*.js"},"./resource":{"import":"./resource.mjs","require":"./resource.js"},"./resource.js":{"default":"./resource.js"},"./resource.mjs":{"default":"./resource.mjs"},"./resources/*.mjs":{"default":"./resources/*.mjs"},"./resources/*.js":{"default":"./resources/*.js"},"./resources/*":{"import":"./resources/*.mjs","require":"./resources/*.js"},"./resources":{"import":"./resources.mjs","require":"./resources.js"},"./resources.js":{"default":"./resources.js"},"./resources.mjs":{"default":"./resources.mjs"},"./streaming":{"import":"./streaming.mjs","require":"./streaming.js"},"./streaming.js":{"default":"./streaming.js"},"./streaming.mjs":{"default":"./streaming.mjs"},"./uploads":{"import":"./uploads.mjs","require":"./uploads.js"},"./uploads.js":{"default":"./uploads.js"},"./uploads.mjs":{"default":"./uploads.mjs"},"./version":{"import":"./version.mjs","require":"./version.js"},"./version.js":{"default":"./version.js"},"./version.mjs":{"default":"./version.mjs"}},"peerDependencies":{"ws":"^8.18.0","zod":"^3.25 || ^4.0"},"peerDependenciesMeta":{"ws":{"optional":true},"zod":{"optional":true}},"_lastModified":"2026-05-15T15:54:55.524Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-05-
|
|
1
|
+
{"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-05-15T15:54:54.107Z"}
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import PluginAIServer from '../plugin';
|
|
10
|
+
type LLMStreamOptions = {
|
|
11
|
+
pollInterval?: number;
|
|
12
|
+
initialWaitTimeout?: number;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
};
|
|
10
15
|
export declare class LLMStreamCachedManager {
|
|
11
16
|
private readonly plugin;
|
|
12
17
|
private cachePromise?;
|
|
@@ -14,14 +19,10 @@ export declare class LLMStreamCachedManager {
|
|
|
14
19
|
getCached(sessionId: string): LLMStreamCached;
|
|
15
20
|
clear(sessionId: string): Promise<void>;
|
|
16
21
|
append(sessionId: string, chunk: string): Promise<void>;
|
|
17
|
-
stream(sessionId: string, options?:
|
|
18
|
-
pollInterval?: number;
|
|
19
|
-
initialWaitTimeout?: number;
|
|
20
|
-
}): AsyncGenerator<string, void, void>;
|
|
22
|
+
stream(sessionId: string, options?: LLMStreamOptions): AsyncGenerator<string, void, void>;
|
|
21
23
|
private getChunks;
|
|
22
24
|
private getCache;
|
|
23
|
-
private
|
|
24
|
-
private getLockKey;
|
|
25
|
+
private get store();
|
|
25
26
|
}
|
|
26
27
|
export declare class LLMStreamCached {
|
|
27
28
|
private readonly sessionId;
|
|
@@ -30,8 +31,13 @@ export declare class LLMStreamCached {
|
|
|
30
31
|
clear(): Promise<void>;
|
|
31
32
|
append(chunk: string): Promise<void>;
|
|
32
33
|
skipped(): Promise<void>;
|
|
33
|
-
stream(options?:
|
|
34
|
-
pollInterval?: number;
|
|
35
|
-
initialWaitTimeout?: number;
|
|
36
|
-
}): AsyncGenerator<string, void, void>;
|
|
34
|
+
stream(options?: LLMStreamOptions): AsyncGenerator<string, void, void>;
|
|
37
35
|
}
|
|
36
|
+
export declare class BufferedLLMStreamCached extends LLMStreamCached {
|
|
37
|
+
private buffer;
|
|
38
|
+
private interval;
|
|
39
|
+
clear(): Promise<void>;
|
|
40
|
+
append(chunk: string): Promise<void>;
|
|
41
|
+
private flush;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
|
@@ -26,54 +26,59 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
26
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
27
|
var llm_stream_manager_exports = {};
|
|
28
28
|
__export(llm_stream_manager_exports, {
|
|
29
|
+
BufferedLLMStreamCached: () => BufferedLLMStreamCached,
|
|
29
30
|
LLMStreamCached: () => LLMStreamCached,
|
|
30
31
|
LLMStreamCachedManager: () => LLMStreamCachedManager
|
|
31
32
|
});
|
|
32
33
|
module.exports = __toCommonJS(llm_stream_manager_exports);
|
|
33
|
-
var import_utils = require("@nocobase/utils");
|
|
34
34
|
const CACHE_NAME = "ai-llm-stream-cache";
|
|
35
|
-
const LOCK_KEY_PREFIX = "ai-llm-stream-lock";
|
|
36
|
-
const WRITE_LOCK_TTL = 3e3;
|
|
37
35
|
const CACHE_TTL = 10 * 60 * 1e3;
|
|
38
36
|
const STREAM_END_MARK = '"type":"stream_end"';
|
|
39
37
|
const SKIPPED_MARK = "__skipped__";
|
|
40
|
-
const
|
|
41
|
-
const DEFAULT_INITIAL_WAIT_TIMEOUT = 1e3;
|
|
38
|
+
const DEFAULT_INITIAL_WAIT_TIMEOUT = 1e4;
|
|
42
39
|
class LLMStreamCachedManager {
|
|
43
40
|
constructor(plugin) {
|
|
44
41
|
this.plugin = plugin;
|
|
45
42
|
}
|
|
46
43
|
cachePromise;
|
|
47
44
|
getCached(sessionId) {
|
|
45
|
+
if (this.store !== "memory") {
|
|
46
|
+
return new BufferedLLMStreamCached(sessionId, this);
|
|
47
|
+
}
|
|
48
48
|
return new LLMStreamCached(sessionId, this);
|
|
49
49
|
}
|
|
50
50
|
async clear(sessionId) {
|
|
51
|
-
await this.
|
|
52
|
-
|
|
53
|
-
await cache.del(sessionId);
|
|
54
|
-
});
|
|
51
|
+
const cache = await this.getCache();
|
|
52
|
+
await cache.del(sessionId);
|
|
55
53
|
}
|
|
56
54
|
async append(sessionId, chunk) {
|
|
57
|
-
await this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
await cache.set(sessionId, chunks, CACHE_TTL);
|
|
62
|
-
});
|
|
55
|
+
const cache = await this.getCache();
|
|
56
|
+
const chunks = await cache.get(sessionId) ?? [];
|
|
57
|
+
chunks.push(chunk);
|
|
58
|
+
await cache.set(sessionId, chunks, CACHE_TTL);
|
|
63
59
|
}
|
|
64
60
|
async *stream(sessionId, options) {
|
|
65
|
-
const pollInterval = (options == null ? void 0 : options.pollInterval) ??
|
|
61
|
+
const pollInterval = (options == null ? void 0 : options.pollInterval) ?? (this.store !== "memory" ? 1e3 : 100);
|
|
66
62
|
const initialWaitTimeout = (options == null ? void 0 : options.initialWaitTimeout) ?? DEFAULT_INITIAL_WAIT_TIMEOUT;
|
|
63
|
+
const signal = options == null ? void 0 : options.signal;
|
|
67
64
|
let offset = 0;
|
|
68
65
|
let waited = 0;
|
|
69
66
|
let completed = false;
|
|
70
67
|
while (!completed) {
|
|
68
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
71
|
const chunks = await this.getChunks(sessionId);
|
|
72
72
|
const lastSkippedIndex = chunks.lastIndexOf(SKIPPED_MARK);
|
|
73
|
+
let hasNewChunks = false;
|
|
73
74
|
if (lastSkippedIndex >= offset) {
|
|
74
75
|
offset = lastSkippedIndex + 1;
|
|
75
76
|
}
|
|
76
77
|
while (offset < chunks.length) {
|
|
78
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
hasNewChunks = true;
|
|
77
82
|
const chunk = chunks[offset++];
|
|
78
83
|
yield chunk;
|
|
79
84
|
waited = 0;
|
|
@@ -85,16 +90,15 @@ class LLMStreamCachedManager {
|
|
|
85
90
|
if (completed) {
|
|
86
91
|
return;
|
|
87
92
|
}
|
|
88
|
-
if (!
|
|
89
|
-
if (offset > 0) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
93
|
+
if (!hasNewChunks) {
|
|
92
94
|
if (waited >= initialWaitTimeout) {
|
|
93
95
|
return;
|
|
94
96
|
}
|
|
95
97
|
waited += pollInterval;
|
|
96
98
|
}
|
|
97
|
-
await (
|
|
99
|
+
if (await abortableSleep(pollInterval, signal)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
async getChunks(sessionId) {
|
|
@@ -104,15 +108,13 @@ class LLMStreamCachedManager {
|
|
|
104
108
|
async getCache() {
|
|
105
109
|
this.cachePromise ??= this.plugin.app.cacheManager.createCache({
|
|
106
110
|
name: CACHE_NAME,
|
|
107
|
-
store: this.
|
|
111
|
+
store: this.store
|
|
108
112
|
});
|
|
109
113
|
return this.cachePromise;
|
|
110
114
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
getLockKey(sessionId) {
|
|
115
|
-
return `${LOCK_KEY_PREFIX}:${sessionId}`;
|
|
115
|
+
get store() {
|
|
116
|
+
var _a;
|
|
117
|
+
return ((_a = this.plugin.app.options.cacheManager) == null ? void 0 : _a.defaultStore) ?? "memory";
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
class LLMStreamCached {
|
|
@@ -135,8 +137,100 @@ class LLMStreamCached {
|
|
|
135
137
|
}
|
|
136
138
|
}
|
|
137
139
|
}
|
|
140
|
+
class BufferedLLMStreamCached extends LLMStreamCached {
|
|
141
|
+
buffer = new ChunksBuffer();
|
|
142
|
+
interval;
|
|
143
|
+
async clear() {
|
|
144
|
+
clearInterval(this.interval);
|
|
145
|
+
delete this.interval;
|
|
146
|
+
await this.flush();
|
|
147
|
+
await super.clear();
|
|
148
|
+
}
|
|
149
|
+
async append(chunk) {
|
|
150
|
+
if (!this.interval) {
|
|
151
|
+
this.interval = setInterval(() => {
|
|
152
|
+
void this.flush();
|
|
153
|
+
}, 1e3);
|
|
154
|
+
}
|
|
155
|
+
this.buffer.append(chunk);
|
|
156
|
+
}
|
|
157
|
+
async flush() {
|
|
158
|
+
if (this.buffer.isEmpty()) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const chunks = this.buffer.compact();
|
|
162
|
+
this.buffer.clear();
|
|
163
|
+
const appendChunks = async () => {
|
|
164
|
+
for (const chunk of chunks) {
|
|
165
|
+
await super.append(chunk);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
await appendChunks();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
class ChunksBuffer {
|
|
172
|
+
_size = 0;
|
|
173
|
+
_chunks = [];
|
|
174
|
+
append(chunk) {
|
|
175
|
+
this._size += chunk.length;
|
|
176
|
+
this._chunks.push(chunk);
|
|
177
|
+
}
|
|
178
|
+
clear() {
|
|
179
|
+
this._size = 0;
|
|
180
|
+
this._chunks = [];
|
|
181
|
+
}
|
|
182
|
+
isEmpty() {
|
|
183
|
+
return this._size === 0;
|
|
184
|
+
}
|
|
185
|
+
get size() {
|
|
186
|
+
return this._size;
|
|
187
|
+
}
|
|
188
|
+
get chunks() {
|
|
189
|
+
return this._chunks;
|
|
190
|
+
}
|
|
191
|
+
compact() {
|
|
192
|
+
const chunks = [];
|
|
193
|
+
let buffer = "";
|
|
194
|
+
for (const chunk of this._chunks) {
|
|
195
|
+
if (chunk === SKIPPED_MARK) {
|
|
196
|
+
if (buffer) {
|
|
197
|
+
chunks.push(buffer);
|
|
198
|
+
buffer = "";
|
|
199
|
+
}
|
|
200
|
+
chunks.push(SKIPPED_MARK);
|
|
201
|
+
} else {
|
|
202
|
+
buffer += chunk;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (buffer) {
|
|
206
|
+
chunks.push(buffer);
|
|
207
|
+
}
|
|
208
|
+
return chunks;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function abortableSleep(ms, signal) {
|
|
212
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
213
|
+
return Promise.resolve(true);
|
|
214
|
+
}
|
|
215
|
+
return new Promise((resolve) => {
|
|
216
|
+
const timeout = setTimeout(() => {
|
|
217
|
+
cleanup();
|
|
218
|
+
resolve(false);
|
|
219
|
+
}, ms);
|
|
220
|
+
const cleanup = () => {
|
|
221
|
+
clearTimeout(timeout);
|
|
222
|
+
signal == null ? void 0 : signal.removeEventListener("abort", abort);
|
|
223
|
+
};
|
|
224
|
+
const abort = () => {
|
|
225
|
+
cleanup();
|
|
226
|
+
resolve(true);
|
|
227
|
+
};
|
|
228
|
+
signal == null ? void 0 : signal.addEventListener("abort", abort, { once: true });
|
|
229
|
+
});
|
|
230
|
+
}
|
|
138
231
|
// Annotate the CommonJS export names for ESM import in node:
|
|
139
232
|
0 && (module.exports = {
|
|
233
|
+
BufferedLLMStreamCached,
|
|
140
234
|
LLMStreamCached,
|
|
141
235
|
LLMStreamCachedManager
|
|
142
236
|
});
|
|
@@ -33,7 +33,7 @@ var import_server = require("@nocobase/server");
|
|
|
33
33
|
class ai_employee_knowledge_base_add_key_default extends import_server.Migration {
|
|
34
34
|
on = "afterSync";
|
|
35
35
|
// 'beforeLoad' or 'afterLoad'
|
|
36
|
-
appVersion = "<2.
|
|
36
|
+
appVersion = "<2.2.0";
|
|
37
37
|
async up() {
|
|
38
38
|
var _a, _b, _c, _d;
|
|
39
39
|
const aiEmployeesRepo = this.app.db.getRepository("aiEmployees");
|
|
@@ -7,28 +7,27 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Context, Next } from '@nocobase/actions';
|
|
10
|
-
declare function
|
|
10
|
+
declare function loginInCheck(ctx: Context, next: Next): Promise<never>;
|
|
11
11
|
declare const _default: {
|
|
12
12
|
name: string;
|
|
13
13
|
middlewares: {
|
|
14
|
-
|
|
15
|
-
handler: typeof parallelConversationsLimit;
|
|
14
|
+
handler: typeof loginInCheck;
|
|
16
15
|
}[];
|
|
17
16
|
actions: {
|
|
18
17
|
list(ctx: Context, next: Next): Promise<void>;
|
|
19
|
-
unreadCount(ctx: Context, next: Next): Promise<
|
|
20
|
-
unreadCounts(ctx: Context, next: Next): Promise<
|
|
21
|
-
create(ctx: Context, next: Next): Promise<
|
|
22
|
-
update(ctx: Context, next: Next): Promise<
|
|
18
|
+
unreadCount(ctx: Context, next: Next): Promise<void>;
|
|
19
|
+
unreadCounts(ctx: Context, next: Next): Promise<void>;
|
|
20
|
+
create(ctx: Context, next: Next): Promise<void>;
|
|
21
|
+
update(ctx: Context, next: Next): Promise<void>;
|
|
23
22
|
updateOptions(ctx: Context, next: Next): Promise<never>;
|
|
24
23
|
destroy(ctx: Context, next: Next): Promise<void>;
|
|
25
|
-
getMessages(ctx: Context, next: Next): Promise<
|
|
24
|
+
getMessages(ctx: Context, next: Next): Promise<void>;
|
|
26
25
|
updateToolArgs(ctx: Context, next: Next): Promise<any>;
|
|
27
|
-
sendMessages(ctx: Context, next: Next): Promise<
|
|
28
|
-
abort(ctx: Context, next: Next): Promise<
|
|
29
|
-
resumeStream(ctx: Context, next: Next): Promise<
|
|
30
|
-
resendMessages(ctx: Context, next: Next): Promise<
|
|
31
|
-
updateUserDecision(ctx: Context, next: Next): Promise<
|
|
26
|
+
sendMessages(ctx: Context, next: Next): Promise<void>;
|
|
27
|
+
abort(ctx: Context, next: Next): Promise<void>;
|
|
28
|
+
resumeStream(ctx: Context, next: Next): Promise<void>;
|
|
29
|
+
resendMessages(ctx: Context, next: Next): Promise<void>;
|
|
30
|
+
updateUserDecision(ctx: Context, next: Next): Promise<void>;
|
|
32
31
|
resumeToolCall(ctx: Context, next: Next): Promise<any>;
|
|
33
32
|
};
|
|
34
33
|
};
|
|
@@ -43,6 +43,7 @@ var import_actions = __toESM(require("@nocobase/actions"));
|
|
|
43
43
|
var import_database = require("@nocobase/database");
|
|
44
44
|
var import_utils = require("../utils");
|
|
45
45
|
var import_ai_employee = require("../ai-employees/ai-employee");
|
|
46
|
+
var import_ai_chat_conversation = require("../manager/ai-chat-conversation");
|
|
46
47
|
async function getAIEmployee(ctx, username) {
|
|
47
48
|
var _a;
|
|
48
49
|
const filter = {
|
|
@@ -67,12 +68,17 @@ function setupSSEHeaders(ctx) {
|
|
|
67
68
|
function sendErrorResponse(ctx, errorMessage) {
|
|
68
69
|
(0, import_utils.sendSSEError)(ctx, errorMessage);
|
|
69
70
|
}
|
|
70
|
-
async function
|
|
71
|
+
async function loginInCheck(ctx, next) {
|
|
71
72
|
var _a;
|
|
72
73
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
73
74
|
if (!userId) {
|
|
74
75
|
return ctx.throw(403);
|
|
75
76
|
}
|
|
77
|
+
await next();
|
|
78
|
+
}
|
|
79
|
+
const isReachParallelLimit = async (ctx) => {
|
|
80
|
+
var _a;
|
|
81
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
76
82
|
const activeStreamCount = await ctx.db.getModel("aiConversations").count({
|
|
77
83
|
where: {
|
|
78
84
|
userId,
|
|
@@ -82,27 +88,32 @@ async function parallelConversationsLimit(ctx, next) {
|
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
});
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
return activeStreamCount > 2;
|
|
92
|
+
};
|
|
93
|
+
const saveUserMessages = async (ctx, sessionId, messages, messageId) => {
|
|
94
|
+
const userMessages = messages.filter((message) => message.role === "user");
|
|
95
|
+
if (!userMessages.length) {
|
|
87
96
|
return;
|
|
88
97
|
}
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
const aiChatConversation = (0, import_ai_chat_conversation.createAIChatConversation)(ctx, sessionId);
|
|
99
|
+
await aiChatConversation.withTransaction(async (conversation) => {
|
|
100
|
+
if (messageId && await conversation.getMessage(messageId)) {
|
|
101
|
+
await conversation.removeMessages({ messageId });
|
|
102
|
+
}
|
|
103
|
+
await conversation.addMessages(userMessages);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
91
106
|
var aiConversations_default = {
|
|
92
107
|
name: "aiConversations",
|
|
93
108
|
middlewares: [
|
|
94
109
|
{
|
|
95
|
-
|
|
96
|
-
handler: parallelConversationsLimit
|
|
110
|
+
handler: loginInCheck
|
|
97
111
|
}
|
|
98
112
|
],
|
|
99
113
|
actions: {
|
|
100
114
|
async list(ctx, next) {
|
|
101
115
|
var _a;
|
|
102
116
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
103
|
-
if (!userId) {
|
|
104
|
-
return ctx.throw(403);
|
|
105
|
-
}
|
|
106
117
|
const filter = ctx.action.params.filter || {};
|
|
107
118
|
ctx.action.mergeParams({
|
|
108
119
|
filter: {
|
|
@@ -117,9 +128,6 @@ var aiConversations_default = {
|
|
|
117
128
|
async unreadCount(ctx, next) {
|
|
118
129
|
var _a;
|
|
119
130
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
120
|
-
if (!userId) {
|
|
121
|
-
return ctx.throw(403);
|
|
122
|
-
}
|
|
123
131
|
const count = await ctx.db.getModel("aiConversations").count({
|
|
124
132
|
where: {
|
|
125
133
|
userId,
|
|
@@ -136,9 +144,6 @@ var aiConversations_default = {
|
|
|
136
144
|
async unreadCounts(ctx, next) {
|
|
137
145
|
var _a;
|
|
138
146
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
139
|
-
if (!userId) {
|
|
140
|
-
return ctx.throw(403);
|
|
141
|
-
}
|
|
142
147
|
const [conversationUnreadCount, workflowTaskUnreadCount] = await Promise.all([
|
|
143
148
|
ctx.db.getModel("aiConversations").count({
|
|
144
149
|
where: {
|
|
@@ -165,9 +170,6 @@ var aiConversations_default = {
|
|
|
165
170
|
var _a;
|
|
166
171
|
const plugin = ctx.app.pm.get("ai");
|
|
167
172
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
168
|
-
if (!userId) {
|
|
169
|
-
return ctx.throw(403);
|
|
170
|
-
}
|
|
171
173
|
const { aiEmployee, systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
|
|
172
174
|
const employee = await getAIEmployee(ctx, aiEmployee.username);
|
|
173
175
|
if (!employee) {
|
|
@@ -196,9 +198,6 @@ var aiConversations_default = {
|
|
|
196
198
|
var _a;
|
|
197
199
|
const plugin = ctx.app.pm.get("ai");
|
|
198
200
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
199
|
-
if (!userId) {
|
|
200
|
-
return ctx.throw(403);
|
|
201
|
-
}
|
|
202
201
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
203
202
|
const { title } = ctx.action.params.values || {};
|
|
204
203
|
ctx.body = await plugin.aiConversationsManager.update({ userId, sessionId, title });
|
|
@@ -208,9 +207,6 @@ var aiConversations_default = {
|
|
|
208
207
|
var _a;
|
|
209
208
|
const plugin = ctx.app.pm.get("ai");
|
|
210
209
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
211
|
-
if (!userId) {
|
|
212
|
-
return ctx.throw(403);
|
|
213
|
-
}
|
|
214
210
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
215
211
|
if (!sessionId) {
|
|
216
212
|
return ctx.throw(400, "invalid sessionId");
|
|
@@ -236,9 +232,6 @@ var aiConversations_default = {
|
|
|
236
232
|
async destroy(ctx, next) {
|
|
237
233
|
var _a;
|
|
238
234
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
239
|
-
if (!userId) {
|
|
240
|
-
return ctx.throw(403);
|
|
241
|
-
}
|
|
242
235
|
ctx.action.mergeParams({
|
|
243
236
|
filter: {
|
|
244
237
|
userId
|
|
@@ -250,9 +243,6 @@ var aiConversations_default = {
|
|
|
250
243
|
var _a, _b;
|
|
251
244
|
const plugin = ctx.app.pm.get("ai");
|
|
252
245
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
253
|
-
if (!userId) {
|
|
254
|
-
return ctx.throw(403);
|
|
255
|
-
}
|
|
256
246
|
const { sessionId, cursor, updateRead: originalUpdateRead } = ctx.action.params || {};
|
|
257
247
|
if (!sessionId) {
|
|
258
248
|
ctx.throw(400);
|
|
@@ -279,9 +269,6 @@ var aiConversations_default = {
|
|
|
279
269
|
var _a;
|
|
280
270
|
const plugin = ctx.app.pm.get("ai");
|
|
281
271
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
282
|
-
if (!userId) {
|
|
283
|
-
return ctx.throw(403);
|
|
284
|
-
}
|
|
285
272
|
const {
|
|
286
273
|
sessionId,
|
|
287
274
|
messageId,
|
|
@@ -320,11 +307,8 @@ var aiConversations_default = {
|
|
|
320
307
|
},
|
|
321
308
|
async sendMessages(ctx, next) {
|
|
322
309
|
var _a, _b, _c, _d;
|
|
323
|
-
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
324
|
-
if (!userId) {
|
|
325
|
-
return ctx.throw(403);
|
|
326
|
-
}
|
|
327
310
|
const plugin = ctx.app.pm.get("ai");
|
|
311
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
328
312
|
const {
|
|
329
313
|
sessionId,
|
|
330
314
|
aiEmployee: employeeName,
|
|
@@ -338,38 +322,27 @@ var aiConversations_default = {
|
|
|
338
322
|
if (shouldStream) {
|
|
339
323
|
setupSSEHeaders(ctx);
|
|
340
324
|
}
|
|
341
|
-
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
} else {
|
|
345
|
-
ctx.status = 400;
|
|
346
|
-
ctx.body = { error: "sessionId is required" };
|
|
325
|
+
try {
|
|
326
|
+
if (!sessionId) {
|
|
327
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
347
328
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
} else {
|
|
355
|
-
ctx.status = 400;
|
|
356
|
-
ctx.body = { error: "user message is required" };
|
|
329
|
+
if (!Array.isArray(messages)) {
|
|
330
|
+
throw new import_utils.ResourceActionError(400, ctx.t("messages must be an array"));
|
|
331
|
+
}
|
|
332
|
+
const userMessage = messages.find((message) => message.role === "user");
|
|
333
|
+
if (!userMessage) {
|
|
334
|
+
throw new import_utils.ResourceActionError(400, ctx.t("user message is required"));
|
|
357
335
|
}
|
|
358
|
-
return next();
|
|
359
|
-
}
|
|
360
|
-
try {
|
|
361
336
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
362
337
|
sessionId,
|
|
363
338
|
userId
|
|
364
339
|
});
|
|
365
340
|
if (!conversation) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
return next();
|
|
341
|
+
throw new import_utils.ResourceActionError(400, ctx.t("conversation not found"));
|
|
342
|
+
}
|
|
343
|
+
const employee = await getAIEmployee(ctx, employeeName);
|
|
344
|
+
if (!employee) {
|
|
345
|
+
throw new import_utils.ResourceActionError(400, ctx.t("AI employee not found"));
|
|
373
346
|
}
|
|
374
347
|
if (!conversation.title) {
|
|
375
348
|
const textUserMessage = messages.find(
|
|
@@ -384,15 +357,9 @@ var aiConversations_default = {
|
|
|
384
357
|
await conversation.save();
|
|
385
358
|
}
|
|
386
359
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
391
|
-
} else {
|
|
392
|
-
ctx.status = 404;
|
|
393
|
-
ctx.body = { error: "AI employee not found" };
|
|
394
|
-
}
|
|
395
|
-
return next();
|
|
360
|
+
if (await isReachParallelLimit(ctx)) {
|
|
361
|
+
await saveUserMessages(ctx, sessionId, messages, editingMessageId);
|
|
362
|
+
throw new import_utils.ResourceActionError(400, ctx.t("There are conversations in progress. Please try again later."));
|
|
396
363
|
}
|
|
397
364
|
const legacy = conversation.thread === 0;
|
|
398
365
|
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
@@ -442,11 +409,19 @@ var aiConversations_default = {
|
|
|
442
409
|
}
|
|
443
410
|
} catch (err) {
|
|
444
411
|
ctx.log.error(err);
|
|
412
|
+
let status = 500;
|
|
413
|
+
let message = ctx.t("Server unexpected error occur");
|
|
414
|
+
if (err instanceof import_utils.ResourceActionError) {
|
|
415
|
+
status = err.status;
|
|
416
|
+
message = err.message;
|
|
417
|
+
} else if (err instanceof Error) {
|
|
418
|
+
status = 500;
|
|
419
|
+
message = err.message;
|
|
420
|
+
}
|
|
445
421
|
if (shouldStream) {
|
|
446
|
-
sendErrorResponse(ctx,
|
|
422
|
+
sendErrorResponse(ctx, message);
|
|
447
423
|
} else {
|
|
448
|
-
ctx.status
|
|
449
|
-
ctx.body = { error: err.message || "Tool call error" };
|
|
424
|
+
ctx.throw(status, message);
|
|
450
425
|
}
|
|
451
426
|
} finally {
|
|
452
427
|
await next();
|
|
@@ -455,9 +430,6 @@ var aiConversations_default = {
|
|
|
455
430
|
async abort(ctx, next) {
|
|
456
431
|
var _a;
|
|
457
432
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
458
|
-
if (!userId) {
|
|
459
|
-
return ctx.throw(403);
|
|
460
|
-
}
|
|
461
433
|
const { sessionId } = ctx.action.params.values || {};
|
|
462
434
|
const plugin = ctx.app.pm.get("ai");
|
|
463
435
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
@@ -474,30 +446,44 @@ var aiConversations_default = {
|
|
|
474
446
|
var _a, _b, _c, _d, _e;
|
|
475
447
|
const plugin = ctx.app.pm.get("ai");
|
|
476
448
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
449
|
+
const abortController = new AbortController();
|
|
450
|
+
const abortStream = () => abortController.abort();
|
|
451
|
+
const shouldStopStream = () => abortController.signal.aborted || ctx.res.destroyed || ctx.res.writableEnded;
|
|
480
452
|
setupSSEHeaders(ctx);
|
|
481
453
|
const sessionId = ((_b = ctx.action.params) == null ? void 0 : _b.sessionId) || ((_d = (_c = ctx.action.params) == null ? void 0 : _c.values) == null ? void 0 : _d.sessionId) || ((_e = ctx.action.params) == null ? void 0 : _e.filterByTk);
|
|
482
454
|
if (!sessionId) {
|
|
483
455
|
sendErrorResponse(ctx, "sessionId is required");
|
|
484
456
|
return;
|
|
485
457
|
}
|
|
458
|
+
ctx.req.once("aborted", abortStream);
|
|
459
|
+
ctx.res.once("close", abortStream);
|
|
486
460
|
try {
|
|
487
461
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
488
462
|
sessionId,
|
|
489
463
|
userId
|
|
490
464
|
});
|
|
465
|
+
if (shouldStopStream()) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
491
468
|
if (!conversation) {
|
|
492
469
|
sendErrorResponse(ctx, "conversation not found");
|
|
493
470
|
return;
|
|
494
471
|
}
|
|
472
|
+
const reachLimit = await isReachParallelLimit(ctx);
|
|
473
|
+
if (shouldStopStream()) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
495
476
|
let hasChunks = false;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
477
|
+
if (!reachLimit) {
|
|
478
|
+
for await (const chunk of plugin.llmStreamCachedManager.getCached(sessionId).stream({ signal: abortController.signal })) {
|
|
479
|
+
if (shouldStopStream()) {
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
hasChunks = true;
|
|
483
|
+
ctx.res.write(chunk);
|
|
484
|
+
}
|
|
499
485
|
}
|
|
500
|
-
if (!hasChunks) {
|
|
486
|
+
if (!hasChunks && !shouldStopStream()) {
|
|
501
487
|
const currentConversation = await plugin.aiConversationsManager.getConversation({
|
|
502
488
|
sessionId,
|
|
503
489
|
userId
|
|
@@ -510,11 +496,16 @@ var aiConversations_default = {
|
|
|
510
496
|
}
|
|
511
497
|
}
|
|
512
498
|
} catch (err) {
|
|
499
|
+
if (shouldStopStream()) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
513
502
|
ctx.log.error(err);
|
|
514
503
|
sendErrorResponse(ctx, err.message || "Resume stream error");
|
|
515
504
|
return;
|
|
516
505
|
} finally {
|
|
517
|
-
|
|
506
|
+
ctx.req.off("aborted", abortStream);
|
|
507
|
+
ctx.res.off("close", abortStream);
|
|
508
|
+
if (!shouldStopStream()) {
|
|
518
509
|
ctx.res.end();
|
|
519
510
|
}
|
|
520
511
|
await next();
|
|
@@ -524,24 +515,26 @@ var aiConversations_default = {
|
|
|
524
515
|
var _a, _b, _c, _d;
|
|
525
516
|
const plugin = ctx.app.pm.get("ai");
|
|
526
517
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
527
|
-
|
|
528
|
-
return ctx.throw(403);
|
|
529
|
-
}
|
|
530
|
-
setupSSEHeaders(ctx);
|
|
531
|
-
const { sessionId, webSearch, model } = ctx.action.params.values || {};
|
|
518
|
+
const { sessionId, webSearch, model, stream = true } = ctx.action.params.values || {};
|
|
532
519
|
let { messageId } = ctx.action.params.values || {};
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
520
|
+
const shouldStream = stream !== false;
|
|
521
|
+
if (shouldStream) {
|
|
522
|
+
setupSSEHeaders(ctx);
|
|
536
523
|
}
|
|
537
524
|
try {
|
|
525
|
+
if (!sessionId) {
|
|
526
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
527
|
+
}
|
|
538
528
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
539
529
|
sessionId,
|
|
540
530
|
userId
|
|
541
531
|
});
|
|
542
532
|
if (!conversation) {
|
|
543
|
-
|
|
544
|
-
|
|
533
|
+
throw new import_utils.ResourceActionError(400, ctx.t("conversation not found"));
|
|
534
|
+
}
|
|
535
|
+
const employee = await getAIEmployee(ctx, conversation.aiEmployeeUsername);
|
|
536
|
+
if (!employee) {
|
|
537
|
+
throw new import_utils.ResourceActionError(400, ctx.t("AI employee not found"));
|
|
545
538
|
}
|
|
546
539
|
const resendMessages = [];
|
|
547
540
|
if (messageId) {
|
|
@@ -551,8 +544,7 @@ var aiConversations_default = {
|
|
|
551
544
|
}
|
|
552
545
|
});
|
|
553
546
|
if (!message) {
|
|
554
|
-
|
|
555
|
-
return next();
|
|
547
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
556
548
|
}
|
|
557
549
|
} else {
|
|
558
550
|
const message = await ctx.db.getRepository("aiConversations.messages", sessionId).findOne({
|
|
@@ -562,8 +554,7 @@ var aiConversations_default = {
|
|
|
562
554
|
sort: ["-messageId"]
|
|
563
555
|
});
|
|
564
556
|
if (!message) {
|
|
565
|
-
|
|
566
|
-
return next();
|
|
557
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
567
558
|
}
|
|
568
559
|
messageId = message.messageId;
|
|
569
560
|
if (["user", "tool"].includes(message.role)) {
|
|
@@ -577,10 +568,8 @@ var aiConversations_default = {
|
|
|
577
568
|
});
|
|
578
569
|
}
|
|
579
570
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
583
|
-
return next();
|
|
571
|
+
if (await isReachParallelLimit(ctx)) {
|
|
572
|
+
throw new import_utils.ResourceActionError(400, ctx.t("There are conversations in progress. Please try again later."));
|
|
584
573
|
}
|
|
585
574
|
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
586
575
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
@@ -593,20 +582,38 @@ var aiConversations_default = {
|
|
|
593
582
|
webSearch,
|
|
594
583
|
model: resolvedModel
|
|
595
584
|
});
|
|
596
|
-
|
|
585
|
+
if (shouldStream) {
|
|
586
|
+
await aiEmployee.stream({ messageId, userMessages: resendMessages.length ? resendMessages : void 0 });
|
|
587
|
+
} else {
|
|
588
|
+
ctx.body = await aiEmployee.invoke({
|
|
589
|
+
messageId,
|
|
590
|
+
userMessages: resendMessages.length ? resendMessages : void 0
|
|
591
|
+
});
|
|
592
|
+
}
|
|
597
593
|
} catch (err) {
|
|
598
594
|
ctx.log.error(err);
|
|
599
|
-
|
|
595
|
+
let status = 500;
|
|
596
|
+
let message = ctx.t("Server unexpected error occur");
|
|
597
|
+
if (err instanceof import_utils.ResourceActionError) {
|
|
598
|
+
status = err.status;
|
|
599
|
+
message = err.message;
|
|
600
|
+
} else if (err instanceof Error) {
|
|
601
|
+
status = 500;
|
|
602
|
+
message = err.message;
|
|
603
|
+
}
|
|
604
|
+
if (shouldStream) {
|
|
605
|
+
sendErrorResponse(ctx, message);
|
|
606
|
+
} else {
|
|
607
|
+
ctx.throw(status, message);
|
|
608
|
+
}
|
|
609
|
+
} finally {
|
|
610
|
+
await next();
|
|
600
611
|
}
|
|
601
|
-
await next();
|
|
602
612
|
},
|
|
603
613
|
async updateUserDecision(ctx, next) {
|
|
604
614
|
var _a;
|
|
605
615
|
const plugin = ctx.app.pm.get("ai");
|
|
606
616
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
607
|
-
if (!userId) {
|
|
608
|
-
return ctx.throw(403);
|
|
609
|
-
}
|
|
610
617
|
const { sessionId, messageId, toolCallId, userDecision } = ctx.action.params.values || {};
|
|
611
618
|
if (!sessionId) {
|
|
612
619
|
ctx.throw(400);
|
|
@@ -686,9 +693,6 @@ var aiConversations_default = {
|
|
|
686
693
|
async resumeToolCall(ctx, next) {
|
|
687
694
|
var _a, _b, _c, _d;
|
|
688
695
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
689
|
-
if (!userId) {
|
|
690
|
-
return ctx.throw(403);
|
|
691
|
-
}
|
|
692
696
|
setupSSEHeaders(ctx);
|
|
693
697
|
const plugin = ctx.app.pm.get("ai");
|
|
694
698
|
const { sessionId, messageId, model, webSearch } = ctx.action.params.values || {};
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -21,3 +21,7 @@ export declare function encodeLocalFile(url: string): Promise<string>;
|
|
|
21
21
|
export declare function encodeFile(ctx: Context, url: string): Promise<string>;
|
|
22
22
|
export declare function parseVariables(ctx: Context, value: string): Promise<any>;
|
|
23
23
|
export declare const buildTool: (toolsEntry: ToolsEntry) => import("@langchain/core/dist/tools").DynamicTool<any>;
|
|
24
|
+
export declare class ResourceActionError extends Error {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
constructor(status: number, message: string, options?: ErrorOptions);
|
|
27
|
+
}
|
package/dist/server/utils.js
CHANGED
|
@@ -36,6 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
var utils_exports = {};
|
|
38
38
|
__export(utils_exports, {
|
|
39
|
+
ResourceActionError: () => ResourceActionError,
|
|
39
40
|
buildTool: () => buildTool,
|
|
40
41
|
encodeFile: () => encodeFile,
|
|
41
42
|
encodeLocalFile: () => encodeLocalFile,
|
|
@@ -179,8 +180,16 @@ const buildTool = (toolsEntry) => {
|
|
|
179
180
|
}
|
|
180
181
|
);
|
|
181
182
|
};
|
|
183
|
+
class ResourceActionError extends Error {
|
|
184
|
+
constructor(status, message, options) {
|
|
185
|
+
super(message, options);
|
|
186
|
+
this.status = status;
|
|
187
|
+
this.name = "ResourceActionError";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
182
190
|
// Annotate the CommonJS export names for ESM import in node:
|
|
183
191
|
0 && (module.exports = {
|
|
192
|
+
ResourceActionError,
|
|
184
193
|
buildTool,
|
|
185
194
|
encodeFile,
|
|
186
195
|
encodeLocalFile,
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "Create AI employees with diverse skills to collaborate with humans, build systems, and handle business operations.",
|
|
7
7
|
"description.ru-RU": "Поддержка интеграции с AI-сервисами: предоставляются AI-узлы для рабочих процессов, расширяя возможности бизнес-обработки.",
|
|
8
8
|
"description.zh-CN": "创建各种技能的 AI 员工,与人类协同,搭建系统,处理业务。",
|
|
9
|
-
"version": "2.1.0-beta.
|
|
9
|
+
"version": "2.1.0-beta.33",
|
|
10
10
|
"main": "dist/server/index.js",
|
|
11
11
|
"homepage": "https://docs.nocobase.com/handbook/action-ai",
|
|
12
12
|
"homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/action-ai",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"keywords": [
|
|
65
65
|
"AI"
|
|
66
66
|
],
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "4815c394e80a264fa8ed619246280923c47aeb72"
|
|
68
68
|
}
|