@h-ai/cli 1.0.0-beta.2 → 1.0.0-beta.21
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 +74 -154
- package/README.ja.md +74 -154
- package/README.md +74 -154
- package/dist/{chunk-AKV2CQZV.js → chunk-2ZL5ORQ2.js} +316 -97
- package/dist/chunk-2ZL5ORQ2.js.map +1 -0
- package/dist/{chunk-EF7WOFWZ.js → chunk-L53P43B2.js} +1312 -163
- package/dist/chunk-L53P43B2.js.map +1 -0
- package/dist/cli-config-templates-LWMD2I6V.js +5 -0
- package/dist/{cli-config-templates-HHFHNXBN.js.map → cli-config-templates-LWMD2I6V.js.map} +1 -1
- package/dist/{cli-skill-templates-PN4FLGBC.js → cli-skill-templates-D6S2OQ6X.js} +3 -3
- package/dist/{cli-skill-templates-PN4FLGBC.js.map → cli-skill-templates-D6S2OQ6X.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30118 -3253
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +22 -18
- package/templates/README.md +45 -30
- package/templates/apps/admin/src/routes/+layout.svelte.hbs +16 -10
- package/templates/apps/admin/src/routes/+page.svelte.hbs +4 -4
- package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +17 -7
- package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +26 -6
- package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +2 -2
- package/templates/apps/api/.dockerignore.hbs +10 -0
- package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +8 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +6 -1
- package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +13 -5
- package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +13 -5
- package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +3 -1
- package/templates/apps/api/apps/{{projectName}}-serv/README.md.hbs +6 -2
- package/templates/apps/api/apps/{{projectName}}-serv/config/_serv.yml.hbs +24 -2
- package/templates/apps/api/apps/{{projectName}}-serv/package.json.hbs +4 -4
- package/templates/apps/api/apps/{{projectName}}-serv/src/app.ts.hbs +74 -24
- package/templates/apps/api/apps/{{projectName}}-serv/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/api/apps/{{projectName}}-serv/src/lib/server/init.ts.hbs +153 -37
- package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/index.ts.hbs +39 -13
- package/templates/apps/api/apps/{{projectName}}-serv/tests/service.test.ts.hbs +106 -33
- package/templates/apps/api/apps/{{projectName}}-serv/tsup.config.ts.hbs +3 -1
- package/templates/apps/api/apps/{{projectName}}-serv/vitest.config.ts.hbs +3 -1
- package/templates/apps/api/e2e/api-serv.spec.ts.hbs +20 -3
- package/templates/apps/api/e2e/capture-evidence.ts.hbs +4 -1
- package/templates/apps/api/eslint.config.js.hbs +3 -1
- package/templates/apps/api/images/serv.Dockerfile.hbs +15 -10
- package/templates/apps/api/playwright.config.ts.hbs +23 -19
- package/templates/apps/api/pnpm-workspace.yaml.hbs +27 -16
- package/templates/apps/fullstack/.dockerignore.hbs +10 -0
- package/templates/apps/fullstack/.gitignore.hbs +7 -2
- package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +14 -12
- package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +5 -3
- package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +10 -2
- package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +10 -2
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +4 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +16 -4
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +10 -8
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +3 -3
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +8 -2
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +0 -2
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +4 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +16 -4
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +2 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +9 -9
- package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +10 -2
- package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +0 -2
- package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +4 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +19 -5
- package/templates/apps/fullstack/docs/security-configuration.md.hbs +4 -1
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +140 -28
- package/templates/apps/fullstack/e2e/session-close.spec.ts.hbs +19 -5
- package/templates/apps/fullstack/eslint.config.js.hbs +3 -1
- package/templates/apps/fullstack/images/serv.Dockerfile.hbs +19 -11
- package/templates/apps/fullstack/images/web.Dockerfile.hbs +17 -8
- package/templates/apps/fullstack/package.json.hbs +2 -1
- package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +7 -5
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +114 -23
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +57 -11
- package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +3 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +17 -7
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +13 -7
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +17 -7
- package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +10 -4
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +65 -30
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/build-metadata.ts.hbs +0 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +1 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +69 -21
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/business-settings.ts.hbs +21 -5
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +63 -11
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +6 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +3 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +147 -33
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/security-roles.ts.hbs +43 -12
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +146 -30
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +33 -10
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/security.test.ts.hbs +142 -26
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +6 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/vitest.config.ts.hbs +3 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +48 -66
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/ja-JP.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +9 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/feedback-client.ts.hbs +0 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/sensitive-actions.svelte.ts.hbs +15 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +33 -7
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/FeedbackEntry.svelte.hbs +16 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/audit.svelte.hbs +104 -13
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/feedback.svelte.hbs +37 -7
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/roles.svelte.hbs +9 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +25 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/users.svelte.hbs +133 -19
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/security/role-label.ts.hbs +14 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/guide-store.ts.hbs +66 -34
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +132 -30
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +8 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +23 -5
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +143 -21
- package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -2
- package/templates/apps/fullstack/playwright.config.ts.hbs +25 -3
- package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +30 -14
- package/templates/apps/h5/src/routes/+layout.svelte.hbs +74 -30
- package/templates/apps/h5/src/routes/+page.svelte.hbs +2 -2
- package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +2 -2
- package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +2 -2
- package/templates/apps/mobile-app/capacitor.config.ts.hbs +5 -2
- package/templates/apps/mobile-app/messages/en-US.json +2 -2
- package/templates/apps/mobile-app/messages/ja-JP.json +2 -2
- package/templates/apps/mobile-app/messages/zh-CN.json +2 -2
- package/templates/apps/mobile-app/src/App.svelte.hbs +17 -5
- package/templates/apps/mobile-app/src/lib/api.ts.hbs +20 -6
- package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +8 -1
- package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +6 -2
- package/templates/apps/mobile-app/src/lib/pages/profile.svelte.hbs +13 -1
- package/templates/apps/mobile-app/src/lib/pages/tasks.svelte.hbs +5 -1
- package/templates/apps/website/scripts/static-website.mjs.hbs +19 -6
- package/templates/apps/website/src/routes/+layout.svelte.hbs +56 -29
- package/templates/apps/website/src/routes/+page.svelte.hbs +4 -4
- package/templates/apps/website/src/routes/about/+page.svelte.hbs +2 -2
- package/templates/apps/website/src/routes/contact/+page.svelte.hbs +2 -2
- package/templates/apps/website/src/routes/services/+page.svelte.hbs +20 -5
- package/templates/base/.dockerignore.hbs +10 -0
- package/templates/base/.gitignore.hbs +7 -2
- package/templates/base/e2e/app.spec.ts.hbs +130 -36
- package/templates/base/eslint-rules.js +44 -25
- package/templates/base/eslint.config.js.hbs +3 -1
- package/templates/base/images/web.Dockerfile.hbs +25 -14
- package/templates/base/package.json.hbs +13 -7
- package/templates/base/patches/daisyui-5.7.50.patch +8 -0
- package/templates/base/patches/deepmerge-4.3.1.patch +51 -0
- package/templates/base/playwright.config.ts +3 -1
- package/templates/base/pnpm-workspace.yaml.hbs +33 -16
- package/templates/base/src/app.d.ts.hbs +1 -1
- package/templates/base/src/app.html.hbs +1 -0
- package/templates/base/src/hooks.server.ts.hbs +44 -33
- package/templates/base/src/lib/build-metadata.ts.hbs +0 -1
- package/templates/base/src/lib/server/init.ts.hbs +146 -35
- package/templates/base/src/lib/server/kit-config.ts.hbs +7 -4
- package/templates/base/src/routes/+layout.server.ts.hbs +2 -2
- package/templates/base/svelte.config.js.hbs +10 -100
- package/templates/base/tests/scaffold.test.ts.hbs +12 -3
- package/templates/base/tsconfig.json.hbs +7 -4
- package/templates/base/vite.config.ts.hbs +108 -14
- package/templates/base/vitest.config.ts.hbs +6 -2
- package/templates/features/ai/routes/api/chat/+server.ts +3 -1
- package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +3 -3
- package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +3 -3
- package/templates/features/payment/routes/api/v1/payment/create/+server.ts +14 -3
- package/templates/shared/browser-check/startup.js +115 -0
- package/templates/shared/browser-check/update.css +37 -0
- package/templates/shared/browser-check/update.html +19 -0
- package/templates/shared/browser-startup.spec.ts +23 -0
- package/templates/shared/build-metadata.ts +18 -4
- package/templates/shared/e2e-env.ts +22 -6
- package/templates/shared/native-name.d.mts +5 -0
- package/templates/shared/native-name.mjs +94 -0
- package/templates/shared/public-base-path.mjs +17 -4
- package/templates/shared/run-e2e.mjs +46 -12
- package/templates/shared/run-node.mjs +56 -0
- package/templates/shared/run-tauri.mjs +74 -0
- package/templates/shared/vite-runtime-config.ts +9 -3
- package/templates/skills/AGENTS.md +10 -73
- package/templates/skills/bridges/admin/AGENTS.md +9 -65
- package/templates/skills/bridges/api/AGENTS.md +8 -59
- package/templates/skills/bridges/fullstack/AGENTS.md.hbs +9 -54
- package/templates/skills/bridges/h5/AGENTS.md +8 -63
- package/templates/skills/bridges/mobile-app/AGENTS.md +8 -62
- package/templates/skills/bridges/website/AGENTS.md +8 -63
- package/templates/skills/hai-ai/SKILL.md +6 -2
- package/templates/skills/hai-ai/acp.md +153 -0
- package/templates/skills/hai-ai/guide.md +27 -12
- package/templates/skills/hai-ai/reference.md +24 -15
- package/templates/skills/hai-ai/resources.md +69 -0
- package/templates/skills/hai-api-client/SKILL.md +1 -1
- package/templates/skills/hai-api-client/reference.md +3 -1
- package/templates/skills/hai-app-create/collaboration.md +7 -0
- package/templates/skills/hai-app-create/development.md +19 -10
- package/templates/skills/hai-app-create/project.md +33 -0
- package/templates/skills/hai-app-create/reference.md +10 -10
- package/templates/skills/hai-app-tests/reference.md +1 -1
- package/templates/skills/hai-app-tests/validation.md +1 -0
- package/templates/skills/hai-build/SKILL.md +19 -9
- package/templates/skills/hai-build/paths.md +4 -2
- package/templates/skills/hai-build/reference.md +26 -8
- package/templates/skills/hai-cache/reference.md +6 -2
- package/templates/skills/hai-capacitor/SKILL.md +1 -0
- package/templates/skills/hai-capacitor/reference.md +24 -0
- package/templates/skills/hai-ci/SKILL.md +3 -0
- package/templates/skills/hai-core/SKILL.md +9 -4
- package/templates/skills/hai-core/reference.md +40 -10
- package/templates/skills/hai-core/request-access.md +2 -2
- package/templates/skills/hai-crypto/SKILL.md +2 -2
- package/templates/skills/hai-crypto/reference.md +7 -3
- package/templates/skills/hai-deploy/SKILL.md +41 -5
- package/templates/skills/hai-deploy/middleware.md +26 -14
- package/templates/skills/hai-framework-sync/SKILL.md +13 -9
- package/templates/skills/hai-framework-sync/sync.md +2 -0
- package/templates/skills/hai-iam/reference.md +2 -2
- package/templates/skills/hai-kit/SKILL.md +1 -1
- package/templates/skills/hai-kit/reference.md +19 -5
- package/templates/skills/hai-payment/reference.md +41 -17
- package/templates/skills/hai-reach/SKILL.md +3 -1
- package/templates/skills/hai-reach/reference.md +29 -9
- package/templates/skills/hai-reldb/SKILL.md +1 -1
- package/templates/skills/hai-reldb/reference.md +9 -2
- package/templates/skills/hai-scheduler/reference.md +1 -1
- package/templates/skills/hai-serv/SKILL.md +2 -1
- package/templates/skills/hai-serv/reference.md +26 -15
- package/templates/skills/hai-storage/reference.md +23 -6
- package/templates/skills/hai-ui/SKILL.md +11 -6
- package/templates/skills/hai-ui/charts.md +51 -0
- package/templates/skills/hai-ui/guide.md +1 -1
- package/templates/skills/hai-ui/reference.md +58 -38
- package/templates/skills/hai-vecdb/reference.md +8 -3
- package/dist/chunk-AKV2CQZV.js.map +0 -1
- package/dist/chunk-EF7WOFWZ.js.map +0 -1
- package/dist/chunk-MUHRBJSW.js +0 -29272
- package/dist/chunk-MUHRBJSW.js.map +0 -1
- package/dist/cli-config-templates-HHFHNXBN.js +0 -5
- package/dist/src-TEBHR5I5.js +0 -5
- package/dist/src-TEBHR5I5.js.map +0 -1
- package/templates/apps/fullstack/playwright.session-close.config.ts.hbs +0 -18
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
从 [SKILL.md](SKILL.md) 选择主题后读取对应小节。代码片段展示 API 用法;省略的业务变量、schema、依赖与 return 上下文需由应用补齐。
|
|
4
4
|
|
|
5
|
-
`@h-ai/ai` 统一提供 LLM、工具、MCP、Embedding、Memory、Retrieval/RAG、Knowledge、Context、File、Rerank、Image、Audio 与
|
|
5
|
+
`@h-ai/ai` 统一提供 LLM、工具、MCP、Embedding、Memory、Retrieval/RAG、Knowledge、Context、File、Rerank、Image、Audio、A2A 与 ACP 能力。工程智能体、工作区和会话见 [ACP 指南](acp.md),配置与数据库资源合并见 [资源清单](resources.md)。
|
|
6
6
|
|
|
7
7
|
## 使用边界
|
|
8
8
|
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
## 初始化与关闭
|
|
17
17
|
|
|
18
|
+
`ai.close()` 等待已开始的初始化完成并清理,合并并发关闭;重初始化先清理旧实例,关闭期间不接受新初始化。
|
|
19
|
+
|
|
18
20
|
```ts
|
|
19
21
|
import { ai } from '@h-ai/ai'
|
|
20
22
|
import { core } from '@h-ai/core'
|
|
@@ -80,16 +82,18 @@ await ai.close()
|
|
|
80
82
|
|
|
81
83
|
## 配置要点
|
|
82
84
|
|
|
85
|
+
LLM 协议使用 `llm.protocol`、`llm.models[].protocol` 和 `tempModel.protocol`,值为 `chat | responses | anthropic`;环境变量使用 `HAI_AI_LLM_PROTOCOL`、`HAI_AI_LLM_MODELS_0_PROTOCOL` 等。旧 `api` 字段及旧协议变量会报迁移错误,密钥字段 `apiKey` 不变。
|
|
86
|
+
|
|
83
87
|
```yaml
|
|
84
88
|
llm:
|
|
85
89
|
apiKey: ''
|
|
86
90
|
baseUrl: https://api.openai.com/v1
|
|
87
91
|
model: gpt-4o-mini
|
|
88
|
-
|
|
92
|
+
protocol: chat # chat(默认)| responses | anthropic——底层协议,对使用方透明
|
|
89
93
|
timeout: 60000
|
|
90
94
|
tempModelCacheTtl: 600000 # 临时模型客户端缓存 TTL(毫秒,默认 10 分钟)
|
|
91
95
|
models: # 可为单个模型指定协议(responses / anthropic)
|
|
92
|
-
- {id: claude, model: claude-3-5-sonnet-latest,
|
|
96
|
+
- {id: claude, model: claude-3-5-sonnet-latest, protocol: anthropic}
|
|
93
97
|
scenarios:
|
|
94
98
|
chat: fast
|
|
95
99
|
reasoning: strong
|
|
@@ -107,7 +111,7 @@ knowledge:
|
|
|
107
111
|
maxSize: 1500
|
|
108
112
|
overlap: 200
|
|
109
113
|
|
|
110
|
-
# 可选:
|
|
114
|
+
# 可选:Mem0 数据格式适配;仅支持 Qdrant,生产不允许临时回退
|
|
111
115
|
memory:
|
|
112
116
|
provider: mem0
|
|
113
117
|
defaultTopK: 10
|
|
@@ -125,7 +129,7 @@ memory:
|
|
|
125
129
|
| ------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
126
130
|
| 非流式对话 | `ai.llm.chat({ messages })` | OpenAI 兼容 Chat Completion |
|
|
127
131
|
| 流式对话 | `ai.llm.chatStream({ messages })` | 返回 `AsyncIterable` |
|
|
128
|
-
| 多协议 | 模型 `
|
|
132
|
+
| 多协议 | 模型 `protocol: chat/responses/anthropic` | 底层走 Chat Completions / Responses / Anthropic,公共形状不变 |
|
|
129
133
|
| 请求取消 | `ai.llm.chat({ messages, signal })` | 传 `AbortSignal`,`abort()` 立即停上游生成 |
|
|
130
134
|
| 临时模型 | `ai.llm.chat({ messages, tempModel })` | 单次请求级临时端点,客户端按 TTL 缓存 |
|
|
131
135
|
| 工具定义 | `ai.tools.define(...)` | Zod schema 转 JSON Schema;`handler(input, ctx)` 第二参为执行上下文 |
|
|
@@ -237,15 +241,17 @@ await server.connect(new StreamableHTTPServerTransport({ sessionIdGenerator: cor
|
|
|
237
241
|
|
|
238
242
|
## 记忆、RAG 与知识库
|
|
239
243
|
|
|
240
|
-
`memory.
|
|
244
|
+
`ai.memory.scoped({ objectId })` 要求非空且非纯空白的主体 ID,否则工厂立即抛 `TypeError`,不会创建未绑定实例。公共 `clear({ scope: {} })` 等空范围返回失败;跨主体全清必须调用显式管理员入口。原生记忆的访问统计与更新使用版本 CAS,迟到读取不会复活已删除记录;数据库或向量清理失败通过 HaiResult 返回,不能当作成功。 Memory/Persona 的存储故障返回固定本地化文案,具体原因仅写服务端日志;先检查 result.success。
|
|
245
|
+
|
|
246
|
+
`memory.provider` 默认为 `native`(推荐),复用 vecdb/reldb/LLM/Embedding 并支持 Mem0 式批量合并。`mem0` 是 Mem0 数据格式适配,复用框架提取与 Embedding,通过原生 HTTP 读写 Qdrant,保留 UUID/payload、主体隔离和既有数据;不运行完整上游引擎。生产拒绝实际内存回退,只有开发或显式 E2E 可配置临时回退。两者提供同一组 `ai.memory.*` 操作。
|
|
247
|
+
|
|
248
|
+
切换 `native` 与 Mem0 数据格式适配不会自动迁移数据。切换前备份关系库和向量集合,并显式迁移/核对每条记忆的 ID、objectId、scope、元数据及 Embedding 模型/维度;不得把一个后端的数据目录或集合名直接配置为另一个后端并当作迁移完成。
|
|
241
249
|
|
|
242
|
-
Mem0 的 `update`
|
|
250
|
+
Mem0 的 `update` 原地修改文本与元数据,保持 `id` 和创建时间。候选扫描有界:`list` / `listPage` / 条件 `clear` 最多支持每主体 1000 条原始候选(含过期条目),多取一条探测完整性;超限返回 `MEMORY_LIST_INCOMPLETE`(906),不会伪造 total 或执行部分条件删除。候选完整时按 UTC 日期剔除过期项,再按类型/scope 过滤和分页;仅 `objectId` 的清理使用后端过滤删除,不受列表上限限制。公共空条件清理被拒绝;跨主体全清仅限受信管理员显式 `admin.clearAll({ confirm: true })`。
|
|
243
251
|
|
|
244
|
-
Mem0 3.3.1 的 Qdrant 适配仍依赖 `QdrantClient.search`;项目将 `@qdrant/js-client-rest` 精确锁定为受测的 `1.18.0`,AI 的可选 peer 也声明此版本。启动会检查该公开方法,缺失时明确配置失败;不要覆盖为已移除此方法的 1.19。
|
|
245
252
|
|
|
246
|
-
Mem0 的 pgvector 组合在所有环境拒绝启动:当前 SDK 将 PostgreSQL 连接保存在私有对象中,未提供公开关闭入口,框架无法履行资源清理契约。需要 pgvector 时选择 `memory.provider: native`;该原生后端保持支持。`disableHistory: true` 使用 SDK 无资源的历史占位实现,不创建历史 SQLite 文件。工厂通过公开的一条有界只读查询等待实际后端 ready 后才发布成功。
|
|
247
253
|
|
|
248
|
-
`add` / `extract`
|
|
254
|
+
`add` / `extract` 的写入回执不含完整业务字段,框架写后读取权威记录再返回;并发提取等待全部在途写入结束。若写入或写后读失败,`error.ext.requiresEffectReconciliation=true`,`memoryIds` 保存已知写入 ID(回执丢失时可能为空)。应按主体核对实际记忆后决定恢复,不能盲目重做 add/extract;框架不自动重放。
|
|
249
255
|
|
|
250
256
|
```ts
|
|
251
257
|
const enriched = await ai.memory.injectMemories(messages, { objectId: 'user-001', topK: 5 })
|
|
@@ -292,7 +298,7 @@ const answer = await ai.knowledge.ask('核心架构是什么?')
|
|
|
292
298
|
|
|
293
299
|
共享单活动生成租约为存储端时钟30秒,每10秒续租,最终 CAS 同时检查版本、owner 和截止时间。过期生成仅 interrupted,不自动重放 LLM/工具/记忆;manual pending 持久保存,可跨节点/重启按 turnId 提交。相同终态与真实文本重复提交幂等,内容冲突失败。queue 可取消轮询,不保证FIFO。reset 更换共享纪元,删除保留永久墓碑且 scope 不复用。外部 LLM/工具/本地后台记忆不与上下文跨系统原子提交;崩溃后的未知副作用必须由应用核对。
|
|
294
300
|
|
|
295
|
-
自定义
|
|
301
|
+
自定义 Store 接入遵守[Context 持久化约束](reference.md#context),包括最终提交时的版本、存储端时钟和截止条件;不能用一次续租或读前检查替代最终原子判断。
|
|
296
302
|
|
|
297
303
|
```ts
|
|
298
304
|
const managerResult = ai.context.createManager({
|
|
@@ -394,6 +400,8 @@ if (!playable.success)
|
|
|
394
400
|
|
|
395
401
|
hai-framework 源码仓库提供 `pnpm model <name> --device cpu` 与 `pnpm model:run <name>`,默认优先使用 Podman,可构建/启动 `faster-whisper-large-v3`、`indextts-2.5`、`qwen3-4b`。三套权重均优先从清单锁定的 ModelScope revision 下载并复用容器 volume,Hugging Face 只作回退。Whisper/IndexTTS 仍配置为 `audio.models[].baseUrl`,Qwen3-4B 仍配置为 OpenAI-compatible `llm.models[].baseUrl`;部署位置不进入 Provider 名称。离线部署使用准备权重后的 bundled 镜像。
|
|
396
402
|
|
|
403
|
+
`model:run` 只发布宿主 `127.0.0.1`;宿主设置 `HAI_MODEL_API_KEY` 时通过引擎环境变量名传入,客户端使用匹配 Bearer,Qwen在进程内映射到 `VLLM_API_KEY`,不能在额外参数中填写密钥。IndexTTS构建每轮需从固定HTTPS端点取得源码树元数据,源码文件可按摘要复用;仓库/缓存父目录须可信,离线目标运行预先完成的镜像。对外生产服务另行配置网络、HTTPS、认证和资源限额。
|
|
404
|
+
|
|
397
405
|
## 文生图(Image)
|
|
398
406
|
|
|
399
407
|
`ai.image` 只暴露稳定的提示词、模型别名、像素尺寸、可选参考图和图片字节;OpenAI、Google、Qwen、Seedream 与 Pollinations 的请求结构、鉴权、响应解析和临时 URL 下载均封装在内部 Provider。
|
|
@@ -425,7 +433,7 @@ await saveImage(image.data.images[0].data, image.data.images[0].mimeType)
|
|
|
425
433
|
```
|
|
426
434
|
|
|
427
435
|
- `Pollinations` 提供可免费起步的开发额度,但仍需 API key;不要把“免费额度”描述为匿名或无限调用。
|
|
428
|
-
- 应用应通过 `core.init({ configDir: './config' })` 加载 `_core.yml` / `_ai.yml
|
|
436
|
+
- 应用应通过 `core.init({ configDir: './config', configSchemas: { ai: AIConfigSchema } })` 加载 `_core.yml` / `_ai.yml`,并登记其他所用模块的公开 Schema,再以 `core.config.validate('ai', AIConfigSchema)` 校验并传给 `ai.init`;不要在启动代码中重复拼装模型、端点和超时,也不要传入 `logging` 覆盖 `_core.yml`。
|
|
429
437
|
- Pollinations 的 HTTP 402 表示账户余额或该 API Key 的预算耗尽;401 是密钥无效,403 是权限或模型访问被拒。诊断日志记录厂商、模型、状态、上游错误码和请求 ID,不记录密钥、提示词或图片内容。
|
|
430
438
|
- Qwen 等返回的临时图片 URL 会在 Provider 内立即下载,公共结果不泄漏易过期 URL。
|
|
431
439
|
- 参考图统一使用 `{ data: Uint8Array, mimeType: 'image/...' }`;不要把厂商 URL、multipart 或 Base64 结构泄漏到业务层。
|
|
@@ -451,7 +459,14 @@ export const POST = kit.handler(async ({ request }) => {
|
|
|
451
459
|
- 只向模型注册允许自动执行的工具;写操作默认要求业务侧确认或幂等键,不能把“模型请求调用”当作授权。
|
|
452
460
|
- 批量导入、批量 embedding 用批量 API,避免 await-in-loop。
|
|
453
461
|
- 文件解析/OCR 失败按 `HaiAIError.FILE_*` 返回,不抛业务异常。
|
|
462
|
+
- HTML 文件按 HTML 结构解析并迭代提取,script/style 不进入结果,正常正文不截断。`data.text` 仍是文本/Markdown,不是可信 HTML;使用文本绑定或 `MarkdownRenderer`,不能直接交给 `{@html}`。
|
|
454
463
|
- A2A 认证失败返回 `A2A_AUTH_FAILED`;`callRemoteAgent` 只依赖 `ai.init()`,无需注册本地 executor。远端 URL 仅接受 HTTP(S) 且不得内嵌凭据,应用仍须配置 origin 白名单与出口网络策略。不要记录 token、apiKey、私钥、完整 headers 或带 query 的 URL。
|
|
455
464
|
- A2A 入站日志保存并重验租约后才执行业务,出站日志在已有有界队列内完成后才发布;日志失败产生 failed/interrupted Task,不重放相同 receipt。日志不是交付回执,按 requiresEffectReconciliation 核对可能已执行的效果;listMessages 失败为安全的 A2A_LIST_MESSAGES_FAILED(984)。
|
|
456
465
|
- A2A 任务与事件只有共享 journal 一套权威,不装配旧 TaskStore;push notification 配置和 authenticated extended card RPC 返回 SDK 标准不支持/未配置错误。应用通过公开 executor 接口接入,不导入内部 handler/Store 装配类型。
|
|
457
466
|
- Context 的 flush 会报告本节点后台提取异常及失败 HaiResult;同轮并发调用共享一次报告,返回即确认该批,后续只观察新任务。save/reset(waitForMemoryTasks)/consolidate 传播失败并停止后续写入,pendingMemoryTasks=0 不代表成功,不自动重试未知副作用。
|
|
467
|
+
|
|
468
|
+
A2A 使用原生 1.0 协议:JSON-RPC 方法为 `SendMessage` / `SendStreamingMessage` / `GetTask` / `CancelTask` / `SubscribeToTask`,不接收旧版方法名。请求的消息 role 使用 `ROLE_USER`;执行器通过 `AgentEvent.message(Message.fromJSON(...))` 或 `AgentEvent.task(Task.fromJSON(...))` 发布事件(构建器与枚举从 `@h-ai/ai` 导入),文本 Part 的 ProtoJSON 为 `{ text: '...' }`,解码后的 SDK Part 从 `content.$case/value` 读取。SDK 的 `Role` / `TaskState` 为数值枚举,远端调用的 `taskState` 同样返回该枚举;直接 HTTP 响应由 `getAgentCard` / `handleRequest` 完成标准 ProtoJSON 编码,无需调用方了解 SDK oneof。远端调用自定义头按大小写不敏感的同名字段覆盖,并拒绝 HTTP 重定向,避免把认证头转发到其它目标。
|
|
469
|
+
|
|
470
|
+
Mem0 格式存储与 VecDB 的 Qdrant Provider 均使用原生 HTTP,无需额外 SDK。固定 REST 请求使用 `query`,路径段编码;30 秒超时覆盖完整响应体,响应超过 16 MiB 明确失败。写入和删除等待 `wait=true` 的实际完成回执。列表和条件清理最多核对每主体 1000 条原始候选(包括过期项),超限返回 `MEMORY_LIST_INCOMPLETE`,不执行部分条件删除;仅按主体清理不受此列表上限限制。
|
|
471
|
+
|
|
472
|
+
Qdrant 格式后端要求 1.19 或更新版本,并拒绝 HTTP 重定向。更新使用服务端 `update_only` 与主体/版本条件,同一次原子写入拒绝已删除或已被其它写入更新的条目;迟到更新不会复活删除记录。写后版本核对失败仍需按已有回执核对实际效果。
|
|
@@ -111,16 +111,13 @@ Embedding OpenAI 客户端按 `apiKey + baseURL + timeout` 缓存;同一 key
|
|
|
111
111
|
Memory 后端通过 `memory.provider` 选择:
|
|
112
112
|
|
|
113
113
|
- `native`(默认):HAI 原生引擎,复用 vecdb/reldb/LLM/Embedding。`extract` 采用 Mem0 式批量合并(ADD/UPDATE/DELETE/NONE + `category`);`maxEntriesPerObject`(单主体配额)/`maxEntriesGlobal`(全局上限)/`recencyDecay`/`embeddingEnabled`/`writebackRelatedTopK` 作用于此后端;淘汰按 `objectId` 分区。
|
|
114
|
-
-
|
|
115
|
-
- 两者对外 API(extract/recall/injectMemories/add/update/get/remove/list/listPage/clear)完全一致;`objectId` 隔离不同主体的记忆,`scope`(key-value)用于业务作用域隔离(recall/list/listPage/clear 均严格过滤)。mem0 后端 `extract`
|
|
114
|
+
- **`mem0`(数据格式适配)**:框架负责提取与 Embedding,通过原生 HTTP 读写 Qdrant 的 Mem0 UUID/payload 格式,可读取既有数据;不运行完整上游引擎、遥测或历史数据库。仅映射带完整连接参数的 Qdrant。生产(`NODE_ENV` 或 `HAI_CORE_ENV=production`)拒绝临时回退;开发或明确 E2E 可显式使用 `memory.allowEphemeralFallback: true`。其它持久化后端选择 `native`。
|
|
115
|
+
- 两者对外 API(extract/recall/injectMemories/add/update/get/remove/list/listPage/clear)完全一致;`objectId` 隔离不同主体的记忆,`scope`(key-value)用于业务作用域隔离(recall/list/listPage/clear 均严格过滤)。mem0 后端 `extract` 在框架层分类打分后直接写入格式存储(保留 `hai_type`/`hai_importance`),`recall` 支持 `types`/`recencyWeight`,与 native 一致;Mem0 的 `update` 原地修改文本与元数据,保持 `id` 和创建时间。候选扫描有界:`list` / `listPage` / 条件 `clear` 最多支持每主体 1000 条原始候选(含过期条目),多取一条探测完整性;超限返回 `MEMORY_LIST_INCOMPLETE`(906),不会伪造 total 或执行部分条件删除。候选完整时按 UTC 日期剔除过期项,再按类型/scope 过滤和分页;仅 `objectId` 的清理使用后端过滤删除,不受列表上限限制。公共空条件清理被拒绝;跨主体全清仅限受信管理员显式 `admin.clearAll({ confirm: true })`。
|
|
116
116
|
|
|
117
|
-
Mem0 3.3.1 的 Qdrant 适配仍依赖 `QdrantClient.search`;项目将 `@qdrant/js-client-rest` 精确锁定为受测的 `1.18.0`,AI 的可选 peer 也声明此版本。启动会检查该公开方法,缺失时明确配置失败;不要覆盖为已移除此方法的 1.19。
|
|
118
117
|
|
|
119
|
-
适配器通过 SDK 公开的 `client` 配置注入独享客户端;Mem0 的 Qdrant 写入与删除均使用 `wait: true`,等待服务端应用完成后才继续写后读或分批清理。
|
|
120
118
|
|
|
121
|
-
Mem0 的 pgvector 组合在所有环境拒绝启动:当前 SDK 将 PostgreSQL 连接保存在私有对象中,未提供公开关闭入口,框架无法履行资源清理契约。需要 pgvector 时选择 `memory.provider: native`;该原生后端保持支持。`disableHistory: true` 使用 SDK 无资源的历史占位实现,不创建历史 SQLite 文件。工厂通过公开的一条有界只读查询等待实际后端 ready 后才发布成功。
|
|
122
119
|
|
|
123
|
-
`add` / `extract`
|
|
120
|
+
`add` / `extract` 的写入回执不含完整业务字段,框架写后读取权威记录再返回;并发提取等待全部在途写入结束。若写入或写后读失败,`error.ext.requiresEffectReconciliation=true`,`memoryIds` 保存已知写入 ID(回执丢失时可能为空)。应按主体核对实际记忆后决定恢复,不能盲目重做 add/extract;框架不自动重放。
|
|
124
121
|
|
|
125
122
|
## Retrieval / RAG
|
|
126
123
|
|
|
@@ -172,9 +169,9 @@ Knowledge `retrieve/ask` 与默认 DB Store 的 filter 透传向量 Provider,
|
|
|
172
169
|
|
|
173
170
|
共享单活动生成租约为存储端时钟30秒,每10秒续租,最终 CAS 同时检查版本、owner 和截止时间。过期生成仅 interrupted,不自动重放 LLM/工具/记忆;manual pending 持久保存,可跨节点/重启按 turnId 提交。相同终态与真实文本重复提交幂等,内容冲突失败。queue 可取消轮询,不保证FIFO。reset 更换共享纪元,删除保留永久墓碑且 scope 不复用。外部 LLM/工具/本地后台记忆不与上下文跨系统原子提交;崩溃后的未知副作用必须由应用核对。
|
|
174
171
|
|
|
175
|
-
自定义 `AIRelStore` 必须提供版本化读取、原子 CAS 和存储端 `currentTime()`;普通 save/saveMany 也推进版本。CAS
|
|
172
|
+
自定义 `AIRelStore` 必须提供版本化读取、原子 CAS 和存储端 `currentTime()`;普通 save/saveMany 也推进版本。CAS 缺失版本只允许创建,`notAfter` 在最终持久化时用存储端时钟严格检查,存储故障抛错不能当空数据,外层业务边界转为 HaiResult 失败。默认关系存储含 `version` 列;SQLite 仅用于开发/测试,生产使用 PostgreSQL/MySQL 与共享向量服务。
|
|
176
173
|
|
|
177
|
-
`ai.context.createManager(options)`
|
|
174
|
+
`ai.context.createManager(options)` 同步返回 `HaiResult<ContextManager>`,适合多轮对话;先判断 `success`,再通过 `data` 使用有状态管理器。`restoreManager(scope, options?)` 为异步恢复入口,同样先检查结果。
|
|
178
175
|
|
|
179
176
|
常用选项:
|
|
180
177
|
|
|
@@ -193,7 +190,7 @@ flush 对本节点后台提取的异常和失败 HaiResult 返回 MEMORY_EXTRACT
|
|
|
193
190
|
|
|
194
191
|
- `ai.file.parse({ content, filename, options })`:text/html/pdf/docx/ocr 解析。
|
|
195
192
|
- `ai.file.parseText(content, filename?)`:直接返回文本。
|
|
196
|
-
- `ai.rerank.rerank(request)` / `rerankTexts(query, texts, topN?)
|
|
193
|
+
- `ai.rerank.rerank(request)` / `rerankTexts(query, texts, topN?)`:相关性重排;模型 `timeout` 覆盖响应头与正文读取,超时返回失败结果。
|
|
197
194
|
- `ai.reasoning.run(query, options?)` / `runStream(query, options?)`:`react`、`cot`、`plan-execute`。
|
|
198
195
|
|
|
199
196
|
## Audio
|
|
@@ -209,13 +206,19 @@ IndexTTS 的 Node HTTP 请求使用同版本 Undici fetch/Agent/FormData;模
|
|
|
209
206
|
| `getCapabilities({ operation, model? })` | `HaiResult<AudioModelCapabilities>` | 按模型与操作查询 `transcribe` / `synthesize` 能力分支,并拒绝操作不匹配模型 |
|
|
210
207
|
|
|
211
208
|
- 音频类型:`AudioContent { data: Uint8Array, format: 'pcm16'|'wav'|'mp3'|'opus', sampleRate?, channels? }`;`pcm16` 等裸音频必须传 `sampleRate`。
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
-
|
|
215
|
-
-
|
|
216
|
-
-
|
|
209
|
+
- 请求可选(识别):`contextHints?`(热词)/ `timestampGranularities?: ('segment'|'word')[]` / `vad?` / `strictCapabilities?`;结果 `TranscriptionResult { text, language?, durationMs?, segments?[{ id?, text, startMs, endMs, words?, speakerId? }] }`(词级时间戳在 `segments[].words`,毫秒整数)。
|
|
210
|
+
- 请求可选(合成):`instruction?` / `language?` / `speakerReference?: { audio, transcript?, language? }`(谁在说)/ `styleReference?`(怎么说)/ `styleStrength?`(`[0,1]`)/ `speed?`(>1 更快,与 `targetDurationMs` 互斥)/ `targetDurationMs?` + `durationToleranceMs?` / `strictCapabilities?`;结果 `SynthesisResult extends AudioContent { durationMs?, metadata?: { durationMatched?, speed? } }`。均支持 `signal`。
|
|
211
|
+
- `strictCapabilities` 为真时请求的高级能力若模型不支持 → 调 Provider 前 `AUDIO_UNSUPPORTED_INPUT`;参数非法(风格强度越界、语速非正、speed 与 targetDurationMs 冲突、durationTolerance 缺 target 等)→ `AUDIO_INVALID_REQUEST`。
|
|
212
|
+
- 模型配置:`audio.models: [{ id, provider: 'openai'|'mimo'|'qwen'|'doubao'|'whisper'|'indextts', model, operations: ('transcribe'|'synthesize')[](至少一项、不重复), apiKey?, baseUrl?, appKey?, accessKey?, resourceId?, workspaceId? }]`。`provider` 表示调用协议而非部署位置;`whisper`(ASR)/ `indextts`(TTS)可自托管,无 canonical 端点,必须显式配置 `baseUrl`(缺失 → `CONFIGURATION_ERROR`),可无凭据(配 `apiKey` 后按 `Authorization: Bearer` 发送);云平台缺凭据 → `CONFIGURATION_ERROR`。
|
|
213
|
+
- 无原生流式的平台:`whisper` 完整音频降级为最终 `transcript`、持续音频输入 → `AUDIO_UNSUPPORTED_INPUT`;`indextts` 按段完整合成降级、`streamingAudioOutput` 保持 `false`。自托管部署参考框架同版本的 `packages/ai/models/`(优先 ModelScope 下载)。
|
|
214
|
+
- 凭据优先级:模型条目 `apiKey` → 显式启用 `audio.inheritLlmApiKey` 后的 LLM `apiKey` → `HAI_AI_AUDIO_<PROVIDER>_APIKEY` 或 `OPENAI_API_KEY` / `MIMO_API_KEY` / `DASHSCOPE_API_KEY` / `VOLC_API_KEY`(豆包旧版控制台额外 `VOLC_APP_KEY` / `VOLC_ACCESS_KEY`)。
|
|
215
|
+
- 资源上限:`audio.maxAudioBytes`(默 10 MiB,同时保护说话人/风格参考)、`audio.maxStreamDurationMs`(默 5 分钟);所有请求支持 `signal: AbortSignal` 打断。
|
|
217
216
|
- Provider 为内部实现,不从根入口导出;不支持的输入方式招 `AUDIO_UNSUPPORTED_INPUT`,不伪装实时。取消 → `AUDIO_CANCELLED`,超时 → `AUDIO_TIMEOUT`,连接失败或 `end` 前异常断连 → `AUDIO_CONNECTION_FAILED`。浏览器客户端(`@h-ai/ai/client`)严格区分正常结束 / 取消 / 异常断连:取消招 `AUDIO_CANCELLED`、`end` 前断连招 `AUDIO_CONNECTION_FAILED`、服务端 error 帧保留其领域错误码,`synthesize` 不把未完成的部分音频当作成功返回。
|
|
218
217
|
|
|
218
|
+
- 播放负载:`serializePlayableAudio(audio)` 返回 `HaiResult<PlayableAudio>`;`PlayableAudio` 为 `{ audioBase64, format: 'wav'|'mp3', mimeType }`。该函数将 `pcm16` 封装为 WAV,透传 WAV/MP3;`opus` 不支持转换。
|
|
219
|
+
|
|
220
|
+
能力快照 `getCapabilities` 为同步读取;跨节点更新模型后,先调用异步 `ai.audio.models.get/list` 或音频操作刷新本节点,再据能力决定参数。
|
|
221
|
+
|
|
219
222
|
## Image
|
|
220
223
|
|
|
221
224
|
| 方法 | 返回 | 说明 |
|
|
@@ -246,7 +249,7 @@ IndexTTS 的 Node HTTP 请求使用同版本 Undici fetch/Agent/FormData;模
|
|
|
246
249
|
| `listMessages(filter)` | 查询 A2A 消息记录 |
|
|
247
250
|
| `callRemoteAgent(remoteUrl, message, options?)` | 调用远端 Agent;只依赖 `ai.init()`,不要求本地 executor |
|
|
248
251
|
|
|
249
|
-
A2A 服务端 SDK handler 在注册 executor 时延迟创建;远端客户端调用不依赖服务端配置。getAgentCard
|
|
252
|
+
A2A 服务端 SDK handler 在注册 executor 时延迟创建;远端客户端调用不依赖服务端配置。getAgentCard 返回可直接 HTTP 输出的标准 A2A 1.0 ProtoJSON Card(supportedInterfaces、MIME、streaming、安全方案);Kit 默认发现路径为 `/.well-known/agent-card.json`。handleRequest 在未初始化时也返回 JSON-RPC 错误;可信 context.agentId 映射 SDK user.userName。Kit 配置 authenticate 后空身份返回 401;不声明 push notifications、gRPC、REST 支持。
|
|
250
253
|
|
|
251
254
|
A2A journal、context 归属和消息表在 `ai.init()` 阶段初始化;可信 agentId 是身份来源,匿名共用主体,生产须认证。Task 与事件一次 CAS 发布,支持任意节点订阅、真实 owner 取消和 input-required 跨节点续接。同 message ID/内容重试复用同一轮,内容改变或旧轮重试拒绝;取消未确认时同一 Task 拒绝新消息,防止迟到回调影响新一代;失租、绝对期限或 working 状态退出标记 failed/interrupted 与 metadata.haiExecution.requiresEffectReconciliation=true,不自动重放未知副作用。a2a.execution 默认 leaseMs=30000、pollIntervalMs=250、maxExecutionMs=300000;单消息1MiB、journal8MiB、每轮2048事件、每Task256回执、32个reference tasks。listMessages 是服务端管理接口,callerId/contextId/since 不能替代调用授权。外部工具须使用稳定业务幂等键并核对未知结果,SDK异常不向用户暴露驱动凭据。
|
|
252
255
|
|
|
@@ -290,3 +293,9 @@ Knowledge 分块直接遵循 datapipe 的单位与硬上限:word 为词,其
|
|
|
290
293
|
JSDoc 公开示例使用真实包入口,内部工厂示例标记“模块内部上下文”;应用使用所安装版本的公开类型,并通过本应用已有的类型检查验证使用示例。调用示例须保留 HaiResult 成功检查、受信主体范围、共享 CAS 版本与存储端期限,不将后台 flush 失败或未知外部效果当作成功重试。
|
|
291
294
|
|
|
292
295
|
SSE:Node 的 ai.stream 解码器支持跨片 LF/CRLF/CR、多行 data,只去冒号后一个空格;无 data 块不派发,空或缺省事件名按 message,id/retry 继承最近有效值,reset 清空连接状态,EOF 不补空行。encodeSSE 允许合法 data 换行并规范化,id/event 换行、id 的 NUL、非负安全整数以外的 retry 显式抛 TypeError/RangeError。真实 Anthropic/MiMo 使用同一内部 UTF-8 reader,退出/取消/协议结束/错误均取消正文并释放 reader;无自动重连/副作用重放。Anthropic 总 timeout 覆盖正文,MiMo 保留每请求独立 timeout。
|
|
296
|
+
|
|
297
|
+
A2A 使用原生 1.0 协议:JSON-RPC 方法为 `SendMessage` / `SendStreamingMessage` / `GetTask` / `CancelTask` / `SubscribeToTask`,不接收旧版方法名。请求的消息 role 使用 `ROLE_USER`;执行器通过 `AgentEvent.message(Message.fromJSON(...))` 或 `AgentEvent.task(Task.fromJSON(...))` 发布事件(构建器与枚举从 `@h-ai/ai` 导入),文本 Part 的 ProtoJSON 为 `{ text: '...' }`,解码后的 SDK Part 从 `content.$case/value` 读取。SDK 的 `Role` / `TaskState` 为数值枚举,远端调用的 `taskState` 同样返回该枚举;直接 HTTP 响应由 `getAgentCard` / `handleRequest` 完成标准 ProtoJSON 编码,无需调用方了解 SDK oneof。
|
|
298
|
+
|
|
299
|
+
Mem0 格式存储与 VecDB 的 Qdrant Provider 均使用原生 HTTP,无需额外 SDK。固定 REST 请求使用 `query`,路径段编码;30 秒超时覆盖完整响应体,响应超过 16 MiB 明确失败。写入和删除等待 `wait=true` 的实际完成回执。列表和条件清理最多核对每主体 1000 条原始候选(包括过期项),超限返回 `MEMORY_LIST_INCOMPLETE`,不执行部分条件删除;仅按主体清理不受此列表上限限制。
|
|
300
|
+
|
|
301
|
+
Qdrant 格式后端要求 1.19 或更新版本,并拒绝 HTTP 重定向。更新使用服务端 `update_only` 与主体/版本条件,同一次原子写入拒绝已删除或已被其它写入更新的条目;迟到更新不会复活删除记录。写后版本核对失败仍需按已有回执核对实际效果。
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# 配置与数据库资源清单
|
|
2
|
+
|
|
3
|
+
AI 的可维护资源统一使用两份来源:初始化配置(通常来自 config/ai.yml)和 AIStoreProvider 数据库。按 ID 合并,同 ID 配置优先;配置条目只读,不复制到数据库。移除配置后,原来被遮蔽的数据库条目重新可见。数据库变更不会修改配置文件。
|
|
4
|
+
|
|
5
|
+
| 清单入口 | 配置数组 | 使用方 |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `ai.llm.models` | `llm.models` | LLM、embedding、rerank、ACP 原生模型配置 |
|
|
8
|
+
| `ai.audio.models` | `audio.models` | ASR/TTS |
|
|
9
|
+
| `ai.image.models` | `image.models` | 图像生成 |
|
|
10
|
+
| `ai.mcp.servers` | `mcp.servers` | ACP `mcpServerIds`,外部 MCP 连接资料 |
|
|
11
|
+
| `ai.retrieval.sources` | `retrieval.sources` | 检索源及旧 addSource/removeSource/listSources 接口 |
|
|
12
|
+
| `ai.acp.agents` | `acp.agents` | 智能体接入、初始化和会话 |
|
|
13
|
+
| `ai.acp.workspaces` | `acp.workspaces` | 工程准备、会话目录及 Git 操作 |
|
|
14
|
+
|
|
15
|
+
这些清单支持 `list/get/register/update/remove`。`list/get` 返回 `HaiResult`,条目为 `{ value, source, version? }`;`source` 是 config 或 database,数据库 `get` 带版本。`update` 接受完整定义,不是部分 patch。编辑前 get,再把 version 传给 update/remove,过期写入返回冲突。已有运行中的 ACP 会话保留原模型绑定;新会话读取最新清单,恢复会话会校验模型与智能体定义是否仍兼容。
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { ai } from '@h-ai/ai'
|
|
19
|
+
|
|
20
|
+
// 已按应用生命周期成功初始化 reldb、vecdb 和 ai。
|
|
21
|
+
async function changeModel() {
|
|
22
|
+
const current = await ai.llm.models.get('coding')
|
|
23
|
+
if (!current.success) return current
|
|
24
|
+
if (current.data.source === 'config') return current
|
|
25
|
+
return ai.llm.models.update({ ...current.data.value, temperature: 0.2 }, current.data.version)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
配置示例(模型名、地址与路径由部署提供):
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
llm:
|
|
33
|
+
models:
|
|
34
|
+
- id: coding
|
|
35
|
+
model: your-model
|
|
36
|
+
protocol: responses
|
|
37
|
+
acp:
|
|
38
|
+
agents:
|
|
39
|
+
- id: coder
|
|
40
|
+
name: Codex
|
|
41
|
+
mode: embedded
|
|
42
|
+
adapter: codex
|
|
43
|
+
modelIds: [coding]
|
|
44
|
+
workspaces:
|
|
45
|
+
- id: project
|
|
46
|
+
storage:
|
|
47
|
+
type: directory
|
|
48
|
+
path: /srv/projects/project
|
|
49
|
+
repositories:
|
|
50
|
+
- id: api
|
|
51
|
+
url: https://git.example.com/team/api.git
|
|
52
|
+
mainBranch: trunk
|
|
53
|
+
mcp:
|
|
54
|
+
servers:
|
|
55
|
+
- id: docs
|
|
56
|
+
name: Docs
|
|
57
|
+
transport: stdio
|
|
58
|
+
command: docs-mcp
|
|
59
|
+
environmentRefs:
|
|
60
|
+
API_TOKEN: DOCS_API_TOKEN
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
创建会话时传 `mcpServerIds: ['docs']`;配置和数据库 MCP 条目都可选择。环境变量在实际启动时解析,不将引用替换为密钥后保存到 MCP 定义。HTTP/SSE 的 headers 使用 `headerEnv`,stdio 的环境变量使用 `environmentRefs`。这份清单只维护外部服务器;`ai.mcp.registerTool/registerResource/registerPrompt` 仍是宿主进程的函数注册,不将可执行函数存进数据库。
|
|
64
|
+
|
|
65
|
+
框架的异步模型调用每次读取最新清单;mem0 外部运行时在初始化时读取合并快照,其内置模型配置修改后需要重新初始化 AI。音频 `getCapabilities()` 保留原同步契约,使用本进程最近一次目录读写或异步音频调用刷新的快照;跨节点修改后先 await `ai.audio.models.get/list` 再同步查询能力。清单不是业务会话历史:session、聊天记录、persona 等继续使用各自已有的持久化 API,不从配置导入运行历史。
|
|
66
|
+
|
|
67
|
+
配置项改写返回 `hai:ai:090`,缺失为 091,版本/重复冲突为 092,无效定义为 093,存储失败为 094。工作区路径重叠、仍被会话引用等使用 ACP 错误。数据库工作区更新/删除前需关闭并移除引用它的会话记录;移除记录不删除磁盘目录、worktree 或 volume。
|
|
68
|
+
|
|
69
|
+
清单 API 是可信服务端管理接口,模型原始定义可能包含 apiKey。应用必须鉴权并自行选择可返回浏览器的字段,不直接透传整个 value。生产继续沿用 AI 模块已有共享数据库及向量库前置要求。
|
|
@@ -29,7 +29,7 @@ description: "接入或排查 @h-ai/api-client typed API、登录 Token、自动
|
|
|
29
29
|
|
|
30
30
|
## 按需参考
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Serv/Kit 对通过请求绑定、签名和 MAC 校验但超出时间窗口的请求返回加密的 HTTP 400 错误。客户端抛出 `TransportTimeError`(`hai:crypto:071`),显示校验时的服务器 UTC 时间,提示开启设备的自动校时或手工修改时间后刷新。`serverTime` 为 Unix 毫秒,旧服务端未提供该值时仍显示校时提示。`api-client` 映射为 `VALIDATION_FAILED`,在 `cause.transportCode` 和 `cause.serverTime` 保留诊断信息。
|
|
33
33
|
|
|
34
34
|
按本次操作读取对应小节;以已安装版本的公开类型核验签名,示例中的业务变量由应用提供。
|
|
35
35
|
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
> `@h-ai/api-client` 是跨端 typed API client。公共 HTTP API 由 `@h-ai/api-contract` 定义,服务端由 `@h-ai/serv` 挂载,客户端直接调用 `apiClient.<domain>.<group>.<operation>()`。
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
认证协议仅支持 v2:独立随机 SM4-CBC 密钥和 HMAC-SM3 密钥由 SM2 封装,先验签、再验证 MAC,最后解密 CBC。请求由客户端私钥签名,响应由所选服务端版本签名。认证字段包括 version、direction、serverKeyId、clientId、128 位随机 requestId(兼 nonce)、issuedAt、HTTP method、pathname + 原始 search 的 SM3 pathHash,以及响应 status
|
|
6
|
+
认证协议仅支持 v2:独立随机 SM4-CBC 密钥和 HMAC-SM3 密钥由 SM2 封装,先验签、再验证 MAC,最后解密 CBC。请求由客户端私钥签名,响应由所选服务端版本签名。认证字段包括 version、direction、serverKeyId、clientId、128 位随机 requestId(兼 nonce)、issuedAt、HTTP method、pathname + 原始 search 的 SM3 pathHash,以及响应 status。请求默认有效期为 5 分钟,客户端时间最多可领先服务器 30 秒。服务端可用 `maxRequestAgeSeconds`(1~600)和 `maxFutureSkewSeconds`(0~300)调整,单位为整数秒。共享 registry 原子消费 (clientId, requestId),nonce 保留到 issuedAt + 11 分钟,覆盖最长可配窗口及节点时钟差,存储故障拒绝请求。Redis 必须保留有效 nonce,使用 noeviction/可靠持久化策略;各节点时钟须同步。此能力防止同一传输消息重放,业务重试仍需自己的幂等键。
|
|
7
7
|
|
|
8
8
|
空 POST 也发送空明文的认证封装;GET/HEAD 将封装放在 X-Hai-Transport 头,204/304/HEAD 等无正文响应也使用同名头承载认证封装。其它请求/响应在 JSON 正文承载封装并带 X-Encrypted: true。客户端必须关联原请求上下文和 HTTP status,缺标记、旧格式或认证失败一律 reject;明文接口由 Serv/Kit 路径规则 `encryption: disabled` 或宿主 `excludePaths` 显式允许;调用方同步选择普通请求,API Client/Kit 包装器使用自己的 `excludePaths`。CORS 须允许并暴露 X-Hai-Transport。握手公钥的真实性依赖 TLS,不替代 IAM 业务授权。
|
|
9
9
|
|
|
10
10
|
## 使用步骤
|
|
11
11
|
|
|
12
|
+
`client.close()` 使旧刷新失效并等待已开始的凭据写入,但不清除宿主 TokenStorage。关闭完成后可复用同一存储重新 init;迟到刷新不能覆盖新身份。请求 timeout 覆盖响应头、完整 JSON 和所有失败响应正文(包括 HTML);超时或取消不启动刷新。自定义流按需读取,以调用方 signal 取消正文。内置 Cookie 适配器的登录和刷新包含跨域凭据,服务端须配置明确 Origin;内存/原生存储保留原请求凭据策略。
|
|
13
|
+
|
|
12
14
|
### 1. 初始化
|
|
13
15
|
|
|
14
16
|
浏览器默认使用 httpOnly cookie 存储(推荐):
|
|
@@ -31,6 +31,13 @@
|
|
|
31
31
|
|
|
32
32
|
## 使用文档与证据
|
|
33
33
|
|
|
34
|
+
- 面向读者说明“谁在什么场景调用、调用后发生什么、限制与恢复办法”。术语第一次出现时用具体行为解释,例如“等待数据库查询后仍能读取当前请求的编号,其他请求不会覆盖它”,不能只给“异步隔离”标签。介绍工厂或管理对象时说明创建是否立即执行、返回对象的常用操作与先后顺序。
|
|
35
|
+
- 入门代码为关键步骤加简短注释,交代配置来源、调用目的、为何检查失败及何时清理;不逐行复述语法。示例可独立运行,额外依赖与省略的应用函数须明确说明;已有多语言版本保留相同的前提和注释含义。
|
|
36
|
+
- 每项功能的示例同时展示具体输入和对应输出,不能只有调用或“转成环境变量”等用途说明。普通返回值写出值和必要类型,HaiResult 展示 success 与 data/error;无返回值的操作写明状态变化、日志或回调内容,工厂展示返回对象的后续调用及结果。随机值、时间和环境相关结果注明示例值与前提,关键结果通过实际运行核对。
|
|
37
|
+
- 使用文档直接介绍最终功能和操作,不保留用户提问、纠错措辞、讨论过程或逐句回应旧文案的话术;将澄清后的结论自然融入正文,必要概念结合操作解释。
|
|
38
|
+
- 框架模块使用入门先给最小启动流程,再按 `<模块名>.xx` 的全部公开子功能分组提供用途、示例和必要注意事项;长签名可放参考,但不能只介绍常用功能。运行能力默认从模块对象进入,独立的类型/Schema、结果构造器或宿主要求的入口须说明真实契约和例外原因。
|
|
39
|
+
- 配置优先级、变量替换、默认值和类型转换要先解释名词,再用“配置与环境输入 → 最终值及类型”举例;缺失、空字符串或不会再次替换的文本等边界,说明实际结果或错误,不能只给压缩规则。
|
|
40
|
+
|
|
34
41
|
按功能或安全项说明用途/适用场景、配置位置/名称/真实默认值、完整示例、前置与操作步骤、生效确认、实际影响和验证说明。没有默认值时明确标注;可选父配置未启用时,不能把子字段默认值写成已经启用。覆盖关系和环境差异应单独说明。
|
|
35
42
|
|
|
36
43
|
默认值以当前实现与实际消费点为依据,已安装应用以其安装版本为准。无界面配置可用脱敏请求响应、日志或验证结果说明。不能验证时写明环境、缺少的前提和可继续的步骤;静态校验、Mock、浏览器、容器、真实外部服务及原生安装的证据不能互相替代。
|
|
@@ -22,7 +22,11 @@ README 编辑先读章节,把功能说明与示例合并到对应章节;新
|
|
|
22
22
|
|
|
23
23
|
### 页面与布局
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
每个模板只安装实际使用的模块:admin/h5 包含认证、验证码及找回密码通知,以及数据库、缓存、加密依赖;website 只包含 Core/Kit/UI;API 包含认证、通知、上传和反馈;fullstack 保留管理后台的认证、审计、存储、通知、调度和反馈;mobile-app 只使用客户端能力。AI、payment、vecdb、datapipe 不默认安装。所有项目保留完整模块 YAML 和 `.env.example`,未启用项以注释提供,只有已启用项进入公共环境默认值。后续添加对应依赖、取消所需配置注释,再接入初始化、关闭及业务路由;添加依赖不会自动启用功能。`--template`、`--features`、`--examples/--no-examples` 已删除,`create --yes/-y` 改为 `--defaults`,旧参数明确报错;`deploy --yes` 保持原义。已有工程不会自动裁剪依赖。
|
|
26
|
+
|
|
27
|
+
website默认SSR;静态发布须先移除服务端业务依赖、初始化及API/actions。静态构建与实际路径验证按[hai-build](../hai-build/SKILL.md)。
|
|
28
|
+
|
|
29
|
+
admin、website、h5 和 Fullstack Web 在入口 HTML 加载 `_hai/browser-check/startup.js` 后才进入应用。检测到 Chrome/Edge 低于 111、Firefox 低于 114、Safari 或 iOS/iPadOS 低于 16.4 时,浏览器跳转到同目录的静态升级页。保留经典脚本标签和静态资源,验证根目录和发布子目录都能在应用包加载失败时显示升级提示。
|
|
26
30
|
|
|
27
31
|
网站挂载到`/yyy/`等目录时,按[网站挂载目录](../hai-build/paths.md)同步资源、链接、认证端点和服务端守卫。SvelteKit在编译时固定base,Vite默认相对资源加hash导航;API基址单独配置。SDK子目录制品使用格式5,健康与增量检查随制品处理,不手工修改旧格式清单来代替重新构建。
|
|
28
32
|
|
|
@@ -40,6 +44,7 @@ README 编辑先读章节,把功能说明与示例合并到对应章节;新
|
|
|
40
44
|
| `.env.test` | 测试环境公共覆盖 | 提交 |
|
|
41
45
|
| `.env.prod` | 生产环境公共覆盖 | 提交 |
|
|
42
46
|
| `.env.local` | 当前机器的私有配置,覆盖公共配置 | 不提交 |
|
|
47
|
+
| `.env.<mode>.local` | 当前模式的私有覆盖、初始密码和传输密钥环 | 不提交 |
|
|
43
48
|
|
|
44
49
|
YAML 使用 `${HAI_DB_TYPE:sqlite}` 等显式引用,冒号后是未配置时的本地默认值。应用仍通过 `core.config.validate(name, ModuleConfigSchema)` 和模块初始化校验类型、枚举、范围和必填项;插值本身不能代替校验。只开启实际使用的模块,未启用模块的整份 YAML 保留注释。
|
|
45
50
|
|
|
@@ -49,8 +54,8 @@ YAML 使用 `${HAI_DB_TYPE:sqlite}` 等显式引用,冒号后是未配置时
|
|
|
49
54
|
|
|
50
55
|
- `HAI_<配置名>_<字段路径>`:`_db.yml` 的 `type` 对应 `HAI_DB_TYPE`;`_ai.yml` 的 `llm.apiKey` 对应 `HAI_AI_LLM_APIKEY`。camelCase 不拆词,数组使用从零开始的索引,如 `HAI_AI_AUDIO_MODELS_0_BASEURL`。
|
|
51
56
|
- 框架配置统一采用路径命名,如 `HAI_REACH_PROVIDERS_0_PASS`。第三方 SDK 自身读取的 `OPENAI_API_KEY` 等外部变量保留厂商约定;应用 YAML 使用框架标准名。
|
|
52
|
-
-
|
|
53
|
-
-
|
|
57
|
+
- Schema 决定类型:布尔用 `true/false`,数字不带单位;字符串直接填写即可保留前导零,无须再嵌套 YAML 引号。没有 Schema 的自定义配置按已有 YAML/JSON 结构与 YAML 标量规则解析。空字符串保持为空字符串。
|
|
58
|
+
- JSON 对象可作为基础,后续按路径细化;同来源先父后子、与行序无关,高来源整段替换会清掉低来源细项。生成配置优先细项,数组保留 JSON;动态字典与空对象保留原意,JSON 放对应模块细项之前。
|
|
54
59
|
- `PUBLIC_` / `VITE_` 只用于浏览器可见的 API 地址和非敏感参数。业务正文、模板 ID、表名/列名及数据结构留在代码/YAML;环境参数不能改变固定表结构契约。
|
|
55
60
|
|
|
56
61
|
#### 加载与启动
|
|
@@ -60,20 +65,24 @@ YAML 使用 `${HAI_DB_TYPE:sqlite}` 等显式引用,冒号后是未配置时
|
|
|
60
65
|
| Vite / SvelteKit | `pnpm dev` | `pnpm dev:test` | `pnpm dev:prod` 预览;build 不选择环境 |
|
|
61
66
|
| Node service | `pnpm dev` | 构建后 `pnpm start:test` | 构建后 `pnpm start:prod` |
|
|
62
67
|
|
|
63
|
-
`hai create` 为 fullstack 在 `.env.dev/.env.test/.env.prod`
|
|
68
|
+
`hai create` 为 fullstack 在 `.env.dev.local/.env.test.local/.env.prod.local` 分别生成初始密码和传输密钥环,API 启用 crypto 时也生成 ring;这些私有文件不提交 Git。克隆后通过受保护配置或 Secret Manager 分发对应环境秘密。同环境节点共享 ring 和 registry,运行时不生成或轮换。模板默认 `pretty` 并声明运行依赖 `pino-pretty`,需要 JSON 时覆盖 `HAI_CORE_LOGGING_FORMAT`。启动失败检查模块、错误码和字段路径;监听冲突检查 `EADDRINUSE` 的地址与端口。
|
|
64
69
|
|
|
65
|
-
所有入口优先级一致:**进程环境 > `.env.local` > `.env.<
|
|
70
|
+
所有入口优先级一致:**进程环境 > `.env.<mode>.local` > `.env.local` > `.env.<mode>` > `.env` > YAML**。Vite 在 Node 阶段通过 `core.config.loadEnvFiles` 读取并检查结果;Node 服务复用 `scripts/run-node.mjs <mode> <环境目录> <入口>`,让来源与对象覆盖规则一致,`NODE_OPTIONS` 在子进程启动前生效。`development`/`production` 映射为 `dev`/`prod`,`core.init` 不自行读取 dotenv。
|
|
66
71
|
|
|
67
72
|
托管 `test:e2e` 是明确的隔离测试入口:服务子进程使用本轮绝对数据目录和完整模块配置,不继承 ambient 模块变量,也不读取用户 `.env.local`。Svelte 仅在 `HAI_E2E=1` 的测试分支跳过 dotenv;API 测试直接执行已构建产物。普通开发与生产的上述优先级和共享后端守卫保持不变,transport 使用测试独立可信 ring 与实际 registry。
|
|
68
73
|
|
|
69
|
-
`prod` 是文件模式名,对应 `HAI_CORE_ENV=production`;环境枚举为 `development | test | production | staging`。SvelteKit adapter-node 产物使用 `node
|
|
74
|
+
`prod` 是文件模式名,对应 `HAI_CORE_ENV=production`;环境枚举为 `development | test | production | staging`。SvelteKit adapter-node 产物使用 `node scripts/run-node.mjs prod . build/index.js`。路径相对工作目录,公共文件提交 Git,私有文件不进入镜像或版本库。部署容器由 SDK 统一运行文件加载,浏览器只接收公开白名单。
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
当前 SDK 的 Node 后端默认读取实际挂载的发布 `.env.runtime`,修改后重启容器生效;托管连接保持更高优先级,静态 Web、中间件、网关路径、端口/挂载和 Node 启动参数按部署流程更新。长期修改同步回源环境,下一次后端发布会重新生成;已交付 `hai-deploy` 的工程按该技能“后端运行配置重载”小节处理,未交付时以本工程实际启动/部署脚本为准。自行维护且只使用 Compose `env_file` 注入环境的容器,改文件后需要重新创建,通常无需重建镜像。请求策略可固定引用只读挂载 YAML,后续改文件并重启服务实例重新读取;运行中不监视文件、不逐请求读盘。同一来源先应用 `HAI_SERV` / `HAI_KIT` 父 JSON,再由叶子变量覆盖;更高来源的父对象才清除低来源细项,遵循本节统一来源顺序。待上传归档与 SDK 策略快照不能手改;运维外部文件和 Compose override 另行备份,SDK 自动回滚不恢复外部文件。
|
|
77
|
+
|
|
78
|
+
SDK 的 SvelteKit SSR 在 HTTP/HTTPS 下均通过独立 gateway,后端不公开端口;协议、Host 与客户端地址由网关覆盖,adapter 转发信任由 Compose 固定。adapter-node 6 不读取运行期 `ORIGIN`,不能靠改该变量切换访问地址;应用默认不固定 `paths.origin`,旧直接公开 SSR 的部署须重新生成全量交付包。
|
|
72
79
|
|
|
73
80
|
Fullstack 的环境文件在工程根;service 脚本通过 `../../.env*` 加载,Web/App/Desktop 的 Vite 自动 dotenv 加载关闭(`envDir: false`),开发和预览由 `core.config.loadEnvFiles` 从工程根读取,构建不读取部署环境文件。API workspace 的环境文件在 `apps/<name>-serv/`。独立应用在各自根目录加载。静态 Web 通过 `runtime-config.js` 获取公开地址,部署环境覆盖无需重建镜像;原生包在复制静态资源前配置该入口。修改编译进客户端的默认值时仍需重新构建;fullstack 的公开应用元数据由 service `app.info` 返回。
|
|
74
81
|
|
|
75
82
|
#### 迁移已有项目
|
|
76
83
|
|
|
84
|
+
原生名称复用 `_core.yml` 的 `name` 和 `HAI_CORE_NAME`。Capacitor 通过生成的 `scripts/native-name.mjs` 加载;Desktop 的 `pnpm tauri` / `tauri:dev` / `tauri:build` 入口同时覆盖 `productName` 和主窗口初始标题,保留其他 Tauri 设置,不回写 JSON。Fullstack 使用工程根环境文件和 serv YAML,根开发依赖需要 `@h-ai/core`。原生打包默认 `prod`,Tauri dev 默认 `dev`,进程 `HAI_CORE_ENV` 可切换模式;源码/镜像编译仍不加载部署环境文件。已有 Capacitor 平台工程还需同步 Android `app_name` / `title_activity_main` 和 iOS `CFBundleDisplayName` 后重新打包。
|
|
85
|
+
|
|
77
86
|
先把原来被忽略的 `.env` 私有值迁入 `.env.local`,再提交公共基础和环境文件。本机文件只保留需要覆盖的值,避免整份复制示例后固定开发环境。旧的 `HAI_AI_LLM_API_KEY` / `HAI_AI_LLM_BASE_URL` 改为 `HAI_AI_LLM_APIKEY` / `HAI_AI_LLM_BASEURL`;音频和图像厂商回退变量同样使用 `APIKEY` 后缀。Reach 和 deploy 凭据按当前 YAML 路径命名,以项目 `.env.example` 为准,同步迁移部署平台变量和本机文件。
|
|
78
87
|
|
|
79
88
|
原 `HAI_AI_ANTHROPIC_API_KEY` / `HAI_AI_ANTHROPIC_BASE_URL` 不再使用。默认协议为 `anthropic` 时改用标准 LLM 变量;混合模型池中有独立凭据或端点时,将 `apiKey` / `baseUrl` 配置在对应模型项。厂商回退 `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL` 保留,优先级以 AI 模块说明为准。
|
|
@@ -92,9 +101,9 @@ Fullstack 的环境文件在工程根;service 脚本通过 `../../.env*` 加
|
|
|
92
101
|
| `HAI_CACHE_TYPE` / `HAI_CACHE_DB` | `memory \| redis`;DB 为整数 0–15;memory 仅单进程使用 |
|
|
93
102
|
| `HAI_STORAGE_TYPE` | `local \| s3`;local 要求 root,s3 要求 bucket、region、accessKeyId、secretAccessKey |
|
|
94
103
|
| `HAI_SERV_SERVER_HOST` / `HAI_SERV_SERVER_PORT` | HTTP 主机和整数端口 1–65535;部署平台 HOST/PORT 可覆盖 |
|
|
95
|
-
| `
|
|
104
|
+
| `HAI_AI_LLM_PROTOCOL` / `HAI_AI_LLM_TEMPERATURE` | `chat \| responses \| anthropic`;temperature 为数字 0–2 |
|
|
96
105
|
| `HAI_AI_LLM_APIKEY` / `HAI_AI_LLM_BASEURL` / `HAI_AI_LLM_MODEL` | 厂商密钥、服务 URL、实际可用模型名;启用时满足厂商要求 |
|
|
97
|
-
| `HAI_ADMIN_DEFAULT_PASSWORD` | 首次创建管理员的密码,满足 IAM 密码策略;CLI 为 fullstack 的 `.env.dev/.env.test/.env.prod` 分别生成独立随机值 |
|
|
106
|
+
| `HAI_ADMIN_DEFAULT_PASSWORD` | 首次创建管理员的密码,满足 IAM 密码策略;CLI 为 fullstack 的 `.env.dev.local/.env.test.local/.env.prod.local` 分别生成独立随机值 |
|
|
98
107
|
| `PUBLIC_API_BASE` | 可公开的 API 地址,不得包含用户名、密码或 token |
|
|
99
108
|
|
|
100
109
|
其余变量逐项见对应 `.env.example` 及模块公开 Schema;可选块启用后也应使用相同命名、显式引用与逐项说明。
|
|
@@ -177,7 +186,7 @@ CLI 用户消息通过现有中英字典输出。初始语言按非空的 `HAI_C
|
|
|
177
186
|
|
|
178
187
|
独立 fullstack 默认后台的 Web/App/Desktop 共用管理组件、状态与 typed client。`@h-ai/serv/features/iam` 默认 procedures 可按需选用并与 contract 对齐;有业务缺口时覆写必要路由。主题的 DOM 更新和安全缓存使用 `@h-ai/ui/theme`(`applyTheme` / `getSavedTheme`),应用保留响应式状态与已编译主题白名单。初始 admin/user、管理员自我保护、头像限额、分页和审计策略都是应用示例,可按需求替换;实际权限、资源范围和写入一致性按目标业务落实。
|
|
179
188
|
|
|
180
|
-
Fullstack 创建时在根 `.env.dev/.env.test/.env.prod` 分别写入独立随机 `HAI_ADMIN_DEFAULT_PASSWORD
|
|
189
|
+
Fullstack 创建时在根 `.env.dev.local/.env.test.local/.env.prod.local` 分别写入独立随机 `HAI_ADMIN_DEFAULT_PASSWORD`,文件不提交 Git,克隆后通过受保护配置共享,`.env.example` 保留空占位。`dev` / `start` 自动读取;已有用户不重设密码。启动边界保留模块错误的具体说明与错误码,失败后反序清理。不能把环境凭据复制到前端配置、日志、源码或镜像。
|
|
181
190
|
|
|
182
191
|
## 落实契约与安全边界
|
|
183
192
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 生成应用共同规则
|
|
2
|
+
|
|
3
|
+
本文件随 hai-app-create 完整目录交付。AGENTS 保留当前工程架构,公共约束在这里维护;先读 README、package.json、相关实现与测试,按任务读取所需 skill,不预加载全部参考。
|
|
4
|
+
|
|
5
|
+
## 需求与授权
|
|
6
|
+
|
|
7
|
+
- 业务以用户当前明确要求及其指定需求/设计文档为准;模板角色、权限、流程、字段、限额、存储和架构是初始实现。冲突时在已有授权内适配,同步 contract、鉴权、迁移、界面、配置、测试与过期规则,不要求把需求改回模板。
|
|
8
|
+
- 未说明的业务行为注明假设;只有实质矛盾、优先级不明或真实技术/安全障碍才提出具体问题。只读或仅规划请求不扩展为实现。
|
|
9
|
+
- 框架结构、配置、核心流程或模块边界的重要变化,按 [hai-change-plan](../hai-change-plan/SKILL.md) 说明方案与影响后等待决定;已确认且未扩大的方案不重复确认。普通应用私有实现沿已有授权推进。
|
|
10
|
+
|
|
11
|
+
## 实现与安全
|
|
12
|
+
|
|
13
|
+
- 先用 rg 查实现、引用、测试与文档,保留已有改动。优先复用真实适用的框架能力和公开类型;skill 已交付不表示模块已安装或启用。不为覆盖清单添加无关依赖、抽象或转发层。
|
|
14
|
+
- 按实际安装版本的 exports/types 核验契约。生命周期模块按依赖顺序 init → use → close,每步检查结果、失败清理、关闭反序;core/serv/kit、工厂、纯函数和流按实际签名使用。HaiResult 先判断 success,tx.wrap 返回失败结果不会自动回滚。
|
|
15
|
+
- 服务端校验输入、身份、权限及资源/租户归属;SQL 值参数化、标识符白名单、文件路径防逃逸。不把隐藏按钮当授权,不执行不可信 HTML/AI 内容。
|
|
16
|
+
- 密钥不进入 PUBLIC_/VITE_、浏览器或日志,敏感 token 不写 localStorage;沿现有 Cookie/内存或原生安全存储流程。用户提示准确且脱敏,日志保留英文操作上下文及可关联错误,未知提交不自动重放。
|
|
17
|
+
- 禁止 any、无说明的 as unknown as、console.log、硬编码密钥。注释中文,结构化日志英文且脱敏,用户文本沿现有 i18n 同步全部 locale。
|
|
18
|
+
|
|
19
|
+
## 代码注释与示例
|
|
20
|
+
|
|
21
|
+
- 尽可能补充有信息量的中文 JSDoc:所有 export 的函数/类/方法、核心算法与业务流程、所有数据库表/列、接口/type/schema 及其字段都必须说明用途、单位、约束和关联关系。核心逻辑解释决策原因、边界、权限与失败路径,不逐行复述代码。
|
|
22
|
+
- 函数按实际契约写 @param、@returns,仅确实抛错时写 @throws;异步、HaiResult 与事务失败行为须说明。类型/表结构说明字段含义、可空性、默认值、主外键和唯一约束。
|
|
23
|
+
- 上述函数和结构的 JSDoc 均提供可理解的 @example:函数给调用及结果判断,结构给合法数据,表给典型行或查询示例。省略上下文要标明,不使用真实凭据。示例随实现同步,不能只堆叠没有信息量的注释。
|
|
24
|
+
- 调用及结构示例见 [development.md](development.md) 的 JSDoc 注释一节。
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## 同步与验证
|
|
28
|
+
|
|
29
|
+
按 [沟通与同步维护](collaboration.md) 先说明结论,区分已确认、待验证、计划、完成和未解决。跨边界变更核对实现、配置、注释、README、网站源、模板、调用方、i18n 与测试;共享任务沿 [交接契约](../hai-spec-implement/handoff.md) 续跑。
|
|
30
|
+
|
|
31
|
+
按真实差异、调用方和用户路径选择必要门禁,遵循 [分轮验证](../hai-app-tests/validation.md),不默认全量重跑。UI/路由验证实际交互、失败恢复和适用尺寸/语言/主题;仅在新页面或明显改版时进入已交付的 hai-ui-design,组件实现用 hai-ui,真实页面走查用 hai-ui-review。纯 API 不加载 UI 路径。临时工程、进程、容器和数据在 teardown/finally 清理,只清理本次创建资源;证据放项目忽略目录。
|
|
32
|
+
|
|
33
|
+
完成时说明行为变化、实际复用、已执行门禁、同步文档/依赖方及未验证原因;文档修改明确是否影响运行时代码。
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
- 新增页面(路由)
|
|
10
10
|
- 新增 API 端点
|
|
11
|
-
-
|
|
11
|
+
- 新增服务层模块(`#lib/server/services/`)
|
|
12
12
|
- 新增数据库表 / 数据模型
|
|
13
13
|
- 新增业务组件
|
|
14
14
|
- 修改或修复已有功能、接口和交互
|
|
@@ -197,7 +197,7 @@ export const POST = kit.handler(async ({ request, locals }) => {
|
|
|
197
197
|
|
|
198
198
|
## 创建服务层
|
|
199
199
|
|
|
200
|
-
服务层位于
|
|
200
|
+
服务层位于 `#lib/server/services/`,处理业务逻辑。
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
203
|
import type { HaiResult, PaginatedResult } from '@h-ai/core'
|
|
@@ -237,7 +237,7 @@ export async function listArticles(params: ListParams): Promise<HaiResult<Pagina
|
|
|
237
237
|
|
|
238
238
|
### Schema 定义(SQL DDL)
|
|
239
239
|
|
|
240
|
-
沿用当前应用的迁移/建表入口;仅开发初始化用的简单 SvelteKit 示例可在
|
|
240
|
+
沿用当前应用的迁移/建表入口;仅开发初始化用的简单 SvelteKit 示例可在 `#lib/server/init.ts` 建表。不要把本例 SQLite DDL 无修改复制到 PostgreSQL/MySQL,迁移与索引需匹配实际数据库。
|
|
241
241
|
|
|
242
242
|
```typescript
|
|
243
243
|
const BUSINESS_SCHEMA = `
|
|
@@ -279,13 +279,13 @@ interface CreateArticleInput {
|
|
|
279
279
|
|
|
280
280
|
## 创建业务组件
|
|
281
281
|
|
|
282
|
-
业务组件放在
|
|
282
|
+
业务组件放在 `#lib/components/`,通用 UI 使用 `@h-ai/ui`。
|
|
283
283
|
|
|
284
284
|
```svelte
|
|
285
285
|
<!-- src/lib/components/ArticleCard.svelte -->
|
|
286
286
|
<script lang="ts">
|
|
287
|
-
import type { Article } from '
|
|
288
|
-
import * as m from '
|
|
287
|
+
import type { Article } from '#lib/types/article.js'
|
|
288
|
+
import * as m from '#lib/paraglide/messages.js'
|
|
289
289
|
|
|
290
290
|
let { article, onEdit }: { article: Article, onEdit?: () => void } = $props()
|
|
291
291
|
</script>
|
|
@@ -311,11 +311,11 @@ interface CreateArticleInput {
|
|
|
311
311
|
- 事件回调通过 props 传入(非 `createEventDispatcher`)
|
|
312
312
|
- 样式使用 TailwindCSS 4 + DaisyUI 5 class
|
|
313
313
|
- 通用 UI 组件优先使用 `@h-ai/ui`,不重复实现
|
|
314
|
-
- i18n 文本使用
|
|
314
|
+
- i18n 文本使用 `#lib/paraglide/messages.js` 中的 key
|
|
315
315
|
|
|
316
316
|
## 初始化顺序
|
|
317
317
|
|
|
318
|
-
CLI 项目统一忽略 `**/data/`,含根目录、workspace 子目录及 `.gitkeep`;数据库/上传文件不入 Git
|
|
318
|
+
CLI 项目统一忽略 `**/data/`,含根目录、workspace 子目录及 `.gitkeep`;数据库/上传文件不入 Git。每个模板只安装实际使用的模块,同时在应用 config 保留 core、serv、kit、db、cache、iam、storage、audit、reach、ai、vecdb、payment、scheduler、feedback 共 14 份 YAML;纯客户端的服务端配置仅作参考。构建部署配置统一位于项目根 hai.json,未启用模块整份注释,可选字段及替代 Provider 按块注释,`.env.example` 保留全部模块变量,未启用项不进入公共环境默认值。新增功能时添加对应依赖、启用所需配置,并接入初始化、反序关闭和业务路由;添加依赖不会自动接入模块。LDAP 只有在 login.ldap 为 true 时才参与部署扫描。
|
|
319
319
|
|
|
320
320
|
H5 所有页面继承根布局的 header/footer;认证页隐藏底部导航,业务页面使用 `@h-ai/ui` 的 `BottomNav` 与移动端壳样式,导航启用 centered/maxWidth/safeArea,与页面同宽。
|
|
321
321
|
|
|
@@ -325,7 +325,7 @@ H5 所有页面继承根布局的 header/footer;认证页隐藏底部导航,
|
|
|
325
325
|
|
|
326
326
|
Fullstack 的公共 `.env` 启用当前模块的运行参数,YAML 显式引用同名变量并保留本地回退;未启用模块与可选字段保留注释。环境文件的用途、加载优先级及私有值保存方式遵守 [环境配置规范](development.md#环境配置),模块仍按公开 Schema 校验。
|
|
327
327
|
|
|
328
|
-
复用当前应用服务端启动/关闭入口;SvelteKit 通常为
|
|
328
|
+
复用当前应用服务端启动/关闭入口;SvelteKit 通常为 `#lib/server/init.ts`,API/fullstack 使用已有 service/serv 初始化文件。下列是启用 IAM 时的常见依赖关系,不要求无关应用安装这些模块:
|
|
329
329
|
|
|
330
330
|
```
|
|
331
331
|
core.init() → crypto.init() → reldb.init() → cache.init() → iam.init() → createBusinessTables()
|
|
@@ -339,7 +339,7 @@ core.init() → crypto.init() → reldb.init() → cache.init() → iam.init()
|
|
|
339
339
|
|
|
340
340
|
- 保持脚手架 `images/*.Dockerfile`、`.dockerignore` 与 `package.json` 中 `build` / `compile` 命令与 hai.json 的 build/deploy 配置同步。保留 `.gitattributes`,让 `.dockerignore`、Dockerfile 和 POSIX 脚本统一使用 LF,保持跨平台输入一致并确保 Linux 脚本可运行。
|
|
341
341
|
- Podman 多阶段构建保持 `--format docker --jobs=1`;前者保留 `HEALTHCHECK`,后者避免部分 Podman 5.8/Buildah 组合在并行 stage 构建时触发内部 semaphore panic。
|
|
342
|
-
- 先复制 lockfile、workspace 配置与构建器准备的 `images/dependencies/` 安装输入执行 `pnpm fetch --ignore-scripts
|
|
342
|
+
- 先复制 lockfile、workspace 配置与构建器准备的 `images/dependencies/` 安装输入执行 `pnpm fetch --ignore-scripts`,再离线安装、复制源码并构建;fetch、安装和 `pnpm pm deploy` 共用 pnpm store,安装与生产依赖整理共用 SQLite 驱动缓存,使源码变化复用下载与安装层,兼容新增 workspace、本地归档与补丁。
|
|
343
343
|
- 默认容器面向 CPU 运行或远程 AI 服务,Dockerfile 设置 `ONNXRUNTIME_NODE_INSTALL_CUDA=skip`,跳过额外 CUDA/TensorRT 下载;使用宿主机 GPU 时定制镜像和运行参数,不修改本机 npm 或全局 AI/GPU 配置。
|
|
344
344
|
- SvelteKit 服务使用 Node adapter;纯 Vite 前端使用带 SPA fallback 的静态镜像;fullstack 的 Service 与 Web 分别交付,Service 直接监听且不增加转发进程。
|
|
345
345
|
- Web 的 `PUBLIC_*` 部署配置在容器启动时生成静态运行时配置,不作为 build arg 烘焙,确保同一镜像可跨环境部署。
|
|
@@ -136,7 +136,7 @@ describe('article persistence', () => {
|
|
|
136
136
|
### Schema 校验测试模板
|
|
137
137
|
|
|
138
138
|
```typescript
|
|
139
|
-
import { CreateUserSchema } from '
|
|
139
|
+
import { CreateUserSchema } from '#lib/server/schemas/user.js'
|
|
140
140
|
// tests/schemas/user-schema.test.ts
|
|
141
141
|
import { describe, expect, it } from 'vitest'
|
|
142
142
|
|