agentscope-ai / agentscope-ai/AgentTeams
[Feature Request] Human 资源缺少 PUT/PATCH 路由 —— 无法在已存在的 Human 上追加 accessibleWorkers
- Vorherrschende Sprache
- Go
- Sterne
- 5.6k
- Forks
- 692
- Ø Merge
- 5 T. 4 Std.
- Gemergte PRs (30 T.)
- 23
Beschreibung
### 摘要
HiClaw 当前提供 `POST /api/v1/humans`、`GET /api/v1/humans/{name}`、`DELETE /api/v1/humans/{name}`,但**没有** `PUT /api/v1/humans/{name}` 或 `PATCH /api/v1/humans/{name}`。这导致**已存在的 Human 资源无法被 mutate**,最直接的阻塞是:当用户后续被授权第二个 Worker 时,**无法把新 Worker 追加到 `Human.spec.accessibleWorkers`**。
对应到 CLI 层:`hiclaw update` 只支持 `manager / team / worker`,**没有 `update human` 子命令**;`hiclaw apply -f human.yaml` 在目标已存在时不能 update(详见复现)。
### 环境
- HiClaw controller: `Controller: dev, Mode: embedded`(`hiclaw status` 输出)
- HiClaw CLI: 同 controller container,本地 docker 部署
- 部署形态:`hiclaw-controller` + 多个 `hiclaw-worker-*` container 在同一 docker compose 网络里
- API base: `http://hiclaw-controller:8090/api/v1`
### 复现
直接对 controller REST API 用 curl 枚举 method 支持:
```bash
# 在 hiclaw-controller container 里:
for method in GET PUT PATCH DELETE; do
curl -s -o /dev/null -w "%{http_code} %{method}\n" \
-X $method http://localhost:8090/api/v1/humans/dummy-name \
-H "Content-Type: application/json" -d "{}"
done
```
观察到的 HTTP 状态码(dummy-name 是任意不存在的 Human 名):
| Method | `/api/v1/humans/{name}` | `/api/v1/workers/{name}`(对照) |
|---|---|---|
| `GET` | 401 (路由存在,需 auth) | 401 |
| `PUT` | **405 Method Not Allowed** | **401** ✓ |
| `PATCH` | **405 Method Not Allowed** | 405 |
| `DELETE` | 401 | 401 |
> 401 表示"路由存在但需要 bearer token 认证";405 表示"路由完全没有挂这个 method 的 handler"。
> 因此 Worker 单实例**有** PUT(路由层接受),Human 单实例**没有** PUT、也没有 PATCH。
> Worker 自身也没有 PATCH,说明 HiClaw 的整体风格是 PUT-style replace,并非 merge —— 这条对修复方向有意义。
CLI 层的对应观察:
```
$ hiclaw update --help
Available Commands:
manager Update a Manager
team Update a Team
worker Update a Worker
```
无 `update human` 子命令。
**`hiclaw apply -f human.yaml` 实测**(对已存在的 Human `tester-a` apply 一份带 `accessibleWorkers` 的 spec):
```
$ hiclaw apply -f /tmp/test-apply-human.yaml
Error: update human/tester-a: HTTP 405: Method Not Allowed
```
这一条很有意思:**CLI 已经实现了 update 路径**(错误信息说"update human/tester-a",说明 CLI 先 GET 探测存在,然后尝试 PUT),只是 backend 没挂 PUT handler 所以返回 405。也就是说**修复只需要 server side 加 PUT route,CLI 不需要任何改动**。
### 期望
`PUT /api/v1/humans/{name}`(和 `hiclaw update human ...`)存在并语义对称于 Worker:
- 用 PUT 替换 `spec`(含 `accessibleWorkers / accessibleTeams / displayName / email / permissionLevel / note`)。
- **`metadata.name` 不可变**(用作主键)。
- **immutable 字段** —— 我们假定包括 Matrix identity、initialPassword、createdAt、Matrix device IDs 等 —— 应该被 PUT **保留**(即使 client 没在请求 body 里带这些字段,server 不应该清空它们)。这一条是 Human 与 Worker 的关键差异:Worker 没有 initialPassword 这种"一次性"字段,但 Human 有,所以语义需要明确。
- 行为可以参考 Worker:`PUT /api/v1/workers/{name}` 已经在 Worker 上工作了,BFF 当前用 `hiclaw apply -f worker.yaml` 走两步 apply(先 zip 后 channelPolicy),第二步就是依赖 Worker 的 update 能力。
`hiclaw update human --name --accessible-workers worker-a,worker-b` 这样的 CLI 入口能把流程闭环。
### 我们为什么需要这个 —— 实际场景
我们在 `agentscope-ai/HiClaw` 之上做了一个 BFF + PWA(项目内部代号 haopaw),交互模型如下:
- 一个**最终用户** = 一个 HiClaw `Human` 资源。每个 Human 在 Matrix 上有一个固定身份和密码。
- 一个**业务**(如"路灯操作")= 一个 HiClaw `Worker` 资源(`accessibleWorkers` 列表里的一项)。
- 一个用户可能被授权使用**多个业务**。
所以"用户授权新业务" = "把新 worker 加进 `Human.spec.accessibleWorkers`"。**没有 PUT,就只能选**:
1. **Delete 旧 Human + Create 新 Human**:会重置 Matrix identity(用户被踢出旧房间、initialPassword 被消耗一次性、设备 ID 全部失效)。从普通用户视角等于"账号清空",**违背产品"无感扩展业务"的目标**。
2. **不支持多业务**:这就是我们当前的状态(BFF 代码会 hard-raise,附 message "Phase 2 prereq: upstream Human PUT support",见 `bff/bff/provisioning/service.py:84-89`)。
我们已经在 Phase 1 的代码里因为这条限制做了一个 awkward 的妥协:**Worker 必须先创建,然后才能 create Human 一次性带上 `accessibleWorkers=[worker_name]`**。也就是说我们利用了 Worker 已经存在的事实来回避 PUT Human 的需求,但这只能 cover "一次性" provision,无法 cover "事后追加"。这个顺序约束本身也带来过启动顺序竞态问题,我们 Phase 1 close-out 的时候吃过亏。
### 建议的 API 形状(供讨论)
1. **PUT `/api/v1/humans/{name}`**(首选,与 Worker 对称)
- Request body:完整 `spec`。
- Server 行为:替换 `spec` 字段,保留所有 immutable 字段(`metadata.name / metadata.createdAt / initialPassword`、Matrix `userId / device IDs / passwordHash`)。
- 失败条件:
- 试图修改 `metadata.name` → 400。
- 试图设置 server-managed 字段(如 `initialPassword`)→ 400 / 字段被 server 忽略,文档说明清楚。
- `accessibleWorkers` 中引用的 Worker 不存在 → 400(与 create 时的校验一致)。
2. **CLI 入口**:`hiclaw update human --name [--accessible-workers x,y] [--display-name ...] ...`,flags 与 `create human` 对齐。
3. **`hiclaw apply -f human.yaml`** 对已存在 Human 也走该 PUT 路径(即 generic apply 对所有 resource 都是 declarative create-or-update)。**注意 CLI 已经实现了这条路径**(实测见上文,错误信息"update human/...: HTTP 405"),所以加了 backend PUT handler 之后 `apply -f` 就直接能用,不需要再改 CLI。
### 不推荐 / 可能不该做
- **PATCH(部分字段)**:HiClaw 现有风格(Worker 也只有 PUT,没 PATCH)是 declarative replace。引入 PATCH 会让 Human 的语义和 Worker 不一致;PUT replace 已经够用。
- **直接放开 `metadata.name` 的修改**:会破坏 Matrix 身份的稳定性,且 BFF 会需要做 binding 表迁移。
### 影响
- Phase 2 多业务入口("一个用户同时持多个 worker entitlement")在 haopaw 侧**完全阻塞**,无法绕开。
- 任何想用 HiClaw 做"用户的 worker 集合会随时间增长"的下游产品都会撞到这条限制。
- 当前的 workaround(**只允许"用户的第一个业务"被 provision,后续硬拒**)是产品上不可接受的;只在 Phase 1 单业务(streetlight)配置下没暴露。
### 相关链接
- HiClaw repo:https://github.com/agentscope-ai/HiClaw
- 我们的 BFF 代码里关于这个 prereq 的位置:`bff/bff/provisioning/service.py` `provision_entitlement` 顶部 docstring + line 84-89 的 hard-fail 分支。
- 我们已经提交的另一个 HiClaw upstream issue(不同问题):#728 —— `copaw-worker` 启动 race;列在这里只是为了说明我们正在系统性向上反馈,不是同一 bug。
### Documentation follow-up
修 PUT route 后建议同步把 `hiclaw apply -f` 在各 resource 类型上的语义表写进 CLI help 或 README:
- 当前 `hiclaw apply --help` 只详写了 `worker` 子命令的 create-or-update 行为;generic `-f` 模式对 Human / Team / Manager 的 "create or update / create only" 语义没有公开文档。
- 实测发现 CLI 在 generic `-f` 路径上对已存在的 Human 会尝试 PUT 然后失败,但 maintainer 没有把"哪些 resource 在 generic apply 路径上支持 update"明示给用户——同步补这张表能避免下游 BFF 写错调用顺序。
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Bewertung
Dieses Issue wurde noch nicht bewertet.