@sogood360/openpartner 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ // openpartner-init-ui bin shim(OpenTUI init 向导入口,设计 §4.3)
3
+ // 按平台 resolve optionalDependencies 子包内的 bun compile 单文件并 exec
4
+ const { spawn } = require("child_process");
5
+ const os = require("os");
6
+
7
+ const PLATFORMS = {
8
+ "win32-x64": "@sogood360/init-ui-win32-x64/bin/openpartner-init-ui.exe",
9
+ "linux-x64": "@sogood360/init-ui-linux-x64/bin/openpartner-init-ui",
10
+ };
11
+
12
+ const key = `${os.platform()}-${os.arch()}`;
13
+ const rel = PLATFORMS[key];
14
+ if (!rel) {
15
+ console.error(`[openpartner-init-ui] 不支持的平台: ${key}(当前仅支持 win32-x64 / linux-x64)`);
16
+ process.exit(1);
17
+ }
18
+
19
+ let bin;
20
+ try {
21
+ bin = require.resolve(rel);
22
+ } catch (e) {
23
+ console.error(
24
+ `[openpartner-init-ui] 平台子包未安装: ${rel.split("/bin/")[0]}\n` +
25
+ ` 可能 optionalDependencies 被跳过(--no-optional)。请重新安装:npm i -g @sogood360/openpartner`
26
+ );
27
+ process.exit(1);
28
+ }
29
+
30
+ const child = spawn(bin, process.argv.slice(2), { stdio: "inherit" });
31
+ child.on("exit", (code, signal) => {
32
+ if (signal) {
33
+ process.kill(process.pid, signal);
34
+ } else {
35
+ process.exit(code ?? 0);
36
+ }
37
+ });
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ // openpartner bin shim(esbuild 分发模式,设计 §3.2)
3
+ // 按平台 resolve optionalDependencies 子包内的 Nuitka onefile 二进制并 exec
4
+ const { spawn } = require("child_process");
5
+ const os = require("os");
6
+
7
+ const PLATFORMS = {
8
+ "win32-x64": "@sogood360/server-win32-x64/bin/openpartner-server.exe",
9
+ "linux-x64": "@sogood360/server-linux-x64/bin/openpartner-server",
10
+ };
11
+
12
+ const key = `${os.platform()}-${os.arch()}`;
13
+ const rel = PLATFORMS[key];
14
+ if (!rel) {
15
+ console.error(`[openpartner] 不支持的平台: ${key}(当前仅支持 win32-x64 / linux-x64)`);
16
+ process.exit(1);
17
+ }
18
+
19
+ let bin;
20
+ try {
21
+ bin = require.resolve(rel);
22
+ } catch (e) {
23
+ console.error(
24
+ `[openpartner] 平台子包未安装: ${rel.split("/bin/")[0]}\n` +
25
+ ` 可能 optionalDependencies 被跳过(--no-optional)。请重新安装:npm i -g @sogood360/openpartner`
26
+ );
27
+ process.exit(1);
28
+ }
29
+
30
+ const child = spawn(bin, process.argv.slice(2), { stdio: "inherit" });
31
+ child.on("exit", (code, signal) => {
32
+ if (signal) {
33
+ process.kill(process.pid, signal);
34
+ } else {
35
+ process.exit(code ?? 0);
36
+ }
37
+ });
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@sogood360/openpartner",
3
+ "version": "1.5.4",
4
+ "description": "企业级 AI 平台 - 员工工作台 / 协作平台 / 业务沉淀 / 自动化运行 (Windows/Linux)",
5
+ "license": "UNLICENSED",
6
+ "private": false,
7
+ "bin": {
8
+ "openpartner": "bin/openpartner.js",
9
+ "openpartner-init-ui": "bin/openpartner-init-ui.js"
10
+ },
11
+ "scripts": {
12
+ "postinstall": "node postinstall.js"
13
+ },
14
+ "files": [
15
+ "bin/openpartner.js",
16
+ "bin/openpartner-init-ui.js",
17
+ "postinstall.js",
18
+ "packages/README.md",
19
+ "packages/README.zh-CN.md"
20
+ ],
21
+ "optionalDependencies": {
22
+ "@sogood360/server-win32-x64": "1.5.3",
23
+ "@sogood360/server-linux-x64": "1.5.3",
24
+ "@sogood360/init-ui-win32-x64": "1.5.3",
25
+ "@sogood360/init-ui-linux-x64": "1.5.3"
26
+ },
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "keywords": [
31
+ "ai-agent",
32
+ "agent-platform",
33
+ "enterprise-ai",
34
+ "workflow-automation",
35
+ "collaboration",
36
+ "internal-tools",
37
+ "multi-tenant",
38
+ "openpartner"
39
+ ]
40
+ }
@@ -0,0 +1,279 @@
1
+ # OpenPartner
2
+
3
+ **Songguo Technology Co., Ltd.**
4
+
5
+ OpenPartner is an enterprise-grade AI agent platform built by Songguo. It serves as the daily AI workbench for employees, the collaboration hub for teams, and the platform where business and data assets continuously accumulate and evolve. Every process and output is fully auditable, and all data stays within the enterprise.
6
+
7
+ ---
8
+
9
+ ## Platform support
10
+
11
+ | Item | Details |
12
+ |---|---|
13
+ | Operating system | Windows x64 ✅ · Linux x64 ✅ |
14
+ | Architecture | x86_64 (Intel / AMD) |
15
+ | Container runtime | Docker (Docker Desktop on Windows, Docker Engine 20.10+ on Linux) |
16
+ | Database | MySQL 8.0+ (including MariaDB 10.6+) |
17
+ | Browser | Chrome / Edge / Firefox / Safari, recent two years |
18
+ | Minimum memory | 4 GB (excluding per-user agent containers) |
19
+ | Network | Single-host install needs no public network; multi-cell deployments require intranet reachability between cells |
20
+
21
+ > **Not supported:** macOS (any architecture), Linux arm64, 32-bit systems. The platform packages declare `os:["win32"]` / `os:["linux"]` and `cpu:["x64"]`, so an unsupported platform would install an empty wrapper that errors out with "unsupported platform".
22
+
23
+
24
+
25
+ ## Installation
26
+
27
+ ### Prerequisites
28
+
29
+ ```bash
30
+ # 1. Docker (required)
31
+ docker version # confirm both Client and Server are present
32
+ # Windows: install and start Docker Desktop
33
+ # Linux: sudo apt install docker.io && sudo systemctl enable --now docker
34
+
35
+ # 2. MySQL 8.0+ (required, can be remote)
36
+ mysql --version
37
+ ```
38
+
39
+ ### One-line install
40
+
41
+ ```bash
42
+ npm i -g @sogood360/openpartner@beta # beta phase private build (UNLICENSED, internal testing only)
43
+ ```
44
+
45
+ > Currently in beta (v1.5.x). The `license` field in package.json is `UNLICENSED`; this is **not a public release**. See `doc/npm发布说明.md` §7 (License roadmap) for the path to MIT.
46
+
47
+ After installation, two commands are available:
48
+
49
+ | Command | Description |
50
+ |---|---|
51
+ | `openpartner` | Backend service and CLI (`init` / `start` / `stop` / `status` / `version`) |
52
+ | `openpartner-init-ui` | Guided TUI initializer (**must be run in a real TTY terminal**) |
53
+
54
+ > ⚠️ `openpartner-init-ui` is a TUI application — run it in Windows Terminal, PowerShell, or a real SSH shell. Git Bash and many IDE integrated terminals exit immediately because `stdio.isTTY === false` is `false`.
55
+
56
+ ### Initialization
57
+
58
+ **Option A: guided TUI (recommended)**
59
+
60
+ ```bash
61
+ openpartner-init-ui
62
+ ```
63
+
64
+ The wizard walks through: environment probe → Docker connection → MySQL initialization → image pull → frontend container creation → config generation → admin password.
65
+
66
+ **Option B: command line**
67
+
68
+ ```bash
69
+ openpartner init # interactive
70
+ openpartner init --from-json params.json # driven by a JSON config
71
+ ```
72
+
73
+ ### Start
74
+
75
+ ```bash
76
+ openpartner start # start in the background
77
+ ```
78
+
79
+ ### Access
80
+
81
+ Open the URL shown at the end of initialization in your browser (default: <http://localhost:9620>).
82
+
83
+ **Default admin account: `admin` / `admin`** — change it immediately under *User Management* on first login.
84
+
85
+ ### File layout
86
+
87
+ | Platform | Configuration | Data |
88
+ |---|---|---|
89
+ | Linux | `/etc/openpartner/config.yaml` | `<workspace.root>` (default `/var/lib/openpartner/workspace`) |
90
+ | Windows | `%ProgramData%\openpartner\config.yaml` | `D:\openpartner\workspace` |
91
+
92
+ Each user gets their own subdirectory at `<workspace.root>/user_<id>/`, bind-mounted into the agent container at `/workspace/user_space`.
93
+
94
+ ---
95
+
96
+ ## JSON configuration
97
+
98
+ Both the TUI wizard and `openpartner init --from-json` accept the same JSON parameter file. It is the recommended way to drive **unattended, automated deployment**.
99
+
100
+ ### Full example
101
+
102
+ ```json
103
+ {
104
+ "server": { "port": 3001 },
105
+ "frontend": { "port": 9620 },
106
+
107
+ "docker": {
108
+ "host": "unix:///var/run/docker.sock",
109
+ "tls": { "ca": "", "cert": "", "key": "" }
110
+ },
111
+
112
+ "database": {
113
+ "host": "127.0.0.1",
114
+ "port": 3306,
115
+ "user": "root",
116
+ "password": "your-password",
117
+ "name": "openpartner"
118
+ },
119
+
120
+ "workspace": { "root": "/var/lib/openpartner/workspace" },
121
+
122
+ "images": {
123
+ "frontend": "sogood360/openpartner-frontend:1.5.1",
124
+ "agent": "sogood360/openpartner-agent:1.5.1"
125
+ },
126
+
127
+ "cell": {
128
+ "id": "cell_a",
129
+ "name": "Primary",
130
+ "cell_url": "http://127.0.0.1:3001",
131
+ "region": "",
132
+ "zone": ""
133
+ },
134
+
135
+ "mode": "primary",
136
+
137
+ "public_base_url": "http://localhost:9620",
138
+
139
+ "secrets": {
140
+ "jwt_secret": "",
141
+ "encryption_key": "",
142
+ "encryption_salt": "",
143
+ "internal_token": ""
144
+ },
145
+
146
+ "admin": { "password": "change-me-now" },
147
+
148
+ "actions": {
149
+ "pull_images": true,
150
+ "create_frontend_container": true,
151
+ "register_autostart": true,
152
+ "reset_db": false
153
+ }
154
+ }
155
+ ```
156
+ ### Field reference
157
+
158
+ #### `server` — backend listener
159
+
160
+ | Key | Type | Default | Description |
161
+ |---|---|---|---|
162
+ | `port` | int | `3001` | Port the backend API listens on |
163
+
164
+ #### `frontend` — frontend container
165
+
166
+ | Key | Type | Default | Description |
167
+ |---|---|---|---|
168
+ | `port` | int | `9620` | External port for the frontend container (also used for port mapping and `public_base_url` fallback calculation) |
169
+
170
+ #### `docker` — container runtime
171
+
172
+ | Key | Type | Default | Description |
173
+ |---|---|---|---|
174
+ | `host` | string | platform default | Docker endpoint. Linux defaults to `unix:///var/run/docker.sock`; for remote Docker use `tcp://host:2376` |
175
+ | `tls` | object | none | Mutual TLS certificate for remote Docker; enabled only when all three fields are filled |
176
+
177
+ #### `database` — MySQL
178
+
179
+ | Key | Type | Default | Description |
180
+ |---|---|---|---|
181
+ | `host` | string | `127.0.0.1` | Database host. In multi-cell deployments, secondary cells use the primary's intranet address |
182
+ | `port` | int | `3306` | Database port |
183
+ | `user` | string | `root` | Database user |
184
+ | `password` | string | empty | Database password. Leave empty to be prompted interactively by the wizard |
185
+ | `name` | string | `openpartner` | Database name. An existing database is preserved (unless `actions.reset_db = true`) |
186
+
187
+ #### `workspace` — user workspaces
188
+
189
+ | Key | Type | Default | Description |
190
+ |---|---|---|---|
191
+ | `root` | string | platform default | Root directory for user workspaces. One `user_<id>/` subdirectory per user. **Must reside on a path the Docker host can bind-mount** |
192
+
193
+ #### `images` — images
194
+
195
+ | Key | Type | Default | Description |
196
+ |---|---|---|---|
197
+ | `frontend` | string | tag for current version | Full frontend image reference. Empty falls back to the built-in default |
198
+ | `agent` | string | tag for current version | Full agent image reference. Empty falls back to the built-in default |
199
+
200
+ > These two images are pulled during initialization. **At runtime**, the version of `agent` actually used by user containers is controlled by the per-cell *Agent image version* policy in Node Management (lock to a specific version or *follow latest*) — not by this field.
201
+
202
+ #### `cell` — node identity
203
+
204
+ | Key | Type | Default | Description |
205
+ |---|---|---|---|
206
+ | `id` | string | `cell_a` | Node ID, in the form `cell_<short-id>`. **Must be unique within a cluster** |
207
+ | `name` | string | same as `id` | Display name |
208
+ | `cell_url` | string | `http://127.0.0.1:<server.port>` | Address reachable by browsers and other cells. **Never use `0.0.0.0`** |
209
+ | `region` | string | empty | Datacenter tag (optional) |
210
+ | `zone` | string | empty | Availability-zone tag (optional) |
211
+
212
+ #### `mode` — deployment role
213
+
214
+ | Value | Description |
215
+ |---|---|
216
+ | `primary` | Primary node: creates the database, the admin user, and writes `jwt_secret` |
217
+ | `secondary` | Secondary node: joins an existing cluster after checking that the cell ID is unique; shares the primary's database and secrets |
218
+ | `auto` (default) | If a node record already exists in the database, treat as `secondary`; otherwise treat as `primary` |
219
+
220
+ Multi-cell: the primary node uses `primary`, every other node uses `secondary` and points at the same `database` and `secrets`.
221
+
222
+ #### `public_base_url` / `primary_public_url` / `container_api_url`
223
+
224
+ | Key | Description |
225
+ |---|---|
226
+ | `public_base_url` | **URL that users type into the browser's address bar**. If empty, derived from `cell_url`'s hostname plus `frontend.port` |
227
+ | `primary_public_url` | Used when a `secondary` cell is initialized; specifies the primary's browser URL so cross-cell WebSocket connections are allowed in `ws_allowed_origins` |
228
+ | `container_api_url` | Address used by user containers to reach the backend. If empty, the platform picks one automatically |
229
+
230
+ #### `secrets` — secrets
231
+
232
+ | Key | Description |
233
+ |---|---|
234
+ | `jwt_secret` | Signing key for login tokens. **Empty generates a fresh one**; in multi-cell deployments, every cell must agree on the same value |
235
+ | `encryption_key` | Encryption key for AI provider API keys stored in the database. Empty generates a fresh one |
236
+ | `encryption_salt` | Salt for the same encryption. Empty generates a fresh one |
237
+ | `internal_token` | Token used between the backend and user containers. Empty generates a fresh one |
238
+
239
+ > ⚠️ Once `encryption_key` + `encryption_salt` are written into the database, they **must not be changed** — changing either will make every stored AI provider key undecryptable and require re-entry. For production, specify them explicitly and back them up.
240
+
241
+ #### `admin` — administrator
242
+
243
+ | Key | Description |
244
+ |---|---|
245
+ | `password` | Initial admin password. Empty keeps the built-in default `admin` (**only suitable for local testing**) |
246
+
247
+ #### `actions` — execution actions
248
+
249
+ | Key | Default | Description |
250
+ |---|---|---|
251
+ | `pull_images` | `true` | Whether to pull frontend and agent images from the registry. Set `false` for offline installs (after pre-loading images with `docker load`) |
252
+ | `create_frontend_container` | `true` | Whether to create the frontend container |
253
+ | `register_autostart` | `true` | Whether to register the service for autostart on boot |
254
+ | `reset_db` | `false` | ⚠️ **Drops and rebuilds the database**. Deletes all users, sessions, and workspace configuration. Use only when an explicit reset is intended |
255
+
256
+ ### Parameter precedence
257
+
258
+ From lowest to highest (later overrides earlier):
259
+
260
+ ```
261
+ built-in defaults < existing config.yaml < --from-json file < environment variables
262
+ ```
263
+
264
+ Only keys **explicitly present** in the JSON override the defaults; anything else is inherited from the layer above.
265
+
266
+ ### Usage examples
267
+
268
+ ```bash
269
+ # Initialize from a file
270
+ openpartner init --from-json ./params.json
271
+
272
+ # Automated deployment (CI / batch rollout)
273
+ openpartner init --from-json ./params.json --non-interactive
274
+ openpartner start
275
+ ```
276
+
277
+ ---
278
+
279
+ Songguo Technology Co., Ltd.
@@ -0,0 +1,279 @@
1
+ # OpenPartner
2
+
3
+ **深圳市松粿科技有限公司**
4
+
5
+ OpenPartner 是松粿科技推出的企业级 AI 智能体平台。它是员工的日常 AI 工作台,也是团队的协作平台,企业业务资产与数据资产的沉淀演进平台;所有过程与产出全程留痕,数据不出企业。
6
+
7
+ ---
8
+
9
+ ## 平台支持
10
+
11
+ | 项 | 支持情况 |
12
+ |---|---|
13
+ | 操作系统 | Windows x64 ✅ · Linux x64 ✅ |
14
+ | 架构 | x86_64(Intel / AMD) |
15
+ | 容器运行时 | Docker(Windows 需 Docker Desktop,Linux 需 Docker Engine 20.10+) |
16
+ | 数据库 | MySQL 8.0+(含 MariaDB 10.6+) |
17
+ | 浏览器 | Chrome / Edge / Firefox / Safari 近两年版本 |
18
+ | 最低内存 | 4 GB(不含用户智能体容器) |
19
+ | 网络 | 单机部署免公网;多节点需节点间内网互通 |
20
+
21
+ > **不支持:** macOS(任何架构)、Linux arm64、32 位系统。子包声明了 `os:["win32"]` / `os:["linux"]` 与 `cpu:["x64"]`,不匹配的系统会装到空 wrapper,运行时直接报 "unsupported platform"。
22
+
23
+
24
+ ## 安装说明
25
+
26
+ ### 前置条件
27
+
28
+ ```bash
29
+ # 1. Docker(必需)
30
+ docker version # 确认 Client + Server 都在
31
+ # Windows: 安装 Docker Desktop 并启动
32
+ # Linux: sudo apt install docker.io && sudo systemctl enable --now docker
33
+
34
+ # 2. MySQL 8.0+(必需,可为远程)
35
+ mysql --version
36
+ ```
37
+
38
+ ### 一条命令安装
39
+
40
+ ```bash
41
+ npm i -g @sogood360/openpartner@beta # beta 阶段私有版本(UNLICENSED,仅供内部测试)
42
+ ```
43
+
44
+ > 当前处于 beta 阶段(v1.5.x),package.json `license` 字段为 `UNLICENSED`,**不构成面向公众的正式发布**。详见 `doc/npm发布说明.md` §7 License 路线图。
45
+
46
+ 安装后得到两个命令:
47
+
48
+ | 命令 | 说明 |
49
+ |---|---|
50
+ | `openpartner` | 后端服务与命令行工具(`init` / `start` / `stop` / `status` / `version`) |
51
+ | `openpartner-init-ui` | 图形化初始化向导(**需在真实终端 TTY 里运行**) |
52
+
53
+ > ⚠️ `openpartner-init-ui` 是 TUI 界面,请在 Windows Terminal / PowerShell / 真正的 SSH shell 里运行。在 Git Bash 或某些 IDE 内置终端里会因为 `stdio.isTTY === false` 直接退出。
54
+
55
+ ### 初始化
56
+
57
+ **方式 A:图形化向导(推荐)**
58
+
59
+ ```bash
60
+ openpartner-init-ui
61
+ ```
62
+
63
+ 按提示依次完成:环境探测 → Docker 连接 → MySQL 初始化 → 拉取镜像 → 创建前端容器 → 生成配置 → 设置管理员密码。
64
+
65
+ **方式 B:命令行**
66
+
67
+ ```bash
68
+ openpartner init # 交互式
69
+ openpartner init --from-json params.json # 按 JSON 配置
70
+ ```
71
+
72
+ ### 启动
73
+
74
+ ```bash
75
+ openpartner start # 后台启动
76
+ ```
77
+
78
+ ### 访问
79
+
80
+ 浏览器打开初始化时提示的地址(默认 <http://localhost:9620>)。
81
+
82
+ **默认管理员账号:`admin` / `admin`** —— 首次登录后请立即在「用户管理」中修改密码。
83
+
84
+ ### 目录约定
85
+
86
+ | 平台 | 配置 | 数据 |
87
+ |---|---|---|
88
+ | Linux | `/etc/openpartner/config.yaml` | `<workspace.root>`(默认 `/var/lib/openpartner/workspace`) |
89
+ | Windows | `%ProgramData%\openpartner\config.yaml` | `D:\openpartner\workspace` |
90
+
91
+ 用户工作空间按 `<workspace.root>/user_<id>/` 划分,用户容器内挂载到 `/workspace/user_space`。
92
+
93
+ ---
94
+
95
+ ## JSON 配置说明
96
+
97
+ 初始化向导和 `openpartner init --from-json` 都接受同一份 JSON 参数文件,用于**无人工干预的自动化部署**。
98
+
99
+ ### 完整示例
100
+
101
+ ```json
102
+ {
103
+ "server": { "port": 3001 },
104
+ "frontend": { "port": 9620 },
105
+
106
+ "docker": {
107
+ "host": "unix:///var/run/docker.sock",
108
+ "tls": { "ca": "", "cert": "", "key": "" }
109
+ },
110
+
111
+ "database": {
112
+ "host": "127.0.0.1",
113
+ "port": 3306,
114
+ "user": "root",
115
+ "password": "your-password",
116
+ "name": "openpartner"
117
+ },
118
+
119
+ "workspace": { "root": "/var/lib/openpartner/workspace" },
120
+
121
+ "images": {
122
+ "frontend": "sogood360/openpartner-frontend:1.5.1",
123
+ "agent": "sogood360/openpartner-agent:1.5.1"
124
+ },
125
+
126
+ "cell": {
127
+ "id": "cell_a",
128
+ "name": "主节点",
129
+ "cell_url": "http://127.0.0.1:3001",
130
+ "region": "",
131
+ "zone": ""
132
+ },
133
+
134
+ "mode": "primary",
135
+
136
+ "public_base_url": "http://localhost:9620",
137
+
138
+ "secrets": {
139
+ "jwt_secret": "",
140
+ "encryption_key": "",
141
+ "encryption_salt": "",
142
+ "internal_token": ""
143
+ },
144
+
145
+ "admin": { "password": "change-me-now" },
146
+
147
+ "actions": {
148
+ "pull_images": true,
149
+ "create_frontend_container": true,
150
+ "register_autostart": true,
151
+ "reset_db": false
152
+ }
153
+ }
154
+ ```
155
+
156
+ ### 字段说明
157
+
158
+ #### `server` —— 后端监听
159
+
160
+ | 键 | 类型 | 默认 | 说明 |
161
+ |---|---|---|---|
162
+ | `port` | int | `3001` | 后端 API 监听端口 |
163
+
164
+ #### `frontend` —— 前端容器
165
+
166
+ | 键 | 类型 | 默认 | 说明 |
167
+ |---|---|---|---|
168
+ | `port` | int | `9620` | 前端容器对外端口(同时用于端口映射与 `public_base_url` 兜底计算) |
169
+
170
+ #### `docker` —— 容器运行时
171
+
172
+ | 键 | 类型 | 默认 | 说明 |
173
+ |---|---|---|---|
174
+ | `host` | string | 平台默认 | Docker endpoint。Linux 默认 `unix:///var/run/docker.sock`;远程 Docker 填 `tcp://host:2376` |
175
+ | `tls` | object | 无 | 远程 Docker 的双向 TLS 证书,三项都填才启用 |
176
+
177
+ #### `database` —— MySQL
178
+
179
+ | 键 | 类型 | 默认 | 说明 |
180
+ |---|---|---|---|
181
+ | `host` | string | `127.0.0.1` | 数据库地址。多节点部署时子节点填主节点内网地址 |
182
+ | `port` | int | `3306` | 数据库端口 |
183
+ | `user` | string | `root` | 数据库账号 |
184
+ | `password` | string | 空 | 数据库密码。留空时向导会交互询问 |
185
+ | `name` | string | `openpartner` | 库名。已存在的库不会被清空(除非 `actions.reset_db = true`) |
186
+
187
+ #### `workspace` —— 工作空间
188
+
189
+ | 键 | 类型 | 默认 | 说明 |
190
+ |---|---|---|---|
191
+ | `root` | string | 平台默认 | 用户工作空间根目录。每个用户一个 `user_<id>/` 子目录。**必须落在 Docker 宿主可 bind mount 的路径上** |
192
+
193
+ #### `images` —— 镜像
194
+
195
+ | 键 | 类型 | 默认 | 说明 |
196
+ |---|---|---|---|
197
+ | `frontend` | string | 当前版本对应 tag | 前端镜像完整引用。留空用内置默认 |
198
+ | `agent` | string | 当前版本对应 tag | 智能体镜像完整引用。留空用内置默认 |
199
+
200
+ > 初始化时拉取这两个镜像。**运行期**用户容器用哪个 agent 版本,由节点管理里的「智能体镜像版本」策略决定(可锁定版本或跟随最新),不由此处决定。
201
+
202
+ #### `cell` —— 节点标识
203
+
204
+ | 键 | 类型 | 默认 | 说明 |
205
+ |---|---|---|---|
206
+ | `id` | string | `cell_a` | 节点 ID,格式 `cell_<短标识>`。**同一集群内不可重复** |
207
+ | `name` | string | 同 `id` | 节点显示名 |
208
+ | `cell_url` | string | `http://127.0.0.1:<server.port>` | 浏览器/其它节点可达的地址。**不能用 `0.0.0.0`** |
209
+ | `region` | string | 空 | 机房标签(可选) |
210
+ | `zone` | string | 空 | 可用区标签(可选) |
211
+
212
+ #### `mode` —— 部署角色
213
+
214
+ | 值 | 说明 |
215
+ |---|---|
216
+ | `primary` | 主节点:建库、创建管理员、生成并写入 `jwt_secret` |
217
+ | `secondary` | 子节点:校验节点 ID 不冲突后入网,共用主节点的数据库与密钥 |
218
+ | `auto`(默认) | 库中已有节点记录 → 按 `secondary` 处理;否则按 `primary` |
219
+
220
+ 多节点部署:主节点 `primary`,其余节点 `secondary` 并连同一套 `database` 与 `secrets`。
221
+
222
+ #### `public_base_url` / `primary_public_url` / `container_api_url`
223
+
224
+ | 键 | 说明 |
225
+ |---|---|
226
+ | `public_base_url` | **浏览器地址栏里输入的地址**(用户视角的入口)。留空时由 `cell_url` 的主机名 + `frontend.port` 兜底推算 |
227
+ | `primary_public_url` | 子节点 `secondary` 部署时填主节点的浏览器入口,用于放行跨节点 WebSocket |
228
+ | `container_api_url` | 用户容器访问后端的地址。留空由平台按平台自动推导 |
229
+
230
+ #### `secrets` —— 密钥
231
+
232
+ | 键 | 说明 |
233
+ |---|---|
234
+ | `jwt_secret` | 登录令牌签名密钥。**留空自动生成**;多节点必须显式统一 |
235
+ | `encryption_key` | 供应商 API Key 的加密密钥。留空自动生成 |
236
+ | `encryption_salt` | 加密盐值。留空自动生成 |
237
+ | `internal_token` | 后端与用户容器之间的内部通信令牌。留空自动生成 |
238
+
239
+ > ⚠️ `encryption_key` + `encryption_salt` 一旦确定并写入数据库,**之后不可更改** —— 改了会导致已存的所有 AI 供应商密钥无法解密,必须重新录入。生产环境请显式指定并妥善备份。
240
+
241
+ #### `admin` —— 管理员
242
+
243
+ | 键 | 说明 |
244
+ |---|---|
245
+ | `password` | 管理员初始密码。留空则保留内置默认 `admin`(**仅建议本地测试使用**) |
246
+
247
+ #### `actions` —— 执行动作
248
+
249
+ | 键 | 默认 | 说明 |
250
+ |---|---|---|
251
+ | `pull_images` | `true` | 是否从镜像仓库拉取前端与智能体镜像。离线环境设 `false`(需事先 `docker load`) |
252
+ | `create_frontend_container` | `true` | 是否创建前端容器 |
253
+ | `register_autostart` | `true` | 是否注册开机自启 |
254
+ | `reset_db` | `false` | ⚠️ **清空并重建数据库**。会删除所有用户、会话、工作空间配置。仅在明确要重置时使用 |
255
+
256
+ ### 参数优先级
257
+
258
+ 从低到高(后者覆盖前者):
259
+
260
+ ```
261
+ 内置默认值 < 已有 config.yaml < --from-json 指定文件 < 环境变量
262
+ ```
263
+
264
+ 只有 JSON 中**显式出现**的键才会覆盖默认值,未出现的沿用上层。
265
+
266
+ ### 使用示例
267
+
268
+ ```bash
269
+ # 从文件初始化
270
+ openpartner init --from-json ./params.json
271
+
272
+ # 自动化部署(CI / 批量装机)
273
+ openpartner init --from-json ./params.json --non-interactive
274
+ openpartner start
275
+ ```
276
+
277
+ ---
278
+
279
+ 深圳市松粿科技有限公司
package/postinstall.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ const PLATFORMS = {
6
+ "win32-x64": [
7
+ ["@sogood360/server-win32-x64", "bin/openpartner-server.exe"],
8
+ ["@sogood360/init-ui-win32-x64", "bin/openpartner-init-ui.exe"],
9
+ ],
10
+ "linux-x64": [
11
+ ["@sogood360/server-linux-x64", "bin/openpartner-server"],
12
+ ["@sogood360/init-ui-linux-x64", "bin/openpartner-init-ui"],
13
+ ],
14
+ };
15
+
16
+ const key = `${process.platform}-${process.arch}`;
17
+ const want = PLATFORMS[key];
18
+
19
+ if (!want) {
20
+ console.warn(`[openpartner] 不支持的平台: ${key}(当前仅支持 win32-x64 / linux-x64)`);
21
+ process.exit(0);
22
+ }
23
+
24
+ function resolveBin(pkg, rel) {
25
+ try {
26
+ const pkgJson = require.resolve(`${pkg}/package.json`, { paths: [__dirname] });
27
+ const bin = path.join(path.dirname(pkgJson), rel);
28
+ return fs.existsSync(bin) ? bin : null;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+
34
+ const missing = [];
35
+ for (const [pkg, rel] of want) {
36
+ const bin = resolveBin(pkg, rel);
37
+ if (!bin) {
38
+ missing.push(pkg);
39
+ continue;
40
+ }
41
+ if (process.platform !== "win32") {
42
+ try {
43
+ fs.chmodSync(bin, 0o755);
44
+ } catch (e) {
45
+ console.error(`[openpartner] chmod +x 失败: ${bin} (${e.message})`);
46
+ process.exit(1);
47
+ }
48
+ }
49
+ }
50
+
51
+ if (missing.length) {
52
+ console.error(`[openpartner] 平台子包未安装: ${missing.join(", ")}`);
53
+ console.error("[openpartner] 可能 optionalDependencies 被跳过(--no-optional / omit=optional)");
54
+ console.error("[openpartner] 请重新安装: npm i -g @sogood360/openpartner --include=optional");
55
+ process.exit(1);
56
+ }
57
+
58
+ console.log("[openpartner] 安装完成,可用命令:");
59
+ console.log(" openpartner 后端服务 + CLI");
60
+ console.log(" openpartner-init-ui 初始化向导");