@h-ai/cli 1.0.0-beta.23 → 1.0.0-beta.24

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@h-ai/cli",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.23",
4
+ "version": "1.0.0-beta.24",
5
5
  "description": "Hai Framework CLI for project scaffolding and code generation.",
6
6
  "license": "Apache-2.0",
7
7
  "keywords": [
@@ -30,7 +30,7 @@
30
30
  "node": "^22.23.4 || ^24.22.1 || ^26.12.1"
31
31
  },
32
32
  "dependencies": {
33
- "@h-ai/core": "1.0.0-beta.23",
33
+ "@h-ai/core": "1.0.0-beta.24",
34
34
  "cac": "^7.1.0",
35
35
  "chalk": "^6.0.1",
36
36
  "fast-wrap-ansi": "^0.2.2",
@@ -41,18 +41,18 @@
41
41
  "yaml": "^2.9.1"
42
42
  },
43
43
  "devDependencies": {
44
- "@h-ai/api-client": "1.0.0-beta.23",
45
- "@h-ai/cache": "1.0.0-beta.23",
46
- "@h-ai/crypto": "1.0.0-beta.23",
47
- "@h-ai/deploy": "1.0.0-beta.23",
48
- "@h-ai/feedback": "1.0.0-beta.23",
49
- "@h-ai/iam": "1.0.0-beta.23",
50
- "@h-ai/kit": "1.0.0-beta.23",
51
- "@h-ai/payment": "1.0.0-beta.23",
52
- "@h-ai/reach": "1.0.0-beta.23",
53
- "@h-ai/reldb": "1.0.0-beta.23",
54
- "@h-ai/storage": "1.0.0-beta.23",
55
- "@h-ai/vecdb": "1.0.0-beta.23",
44
+ "@h-ai/api-client": "1.0.0-beta.24",
45
+ "@h-ai/cache": "1.0.0-beta.24",
46
+ "@h-ai/crypto": "1.0.0-beta.24",
47
+ "@h-ai/deploy": "1.0.0-beta.24",
48
+ "@h-ai/feedback": "1.0.0-beta.24",
49
+ "@h-ai/iam": "1.0.0-beta.24",
50
+ "@h-ai/kit": "1.0.0-beta.24",
51
+ "@h-ai/payment": "1.0.0-beta.24",
52
+ "@h-ai/reach": "1.0.0-beta.24",
53
+ "@h-ai/reldb": "1.0.0-beta.24",
54
+ "@h-ai/storage": "1.0.0-beta.24",
55
+ "@h-ai/vecdb": "1.0.0-beta.24",
56
56
  "@types/fs-extra": "^11.0.4",
57
57
  "@types/node": "^26.6.6",
58
58
  "@types/prompts": "^2.4.9",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "engines": { "node": "^22.23.4 || ^24.22.1 || ^26.12.1" },
3
3
  "name": "{{projectName}}",
4
- "version": "1.0.0-beta.23",
4
+ "version": "1.0.0-beta.24",
5
5
  "private": true,
6
6
  "packageManager": "pnpm@12.11.2",
7
7
  "description": "{{#if_eq appType 'admin'}}Enterprise management system built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'website'}}Enterprise website built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'h5'}}Mobile H5 app built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'api'}}REST API service built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'mobile-app'}}Mobile app built with hai Agent Framework{{/if_eq}}",
@@ -10,13 +10,21 @@ ACP 把宿主应用接到能操作工程的智能体。`ai.llm` 负责模型调
10
10
  | `builtin-service` | 使用已构建镜像启动专属容器 | 引用 Hai 模型;workspace volume 挂 `/workspace`,状态卷挂 `/state` |
11
11
  | `custom-service` | 已有原生 HTTP/WS ACP 服务 | 远端自行维护模型;传远端可见的 cwd;框架不操作远端 Git |
12
12
 
13
- Codex 用 `adapter: 'codex'`,DeepSeek Harness 用 `adapter: 'deepseek-harness'`,其他已配置模型的 ACP 程序用 `adapter: 'generic'` 和 `command/args`。需生成其他原生配置时,向 `ai.init(config, { acpAdapters })` 提供可信服务端适配器;适配器返回 command、args、env、可选 files(写到隔离状态目录)。不把密钥存入 Agent 定义,`environmentRefs` 是目标变量名到宿主环境变量名的映射。
13
+ Codex 用 `adapter: 'codex'`,DeepSeek Harness 用 `adapter: 'deepseek-harness'`,Goose 用 `adapter: 'goose'`。其他已配置模型的 ACP 程序用 `adapter: 'generic'` 和 `command/args`。需生成其他原生配置时,向 `ai.init(config, { acpAdapters })` 提供可信服务端适配器。适配器返回 command、args、env 和写到隔离状态目录的可选 files。`environmentRefs` 保存目标变量名到宿主环境变量名的映射。
14
14
 
15
- 内置 Codex/dsh 通过 stdio 使用。HTTP/WS 是锁定 SDK 2.2.0 的官方实验传输,服务必须实现相同的 ACP 传输版本;不把任意 HTTP 聊天接口当 ACP,也不自动架设 stdio 网关。自定义服务必须声明 `supportedTransports`,协议不匹配返回错误。
15
+ 内置 Codex、DSH 和 Goose 通过原生 stdio 接入。HTTP/WS 是锁定 SDK 2.2.0 的官方实验传输,服务必须实现相同的 ACP 传输版本。自定义服务必须声明 `supportedTransports`,协议不匹配返回错误。
16
+
17
+ Agent 镜像按任务选择 `minimal`、`documents`、`office`、`browser` 或 `developer`。将构建后的镜像 ID 或仓库清单 digest 登记到 Runner 环境。无需在任务内安装工具链。需要直接处理文件时,也可使用具备相应权限的独立工具作业。
18
+
19
+ 使用 `session.changeExecution({ mode: 'task', acceptNewSession: true, historySummary })` 切换到任务独占容器时,可带入当前用户确认过的历史摘要。摘要最多 8 KiB UTF-8,作为新会话首次请求的历史文本发送一次。会话工具和资料仍按当前授权重新核验。
20
+
21
+ 受管请求可传 `workspaceId`。应用用 `acpPolicy.allowWorkspace` 核验主体,用 `resolveWorkspace` 在执行节点提供文件名到 `Uint8Array` 的映射。快照最多 8 个平铺文件、合计不超过 16 MiB 和环境 `scratchMiB`,仅挂载到独占任务的只读 `/input`。临时副本写入 `/workspace`,会话结束后回收。
16
22
 
17
23
  Linux 上运行 embedded Codex 前,按 [Codex 沙箱前置](https://learn.chatgpt.com/docs/sandboxing) 准备 bubblewrap 和所需的 AppArmor profile,并用 `codex sandbox` 在临时目录验证读写。沙箱初始化失败应先修复宿主环境,不能通过关闭沙箱或让模型猜测文件内容完成任务。
18
24
 
19
- ## 原生 HTTP/WS 服务:Goose
25
+ ## Goose 的原生接入
26
+
27
+ 受管 Goose 使用 `goose acp`,选择 `adapter: 'goose'`、`mode: 'embedded'` 或 `'builtin-service'`,绑定登记的 Hai 模型。适配器使用独立 Goose 状态目录和逐次工具审批,模型协议支持 Chat Completions、Responses 和 Anthropic。Goose 和 DSH 的每次受管启动只注入本次选中模型的凭据。
20
28
 
21
29
  Goose 1.57.0 自身提供 `goose serve` 与 `/acp` HTTP/WS,使用 custom-service 接入。先由部署方启动服务、挂载工作区/状态卷,并在 Goose 端维护模型(例如 `GOOSE_PROVIDER=openrouter`、`GOOSE_MODEL`、`OPENROUTER_API_KEY`);服务独立设置 `GOOSE_SERVER__SECRET_KEY`。Hai 只使用 `X-Secret-Key` 认证,不向服务注入 Hai 模型密钥。
22
30
 
@@ -42,6 +50,62 @@ WebSocket 改为 `transport: 'ws'` 和 `ws://` 地址。`cwd` 是远端可见路
42
50
 
43
51
  `acp.agents`、`acp.workspaces` 可以直接写在配置文件里,也可通过 register 保存到数据库。get/list 返回 `{ value, source, version? }`,配置同 ID 优先且不可修改;数据库支持完整 update 和 remove。模型、MCP 等清单也遵循此规则,见 [资源清单](resources.md)。创建会话可通过 `mcpServerIds` 绑定合并清单里的 MCP。
44
52
 
53
+ ## 为受管会话绑定第三方工具
54
+
55
+ 先在 `mcp.servers` 登记第三方 Streamable HTTP 服务,设置 `allowedTools` 和上游认证头引用。每个执行节点挂载自己的工具入口,并给 Worker 提供可达的地址。入口只把当前会话的短期 Bearer 传给 Agent,真实上游凭据由服务端解析。建议使用执行节点的内网服务地址和受保护的网络。
56
+
57
+ ```ts
58
+ import { createServer } from 'node:http'
59
+ import { ai, type ACPPlatformPolicy, type MCPServiceBroker, type MCPServiceBrokerOptions } from '@h-ai/ai'
60
+
61
+ // 应用传入真实 IAM 检查。该函数复核任务归属、权限及实际工具参数。
62
+ function prepareTools(url: string, authorize: MCPServiceBrokerOptions['authorize']) {
63
+ let broker: MCPServiceBroker | undefined
64
+ const http = createServer((req, res) => {
65
+ if (broker) return void broker.handleRequest(req, res)
66
+ res.writeHead(503).end()
67
+ })
68
+ const policy: ACPPlatformPolicy = {
69
+ // 示例只给 manuals 租户的 librarian 账号开放这一个工具。
70
+ allowTools: (scope, _agentId, ids) =>
71
+ scope.tenantId === 'manuals' && scope.userId === 'librarian' && ids.every(id => id === 'manual_search'),
72
+ async bindTools(scope, sessionId, ids, signal) {
73
+ if (!broker || ids.length !== 1 || ids[0] !== 'manual_search')
74
+ throw new Error('Manual tool binding is unavailable')
75
+ const bound = await broker.bind({
76
+ principal: { tenantId: scope.tenantId, userId: scope.userId },
77
+ taskId: sessionId,
78
+ signal,
79
+ tools: [{
80
+ id: 'manual_search',
81
+ serviceId: 'manual',
82
+ tool: 'search_manual',
83
+ description: 'Search authorized manuals',
84
+ inputSchema: {
85
+ type: 'object', properties: { query: { type: 'string', maxLength: 1000 } },
86
+ required: ['query'], additionalProperties: false,
87
+ },
88
+ }],
89
+ })
90
+ if (!bound.success) throw new Error(bound.error.message)
91
+ return bound.data
92
+ },
93
+ }
94
+ return {
95
+ http, policy,
96
+ activate() {
97
+ // ai.init(config, { runner, acpPolicy: policy }) 成功后,监听 HTTP 端口之前激活。
98
+ const created = ai.mcp.services.createBroker({ url, authorize })
99
+ if (created.success) broker = created.data
100
+ return created
101
+ },
102
+ close() { broker?.close() },
103
+ }
104
+ }
105
+ ```
106
+
107
+ 创建绑定时,工具入口为每项工具检查目录白名单和输入 Schema。每次调用重新检查业务权限和目录,网络重定向会失败。绑定默认有效 15 分钟。会话关闭、租约失效或服务停止时撤销绑定。多个执行节点分别挂载自己的入口,使 Agent 始终访问签发本次凭据的节点。
108
+
45
109
  ## 最小本机接入
46
110
 
47
111
  下面的目录、Git 地址、模型和密钥由部署方提供。首次登记一次,后续用 get/list 读取;重复 register 返回冲突。普通 API 都先检查 `success`。