@h-ai/cli 0.1.0-alpha.59 → 0.1.0-alpha.61
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/README.en.md +19 -1
- package/README.ja.md +19 -1
- package/README.md +19 -1
- package/dist/{chunk-WUSFJFW5.js → chunk-WW2MIO6T.js} +437 -126
- package/dist/chunk-WW2MIO6T.js.map +1 -0
- package/dist/cli-config-templates-QRF6B5T4.js +5 -0
- package/dist/{cli-config-templates-6XA7V6CC.js.map → cli-config-templates-QRF6B5T4.js.map} +1 -1
- package/dist/index.js +28 -7
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/templates/README.md +14 -0
- package/templates/apps/api/.gitignore.hbs +1 -0
- package/templates/apps/api/apps/{{projectName}}-service/README.md.hbs +12 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +4 -7
- package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +11 -1
- package/templates/apps/api/apps/{{projectName}}-service/tests/service.test.ts.hbs +2 -1
- package/templates/apps/api/e2e/api-service.spec.ts.hbs +72 -6
- package/templates/apps/api/package.json.hbs +4 -0
- package/templates/apps/fullstack/.gitignore.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +10 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/project.inlang/settings.json.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +10 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/project.inlang/settings.json.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +2 -0
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/project.inlang/settings.json.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +10 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/project.inlang/settings.json.hbs +1 -1
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +63 -1
- package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +8 -1
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +18 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_ai.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_audit.yml.hbs +1 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_cache.yml.hbs +1 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +7 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_db.yml.hbs +1 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_deploy.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_iam.yml.hbs +1 -21
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_payment.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +52 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_scheduler.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +8 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_storage.yml.hbs +1 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_vecdb.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +7 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +11 -4
- package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +12 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/project.inlang/settings.json.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +3 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +32 -23
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ProfileSettings.svelte.hbs +24 -24
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/UserManagement.svelte.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +20 -20
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +7 -8
- package/templates/apps/h5/src/routes/+layout.svelte.hbs +35 -23
- package/templates/apps/mobile-app/src/App.svelte.hbs +43 -0
- package/templates/base/.gitignore.hbs +1 -2
- package/templates/base/e2e/app.spec.ts.hbs +147 -0
- package/templates/base/package.json.hbs +1 -1
- package/templates/base/src/hooks.server.ts.hbs +2 -2
- package/templates/base/src/lib/server/init.ts.hbs +1 -1
- package/templates/base/src/routes/+layout.server.ts.hbs +6 -0
- package/templates/base/tests/scaffold.test.ts.hbs +3 -0
- package/templates/base/vite.config.ts.hbs +1 -0
- package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +2 -16
- package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +6 -95
- package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +6 -117
- package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +6 -97
- package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +6 -112
- package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-shared/api/auth/config/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/login/+server.ts +1 -33
- package/templates/features/iam/routes-shared/api/auth/login/ldap/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/login/otp/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/otp/send/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/password-reset/confirm/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/password-reset/request/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/register/+server.ts +1 -23
- package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +11 -0
- package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +11 -0
- package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +10 -0
- package/templates/skills/hai-api-client/SKILL.md +5 -0
- package/templates/skills/hai-app-create/reference.md +10 -0
- package/templates/skills/hai-iam/SKILL.md +9 -2
- package/templates/skills/hai-iam/reference.md +76 -11
- package/templates/skills/hai-reach/SKILL.md +2 -0
- package/templates/skills/hai-ui/reference.md +47 -0
- package/dist/chunk-WUSFJFW5.js.map +0 -1
- package/dist/cli-config-templates-6XA7V6CC.js +0 -5
|
@@ -37,9 +37,6 @@ function generateConfigFile(moduleKey, configs) {
|
|
|
37
37
|
function generateCoreConfig(cfg) {
|
|
38
38
|
const name = cfg?.name ?? "my-app";
|
|
39
39
|
const locale = cfg?.defaultLocale ?? "zh-CN";
|
|
40
|
-
const supportedLocales = locale === "en-US" ? ` - en-US
|
|
41
|
-
- zh-CN` : ` - zh-CN
|
|
42
|
-
- en-US`;
|
|
43
40
|
return `# =============================================================================
|
|
44
41
|
# \u5E94\u7528\u914D\u7F6E
|
|
45
42
|
# =============================================================================
|
|
@@ -52,14 +49,18 @@ debug: false
|
|
|
52
49
|
logging:
|
|
53
50
|
level: info
|
|
54
51
|
format: json
|
|
52
|
+
# context:
|
|
53
|
+
# service: api
|
|
55
54
|
redact:
|
|
56
55
|
- password
|
|
57
56
|
- token
|
|
58
57
|
- secret
|
|
59
58
|
|
|
60
59
|
defaultLocale: ${locale}
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
# \u77ED ID \u751F\u6210\u9009\u9879\uFF1B\u8BED\u8A00\u5217\u8868\u5728\u524D\u7AEF project.inlang/settings.json \u4E2D\u7EF4\u62A4\u3002
|
|
61
|
+
# id:
|
|
62
|
+
# prefix: app_
|
|
63
|
+
# length: 21
|
|
63
64
|
`;
|
|
64
65
|
}
|
|
65
66
|
function generateServConfig() {
|
|
@@ -67,19 +68,42 @@ function generateServConfig() {
|
|
|
67
68
|
# Service / HTTP \u5165\u53E3\u914D\u7F6E
|
|
68
69
|
# =============================================================================
|
|
69
70
|
|
|
71
|
+
server:
|
|
72
|
+
host: 127.0.0.1
|
|
73
|
+
port: 3000
|
|
74
|
+
|
|
70
75
|
http:
|
|
71
76
|
apiPrefix: /api/v1
|
|
72
77
|
openapi:
|
|
73
78
|
path: /openapi.json
|
|
74
79
|
docs:
|
|
75
80
|
path: /docs
|
|
81
|
+
# requireAuth: true
|
|
76
82
|
health:
|
|
77
83
|
path: /health
|
|
78
84
|
readyPath: /ready
|
|
79
85
|
rpc: false
|
|
86
|
+
# \u542F\u7528\u5185\u90E8 RPC \u65F6\u7528\u5BF9\u8C61\u66FF\u6362 false\uFF0Cgateway-only \u5FC5\u987B\u914D\u7F6E\u7F51\u5173\u5BC6\u94A5\u3002
|
|
87
|
+
# rpc:
|
|
88
|
+
# prefix: /api/rpc
|
|
89
|
+
# access: gateway-only # loopback | private-network | gateway-only
|
|
90
|
+
# gatewayHeader: X-Gateway-Key
|
|
91
|
+
# gatewaySecret: \${HAI_SERV_HTTP_RPC_GATEWAYSECRET}
|
|
92
|
+
|
|
93
|
+
# \u6309\u9700\u5F00\u542F\u8DE8\u57DF\u8BBF\u95EE\uFF0C\u751F\u4EA7\u73AF\u5883\u586B\u5199\u660E\u786E\u7684 Origin\u3002
|
|
94
|
+
# cors:
|
|
95
|
+
# origin: https://app.example.com
|
|
96
|
+
# nativeOrigins: capacitor://localhost,tauri://localhost
|
|
97
|
+
# allowedHeaders: [Authorization, Content-Type, X-Request-Id]
|
|
98
|
+
# exposedHeaders: [X-Request-Id]
|
|
99
|
+
# credentials: true
|
|
80
100
|
|
|
81
101
|
# \u5F00\u53D1\u671F\u9ED8\u8BA4\u5173\u95ED transport\uFF1B\u542F\u7528 @h-ai/crypto \u540E\u53EF\u6309\u9700\u6539\u4E3A\u5BF9\u8C61\u914D\u7F6E
|
|
82
102
|
transport: false
|
|
103
|
+
# transport:
|
|
104
|
+
# keyExchangePath: /_hai/key-exchange
|
|
105
|
+
# excludePaths: [/health, /ready]
|
|
106
|
+
# maxClients: 10000
|
|
83
107
|
`;
|
|
84
108
|
}
|
|
85
109
|
function generateDbConfig(cfg) {
|
|
@@ -87,25 +111,19 @@ function generateDbConfig(cfg) {
|
|
|
87
111
|
const database = cfg?.database ?? (dbType === "sqlite" ? "./data/app.db" : "hai");
|
|
88
112
|
const host = cfg?.host ?? "localhost";
|
|
89
113
|
const port = cfg?.port ?? (dbType === "postgresql" ? 5432 : 3306);
|
|
90
|
-
if (dbType === "sqlite") {
|
|
91
|
-
return `# =============================================================================
|
|
92
|
-
# \u6570\u636E\u5E93\u914D\u7F6E
|
|
93
|
-
# =============================================================================
|
|
94
|
-
|
|
95
|
-
# \u6570\u636E\u5E93\u7C7B\u578B: sqlite | postgresql | mysql
|
|
96
|
-
type: sqlite
|
|
97
|
-
|
|
98
|
-
# SQLite \u6570\u636E\u5E93\u8DEF\u5F84
|
|
99
|
-
database: ${database}
|
|
100
|
-
|
|
101
|
-
# PostgreSQL/MySQL \u914D\u7F6E\uFF08\u53EF\u9009\uFF09
|
|
102
|
-
# host: localhost
|
|
103
|
-
# port: 5432
|
|
104
|
-
# user: postgres
|
|
105
|
-
# password: ''
|
|
106
|
-
`;
|
|
107
|
-
}
|
|
108
114
|
const user = dbType === "postgresql" ? "postgres" : "root";
|
|
115
|
+
const connection = stringify({ host, port, user, password: "" }).trim();
|
|
116
|
+
const networkOptions = `# url: \${HAI_DB_URL} # \u53EF\u7528\u8FDE\u63A5\u4E32\u66FF\u4EE3 host/port/user/password
|
|
117
|
+
# ssl: false # false | true | require | prefer | allow | disable\uFF0C\u6216 TLS \u5BF9\u8C61
|
|
118
|
+
# pool:
|
|
119
|
+
# min: 1
|
|
120
|
+
# max: 10
|
|
121
|
+
# idleTimeout: 30000
|
|
122
|
+
# acquireTimeout: 10000
|
|
123
|
+
# MySQL \u4E13\u7528\uFF1BPostgreSQL \u65E0\u9700\u6B64\u5757\u3002
|
|
124
|
+
# mysql:
|
|
125
|
+
# charset: utf8mb4
|
|
126
|
+
# timezone: '+08:00'`;
|
|
109
127
|
return `# =============================================================================
|
|
110
128
|
# \u6570\u636E\u5E93\u914D\u7F6E
|
|
111
129
|
# =============================================================================
|
|
@@ -113,48 +131,68 @@ database: ${database}
|
|
|
113
131
|
# \u6570\u636E\u5E93\u7C7B\u578B: sqlite | postgresql | mysql
|
|
114
132
|
type: ${dbType}
|
|
115
133
|
|
|
116
|
-
# \u6570\u636E\u5E93\u540D\u79F0
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
# SQLite \u4F7F\u7528\u6587\u4EF6\u8DEF\u5F84\uFF0CPostgreSQL/MySQL \u4F7F\u7528\u6570\u636E\u5E93\u540D\u79F0\u3002
|
|
135
|
+
${stringify({ database }).trim()}
|
|
136
|
+
|
|
137
|
+
${dbType === "sqlite" ? `# SQLite \u9A71\u52A8\u9009\u9879\uFF1Bworker \u5C06\u67E5\u8BE2\u79FB\u5230\u5DE5\u4F5C\u7EBF\u7A0B\u3002
|
|
138
|
+
# sqlite:
|
|
139
|
+
# walMode: true
|
|
140
|
+
# readonly: false
|
|
141
|
+
# executor: sync # sync | worker
|
|
142
|
+
# workerConnectTimeoutMs: 10000
|
|
143
|
+
|
|
144
|
+
# \u5207\u6362\u5230 PostgreSQL/MySQL \u65F6\u4FEE\u6539 type\u3001database\uFF0C\u5E76\u53D6\u6D88\u8FDE\u63A5\u9879\u7684\u6CE8\u91CA\u3002
|
|
145
|
+
${stringify({ host: "localhost", port: 5432, user: "postgres", password: "" }).trim().split("\n").map((line) => `# ${line}`).join("\n")}` : `# \u7F51\u7EDC\u6570\u636E\u5E93\u8FDE\u63A5\uFF1B\u51ED\u636E\u901A\u8FC7\u73AF\u5883\u53D8\u91CF\u6CE8\u5165\u3002
|
|
146
|
+
${connection}
|
|
147
|
+
# SQLite \u66FF\u4EE3\u65B9\u6848\uFF1Atype: sqlite\uFF0Cdatabase: ./data/app.db
|
|
148
|
+
# sqlite:
|
|
149
|
+
# walMode: true
|
|
150
|
+
# readonly: false
|
|
151
|
+
# executor: sync
|
|
152
|
+
# workerConnectTimeoutMs: 10000`}
|
|
153
|
+
${networkOptions}
|
|
154
|
+
|
|
155
|
+
# SQL \u65E5\u5FD7\u6309\u9700\u5F00\u542F\uFF1BmaxLength \u9650\u5236 SQL / \u53C2\u6570\u8F93\u51FA\u957F\u5EA6\u3002
|
|
156
|
+
# operationLog:
|
|
157
|
+
# read: false
|
|
158
|
+
# write: false
|
|
159
|
+
# maxLength: 1000
|
|
160
|
+
# level: debug # trace | debug | info
|
|
124
161
|
`;
|
|
125
162
|
}
|
|
126
163
|
function generateCacheConfig(cfg) {
|
|
127
164
|
const cacheType = cfg?.type ?? "memory";
|
|
128
|
-
if (cacheType === "memory") {
|
|
129
|
-
return `# =============================================================================
|
|
130
|
-
# \u7F13\u5B58\u914D\u7F6E
|
|
131
|
-
# =============================================================================
|
|
132
|
-
|
|
133
|
-
# \u7F13\u5B58\u7C7B\u578B: memory | redis
|
|
134
|
-
type: memory
|
|
135
|
-
|
|
136
|
-
# Redis \u914D\u7F6E\uFF08\u5F53 type \u4E3A redis \u65F6\u4F7F\u7528\uFF09
|
|
137
|
-
# url: redis://localhost:6379/0
|
|
138
|
-
# host: localhost
|
|
139
|
-
# port: 6379
|
|
140
|
-
# password: ''
|
|
141
|
-
# keyPrefix: 'hai:'
|
|
142
|
-
`;
|
|
143
|
-
}
|
|
144
165
|
const host = cfg?.host ?? "localhost";
|
|
145
166
|
const port = cfg?.port ?? 6379;
|
|
167
|
+
const connection = stringify({ host, port, password: "", keyPrefix: "hai:" }).trim();
|
|
146
168
|
return `# =============================================================================
|
|
147
169
|
# \u7F13\u5B58\u914D\u7F6E
|
|
148
170
|
# =============================================================================
|
|
149
171
|
|
|
150
172
|
# \u7F13\u5B58\u7C7B\u578B: memory | redis
|
|
151
|
-
type:
|
|
173
|
+
type: ${cacheType}
|
|
152
174
|
|
|
153
|
-
# Redis \u914D\u7F6E
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
175
|
+
# Redis \u914D\u7F6E\uFF1Bmemory \u65F6\u5747\u4E0D\u751F\u6548\uFF0C\u5207\u6362 type \u540E\u53D6\u6D88\u9700\u8981\u7684\u6CE8\u91CA\u3002
|
|
176
|
+
${cacheType === "redis" ? connection : connection.split("\n").map((line) => `# ${line}`).join("\n")}
|
|
177
|
+
# url: redis://localhost:6379/0
|
|
178
|
+
# db: 0
|
|
179
|
+
# connectTimeout: 10000
|
|
180
|
+
# commandTimeout: 5000
|
|
181
|
+
# tls: false
|
|
182
|
+
# maxRetries: 3
|
|
183
|
+
# retryDelay: 50
|
|
184
|
+
# readOnly: false
|
|
185
|
+
# \u96C6\u7FA4\u4E0E Sentinel \u4E8C\u9009\u4E00\uFF1B\u666E\u901A Redis \u4E0D\u9700\u8981\u8FD9\u4E24\u5757\u3002
|
|
186
|
+
# cluster:
|
|
187
|
+
# - host: redis-1.internal
|
|
188
|
+
# port: 6379
|
|
189
|
+
# - host: redis-2.internal
|
|
190
|
+
# port: 6379
|
|
191
|
+
# sentinel:
|
|
192
|
+
# sentinels:
|
|
193
|
+
# - host: sentinel.internal
|
|
194
|
+
# port: 26379
|
|
195
|
+
# name: mymaster
|
|
158
196
|
`;
|
|
159
197
|
}
|
|
160
198
|
function generateIamConfig(cfg) {
|
|
@@ -169,6 +207,69 @@ login:
|
|
|
169
207
|
password: ${loginPassword}
|
|
170
208
|
otp: ${loginOtp}
|
|
171
209
|
ldap: false
|
|
210
|
+
apikey: false
|
|
211
|
+
|
|
212
|
+
# \u6CE8\u518C\u4E0E\u767B\u5F55\u5B89\u5168
|
|
213
|
+
register:
|
|
214
|
+
enabled: true
|
|
215
|
+
defaultEnabled: true
|
|
216
|
+
security:
|
|
217
|
+
maxLoginAttempts: 5
|
|
218
|
+
lockoutDuration: 900
|
|
219
|
+
|
|
220
|
+
# LDAP \u53EF\u9009\uFF1A\u5B89\u88C5 ldapts \u540E\u5F00\u542F login.ldap\uFF1B\u4E5F\u53EF\u5728 iam.init \u4E2D\u6CE8\u5165 ldapClientFactory\u3002
|
|
221
|
+
# ldap:
|
|
222
|
+
# url: ldaps://ldap.example.com:636
|
|
223
|
+
# bindDn: cn=service,dc=example,dc=com
|
|
224
|
+
# bindPassword: \${HAI_IAM_LDAP_BINDPASSWORD}
|
|
225
|
+
# searchBase: ou=users,dc=example,dc=com
|
|
226
|
+
# searchFilter: '(uid={{username}})'
|
|
227
|
+
# usernameAttribute: uid
|
|
228
|
+
# emailAttribute: mail
|
|
229
|
+
# displayNameAttribute: cn
|
|
230
|
+
# useTls: false # ldap:// \u8FDE\u63A5\u53EF\u5F00\u542F STARTTLS\uFF1Bldaps:// \u5DF2\u4F7F\u7528 TLS
|
|
231
|
+
# connectTimeout: 5000
|
|
232
|
+
# API Key \u767B\u5F55\u53EF\u9009\uFF1B\u5BC6\u94A5\u7BA1\u7406\u5165\u53E3\u7531\u5E94\u7528\u6309\u6743\u9650\u63A5\u5165\u3002
|
|
233
|
+
# apikey:
|
|
234
|
+
# maxKeysPerUser: 10
|
|
235
|
+
# defaultExpirationDays: 0 # 0 \u8868\u793A\u4E0D\u9650\u5236\u6709\u6548\u671F
|
|
236
|
+
# prefix: hai_
|
|
237
|
+
# OTP \u9700\u542F\u7528 login.otp\uFF0C\u5E76\u9009\u62E9 Reach \u6807\u51C6\u6A21\u677F\u6216\u81EA\u5B9A\u4E49\u53D1\u9001\u56DE\u8C03\u3002
|
|
238
|
+
${(loginOtp ? "" : "# \u4FDD\u7559\u9ED8\u8BA4\u7B56\u7565\u5165\u53E3\uFF0C\u5355\u72EC\u5207\u6362 login.otp \u5373\u53EF\u542F\u7528\u9A8C\u8BC1\u7801\u767B\u5F55\u3002\notp: {}\n# \u5B9A\u5236\u7B56\u7565\u65F6\u7528\u4E0B\u65B9\u914D\u7F6E\u5757\u66FF\u6362\u7A7A\u5BF9\u8C61\uFF0C\u6216\u901A\u8FC7 HAI_IAM_OTP \u6574\u4F53\u8986\u76D6\u3002\n") + `otp:
|
|
239
|
+
email: true
|
|
240
|
+
sms: true
|
|
241
|
+
length: 6
|
|
242
|
+
expiresIn: 300
|
|
243
|
+
maxAttempts: 3
|
|
244
|
+
resendInterval: 60`.split("\n").map((line) => loginOtp ? line : `# ${line}`).join("\n")}
|
|
245
|
+
passwordReset:
|
|
246
|
+
enabled: true
|
|
247
|
+
mode: email # phone \u4F7F\u7528 password_reset_sms \u6A21\u677F
|
|
248
|
+
tokenExpiresIn: 3600
|
|
249
|
+
maxAttempts: 3
|
|
250
|
+
# resetUrl: https://example.com/auth/reset-password
|
|
251
|
+
agreements:
|
|
252
|
+
showOnRegister: true
|
|
253
|
+
showOnLogin: false
|
|
254
|
+
# \u7528 | \u914D\u7F6E Markdown \u6B63\u6587\uFF1B\u540C\u4E3B\u9898\u540C\u65F6\u63D0\u4F9B URL \u65F6\u4F18\u5148\u663E\u793A\u6B63\u6587\u3002
|
|
255
|
+
userAgreementMarkdown: |
|
|
256
|
+
# \u7528\u6237\u534F\u8BAE\u793A\u4F8B
|
|
257
|
+
|
|
258
|
+
\u8BF7\u59A5\u5584\u4FDD\u7BA1\u8D26\u6237\u51ED\u636E\uFF0C\u5E76\u6309\u5E94\u7528\u63D0\u4F9B\u7684\u529F\u80FD\u4F7F\u7528\u670D\u52A1\u3002
|
|
259
|
+
privacyPolicyMarkdown: |
|
|
260
|
+
# \u9690\u79C1\u653F\u7B56\u793A\u4F8B
|
|
261
|
+
|
|
262
|
+
\u6CE8\u518C\u8D44\u6599\u7528\u4E8E\u8D26\u6237\u7BA1\u7406\uFF0C\u4F1A\u8BDD\u4FE1\u606F\u7528\u4E8E\u8EAB\u4EFD\u8BA4\u8BC1\u3002
|
|
263
|
+
# userAgreementUrl: https://example.com/terms
|
|
264
|
+
# privacyPolicyUrl: https://example.com/privacy
|
|
265
|
+
ui:
|
|
266
|
+
variant: card
|
|
267
|
+
# title: Account center
|
|
268
|
+
# subtitle: Welcome back
|
|
269
|
+
# brandTitle: Your application
|
|
270
|
+
# brandText: Sign in securely
|
|
271
|
+
# logoUrl: /logo.svg
|
|
272
|
+
# illustrationUrl: /auth-illustration.svg
|
|
172
273
|
|
|
173
274
|
# \u5BC6\u7801\u7B56\u7565
|
|
174
275
|
password:
|
|
@@ -178,6 +279,7 @@ password:
|
|
|
178
279
|
requireLowercase: false
|
|
179
280
|
requireNumber: false
|
|
180
281
|
requireSpecialChar: false
|
|
282
|
+
expirationDays: 0 # 0 \u8868\u793A\u4E0D\u9650\u5236\u5BC6\u7801\u6709\u6548\u671F
|
|
181
283
|
|
|
182
284
|
# \u4F1A\u8BDD\u914D\u7F6E
|
|
183
285
|
session:
|
|
@@ -188,6 +290,8 @@ session:
|
|
|
188
290
|
|
|
189
291
|
# RBAC \u914D\u7F6E
|
|
190
292
|
rbac:
|
|
293
|
+
enabled: true
|
|
294
|
+
superAdminRole: super_admin
|
|
191
295
|
defaultRole: user
|
|
192
296
|
|
|
193
297
|
# \u662F\u5426\u81EA\u52A8\u521B\u5EFA\u9ED8\u8BA4\u6570\u636E
|
|
@@ -195,24 +299,35 @@ seedDefaultData: true
|
|
|
195
299
|
`;
|
|
196
300
|
}
|
|
197
301
|
function generateStorageConfig(cfg) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
return `# S3 \u5B58\u50A8\u914D\u7F6E
|
|
205
|
-
type: s3
|
|
206
|
-
bucket: ''
|
|
302
|
+
const type = cfg?.type ?? "local";
|
|
303
|
+
const local = `${stringify({ root: cfg?.localPath ?? "./data/uploads" }).trim()}
|
|
304
|
+
# directoryMode: 493 # 0o755
|
|
305
|
+
# fileMode: 420 # 0o644`;
|
|
306
|
+
const s3 = `bucket: ''
|
|
207
307
|
region: us-east-1
|
|
208
308
|
accessKeyId: ''
|
|
209
309
|
secretAccessKey: ''
|
|
210
|
-
endpoint: https://s3.amazonaws.com
|
|
211
|
-
forcePathStyle: false
|
|
310
|
+
# endpoint: https://s3.amazonaws.com
|
|
311
|
+
# forcePathStyle: false
|
|
312
|
+
# prefix: ''
|
|
313
|
+
# publicUrl: https://cdn.example.com`;
|
|
314
|
+
return `# \u5B58\u50A8\u914D\u7F6E\uFF1BHAI_STORAGE \u53EF\u6574\u4F53\u66FF\u6362\u8FDE\u63A5\u914D\u7F6E\u3002
|
|
315
|
+
type: ${type}
|
|
316
|
+
${type === "local" ? local : s3}
|
|
317
|
+
|
|
318
|
+
# \u5207\u6362 type \u540E\u4F7F\u7528\u53E6\u4E00\u79CD\u5B58\u50A8\u7684\u8FDE\u63A5\u9879\u3002
|
|
319
|
+
${(type === "local" ? s3 : local).split("\n").map((line) => line.startsWith("#") ? line : `# ${line}`).join("\n")}
|
|
320
|
+
|
|
321
|
+
# operationLog:
|
|
322
|
+
# read: false
|
|
323
|
+
# write: false
|
|
324
|
+
# maxLength: 1000
|
|
325
|
+
# level: debug # trace | debug | info
|
|
212
326
|
`;
|
|
213
327
|
}
|
|
214
328
|
function generateAiConfig(cfg) {
|
|
215
329
|
const model = cfg?.model ?? "gpt-4o-mini";
|
|
330
|
+
const api = cfg?.defaultProvider === "anthropic" ? "anthropic" : "chat";
|
|
216
331
|
return `# =============================================================================
|
|
217
332
|
# AI \u914D\u7F6E
|
|
218
333
|
# =============================================================================
|
|
@@ -224,18 +339,26 @@ llm:
|
|
|
224
339
|
# Base URL\uFF08\u7EA6\u5B9A\u73AF\u5883\u53D8\u91CF HAI_AI_LLM_BASEURL \u4F18\u5148\uFF09
|
|
225
340
|
# baseUrl: https://api.openai.com/v1
|
|
226
341
|
# \u9ED8\u8BA4\u6A21\u578B
|
|
227
|
-
|
|
342
|
+
${stringify({ model }).trim().split("\n").map((line) => ` ${line}`).join("\n")}
|
|
343
|
+
api: ${api} # chat | responses | anthropic
|
|
228
344
|
# \u5168\u5C40\u6700\u5927 Token \u6570\uFF08\u9ED8\u8BA4 4096\uFF09
|
|
229
345
|
# maxTokens: 4096
|
|
230
346
|
# \u91C7\u6837\u6E29\u5EA6\uFF080-2\uFF0C\u9ED8\u8BA4 0.7\uFF09
|
|
231
347
|
# temperature: 0.7
|
|
232
348
|
# \u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 60000\uFF09
|
|
233
349
|
# timeout: 60000
|
|
350
|
+
# tempModelCacheTtl: 600000
|
|
234
351
|
|
|
235
352
|
# \u591A\u6A21\u578B\u914D\u7F6E\uFF08\u53EF\u9009\uFF0C\u7528\u4E8E\u573A\u666F\u8DEF\u7531\uFF09
|
|
236
353
|
# models:
|
|
237
354
|
# - id: fast
|
|
238
355
|
# model: gpt-4o-mini
|
|
356
|
+
# api: chat
|
|
357
|
+
# apiKey: ''
|
|
358
|
+
# baseUrl: https://api.openai.com/v1
|
|
359
|
+
# maxTokens: 4096
|
|
360
|
+
# temperature: 0.7
|
|
361
|
+
# timeout: 60000
|
|
239
362
|
# - id: smart
|
|
240
363
|
# model: gpt-4o
|
|
241
364
|
# apiKey: ''
|
|
@@ -243,10 +366,134 @@ llm:
|
|
|
243
366
|
# \u573A\u666F\u6A21\u578B\u6620\u5C04\uFF08\u53EF\u9009\uFF09
|
|
244
367
|
# scenarios:
|
|
245
368
|
# default: fast
|
|
246
|
-
#
|
|
369
|
+
# chat: fast
|
|
370
|
+
# reasoning: smart
|
|
371
|
+
# plan: smart
|
|
372
|
+
# execute: fast
|
|
373
|
+
# extraction: fast
|
|
374
|
+
# summary: fast
|
|
375
|
+
# embedding: embedding
|
|
376
|
+
# rerank: rerank
|
|
377
|
+
# ocr: vision
|
|
378
|
+
# fast: fast
|
|
379
|
+
# embedding / rerank / vision \u987B\u5728 models \u4E2D\u58F0\u660E\u5BF9\u5E94\u5382\u5546\u6A21\u578B\uFF0C\u4E0D\u80FD\u53EA\u586B\u5199\u573A\u666F ID\u3002
|
|
380
|
+
|
|
381
|
+
# \u53EF\u9009\u5B50\u6A21\u5757\uFF1A\u53EA\u53D6\u6D88\u9700\u8981\u7684\u5757\u7684\u6CE8\u91CA\uFF0C\u6A21\u578B\u3001\u5411\u91CF\u5E93\u4E0E\u6570\u636E\u5E93\u4F9D\u8D56\u6309\u4F7F\u7528\u573A\u666F\u521D\u59CB\u5316\u3002
|
|
382
|
+
# mcp:
|
|
383
|
+
# server:
|
|
384
|
+
# name: my-app
|
|
385
|
+
# version: 1.0.0
|
|
386
|
+
# capabilities:
|
|
387
|
+
# tools: true
|
|
388
|
+
# resources: true
|
|
389
|
+
# prompts: true
|
|
390
|
+
# embedding:
|
|
391
|
+
# dimensions: 1536
|
|
392
|
+
# batchSize: 100
|
|
393
|
+
# knowledge:
|
|
394
|
+
# collection: hai_ai_knowledge
|
|
395
|
+
# dimension: 1536
|
|
396
|
+
# enableEntityExtraction: true
|
|
397
|
+
# entityBoostWeight: 0.15
|
|
398
|
+
# entityTypes: [person, organization, location]
|
|
399
|
+
# systemPrompt: 'Extract entities from the input.'
|
|
400
|
+
# cleanOptions:
|
|
401
|
+
# removeHtml: true
|
|
402
|
+
# removeUrls: false
|
|
403
|
+
# removeEmails: false
|
|
404
|
+
# normalizeWhitespace: true
|
|
405
|
+
# trim: true
|
|
406
|
+
# customReplacements:
|
|
407
|
+
# - pattern: '\\t+'
|
|
408
|
+
# replacement: ' '
|
|
409
|
+
# chunkOptions:
|
|
410
|
+
# mode: markdown # sentence | paragraph | markdown | page | word | character | custom
|
|
411
|
+
# maxSize: 1500
|
|
412
|
+
# overlap: 200
|
|
413
|
+
# separator: '\\n\\n' # \u4EC5 custom \u6A21\u5F0F\u4F7F\u7528
|
|
414
|
+
# markdownMinLevel: 2
|
|
415
|
+
# markdownKeepTitle: true
|
|
416
|
+
# memory:
|
|
417
|
+
# provider: native # native | mem0
|
|
418
|
+
# allowEphemeralFallback: false
|
|
419
|
+
# maxEntriesPerObject: 1000
|
|
420
|
+
# maxEntriesGlobal: 100000
|
|
421
|
+
# systemPrompt: 'Extract useful memories from the conversation.'
|
|
422
|
+
# recencyDecay: 0.95
|
|
423
|
+
# embeddingEnabled: true
|
|
424
|
+
# defaultTopK: 10
|
|
425
|
+
# candidateMultiplier: 5
|
|
426
|
+
# writebackRelatedTopK: 20
|
|
427
|
+
# token:
|
|
428
|
+
# tokenRatio: 0.25
|
|
429
|
+
# summary:
|
|
430
|
+
# systemPrompt: 'Summarize the conversation.'
|
|
431
|
+
# compress:
|
|
432
|
+
# defaultStrategy: hybrid # summary | sliding-window | hybrid
|
|
433
|
+
# defaultMaxTokens: 0
|
|
434
|
+
# preserveLastN: 4
|
|
435
|
+
# retrieval:
|
|
436
|
+
# sources:
|
|
437
|
+
# - id: docs
|
|
438
|
+
# collection: documentation
|
|
439
|
+
# name: Product documentation
|
|
440
|
+
# url: https://docs.example.com
|
|
441
|
+
# topK: 5
|
|
442
|
+
# minScore: 0.7
|
|
443
|
+
# filter:
|
|
444
|
+
# published: true
|
|
445
|
+
# file:
|
|
446
|
+
# systemPrompt: 'Extract text from the image.'
|
|
447
|
+
# a2a:
|
|
448
|
+
# agentCard:
|
|
449
|
+
# name: my-agent
|
|
450
|
+
# description: Application agent
|
|
451
|
+
# url: https://agent.example.com
|
|
452
|
+
# version: 1.0.0
|
|
453
|
+
# skills:
|
|
454
|
+
# - id: chat
|
|
455
|
+
# name: Chat
|
|
456
|
+
# description: General conversation
|
|
457
|
+
# tags: [chat]
|
|
458
|
+
# security:
|
|
459
|
+
# apiKey:
|
|
460
|
+
# in: header # header | query
|
|
461
|
+
# name: x-api-key
|
|
462
|
+
# audio:
|
|
463
|
+
# inheritLlmApiKey: false
|
|
464
|
+
# transcribeModel: asr
|
|
465
|
+
# synthesizeModel: tts
|
|
466
|
+
# maxAudioBytes: 10485760
|
|
467
|
+
# maxStreamDurationMs: 300000
|
|
468
|
+
# models:
|
|
469
|
+
# - id: asr
|
|
470
|
+
# provider: openai # openai | mimo | qwen | doubao | whisper | indextts
|
|
471
|
+
# model: whisper-1
|
|
472
|
+
# operations: [transcribe]
|
|
473
|
+
# apiKey: ''
|
|
474
|
+
# baseUrl: https://api.openai.com/v1
|
|
475
|
+
# timeout: 60000
|
|
476
|
+
# appKey: '' # \u8C46\u5305\u65E7\u7248\u63A7\u5236\u53F0 ASR \u4F7F\u7528
|
|
477
|
+
# accessKey: ''
|
|
478
|
+
# resourceId: ''
|
|
479
|
+
# workspaceId: '' # \u767E\u70BC\u4E1A\u52A1\u7A7A\u95F4
|
|
480
|
+
# - id: tts
|
|
481
|
+
# provider: openai
|
|
482
|
+
# model: tts-1
|
|
483
|
+
# operations: [synthesize]
|
|
484
|
+
# image:
|
|
485
|
+
# generateModel: image
|
|
486
|
+
# models:
|
|
487
|
+
# - id: image
|
|
488
|
+
# provider: openai # openai | google | qwen | seedream | pollinations
|
|
489
|
+
# model: gpt-image-1
|
|
490
|
+
# apiKey: ''
|
|
491
|
+
# baseUrl: https://api.openai.com/v1
|
|
492
|
+
# workspaceId: ''
|
|
493
|
+
# timeout: 120000
|
|
247
494
|
`;
|
|
248
495
|
}
|
|
249
|
-
function generateEnvExample(features, configs) {
|
|
496
|
+
function generateEnvExample(features, configs, includeDisabled = false) {
|
|
250
497
|
const sections = [];
|
|
251
498
|
sections.push(`# =============================================================================
|
|
252
499
|
# Environment Variables
|
|
@@ -254,6 +501,7 @@ function generateEnvExample(features, configs) {
|
|
|
254
501
|
#
|
|
255
502
|
# Copy this file to .env and fill in actual values.
|
|
256
503
|
# Config files use literal defaults; matching HAI variables override YAML leaves.
|
|
504
|
+
# Uncomment the matching YAML keys before using leaf overrides; HAI_<module> replaces the whole object.
|
|
257
505
|
#
|
|
258
506
|
# Naming convention: HAI_<config name>_<YAML path>
|
|
259
507
|
# =============================================================================`);
|
|
@@ -265,7 +513,7 @@ function generateEnvExample(features, configs) {
|
|
|
265
513
|
HAI_CORE_ENV=development
|
|
266
514
|
# Enable debug mode
|
|
267
515
|
HAI_CORE_DEBUG=false`);
|
|
268
|
-
if (features.includes("db")) {
|
|
516
|
+
if (features.includes("db") || includeDisabled) {
|
|
269
517
|
const dbType = configs?.db?.type ?? "sqlite";
|
|
270
518
|
const dbDatabase = configs?.db?.database ?? (dbType === "sqlite" ? "./data/app.db" : "hai");
|
|
271
519
|
const isSqlite = dbType === "sqlite";
|
|
@@ -288,7 +536,7 @@ HAI_DB_PORT=${configs?.db?.port ?? (dbType === "postgresql" ? 5432 : 3306)}
|
|
|
288
536
|
HAI_DB_USER=${dbType === "postgresql" ? "postgres" : "root"}
|
|
289
537
|
HAI_DB_PASSWORD=`}`);
|
|
290
538
|
}
|
|
291
|
-
if (features.includes("iam")) {
|
|
539
|
+
if (features.includes("iam") || includeDisabled) {
|
|
292
540
|
sections.push(`
|
|
293
541
|
# =============================================================================
|
|
294
542
|
# IAM (@h-ai/iam)
|
|
@@ -296,10 +544,13 @@ HAI_DB_PASSWORD=`}`);
|
|
|
296
544
|
# HAI_IAM_PASSWORD_MINLENGTH=8
|
|
297
545
|
# HAI_IAM_SESSION_MAXAGE=86400
|
|
298
546
|
# HAI_IAM_SESSION_REFRESHTOKENMAXAGE=604800
|
|
547
|
+
# HAI_IAM_OTP={"email":true,"sms":true,"length":6,"expiresIn":300,"maxAttempts":3,"resendInterval":60}
|
|
548
|
+
# HAI_IAM_LDAP_BINDPASSWORD= # Enable login.ldap and uncomment the ldap block first.
|
|
549
|
+
# HAI_IAM_PASSWORDRESET_RESETURL=https://app.example.com/auth/reset-password
|
|
299
550
|
# HAI_KIT_COOKIE_KEY= # 32-char hex for SM4-CBC cookie encryption
|
|
300
551
|
`);
|
|
301
552
|
}
|
|
302
|
-
if (features.includes("cache")) {
|
|
553
|
+
if (features.includes("cache") || includeDisabled) {
|
|
303
554
|
const cacheType = configs?.cache?.type ?? "memory";
|
|
304
555
|
if (cacheType === "redis") {
|
|
305
556
|
sections.push(`
|
|
@@ -314,9 +565,9 @@ HAI_CACHE_PORT=${configs?.cache?.port ?? 6379}
|
|
|
314
565
|
HAI_CACHE_PASSWORD=
|
|
315
566
|
# HAI_CACHE_URL=redis://localhost:6379/0
|
|
316
567
|
# HAI_CACHE_DB=0
|
|
317
|
-
#
|
|
318
|
-
#
|
|
319
|
-
#
|
|
568
|
+
# HAI_CACHE_CONNECTTIMEOUT=10000
|
|
569
|
+
# HAI_CACHE_COMMANDTIMEOUT=5000
|
|
570
|
+
# HAI_CACHE_KEYPREFIX=hai:`);
|
|
320
571
|
} else {
|
|
321
572
|
sections.push(`
|
|
322
573
|
# =============================================================================
|
|
@@ -330,12 +581,12 @@ HAI_CACHE_TYPE=memory
|
|
|
330
581
|
# HAI_CACHE_PORT=6379
|
|
331
582
|
# HAI_CACHE_PASSWORD=
|
|
332
583
|
# HAI_CACHE_DB=0
|
|
333
|
-
#
|
|
334
|
-
#
|
|
335
|
-
#
|
|
584
|
+
# HAI_CACHE_CONNECTTIMEOUT=10000
|
|
585
|
+
# HAI_CACHE_COMMANDTIMEOUT=5000
|
|
586
|
+
# HAI_CACHE_KEYPREFIX=hai:`);
|
|
336
587
|
}
|
|
337
588
|
}
|
|
338
|
-
if (features.includes("storage")) {
|
|
589
|
+
if (features.includes("storage") || includeDisabled) {
|
|
339
590
|
const storageType = configs?.storage?.type ?? "local";
|
|
340
591
|
if (storageType === "s3") {
|
|
341
592
|
sections.push(`
|
|
@@ -371,46 +622,23 @@ HAI_STORAGE_ROOT=${configs?.storage?.localPath ?? "./data/uploads"}
|
|
|
371
622
|
# HAI_STORAGE_FORCEPATHSTYLE=false`);
|
|
372
623
|
}
|
|
373
624
|
}
|
|
374
|
-
if (features.includes("ai")) {
|
|
375
|
-
|
|
376
|
-
if (provider === "anthropic") {
|
|
377
|
-
sections.push(`
|
|
378
|
-
# =============================================================================
|
|
379
|
-
# AI (@h-ai/ai)
|
|
380
|
-
# =============================================================================
|
|
381
|
-
# OpenAI-compatible API Key (Anthropic models via OpenAI-compatible proxy)
|
|
382
|
-
HAI_AI_LLM_APIKEY=
|
|
383
|
-
# HAI_AI_LLM_BASEURL= # Custom base URL
|
|
384
|
-
# Optional compatibility fallback
|
|
385
|
-
# OPENAI_API_KEY=`);
|
|
386
|
-
} else if (provider === "openai") {
|
|
387
|
-
sections.push(`
|
|
388
|
-
# =============================================================================
|
|
389
|
-
# AI (@h-ai/ai)
|
|
390
|
-
# =============================================================================
|
|
391
|
-
# OpenAI / OpenAI-compatible
|
|
392
|
-
HAI_AI_LLM_APIKEY=
|
|
393
|
-
# HAI_AI_LLM_BASEURL= # Custom base URL (e.g. local proxy, Azure)
|
|
394
|
-
# Optional compatibility fallback
|
|
395
|
-
# OPENAI_API_KEY=`);
|
|
396
|
-
} else {
|
|
397
|
-
sections.push(`
|
|
625
|
+
if (features.includes("ai") || includeDisabled) {
|
|
626
|
+
sections.push(`
|
|
398
627
|
# =============================================================================
|
|
399
628
|
# AI (@h-ai/ai)
|
|
400
629
|
# =============================================================================
|
|
401
|
-
#
|
|
630
|
+
# Select chat / responses / anthropic in _ai.yml (llm.api).
|
|
402
631
|
HAI_AI_LLM_APIKEY=
|
|
403
632
|
# HAI_AI_LLM_BASEURL= # Custom base URL
|
|
404
633
|
# Optional compatibility fallback
|
|
405
634
|
# OPENAI_API_KEY=`);
|
|
406
|
-
}
|
|
407
635
|
}
|
|
408
|
-
if (features.includes("vecdb")) {
|
|
636
|
+
if (features.includes("vecdb") || includeDisabled) {
|
|
409
637
|
sections.push(`
|
|
410
638
|
# =============================================================================
|
|
411
639
|
# Vector Database (@h-ai/vecdb)
|
|
412
640
|
# =============================================================================
|
|
413
|
-
# Backend type: lancedb | pgvector | qdrant
|
|
641
|
+
# Backend type: lancedb | pgvector | qdrant | chroma
|
|
414
642
|
HAI_VECDB_TYPE=lancedb
|
|
415
643
|
# LanceDB data path
|
|
416
644
|
HAI_VECDB_PATH=./data/vecdb
|
|
@@ -419,7 +647,7 @@ HAI_VECDB_PATH=./data/vecdb
|
|
|
419
647
|
# HAI_VECDB_APIKEY=
|
|
420
648
|
`);
|
|
421
649
|
}
|
|
422
|
-
if (features.includes("reach")) {
|
|
650
|
+
if (features.includes("reach") || includeDisabled) {
|
|
423
651
|
sections.push(`
|
|
424
652
|
# =============================================================================
|
|
425
653
|
# Reach (@h-ai/reach)
|
|
@@ -430,9 +658,13 @@ HAI_VECDB_PATH=./data/vecdb
|
|
|
430
658
|
# HAI_REACH_SMTP_USER=
|
|
431
659
|
# HAI_REACH_SMTP_PASS=
|
|
432
660
|
# HAI_REACH_SMTP_FROM=noreply@example.com
|
|
661
|
+
# HAI_REACH_SMS_ACCESS_KEY=
|
|
662
|
+
# HAI_REACH_SMS_SECRET_KEY=
|
|
663
|
+
# HAI_REACH_API_TOKEN=
|
|
664
|
+
# HAI_REACH_PROVIDERS= # JSON array replacing all providers, while retaining templates.
|
|
433
665
|
`);
|
|
434
666
|
}
|
|
435
|
-
if (features.includes("payment")) {
|
|
667
|
+
if (features.includes("payment") || includeDisabled) {
|
|
436
668
|
sections.push(`
|
|
437
669
|
# =============================================================================
|
|
438
670
|
# Payment (@h-ai/payment)
|
|
@@ -442,6 +674,7 @@ HAI_VECDB_PATH=./data/vecdb
|
|
|
442
674
|
# HAI_PAYMENT_WECHAT_APIV3KEY=
|
|
443
675
|
# HAI_PAYMENT_WECHAT_SERIALNO=
|
|
444
676
|
# HAI_PAYMENT_WECHAT_PRIVATEKEY=
|
|
677
|
+
# HAI_PAYMENT_WECHAT_PLATFORMCERT=
|
|
445
678
|
# HAI_PAYMENT_WECHAT_APPID=
|
|
446
679
|
# Alipay
|
|
447
680
|
# HAI_PAYMENT_ALIPAY_APPID=
|
|
@@ -450,6 +683,42 @@ HAI_VECDB_PATH=./data/vecdb
|
|
|
450
683
|
# Stripe
|
|
451
684
|
# HAI_PAYMENT_STRIPE_SECRETKEY=
|
|
452
685
|
# HAI_PAYMENT_STRIPE_WEBHOOKSECRET=
|
|
686
|
+
`);
|
|
687
|
+
}
|
|
688
|
+
if (features.includes("deploy") || includeDisabled) {
|
|
689
|
+
sections.push(`
|
|
690
|
+
# =============================================================================
|
|
691
|
+
# Deployment (@h-ai/deploy)
|
|
692
|
+
# =============================================================================
|
|
693
|
+
# HAI_DEPLOY_VERCEL_TOKEN=
|
|
694
|
+
# HAI_DEPLOY_SSH_HOST=
|
|
695
|
+
# HAI_DEPLOY_SSH_KEY=
|
|
696
|
+
# HAI_DEPLOY_SSH_KNOWNHOSTSFILE=
|
|
697
|
+
# HAI_DEPLOY_NEON_API_KEY=
|
|
698
|
+
# HAI_DEPLOY_UPSTASH_EMAIL=
|
|
699
|
+
# HAI_DEPLOY_UPSTASH_API_KEY=
|
|
700
|
+
# HAI_DEPLOY_CF_ACCOUNT_ID=
|
|
701
|
+
# HAI_DEPLOY_CF_API_TOKEN=
|
|
702
|
+
# HAI_DEPLOY_R2_ACCESS_KEY_ID=
|
|
703
|
+
# HAI_DEPLOY_R2_SECRET_ACCESS_KEY=
|
|
704
|
+
# HAI_DEPLOY_RESEND_API_KEY=
|
|
705
|
+
# HAI_DEPLOY_RESEND_FROM=
|
|
706
|
+
# HAI_DEPLOY_ALIYUN_ACCESS_KEY_ID=
|
|
707
|
+
# HAI_DEPLOY_ALIYUN_ACCESS_KEY_SECRET=
|
|
708
|
+
# HAI_DEPLOY_ALIYUN_SIGN_NAME=
|
|
709
|
+
`);
|
|
710
|
+
}
|
|
711
|
+
if (includeDisabled) {
|
|
712
|
+
sections.push(`
|
|
713
|
+
# =============================================================================
|
|
714
|
+
# Service (@h-ai/serv)
|
|
715
|
+
# =============================================================================
|
|
716
|
+
# HOST=127.0.0.1 # HOST/PORT override _serv.yml server settings.
|
|
717
|
+
# PORT=3000
|
|
718
|
+
# HAI_CORS_ORIGIN=http://127.0.0.1:4173,http://localhost:4173
|
|
719
|
+
# HAI_CORS_NATIVEORIGINS=http://localhost,https://localhost,http://tauri.localhost,https://tauri.localhost,tauri://localhost,capacitor://localhost
|
|
720
|
+
# HAI_CORS_CREDENTIALS=true
|
|
721
|
+
# HAI_SERV_HTTP_RPC_GATEWAYSECRET= # Enable the gateway-only RPC block before setting this.
|
|
453
722
|
`);
|
|
454
723
|
}
|
|
455
724
|
sections.push(`
|
|
@@ -459,7 +728,8 @@ HAI_VECDB_PATH=./data/vecdb
|
|
|
459
728
|
# E2E test mode (relaxes rate limiting etc.)
|
|
460
729
|
# HAI_E2E=1
|
|
461
730
|
`);
|
|
462
|
-
|
|
731
|
+
const content = sections.join("\n");
|
|
732
|
+
return includeDisabled ? content.split("\n").map((line) => line && !line.startsWith("#") ? `# ${line}` : line).join("\n") : content;
|
|
463
733
|
}
|
|
464
734
|
function generateDeployConfig() {
|
|
465
735
|
return `# =============================================================================
|
|
@@ -485,6 +755,9 @@ provider:
|
|
|
485
755
|
# port: 22
|
|
486
756
|
# username: deploy
|
|
487
757
|
# identityFile: \${HAI_DEPLOY_SSH_KEY} # \u79C1\u94A5\u6587\u4EF6\u8DEF\u5F84\uFF08\u7701\u7565\u5219\u7528 ssh-agent\uFF09
|
|
758
|
+
# knownHostsFile: \${HAI_DEPLOY_SSH_KNOWNHOSTSFILE}
|
|
759
|
+
# strictHostKeyChecking: true
|
|
760
|
+
# connectTimeoutSeconds: 10
|
|
488
761
|
# remote:
|
|
489
762
|
# baseDir: /opt/hai/apps
|
|
490
763
|
# runtime: auto # auto \u4F18\u5148 podman\uFF0C\u5176\u6B21 docker
|
|
@@ -498,7 +771,7 @@ provider:
|
|
|
498
771
|
# runtime: auto
|
|
499
772
|
|
|
500
773
|
# \u57FA\u7840\u8BBE\u65BD\u670D\u52A1\uFF08\u6309\u9700\u5F00\u542F\uFF09
|
|
501
|
-
services:
|
|
774
|
+
# services:
|
|
502
775
|
# PostgreSQL \u6570\u636E\u5E93 (Neon)
|
|
503
776
|
# db:
|
|
504
777
|
# provisioner: neon
|
|
@@ -542,7 +815,7 @@ function generateVecdbConfig() {
|
|
|
542
815
|
# \u5411\u91CF\u6570\u636E\u5E93\u914D\u7F6E (@h-ai/vecdb)
|
|
543
816
|
# =============================================================================
|
|
544
817
|
|
|
545
|
-
# \u6570\u636E\u5E93\u7C7B\u578B: lancedb | pgvector | qdrant
|
|
818
|
+
# \u6570\u636E\u5E93\u7C7B\u578B: lancedb | pgvector | qdrant | chroma
|
|
546
819
|
type: lancedb
|
|
547
820
|
|
|
548
821
|
# LanceDB \u6570\u636E\u76EE\u5F55
|
|
@@ -553,6 +826,7 @@ path: ./data/vecdb
|
|
|
553
826
|
|
|
554
827
|
# pgvector \u914D\u7F6E\uFF08\u5F53 type \u4E3A pgvector \u65F6\u4F7F\u7528\uFF09
|
|
555
828
|
# type: pgvector
|
|
829
|
+
# url: \${HAI_VECDB_URL}
|
|
556
830
|
# host: localhost
|
|
557
831
|
# port: 5432
|
|
558
832
|
# database: hai
|
|
@@ -565,6 +839,22 @@ path: ./data/vecdb
|
|
|
565
839
|
# type: qdrant
|
|
566
840
|
# url: http://localhost:6333
|
|
567
841
|
# apiKey: ''
|
|
842
|
+
|
|
843
|
+
# Chroma \u914D\u7F6E\uFF08\u66FF\u6362 type\uFF1Burl \u6307\u5411\u5DF2\u6709\u670D\u52A1\uFF0Cpath \u7528\u4E8E\u672C\u5730\u5B50\u8FDB\u7A0B\u6570\u636E\u76EE\u5F55\uFF09
|
|
844
|
+
# type: chroma
|
|
845
|
+
# path: ./data/chroma
|
|
846
|
+
# url: http://localhost:8000
|
|
847
|
+
# host: localhost
|
|
848
|
+
# port: 8000
|
|
849
|
+
# apiKey: ''
|
|
850
|
+
# serverCommand: chroma
|
|
851
|
+
# startupTimeout: 30000
|
|
852
|
+
|
|
853
|
+
# operationLog:
|
|
854
|
+
# read: false
|
|
855
|
+
# write: false
|
|
856
|
+
# maxLength: 1000
|
|
857
|
+
# level: debug # trace | debug | info
|
|
568
858
|
`;
|
|
569
859
|
}
|
|
570
860
|
function generateReachConfig() {
|
|
@@ -593,13 +883,35 @@ providers:
|
|
|
593
883
|
# accessKeyId: \${HAI_REACH_SMS_ACCESS_KEY}
|
|
594
884
|
# accessKeySecret: \${HAI_REACH_SMS_SECRET_KEY}
|
|
595
885
|
# signName: MyApp
|
|
596
|
-
|
|
597
|
-
|
|
886
|
+
# endpoint: dysmsapi.aliyuncs.com
|
|
887
|
+
|
|
888
|
+
# \u901A\u7528 API\uFF08\u6309\u9700\u5F00\u542F\uFF1B\u53EF\u5BF9\u63A5\u5E94\u7528\u81EA\u6709\u6295\u9012\u670D\u52A1\uFF09
|
|
889
|
+
# - name: custom
|
|
890
|
+
# type: api
|
|
891
|
+
# url: https://notify.example.com/send
|
|
892
|
+
# method: POST # POST | PUT
|
|
893
|
+
# headers:
|
|
894
|
+
# Authorization: 'Bearer \${HAI_REACH_API_TOKEN}'
|
|
895
|
+
# timeout: 10000
|
|
896
|
+
|
|
897
|
+
# IAM \u6807\u51C6\u6A21\u677F\uFF1A\u4FDD\u7559\u7A7A\u6570\u7EC4\u4EE5\u652F\u6301 HAI_REACH_TEMPLATES \u6574\u4F53\u8986\u76D6\u3002
|
|
898
|
+
templates: []
|
|
899
|
+
# \u5F00\u542F\u5BF9\u5E94 Provider \u540E\uFF0C\u5C06\u7A7A\u6570\u7EC4\u66FF\u6362\u4E3A\u9700\u8981\u7684\u6A21\u677F\u5217\u8868\uFF0C\u4F8B\u5982\uFF1A
|
|
598
900
|
# templates:
|
|
599
|
-
# - name:
|
|
901
|
+
# - name: otp_email
|
|
902
|
+
# provider: email
|
|
903
|
+
# subject: "Verification code"
|
|
904
|
+
# body: "Your verification code is {code}."
|
|
905
|
+
# - name: otp_sms
|
|
906
|
+
# provider: sms
|
|
907
|
+
# body: "Your verification code is {code}."
|
|
908
|
+
# - name: password_reset
|
|
600
909
|
# provider: email
|
|
601
|
-
# subject: "
|
|
602
|
-
# body: "
|
|
910
|
+
# subject: "Password reset"
|
|
911
|
+
# body: "Reset your password: {resetUrl}. Expires at {expiresAt}."
|
|
912
|
+
# - name: password_reset_sms
|
|
913
|
+
# provider: sms
|
|
914
|
+
# body: "Reset your password: {resetUrl}. Expires at {expiresAt}."
|
|
603
915
|
|
|
604
916
|
# \u514D\u6253\u6270\uFF08\u53EF\u9009\uFF09
|
|
605
917
|
# dnd:
|
|
@@ -617,20 +929,17 @@ function generateSchedulerConfig() {
|
|
|
617
929
|
# \u662F\u5426\u542F\u7528\u6570\u636E\u5E93\u65E5\u5FD7\uFF08\u9700\u8981 @h-ai/reldb\uFF09
|
|
618
930
|
enableDb: true
|
|
619
931
|
|
|
620
|
-
# \u6267\u884C\u65E5\u5FD7\u8868\u540D
|
|
621
|
-
tableName: hai_scheduler_logs
|
|
622
|
-
|
|
623
|
-
# \u4EFB\u52A1\u5B9A\u4E49\u8868\u540D
|
|
624
|
-
taskTableName: hai_scheduler_tasks
|
|
625
|
-
|
|
626
|
-
# \u5206\u5E03\u5F0F\u9501\u8868\u540D
|
|
627
|
-
lockTableName: hai_scheduler_locks
|
|
628
|
-
|
|
629
932
|
# \u68C0\u67E5\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09
|
|
630
933
|
tickInterval: 1000
|
|
631
934
|
|
|
632
935
|
# \u9501\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09
|
|
633
936
|
lockExpireMs: 300000
|
|
937
|
+
|
|
938
|
+
# \u8282\u70B9 ID \u9ED8\u8BA4\u81EA\u52A8\u751F\u6210\uFF1B\u591A\u8282\u70B9\u90E8\u7F72\u65F6\u6BCF\u4E2A\u5B9E\u4F8B\u5E94\u4F7F\u7528\u72EC\u7ACB ID\u3002
|
|
939
|
+
# nodeId: worker-1
|
|
940
|
+
# \u6267\u884C\u65E5\u5FD7\u4FDD\u7559\u7B56\u7565\uFF08\u542F\u7528\u6570\u636E\u5E93\u65F6\u4F7F\u7528\uFF09
|
|
941
|
+
# maxLogs: 10000
|
|
942
|
+
# retentionDays: 30
|
|
634
943
|
`;
|
|
635
944
|
}
|
|
636
945
|
function generateAuditConfig() {
|
|
@@ -659,6 +968,7 @@ function generatePaymentConfig() {
|
|
|
659
968
|
# apiV3Key: ''
|
|
660
969
|
# serialNo: ''
|
|
661
970
|
# privateKey: ''
|
|
971
|
+
# platformCert: ''
|
|
662
972
|
# appId: ''
|
|
663
973
|
|
|
664
974
|
# \u652F\u4ED8\u5B9D\uFF08\u6309\u9700\u5F00\u542F\uFF09
|
|
@@ -673,9 +983,10 @@ function generatePaymentConfig() {
|
|
|
673
983
|
# stripe:
|
|
674
984
|
# secretKey: ''
|
|
675
985
|
# webhookSecret: ''
|
|
986
|
+
# webhookToleranceSeconds: 300
|
|
676
987
|
`;
|
|
677
988
|
}
|
|
678
989
|
|
|
679
990
|
export { generateConfigFile, generateEnvExample };
|
|
680
|
-
//# sourceMappingURL=chunk-
|
|
681
|
-
//# sourceMappingURL=chunk-
|
|
991
|
+
//# sourceMappingURL=chunk-WW2MIO6T.js.map
|
|
992
|
+
//# sourceMappingURL=chunk-WW2MIO6T.js.map
|