diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1aeb0a0 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,64 @@ +# CLAUDE.md — Heicode 单仓导航(给 Claude Code / 助手) + +本文是 **仓库根级** 的快速地图与协作约定。细分栈的规则请看各子目录自带文档(避免重复与漂移)。 + +## 仓库地图(explore 摘要) + +| 路径 | 角色 | 栈 / 备注 | +|------|------|-----------| +| `cc-haha/` | **Heicode** 客户端:CLI(Ink)+ 本地 HTTP/WS 服务 + **Desktop**(Tauri + React) | Bun + TypeScript;产品入口 `bin/heicode` | +| `new-api/` | **Heicode Manager**:网关 + 管理控制台 | Go(Gin/GORM)+ `web/default` 前端(Bun/Rsbuild/React) | +| `website/` | 产品介绍站点 | Next.js;根 `docker-compose.yml` 提供 `heicode-www` :8888 | +| `docs/` | 愿景、**里程碑**(`docs/milestones/`)、**Agnet 集成**(`docs/integration/`) | Markdown | + +根 `package.json` 仅少量 workspace 级依赖(如适配器用到的包);**主要开发依赖在 `cc-haha/package.json`**。 + +## 权威子文档(改代码前先打开对应一篇) + +- **客户端(cc-haha)**:[`cc-haha/AGENTS.md`](./cc-haha/AGENTS.md) — 目录结构、运行命令、测试、提交约定。 +- **网关(new-api)**:[`new-api/CLAUDE.md`](./new-api/CLAUDE.md) — Go 分层、JSON/i18n/DB 规则等。 +- **产品愿景与交付节奏**:[`docs/vision-heicode-full-stack-agentic-dev.md`](./docs/vision-heicode-full-stack-agentic-dev.md)、[`docs/milestones/README.md`](./docs/milestones/README.md)。 + +## 最小开发闭环 + +```bash +# 依赖(客户端主体) +cd cc-haha && bun install + +# 终端 A:本地 API(桌面端依赖) +bun run src/server/index.ts + +# 终端 B:桌面 +cd desktop && bun run tauri dev +``` + +联调本机 Manager(new-api)时常见: + +```bash +HEICODE_TAIJIAICLOUD_BASE_URL=http://localhost:3000 bun run src/server/index.ts +``` + +更多变量见 `cc-haha/src/server/config/providerPresets.ts` 与 `cc-haha/src/server/api/heicode-auth.ts`(如 `HEICODE__OAUTH_*`)。 + +## Heicode ↔ Manager 关键触摸点(代码索引) + +- **客户端登录 / Provider**:`cc-haha/src/server/api/heicode-auth.ts`,路由前缀 `/api/heicode-auth/*`(由 `cc-haha/src/server/router.ts` 挂载)。 +- **模型发现**:`cc-haha/src/server/services/providerService.ts`、`cc-haha/src/server/api/providers.ts`。 +- **Provider 预设**:`cc-haha/src/server/config/providerPresets.json` + `providerPresets.ts`。 +- **Manager 侧 Heicode OAuth**:`new-api/controller/heicode_oauth.go`,路由 `new-api/router/heicode-router.go`(例如 `/heicode/oauth/authorize`、`/heicode/oauth/session`)。 + +## 协作约定(根级) + +1. **改哪一层跟哪篇文档**:Go 行为以 `new-api/CLAUDE.md` 为准;客户端 TS/React 以 `cc-haha/AGENTS.md` 为准。 +2. **小步提交**:沿用历史风格(如 `feat:` / `fix:` / `docs:`);PR 写清影响面与验证步骤。 +3. **集成与「SK」边界**:平台契约见 [`docs/integration/agnet-platform-api-design.md`](./docs/integration/agnet-platform-api-design.md),里程碑见 `docs/milestones/`。 +4. **不要臆测计费**:计费与订阅在平台侧,不在 Heicode 客户端内实现。 + +## Docker / 站点 + +- 根目录 [`docker-compose.yml`](./docker-compose.yml):构建 `website/` 静态站点镜像(端口 **8888**)。 +- Manager 本地编排以 `new-api/docker-compose.yml` 及仓库内 override 为准(若存在)。 + +--- + +*若本文件与子目录 `AGENTS.md` / `CLAUDE.md` 冲突,以子目录为准并及时更新根文件摘要。* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..f87ef84 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,39 @@ +# Heicode 文档入口 + +本目录是 Heicode 仓库的**文档主索引**。整体内容按受众分两条阅读路径,再共享一组通用骨架。 + +## 共用骨架(建议都先读) + +| 文档 | 用途 | +|------|------| +| [`vision-heicode-full-stack-agentic-dev.md`](./vision-heicode-full-stack-agentic-dev.md) | 产品愿景与协作范式(方向性,非排期) | +| [`glossary.md`](./glossary.md) | 术语表:Heicode / Manager / 客户端 / 子 agent / SK 等 | +| [`architecture.md`](./architecture.md) | 架构图与关键数据流(mermaid) | +| [`sk-lifecycle.md`](./sk-lifecycle.md) | SK(Skill 资产)单点真相:来源、快照、刷新、写权边界 | + +## 路径 A · 内部研发 / 新成员上手 + +适合刚加入团队、负责 `cc-haha`(客户端)或 `new-api`(Manager)开发的同学。 + +1. [`onboarding/README.md`](./onboarding/README.md):阅读顺序 +2. [`onboarding/local-dev.md`](./onboarding/local-dev.md):本地联调步骤与排错 +3. [`onboarding/env-variables.md`](./onboarding/env-variables.md):环境变量手册 +4. 回到共用骨架:[`architecture.md`](./architecture.md) → [`glossary.md`](./glossary.md) +5. 计划与现状:[`milestones/README.md`](./milestones/README.md)、[`milestones/STATUS.md`](./milestones/STATUS.md) + +## 路径 B · Agnet / 平台集成方 + +适合实现 Agnet 平台侧、与 Heicode 对接编排或事件流的工程师。 + +1. [`glossary.md`](./glossary.md) → [`architecture.md`](./architecture.md) +2. [`integration/README.md`](./integration/README.md):集成方阅读地图 +3. [`sk-lifecycle.md`](./sk-lifecycle.md):SK 边界(Heicode 端写、Agnet 只读快照) +4. [`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md):详细 API 设计 +5. [`integration/heicode-oauth-flow.md`](./integration/heicode-oauth-flow.md):HeiCode 客户端 ↔ Manager 浏览器登录流程 +6. 落地节奏:[`milestones/README.md`](./milestones/README.md)(M3–M5)+ [`milestones/STATUS.md`](./milestones/STATUS.md) + +## 关于版本与更新 + +- 本目录下的文档以 **设计意图与契约语义** 为准;实现细节以仓库代码为准。 +- 任一文档与代码出现冲突时,请在 PR 里同步更新文档与 [`milestones/STATUS.md`](./milestones/STATUS.md)。 +- 受众边界:`docs/` 内不做产品营销文案,营销内容归 `website/`。 diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..08e2c3e --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,126 @@ +# Heicode 架构与关键数据流 + +本文用 mermaid 图示统一表达 **Heicode 客户端 / Manager / Agnet** 之间的边界与数据流,作为愿景与集成 API 设计的视觉补充。 + +> 与文字版的对应关系:[`vision-heicode-full-stack-agentic-dev.md`](./vision-heicode-full-stack-agentic-dev.md) 第五节、[`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md) §1.1 / §5 / §6 / §7。 + +--- + +## 一、概念分层(鸟瞰) + +```mermaid +flowchart TD + entry["人机入口
官网 · 控制台 · CLI · Desktop"] + manager["Heicode Manager
(new-api)"] + client["Heicode 客户端
(cc-haha)"] + agnet["Agnet 平台
(角色模板 · 执行单元)"] + assets["资产与环境
仓库 · 流水线 · 运行时"] + + entry --> manager + entry --> client + manager <--> client + manager --> agnet + client -. "会话子 agent 输出" .- agnet + agnet --> assets + manager --> assets +``` + +要点: +- **同一身份与策略边界** 跨越 Manager 与客户端 +- 编排细节归 Agnet 内部;Heicode 关注 **契约、体验与安全边界** +- 资产层(仓库 / 流水线 / 运行时)是被动载体 + +--- + +## 二、HeiCode 客户端 ↔ Manager ↔ Agnet 主链路 + +```mermaid +flowchart LR + user["开发者"] + desktop["Heicode 客户端
(Desktop / CLI + 本地服务)"] + manager["Heicode Manager"] + agnet["Agnet 平台"] + + user --> desktop + desktop -->|"OAuth: /heicode/oauth/*"| manager + desktop -->|"Anthropic Messages /
OpenAI Chat 调用"| manager + manager -->|"模型路由 / 计费 / RBAC"| manager + manager -->|"M2M JWT · 部署/查询编队"| agnet + agnet -->|"webhook / events"| manager + agnet -.->|"sub_agent.output (SSE/WS)"| desktop +``` + +关键边界: +- 客户端 **不直连** 模型供应商,所有调用经 Manager 路由 +- Manager 用 **服务账号 / 用户委派令牌** 调 Agnet +- 客户端按 [`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md) §6.4 订阅会话内子 agent 输出流 + +--- + +## 三、SK 数据流(Git / Upload → 快照 → 子 agent 注入) + +```mermaid +flowchart TB + authoring["SK 编辑入口
仅 Heicode 客户端"] + git["Git 仓库
(SK 事实源)"] + upload["上传制品
(对象存储 / artifact_id)"] + manager["Heicode Manager
展开 sk_sources 与刷新策略"] + agnet["Agnet 平台"] + snapshot["不可变快照
commit_sha · artifact 版本"] + subAgent["Agnet 子 agent
(运行时只读)"] + + authoring -->|"git push"| git + authoring -->|"上传 / 替换"| upload + manager -->|"声明 sk_sources"| agnet + git -->|"fetch + checkout ref"| agnet + upload -->|"只读获取"| agnet + agnet --> snapshot + snapshot -->|"注入"| subAgent +``` + +要点: +- SK **写入路径单一**:经 Heicode 客户端到 Git,或经 Heicode 上传入口 +- Agnet 与 Manager **不得提供 SK 正文写 API** +- 运行注入仅使用解析出的 **不可变快照**,避免「执行中偷偷换版本」 + +详见 [`sk-lifecycle.md`](./sk-lifecycle.md)。 + +--- + +## 四、事件流双轨(平台运行态 vs 会话子代理输出) + +```mermaid +flowchart LR + agnet["Agnet 平台"] + manager["Heicode Manager
控制台与 Dashboard"] + client["Heicode 客户端
编码会话面板"] + + agnet -->|"phase / health / metrics
(SSE · WS · webhook)"| manager + agnet -->|"sub_agent.output
(SSE · WS)"| client +``` + +两类事件 **同源端点可复用**,但 `event` / `type` 必须可区分: +- 面向 Manager 的:`deployment.*`、`instance.*`、`phase_changed`、`health_changed` +- 面向客户端的:`sub_agent.output`、`sub_agent.tool_result`、`output_delta` + +--- + +## 五、模块关注点对照 + +| 关注点 | Heicode 客户端 (`cc-haha/`) | Heicode Manager (`new-api/`) | Agnet 平台 | +|--------|------------------------------|-------------------------------|------------| +| 用户身份 | 浏览器登录 / API Key 兼容 | OAuth 提供方、Token 颁发与吊销 | 接收 M2M JWT 与用户委派令牌 | +| 模型调用 | 不直连模型,请求经 Manager | 路由、计费、RBAC | 不参与基础模型调用 | +| 编排 | 触发部署、订阅子 agent 输出 | 一键部署入口、Webhook 注册 | 实际执行编队、维护实例生命周期 | +| SK | 唯一编辑入口(写 Git / 上传) | 展开 `sk_sources`、刷新策略 | 拉取快照、运行时只读注入 | +| 观测 | 会话内子 agent 输出 | 平台运行态聚合 | 提供事件流、指标导出 | + +--- + +## 六、相关代码索引 + +- 客户端登录:`cc-haha/src/server/api/heicode-auth.ts` +- 客户端 Provider 预设:`cc-haha/src/server/config/providerPresets.ts` +- Manager OAuth:`new-api/controller/heicode_oauth.go`、`new-api/router/heicode-router.go` + +> 代码会演进,本文以 **架构关系** 为准;具体路径请以仓库当前实现为最终事实。 diff --git a/docs/glossary.md b/docs/glossary.md new file mode 100644 index 0000000..756cd0d --- /dev/null +++ b/docs/glossary.md @@ -0,0 +1,97 @@ +# 术语表 + +本术语表是 Heicode 仓库内 **跨文档共享的命名标准**。任意文档涉及以下名称时,请相对链接回本文件锚点,避免规则漂移。 + +> 与代号相关的方向性来源:[`vision-heicode-full-stack-agentic-dev.md`](./vision-heicode-full-stack-agentic-dev.md)。 +> 与 API 字段相关的来源:[`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md)。 + +## 产品级代号 + +### Heicode +仓库与产品族的总称。在区分产品形态时,亦称 **Heicode 客户端**。 + +### Heicode Manager +账户、模型策略、渠道、计费与平台管控的服务端,源码目录 `new-api/`。在文档中亦称 **Manager**。 + +### Heicode 客户端 +面向开发者的 CLI(Ink)+ 桌面应用(Tauri + React)+ 本地 HTTP/WS 服务,源码目录 `cc-haha/`。 + +### Orchard +**子智能体编排与团队模板** 所在平台的概念名。它是一个抽象代号,用以保持愿景叙事不绑死在某个厂商。落地形态可对应 Agnet。 + +### Agnet +当前实际接入的编排平台名称。规范上 Heicode 与 Agnet 通过 [`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md) 中定义的契约通信。 + +## 编排相关 + +### 执行单元 (`agent_instance`) +按角色模板在编排侧实例化的智能体实例。生命周期字段详见 API 设计 §6.1。 + +### 子 agent +本仓库语境下,特指 **Agnet 平台内部** 的子智能体 / 子执行单元,由 Agnet 编排实例化,**不是** Heicode 自研运行时。 + +### 部署 (`deployment`) +一次「按团队模板把多个执行单元拉起」的整体行为,由 `deployment_id` 唯一标识。 + +### 团队 / 编队 +一组在同一 `deployment` 中协同工作的执行单元。瀑布与敏捷下的最小/最大编队详见愿景附录 A。 + +## 资产与边界 + +### SK(Skill 资产) +为子 agent 提供运行时只读上下文的说明类正文,多为 Markdown。详见 [`sk-lifecycle.md`](./sk-lifecycle.md)。 + +### `sk_sources` +SK 的来源数组。每个元素声明其来源类型: +- `git`:以 commit SHA 为快照锚点 +- `upload`:以 `artifact_id` + 版本为快照锚点 + +### `sk_file_refs` +简化字段(路径数组),可视为 `sk_sources` 的简写;展开规则需在联合 RFC 中声明。 + +### Provider Preset +Heicode 客户端预先配置的供应商描述(baseUrl、默认模型、API 格式等),目前仅保留 `taijiaicloud` 与 `clawdrouter`,定义于 `cc-haha/src/server/config/providerPresets.json`。 + +## 标识符 + +| 名称 | 含义 | 出处 | +|------|------|------| +| `tenant_id` | 顶层租户隔离边界,所有持久化资源必带 | API 设计 §4.1 | +| `org_id` | 租户内组织划分(可选) | API 设计 §4.1 | +| `project_id` | 编排资源挂载点 | API 设计 §4.1 | +| `deployment_id` | 一次部署的全局标识 | API 设计 §5.1 | +| `instance_id` / `agent_instance_id` | 执行单元实例 | API 设计 §5.1 / §6.1 | +| `sub_agent_id` | Agnet 内子 agent 实例 | API 设计 §5.0 / §6.4 | +| `correlation_id` / `X-Heicode-Correlation-Id` | Heicode → Agnet 全链路关联键 | API 设计 §2.3 | +| `request_id` / `X-Request-Id` | 单次请求追踪 | API 设计 §2.3 | +| `state` | OAuth 流程会话标识 | [`integration/heicode-oauth-flow.md`](./integration/heicode-oauth-flow.md) | + +## 状态字段 + +### `phase` +执行单元的生命周期阶段:`pending` / `running` / `succeeded` / `failed` / `stopped` 等。 + +### `health` +执行单元健康度:`ok` / `degraded` / `unknown`。 + +### `schema_version` +事件载荷与某些资源体的版本号。客户端遇到未知字段必须忽略,破坏性变更须升级版本号。 + +## 认证相关 + +### M2M JWT +`Authorization: Bearer ` 形式的服务间令牌,由 Manager 或 Agnet 签发;至少包含 `sub` / `tenant_id` / `scope` / `exp`。 + +### 用户委派令牌 +终端用户经 Heicode OAuth 后,由 Manager 代发用于访问 Agnet 受限接口的令牌;Claims 含 `user_id` / `org_id` / `roles`。 + +### loopback redirect_uri +Heicode 客户端浏览器登录时使用的回跳地址,必须使用 `127.0.0.1` / `localhost` / `::1`。详见 [`integration/heicode-oauth-flow.md`](./integration/heicode-oauth-flow.md)。 + +## 范式与角色(参考) + +### 瀑布隐喻 / 敏捷隐喻 +两种协作叙事,分别强调「阶段闸门可审计」与「短迭代闭环」。详见愿景正文第六节。 + +### 编队角色代号 +`WF-*` 表示瀑布编队角色(如 `WF-DEV`、`WF-QA`、`WF-REL`),`AG-*` 表示敏捷编队角色(如 `AG-PO`、`AG-DEV`、`AG-QA`)。完整对照见愿景附录 A。 diff --git a/docs/integration/README.md b/docs/integration/README.md index 584b5c4..8a6e726 100644 --- a/docs/integration/README.md +++ b/docs/integration/README.md @@ -1,18 +1,61 @@ -# 集成与平台接口 +# 集成与平台接口(阅读地图) -| 文档 | 说明 | -|------|------| -| [agnet-platform-api-design.md](./agnet-platform-api-design.md) | **Agnet 平台**对 Heicode 暴露的 API 设计:身份、RBAC、多租户隔离、编排、运行态、事件流、审计。 | +> 受众:实现 Agnet 平台侧、与 Heicode 对接编排或事件流的工程师;以及 Heicode Manager / 客户端中负责对外契约的同学。 -**Agnet 可视化分工(摘要)** +本目录回答三个问题: -- **Heicode Manager**:呈现 Agnet 平台回传的 **运行态与性能类字段**(是否在跑、阶段、健康、资源、聚合指标等)。 -- **Heicode 客户端**:在编码与会话中 **实时展示 Agnet 平台子 agent 产出**(流式输出等),与 §6.4 / 事件流中的会话侧增量对应。 -团队与个人均可使用两端;划分依据是 **信息类型与载体**,详见集成文档 **§1.1**。 +1. Heicode 与 Agnet **谁负责什么**(产品分工与边界) +2. 二者之间走 **什么协议、什么字段**(API 契约) +3. 这些能力 **何时落地**(与里程碑对齐) -**Manager 一键部署与 SK(摘要)** +## 推荐阅读顺序 -- **Heicode Manager** 须支持 **一键部署 Agnet 团队**,并在契约中写清 **团队成员**、**各成员所用模型**、**Agnet 子 agent 绑定的 SK 源(只读)**。 -- **SK**:以 **Git 为统一事实源**,并允许 **上传 MD** 等作为补充;对 Agnet 的接口与语义要求见集成文档 **§5.0.1**。SK 正文不经 Agnet/Manager 编辑,详见 **§5.0**、**§3.2**。 -**里程碑**(何时落地哪些能力)见 [`../milestones/README.md`](../milestones/README.md)。 +| 步骤 | 文档 | 你将得到 | +| --- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| 1 | `[../glossary.md](../glossary.md)` | 统一术语:Heicode / Manager / 客户端 / 子 agent / SK / 标识符等 | +| 2 | `[../architecture.md](../architecture.md)` | 整体架构与数据流(mermaid) | +| 3 | `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §1.1 | Manager 与客户端在 Agnet 可视化中的职责划分 | +| 4 | `[../sk-lifecycle.md](../sk-lifecycle.md)` | SK 来源、快照、写权边界(**单点真相**) | +| 5 | `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §2–§3 | 身份、调用方式、RBAC | +| 6 | `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §4 | 多租户与隔离 | +| 7 | `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §5 | 一键部署、SK 绑定、控制面 API | +| 8 | `[./orchestration-plan-contract.md](./orchestration-plan-contract.md)` | 模型提案对象与平台裁决规则 | +| 9 | `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §6–§7 | 运行态、聚合视图、事件流(双轨) | +| 10 | `[./heicode-oauth-flow.md](./heicode-oauth-flow.md)` | 客户端浏览器登录到 Manager 的完整流程 | +| 11 | `[./acceptance-matrix.md](./acceptance-matrix.md)` | 集成验收最小测试矩阵 | +| 12 | `[../milestones/README.md](../milestones/README.md)` + `[../milestones/STATUS.md](../milestones/STATUS.md)` | 落地节奏与现状 | + + +## 边界速览 + + +| 主题 | Heicode Manager | Heicode 客户端 | Agnet 平台 | +| -------------- | --------------- | ----------- | ---------------------- | +| 一键部署 Agnet 团队 | 入口与编排请求 | 不参与 | 接收 `POST /deployments` | +| 模型策略与计费 | 路由 / RBAC / 计费 | 调用 Manager | 不参与 | +| 子 agent 输出展示 | 平台运行态汇总 | 会话内增量展示 | 提供 SSE/WS 流 | +| SK 正文写入 | **不允许** | 唯一编辑入口 | **不允许**(仅只读快照) | +| 凭据(Git/云 SA)写入 | 持久化与轮换 | 发起授权 | 按租户使用 | + + +## 与里程碑的关系 + +API 设计中的章节与里程碑的对应: + + +| API 设计章节 | 主对应里程碑 | +| --------------- | ------------------------------------------------------------------------------------------------------- | +| §2 身份 / §3 RBAC | [M1](../milestones/M1-contract-identity.md)、[M4](../milestones/M4-tenant-rbac-isolation.md) | +| §4 多租户隔离 | [M4](../milestones/M4-tenant-rbac-isolation.md) | +| §5 编排控制面 | [M3](../milestones/M3-agnet-orchestration-bridge.md) | +| §6 / §7 运行态、事件流 | [M5](../milestones/M5-observability-visualization.md) | +| §8 审计 | [M4](../milestones/M4-tenant-rbac-isolation.md) / [M5](../milestones/M5-observability-visualization.md) | + + +## 集成方常见疑问 + +- **「Agnet 控制台为什么不能改 SK?」** 见 `[../sk-lifecycle.md](../sk-lifecycle.md)` §二 / §六 +- **「子 agent 输出走 §6 还是 §7?」** 两节互补:`§6.4` 强调内容增量,`§7` 强调订阅与重连;事件 `type` 必须可区分 +- **「跨租户负例怎么测?」** 见 `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §4.3 +- **「破坏性变更怎么走?」** 见 `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §10 \ No newline at end of file diff --git a/docs/integration/acceptance-matrix.md b/docs/integration/acceptance-matrix.md new file mode 100644 index 0000000..f2eb52c --- /dev/null +++ b/docs/integration/acceptance-matrix.md @@ -0,0 +1,52 @@ +# Agnet 集成验收矩阵 + +本文用于把集成设计从“建议”变成“可执行验收项”。 + +## 1. 验收范围 + +- 编排控制面(部署/停止/查询) +- 租户隔离与权限 +- SK 快照只读边界 +- 事件流(运行态 + 子 agent 输出) +- 回调签名与重试 + +## 2. 用例矩阵(最小集) + +| ID | 类别 | 场景 | 前置条件 | 期望结果 | +|----|------|------|----------|----------| +| A01 | Happy path | `agile_min` 一键部署成功 | 模板可用、成员与模型已授权 | 返回 `deployment_id`,实例进入 `pending→running` | +| A02 | Happy path | `waterfall_min` 一键部署成功 | 同 A01 | 返回 `deployment_id`,角色实例齐全 | +| A03 | 授权 | 成员指定未授权模型 | 组织模型白名单不包含该模型 | 拒绝,`MODEL_NOT_ALLOWED` | +| A04 | 多租户 | Tenant A 访问 Tenant B 部署 | 两租户均有数据 | 返回 `403` 或 `404`(不泄漏存在性) | +| A05 | SK 边界 | 子 agent 绑定越权路径 | `sk_sources` 路径超白名单 | 拒绝,`SK_SOURCE_UNRESOLVABLE` 或 `FORBIDDEN_CROSS_TENANT` | +| A06 | 预算 | 模型提案预算超限 | 策略设定 max budget | 拒绝,`BUDGET_EXCEEDED` | +| A07 | 幂等 | 同 `intent_id` 重复提交 | 首次已 accepted | 第二次返回冲突或幂等复用,`DEPLOYMENT_CONFLICT` | +| A08 | 回调安全 | callback 签名错误 | 模拟篡改签名 | 拒绝处理并记审计 | +| A09 | 事件流 | SSE 断线后续传 | 已产生事件、支持 `Last-Event-ID` | 重连后补齐丢失窗口事件 | +| A10 | 子输出流 | 会话订阅 `sub_agent.output` | 会话内子 agent 正在运行 | 客户端收到 `output_delta` 流式事件 | + +## 3. 验收字段(每条事件必须) + +- `event_id` +- `schema_version` +- `tenant_id` +- `project_id` +- `deployment_id` +- `correlation_id` +- `occurred_at` + +## 4. 验收结论模板 + +| 项目 | 结果 | 备注 | +|------|------|------| +| 通过数 / 总数 | | | +| 阻断问题 | | | +| 风险接受项 | | | +| 下一轮回归时间 | | | + +## 5. 执行建议 + +- 每次版本上线前至少执行 A01/A02/A04/A05/A08/A09 +- 每次策略变更后追加 A03/A06 回归 +- 验收输出应关联 `request_id` 与 `correlation_id`,便于排障 + diff --git a/docs/integration/agnet-platform-api-design.md b/docs/integration/agnet-platform-api-design.md index d72e264..3086bde 100644 --- a/docs/integration/agnet-platform-api-design.md +++ b/docs/integration/agnet-platform-api-design.md @@ -9,21 +9,25 @@ ## 1. 设计目标 -| 目标 | 说明 | -|------|------| -| **权界清晰** | 调用方身份可解析为「谁、属于哪一租户、具备何种角色」 | -| **租户默认隔离** | 无显式授权则不可读他租户资源 | -| **有状态可观测** | 执行单元生命周期与运行态可通过 API + 事件流呈现 | -| **可演进** | 资源带 `api_version` / schema 版本;破坏性变更走新版本路径 | + +| 目标 | 说明 | +| ---------- | ----------------------------------------- | +| **权界清晰** | 调用方身份可解析为「谁、属于哪一租户、具备何种角色」 | +| **租户默认隔离** | 无显式授权则不可读他租户资源 | +| **有状态可观测** | 执行单元生命周期与运行态可通过 API + 事件流呈现 | +| **可演进** | 资源带 `api_version` / schema 版本;破坏性变更走新版本路径 | + ### 1.1 Agnet 可视化:Heicode Manager 与 Heicode 客户端的职责划分 **使用方**:团队与个人都会使用 Heicode;下列划分依据的是 **信息类型与界面载体**,不是「只有某类用户才用某一端」。 -| 载体 | 主要职责 | 典型内容 | -|------|----------|----------| -| **Heicode Manager** | 呈现 **Agnet 平台回传的运行态与性能类字段**:编队/实例是否在跑、阶段(phase)、健康度、资源占用、队列与心跳、项目级聚合指标与近期错误摘要等。 | 控制台、Dashboard、与平台 SLA/运维相关的观测面。 | -| **Heicode(客户端)** | 在 **编码与工作会话过程中**,**实时或准实时展示 Agnet 平台内子 agent 产出的内容**(流式文本/结构化片段/工具结果等),与编辑、会话上下文同屏。 | 会话内输出面板、流式增量、与当前任务绑定的子 agent 交付物。 | + +| 载体 | 主要职责 | 典型内容 | +| ------------------- | ----------------------------------------------------------------------------------- | --------------------------------- | +| **Heicode Manager** | 呈现 **Agnet 平台回传的运行态与性能类字段**:编队/实例是否在跑、阶段(phase)、健康度、资源占用、队列与心跳、项目级聚合指标与近期错误摘要等。 | 控制台、Dashboard、与平台 SLA/运维相关的观测面。 | +| **Heicode(客户端)** | 在 **编码与工作会话过程中**,**实时或准实时展示 Agnet 平台内子 agent 产出的内容**(流式文本/结构化片段/工具结果等),与编辑、会话上下文同屏。 | 会话内输出面板、流式增量、与当前任务绑定的子 agent 交付物。 | + **边界**:Manager 侧重 **平台契约下的状态与指标**;Heicode 侧重 **工作流中的执行输出**。二者可调用同源底层 API,但 **不得**把「平台大盘」与「子代理会话输出」混为同一套 UI 假设——后者通常带更强会话/项目上下文与更细粒度流式协议。 @@ -43,15 +47,17 @@ ### 2.3 必需传递的上下文头(建议) -| Header | 必填 | 说明 | -|--------|------|------| -| `Authorization` | 是 | Bearer Token | -| `X-Request-Id` | 强建议 | 全链路追踪 | -| `X-Tenant-Id` | 多租户时必填 | 顶层隔离键;与 Token 声明互相校验,不一致则 **401** | -| `X-Org-Id` | 视模型 | 组织内子划分 | -| `X-Project-Id` | 编排相关 API 建议 | 资源挂载点 | -| `X-Environment` | 可选 | `dev` / `staging` / `prod` | -| `X-Heicode-Correlation-Id` | 强建议 | 与 Manager 审计日志关联 | + +| Header | 必填 | 说明 | +| -------------------------- | ----------- | --------------------------------- | +| `Authorization` | 是 | Bearer Token | +| `X-Request-Id` | 强建议 | 全链路追踪 | +| `X-Tenant-Id` | 多租户时必填 | 顶层隔离键;与 Token 声明互相校验,不一致则 **401** | +| `X-Org-Id` | 视模型 | 组织内子划分 | +| `X-Project-Id` | 编排相关 API 建议 | 资源挂载点 | +| `X-Environment` | 可选 | `dev` / `staging` / `prod` | +| `X-Heicode-Correlation-Id` | 强建议 | 与 Manager 审计日志关联 | + --- @@ -59,13 +65,15 @@ ### 3.1 角色(示例命名,可映射贵司 IAM) -| 角色 | 典型 scope | 说明 | -|------|------------|------| -| `agnet:platform_admin` | 全租户元数据、调试接口 | 极少人数 | -| `agnet:org_admin` | 本租户内项目、编队、凭据绑定 | | -| `agnet:project_editor` | 指定项目下部署/停止/读状态 | | -| `agnet:operator_readonly` | 读状态、读事件、读审计 | | -| `agnet:auditor` | 仅审计与导出 | | + +| 角色 | 典型 scope | 说明 | +| ------------------------- | -------------- | ---- | +| `agnet:platform_admin` | 全租户元数据、调试接口 | 极少人数 | +| `agnet:org_admin` | 本租户内项目、编队、凭据绑定 | | +| `agnet:project_editor` | 指定项目下部署/停止/读状态 | | +| `agnet:operator_readonly` | 读状态、读事件、读审计 | | +| `agnet:auditor` | 仅审计与导出 | | + ### 3.2 权限分离原则 @@ -93,11 +101,13 @@ Tenant(租户) ### 4.2 数据面实现选项(择一或组合) -| 方案 | 适用 | Agnet 侧责任 | -|------|------|----------------| -| **逻辑隔离** | 快速迭代 | 每张业务表 `tenant_id` + RLS 或统一拦截器 | -| **Schema 分库** | 强合规 | 每租户独立 schema / database | -| **命名空间隔离(K8s)** | 执行单元运行时 | 编排器按租户分配 NS 与网络策略 | + +| 方案 | 适用 | Agnet 侧责任 | +| --------------- | ------- | ------------------------------ | +| **逻辑隔离** | 快速迭代 | 每张业务表 `tenant_id` + RLS 或统一拦截器 | +| **Schema 分库** | 强合规 | 每租户独立 schema / database | +| **命名空间隔离(K8s)** | 执行单元运行时 | 编排器按租户分配 NS 与网络策略 | + ### 4.3 负例测试(验收必备) @@ -114,14 +124,16 @@ Tenant(租户) 下列条款为 **Heicode 与 Agnet 联合落地时必须写清** 的契约;API 形状可与 **`POST /deployments`** 合一或拆为 **`POST /teams/deployments`** 等聚合端点,但 **语义不得缩水**。 -| 契约项 | 要求 | -|--------|------| -| **一键部署** | 在 **Heicode Manager** 控制台提供 **单次操作**(按钮或向导终点)完成:在 Agnet 上 **部署一支 Agnet 团队/编队**,并得到可追踪的 `deployment_id`、团队视图入口与后续观测衔接(见 §1.1、§6)。不得依赖用户在 Agnet 原生控制台重复手工编排才能跑通 Heicode 叙事。 | -| **团队成员** | 部署配置须 **显式包含团队成员**(至少:`user_id`、组织内角色、是否纳入该 Agnet 团队)。成员关系由 Manager/Agnet 持久化,供 **RBAC、配额与审计**;团队管理员经 **Manager 控制面**维护名单(增删改须审计)。 | -| **成员所用模型** | 须能声明 **各成员默认使用的模型/路由**(如 `default_model_id`、`provider_profile_id` 或与 Manager **模型策略**对齐的引用)。支持「团队缺省 + 成员覆盖」;未授权模型 **不得**在执行路径上静默生效。 | -| **子 agent(Agnet 平台内)与 SK** | 本文所称 **子 Agnet / 子 agent** 均指 **Agnet 平台内部的子智能体/子执行单元**(由 Agnet 编排与实例化),非 Heicode 自研运行时。部署配置须支持为 **指定子 agent** 绑定 **SK 输入源**;运行态下该子 agent **只读**白名单内的 SK 内容。 | -| **SK 与 Git / 上传 MD** | **SK 正文资产以 Git 仓库为统一事实源**(用户指定的远端/连接与分支、路径规则由集成约定)。同时允许用户 **上传 Markdown 等文件** 作为 **补充 SK 源**(租户内对象存储/制品 ID)。Agnet 执行前将两类来源 **解析为不可变快照**(commit SHA / upload version),再注入子 agent 上下文。 | -| **SK 文件仅在 Heicode 中编辑** | Git 侧 SK 的 **创建、修改、删除** 经 **Heicode 客户端**提交到仓库(或 Heicode 发起变更后再同步);**上传类 SK** 的 **新增/替换** 仅通过 **Heicode 提供的入口**(Manager 可做登记与透传,**不提供 SK 正文在线编辑器**)。**Agnet 平台与子 agent 对 SK 均只读**;若 Agnet 控制台出现可直接改 SK 正文的 API/UI,视为 **违背产品边界**。 | + +| 契约项 | 要求 | +| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **一键部署** | 在 **Heicode Manager** 控制台提供 **单次操作**(按钮或向导终点)完成:在 Agnet 上 **部署一支 Agnet 团队/编队**,并得到可追踪的 `deployment_id`、团队视图入口与后续观测衔接(见 §1.1、§6)。不得依赖用户在 Agnet 原生控制台重复手工编排才能跑通 Heicode 叙事。 | +| **团队成员** | 部署配置须 **显式包含团队成员**(至少:`user_id`、组织内角色、是否纳入该 Agnet 团队)。成员关系由 Manager/Agnet 持久化,供 **RBAC、配额与审计**;团队管理员经 **Manager 控制面**维护名单(增删改须审计)。 | +| **成员所用模型** | 须能声明 **各成员默认使用的模型/路由**(如 `default_model_id`、`provider_profile_id` 或与 Manager **模型策略**对齐的引用)。支持「团队缺省 + 成员覆盖」;未授权模型 **不得**在执行路径上静默生效。 | +| **子 agent(Agnet 平台内)与 SK** | 本文所称 **子 Agnet / 子 agent** 均指 **Agnet 平台内部的子智能体/子执行单元**(由 Agnet 编排与实例化),非 Heicode 自研运行时。部署配置须支持为 **指定子 agent** 绑定 **SK 输入源**;运行态下该子 agent **只读**白名单内的 SK 内容。 | +| **SK 与 Git / 上传 MD** | **SK 正文资产以 Git 仓库为统一事实源**(用户指定的远端/连接与分支、路径规则由集成约定)。同时允许用户 **上传 Markdown 等文件** 作为 **补充 SK 源**(租户内对象存储/制品 ID)。Agnet 执行前将两类来源 **解析为不可变快照**(commit SHA / upload version),再注入子 agent 上下文。 | +| **SK 文件仅在 Heicode 中编辑** | Git 侧 SK 的 **创建、修改、删除** 经 **Heicode 客户端**提交到仓库(或 Heicode 发起变更后再同步);**上传类 SK** 的 **新增/替换** 仅通过 **Heicode 提供的入口**(Manager 可做登记与透传,**不提供 SK 正文在线编辑器**)。**Agnet 平台与子 agent 对 SK 均只读**;若 Agnet 控制台出现可直接改 SK 正文的 API/UI,视为 **违背产品边界**。 | + **部署请求体扩展(示意,可与 §5.1 合并)** @@ -180,14 +192,16 @@ Tenant(租户) 下列为 **Agnet 应向 Heicode/Manager 提供或可观测** 的最小要求;路径可为等价 gRPC。 -| 类别 | 要求 | -|------|------| -| **部署与编队** | 实现 **`POST /deployments`**(或 **`POST /teams/deployments`**)可接收 **成员、成员模型、子 agent 模板及 `sk_sources`**;返回 **`deployment_id`**、实例/子 agent 标识,供 Callback 与观测关联。 | -| **SK 快照只读** | 对每个 `deployment_id` / `sub_agent_id`,Agnet 须能记录 **已解析的 SK 快照**(Git:`commit_sha` + 路径哈希;Upload:`artifact_id` + 版本)。运行注入 **仅此快照**,不得在执行中「瞒报版本」拉未授权路径。 | -| **Git 拉取** | Agnet 须支持 **按租户注册 Git 凭据/连接**(`connection_id` 或等价),由用户在 **Heicode/Manager 流程**中授权;**Agnet 不提供 Git 写接口用于改 SK**——写操作发生在 Git 远端或经 Heicode 提交后,Agnet 仅 **fetch + checkout 指定 ref**。 | -| **上传制品** | 若支持 `type: "upload"`:Agnet(或与 Manager 分工)须提供 **`artifact_id` 的只读获取**(如 `GET /sk-artifacts/{artifact_id}/content` 或预签名 URL),**无 `PUT` 修改正文**于 Agnet 控制台;上传入口 **仅** Heicode 侧发起、Agnet 存只读副本。 | -| **刷新策略** | 约定 **何时重新解析 SK**(如新 commit、用户触发刷新、部署新版本);须可通过 API 或事件暴露 **`sk_snapshot_refreshed`**,便于 Heicode 提示「已用新版本 SK」。 | -| **禁止项** | **不得**提供面向 SK 正文的 **通用写 API**(与 §3.2 一致);子 agent **只读**绑定列表内的快照。 | + +| 类别 | 要求 | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **部署与编队** | 实现 **`POST /deployments`**(或 **`POST /teams/deployments`**)可接收 **成员、成员模型、子 agent 模板及 `sk_sources`**;返回 **`deployment_id`**、实例/子 agent 标识,供 Callback 与观测关联。 | +| **SK 快照只读** | 对每个 `deployment_id` / `sub_agent_id`,Agnet 须能记录 **已解析的 SK 快照**(Git:`commit_sha` + 路径哈希;Upload:`artifact_id` + 版本)。运行注入 **仅此快照**,不得在执行中「瞒报版本」拉未授权路径。 | +| **Git 拉取** | Agnet 须支持 **按租户注册 Git 凭据/连接**(`connection_id` 或等价),由用户在 **Heicode/Manager 流程**中授权;**Agnet 不提供 Git 写接口用于改 SK**——写操作发生在 Git 远端或经 Heicode 提交后,Agnet 仅 **fetch + checkout 指定 ref**。 | +| **上传制品** | 若支持 `type: "upload"`:Agnet(或与 Manager 分工)须提供 **`artifact_id`** 的只读获取(如 `GET /sk-artifacts/{artifact_id}/content` 或预签名 URL),**无 `PUT` 修改正文**于 Agnet 控制台;上传入口 **仅** Heicode 侧发起、Agnet 存只读副本。 | +| **刷新策略** | 约定 **何时重新解析 SK**(如新 commit、用户触发刷新、部署新版本);须可通过 API 或事件暴露 **`sk_snapshot_refreshed`**,便于 Heicode 提示「已用新版本 SK」。 | +| **禁止项** | **不得**提供面向 SK 正文的 **通用写 API**(与 §3.2 一致);子 agent **只读**绑定列表内的快照。 | + - **`sk_file_refs`**(若保留简化字段):视为 **相对某默认 Git 根**或 **由 Manager 展开为 `sk_sources`** 前的简写;联合 RFC 须声明展开规则。 - **验收**:部署完成后,Manager 可展示「团队成员—模型—**Agnet 子 agent**—SK 源(Git ref / 上传件)—快照版本」;Git 更新或 Heicode 重新上传后,按刷新策略在后续运行使用新快照。 @@ -348,15 +362,17 @@ Tenant(租户) ## 9. 错误模型 -| HTTP | 含义 | 客户端行为 | -|------|------|------------| -| 400 | 参数错误 | 展示校验细节 | -| 401 | 未认证 | 刷新令牌 | -| 403 | 权限不足 | 引导申请角色 | -| 404 | 不存在或无权(对外统一) | 不泄漏存在性 | -| 409 | 状态冲突(重复部署) | 幂等重试策略 | -| 429 | 限流 | 退避 | -| 503 | 编排背压 | 重试 + 降级文案 | + +| HTTP | 含义 | 客户端行为 | +| ---- | ------------ | --------- | +| 400 | 参数错误 | 展示校验细节 | +| 401 | 未认证 | 刷新令牌 | +| 403 | 权限不足 | 引导申请角色 | +| 404 | 不存在或无权(对外统一) | 不泄漏存在性 | +| 409 | 状态冲突(重复部署) | 幂等重试策略 | +| 429 | 限流 | 退避 | +| 503 | 编排背压 | 重试 + 降级文案 | + **响应体**统一 envelope: @@ -380,4 +396,67 @@ Tenant(租户) --- -*本文档随里程碑评审更新;实现细节以 Agnet 与 Heicode 联合 RFC 为准。* +## 12. 编排决策权模型(新增约束) + +为避免“模型直接执行导致越权/失控”,本项目明确采用: + +- **模型提案**:模型基于 SK 产出 `orchestration_plan` +- **平台裁决**:Agnet 对提案执行权限、租户、预算、模型授权校验后决定执行 +- **Manager 入口**:Heicode Manager 仅作为调用入口与状态展示,不绕过裁决链路 + +详见:[`./orchestration-plan-contract.md`](./orchestration-plan-contract.md)。 + +最低校验项(平台必须执行): + +1. `tenant_id` / `project_id` 与令牌一致 +2. 成员与角色具备部署权限 +3. `default_model_id` 在组织策略允许范围 +4. `sk_sources` 可解析且无越权路径 +5. 预算上限(tokens / cost / duration)未超策略阈值 + +--- + +## 13. 事件字典(建议最小集) + +建议固定以下事件名,避免前后端各自命名造成协议漂移: + +| event | 用途 | +|------|------| +| `deployment.accepted` | 部署请求被接受,进入编排队列 | +| `deployment.rejected` | 部署被策略拒绝 | +| `instance.phase_changed` | 执行单元阶段变化 | +| `instance.health_changed` | 执行单元健康状态变化 | +| `sub_agent.output_delta` | 子 agent 流式输出增量 | +| `sk_snapshot_refreshed` | SK 快照刷新完成 | + +每个事件最小字段建议: + +- `event_id` +- `schema_version` +- `tenant_id` +- `project_id` +- `deployment_id` +- `correlation_id` +- `occurred_at` + +--- + +## 14. 业务错误码字典(补充) + +除 HTTP 状态码外,建议统一错误码最小集合: + +| code | 说明 | +|------|------| +| `POLICY_REJECTED` | 平台策略拒绝执行提案 | +| `MODEL_NOT_ALLOWED` | 模型未授权 | +| `SK_SOURCE_UNRESOLVABLE` | SK 源不可解析或不可读 | +| `BUDGET_EXCEEDED` | 超预算 | +| `FORBIDDEN_CROSS_TENANT` | 跨租户访问拒绝 | +| `DEPLOYMENT_CONFLICT` | 幂等或状态冲突 | +| `CALLBACK_SIGNATURE_INVALID` | 回调签名校验失败 | + +验收用例集合见:[`./acceptance-matrix.md`](./acceptance-matrix.md)。 + +--- + +*本文档随里程碑评审更新;实现细节以 Agnet 与 Heicode 联合 RFC 为准。* \ No newline at end of file diff --git a/docs/integration/heicode-oauth-flow.md b/docs/integration/heicode-oauth-flow.md new file mode 100644 index 0000000..2ca188f --- /dev/null +++ b/docs/integration/heicode-oauth-flow.md @@ -0,0 +1,139 @@ +# HeiCode 浏览器登录流程(客户端 ↔ Manager) + +本文给出 Heicode 客户端通过浏览器完成 Manager 登录的端到端流程,并说明字段、错误模型与扩展点。当前实现以 **loopback 直接回 token** 为主,OAuth2 + PKCE 已在客户端预留。 + +> 代码位置: +> +> - 客户端:`cc-haha/src/server/api/heicode-auth.ts` +> - 服务端:`new-api/controller/heicode_oauth.go`、`new-api/router/heicode-router.go` + +## 一、设计目标 + +- 用户启动 Heicode 客户端 → 看到登录卡片 → 点击「浏览器登录」 +- 浏览器跳到 Manager 控制台,完成账号登录 +- Manager 颁发 / 复用一条专用 Token,回跳客户端 loopback 地址 +- 客户端落地 Token,激活 Provider,自动拉模型列表 + +整体不要求平台事先支持完整 OAuth2,loopback + token 即可工作;后续可平滑切换到 Authorization Code + PKCE。 + +## 二、参与方与端点 + + +| 端点 | 谁实现 | 用途 | +| -------------------------------------- | ---------------- | ---------------------------------- | +| `POST /api/heicode-auth/oauth/start` | 客户端本地服务 | 生成 `state` / PKCE,返回 authorize URL | +| `GET /heicode/oauth/authorize` | Manager(new-api) | 校验 loopback、引导登录、回跳 token | +| `GET /heicode/oauth/session` | Manager(new-api) | 给「请先登录」过渡页轮询登录态 | +| `GET /api/heicode-auth/oauth/callback` | 客户端本地服务 | 接收 token / code,落地并激活 | + + +## 三、当前实现(loopback + token 直回) + +```mermaid +sequenceDiagram + autonumber + participant U as 用户 + participant C as Heicode 客户端
(本地 HTTP 服务) + participant B as 浏览器 + participant M as Heicode Manager
(new-api) + + U->>C: 点击「浏览器登录」 + C->>C: 生成 state / PKCE 并写入会话 + C-->>B: 返回 authorize URL + B->>M: GET /heicode/oauth/authorize?state=...&redirect_uri=...&provider_id=... + alt 用户未登录 + M-->>B: 渲染过渡页(链接到 /login) + loop 每 1.5s + B->>M: GET /heicode/oauth/session + M-->>B: { logged_in } + end + B->>M: 重新请求 authorize + end + M->>M: 校验 loopback redirect_uri + M->>M: 取或新建名为 "HeiCode" 的 Token + M-->>B: 302 redirect_uri?state=...&token=sk-XXXX + B->>C: GET /api/heicode-auth/oauth/callback?token=...&state=... + C->>C: 校验 state、激活 Provider、拉模型 + C-->>B: 返回成功页(用户可关闭浏览器) +``` + + + +### 关键校验 + +- `state` 与 `redirect_uri` 必填,`redirect_uri` 必须是 loopback 主机:`127.0.0.1` / `localhost` / `::1` +- 客户端会话过期(默认 5 分钟)后回调直接判失败 +- 客户端默认从 `?token=` / `?access_token=` / `?apiKey=` / `?apikey=` 任一字段读取 Token + +### 字段表 + + +| 名称 | 在 | 说明 | +| ------------------------------------------ | --------- | --------------------------------------------------- | +| `state` | URL query | 客户端生成的不可猜测随机串,回跳时校验 | +| `redirect_uri` | URL query | 必须是 loopback;Manager 会拒绝其它主机 | +| `provider_id` | URL query | `taijiaicloud` / `clawdrouter`;用于客户端识别落到哪个 provider | +| `token` | 回跳 query | Manager 颁发的 HeiCode 专用 Token,前缀 `sk-` | +| `code` / `code_verifier` | 标准 OAuth | 当前 loopback 模式不使用;启用 PKCE 时必需 | +| `code_challenge` / `code_challenge_method` | URL query | 启用 PKCE 时由客户端附带,方法固定 `S256` | +| `client_id` / `scope` | URL query | 启用 PKCE 时附带,分别来自客户端环境变量 | + + +## 四、扩展形态:标准 OAuth2 + PKCE + +当平台具备 token 端点后,仅需在客户端配置环境变量即可启用: + + +| 变量 | 用途 | +| ---------------------------------------- | ----------------------------------------- | +| `HEICODE__OAUTH_AUTHORIZE_URL` | 自定义 authorize 端点 | +| `HEICODE__OAUTH_TOKEN_URL` | code → access_token 交换端点 | +| `HEICODE__OAUTH_CLIENT_ID` | OAuth Client ID(启用 PKCE 时必需) | +| `HEICODE__OAUTH_SCOPE` | 申请的 scope,例如 `models:read,messages:write` | + + +详见 `[../onboarding/env-variables.md](../onboarding/env-variables.md)`。 + +```mermaid +sequenceDiagram + participant C as 客户端 + participant B as 浏览器 + participant P as 平台 Authorize + participant T as 平台 Token + + C->>B: authorize URL?response_type=code&client_id&...&code_challenge + B->>P: 用户登录授权 + P-->>B: 302 redirect_uri?code=&state= + B->>C: callback?code=&state= + C->>T: POST /token { grant_type=authorization_code, code, code_verifier, ... } + T-->>C: { access_token } + C->>C: 激活 Provider 并拉模型 +``` + + + +## 五、错误模型 + + +| 触发 | HTTP / 行为 | 客户端展示 | +| --------------------------- | ----------------------------------------------------- | -------------------------- | +| `state` / `redirect_uri` 缺失 | Manager 400 | 浏览器停留报错 | +| `redirect_uri` 非 loopback | Manager 400 `redirect_uri must be a loopback address` | 检查客户端配置 | +| 用户未登录 | Manager 渲染过渡页并轮询 session | 浏览器停留并自动跳转 | +| 客户端会话过期 | 客户端 callback 返回错误页 | 提示「登录会话已过期,请回到 HeiCode 重试」 | +| 平台未配置 token 端点但只回了 code | 客户端 callback 错误页 | 提示「平台未配置 token 交换端点」 | +| Provider 模型校验失败 | 客户端 400 | 拉模型异常或返回空集 | + + +## 六、与 Agnet API 设计的衔接 + +- 这里的 Token 用于 Heicode 客户端调 Manager;Manager 调 Agnet 时使用 `[./agnet-platform-api-design.md](./agnet-platform-api-design.md)` §2.1 / §2.2 中的 M2M JWT 或用户委派令牌 +- 跨链路追踪建议在 Manager 调 Agnet 时附带 `X-Heicode-Correlation-Id` 与本登录会话关联 + +## 七、安全注意事项 + +- 客户端必须在每次启动时 **新生成** `state` / `code_verifier`,禁止复用 +- Manager 必须 **拒绝** 非 loopback 的 `redirect_uri`(已实现) +- Token 长生命周期使用前提:Manager 端可吊销且具备审计;不要在跨设备粘贴中传播 +- 出现安全事件时,Manager 应能批量吊销名为 `HeiCode` 的 Token + diff --git a/docs/integration/orchestration-plan-contract.md b/docs/integration/orchestration-plan-contract.md new file mode 100644 index 0000000..9b38ec7 --- /dev/null +++ b/docs/integration/orchestration-plan-contract.md @@ -0,0 +1,105 @@ +# 编排提案契约(`orchestration_plan`) + +本文定义「模型提案、平台裁决」模式下的最小编排对象,供 Heicode / Manager / Agnet 三方对齐。 + +## 1. 决策边界 + +- **模型(经 SK 引导)**:产出编排提案 `orchestration_plan` +- **Agnet 平台**:执行策略裁决(权限、预算、模型授权、租户隔离),并决定是否执行 +- **Heicode Manager**:承载入口与状态展示,透传提案并记录 `correlation_id` + +## 2. 最小对象 + +```json +{ + "intent_id": "intent_20260430_001", + "template_hint": "agile_min", + "objective": "实现并验证用户登录链路", + "risk_level": "medium", + "budget": { + "max_tokens": 120000, + "max_cost_usd": 8.0, + "max_duration_sec": 3600 + }, + "agents": [ + { + "role_template": "AG-PO", + "goal": "拆解验收标准并输出任务分配", + "default_model_id": "mdl_claude_sonnet", + "sk_sources": [ + { + "type": "git", + "repo_ref": { + "connection_id": "gitconn_1", + "repo_url": "https://example.com/org/sk-repo.git", + "ref": "main", + "paths": ["agile/po-guideline.md"] + } + } + ] + }, + { + "role_template": "AG-DEV", + "goal": "按拆解清单完成实现与自测", + "default_model_id": "mdl_claude_sonnet", + "sk_sources": [] + } + ], + "constraints": { + "allowed_model_ids": ["mdl_claude_sonnet", "mdl_claude_haiku"], + "forbidden_actions": ["cross_tenant_read", "credential_write"] + }, + "metadata": { + "tenant_id": "ten_001", + "project_id": "prj_auth", + "correlation_id": "mgr_cor_abc" + } +} +``` + +## 3. 字段说明(最小集) + +| 字段 | 必填 | 说明 | +|------|------|------| +| `intent_id` | 是 | 业务意图 ID,幂等与审计用 | +| `template_hint` | 是 | 期望模板(如 `agile_min` / `waterfall_min`) | +| `objective` | 是 | 任务目标摘要 | +| `risk_level` | 是 | `low` / `medium` / `high` | +| `budget.*` | 是 | token、成本、时长预算上限 | +| `agents[]` | 是 | 子 agent 提案列表 | +| `agents[].role_template` | 是 | 角色模板 | +| `agents[].goal` | 是 | 该角色目标 | +| `agents[].default_model_id` | 否 | 建议模型;最终由平台策略裁决 | +| `agents[].sk_sources` | 否 | SK 来源列表 | +| `constraints.allowed_model_ids` | 否 | 允许模型白名单 | +| `metadata.tenant_id` | 是 | 顶层隔离键 | +| `metadata.project_id` | 是 | 项目标识 | +| `metadata.correlation_id` | 是 | 全链路追踪键 | + +## 4. 裁决规则(平台侧) + +Agnet 在执行前必须做下列校验: + +1. 租户与项目一致性:`tenant_id` / `project_id` 与令牌声明匹配 +2. 权限校验:调用主体具备部署与读取权限 +3. 模型授权:`default_model_id` 在组织与项目策略允许范围内 +4. SK 边界:`sk_sources` 可解析、可读、无越权路径 +5. 预算约束:`max_tokens` / `max_cost_usd` / `max_duration_sec` 不超策略上限 + +## 5. 典型拒绝码 + +| code | 含义 | +|------|------| +| `POLICY_REJECTED` | 平台策略拒绝执行 | +| `MODEL_NOT_ALLOWED` | 模型未授权 | +| `SK_SOURCE_UNRESOLVABLE` | SK 源无法解析或无权限读取 | +| `BUDGET_EXCEEDED` | 预算超限 | +| `FORBIDDEN_CROSS_TENANT` | 跨租户访问拒绝 | +| `DEPLOYMENT_CONFLICT` | 幂等冲突或状态冲突 | + +## 6. 对接建议 + +- `orchestration_plan` 建议由 Manager 转换成 Agnet `POST /deployments` 标准 payload +- 拒绝时应返回 `error.code` + `request_id` + `correlation_id` +- 接受后返回 `deployment_id`,并通过事件流持续反馈执行状态 + diff --git a/docs/milestones/README.md b/docs/milestones/README.md index f9816e4..9a53ddd 100644 --- a/docs/milestones/README.md +++ b/docs/milestones/README.md @@ -1,7 +1,9 @@ # Heicode 交付里程碑(索引) +> 导航:[`../README.md`](../README.md) · [`../glossary.md`](../glossary.md) · [`../architecture.md`](../architecture.md) · [`./STATUS.md`](./STATUS.md) + 本目录将整体交付拆成**可验收、可并行准备**的里程碑事件;每个文件定义**完成定义(DoD)**、**依赖**与**与 Agnet 平台的衔接点**。 -全局范式仍以 [`../vision-heicode-full-stack-agentic-dev.md`](../vision-heicode-full-stack-agentic-dev.md) 为准。 +全局范式仍以 [`../vision-heicode-full-stack-agentic-dev.md`](../vision-heicode-full-stack-agentic-dev.md) 为准;当前实现状态见 [`./STATUS.md`](./STATUS.md)。 ## 推荐阅读顺序 diff --git a/docs/milestones/STATUS.md b/docs/milestones/STATUS.md new file mode 100644 index 0000000..33b4a85 --- /dev/null +++ b/docs/milestones/STATUS.md @@ -0,0 +1,76 @@ +# 里程碑现状对齐 + +本文以仓库当前代码为依据,对 M1–M5 的 DoD 项做粗粒度盘点,便于例会与评审快速对齐。**不替代** 各里程碑文档的 DoD 原文。 + +> 状态图例: +> - `done`:代码已落地并经过基本验证 +> - `partial`:部分项可用,关键缺口已知 +> - `todo`:尚未开始或仅有占位 +> - `docs-only`:仅文档定义,待实现承接 +> +> 来源依据:`cc-haha/src/server/api/heicode-auth.ts`、`cc-haha/src/server/services/providerService.ts`、`new-api/controller/heicode_oauth.go`、`new-api/router/heicode-router.go`、本仓库 `docs/`。 + +## M1 · 契约与身份对齐 + +| DoD | 状态 | 备注 | +|-----|------|------| +| 登录与会话语义文档化 | `done` | 详见 [`../integration/heicode-oauth-flow.md`](../integration/heicode-oauth-flow.md) | +| `/v1/models` 模型发现契约 | `partial` | 客户端 `providerService.fetchProviderModels` 已支持探活与多种返回结构;分页/过滤约定尚未文档化 | +| 用户上下文 `tenant_id` / `org_id` 传播 | `todo` | Heicode 客户端尚未在请求中显式注入;预留位置在请求头层 | +| 版本协商 `User-Agent` / `X-Heicode-Client-Version` | `todo` | 未在客户端统一植入 | +| `X-Tenant-Id` 预留约定 | `docs-only` | 见 API 设计 §2.3 | + +## M2 · 本地端到端闭环 + +| DoD | 状态 | 备注 | +|-----|------|------| +| 本地可启动 Manager 与客户端 | `done` | 步骤见 [`../onboarding/local-dev.md`](../onboarding/local-dev.md) | +| 登录 → 模型 → 至少一类任务调用 | `partial` | API Key 路径完整;浏览器登录可达;端到端任务回归未自动化 | +| 可追溯锚点(Git commit / CI Run) | `todo` | 客户端尚未把会话与 Git/CI 关联 | +| 文档:30 分钟内复现 | `done` | 根 README + `onboarding/` 已覆盖 | + +## M3 · Agnet 编排桥接 + +| DoD | 状态 | 备注 | +|-----|------|------| +| Agnet 控制面最小集(部署/伸缩/停止) | `docs-only` | 设计完整,本仓库不含实现 | +| Heicode Manager「一键部署 Agnet 团队」 | `todo` | 尚未在 `new-api` 中提供 | +| SK 边界(写权仅 Heicode、子 agent 只读) | `partial` | 文档单点真相已就绪([`../sk-lifecycle.md`](../sk-lifecycle.md));客户端 SK 编辑入口待落地 | +| Webhook / 回调(Agnet → Heicode) | `todo` | Manager 未提供回调注册端点 | +| 幂等与 `deployment_id` / `correlation_id` | `docs-only` | 字段约定见 API 设计 §5.1、§2.3 | +| 失败语义(超时 / 部分就绪 / 不可调度) | `docs-only` | 待与 Agnet 联合评审落地 | +| 联调环境对打成功 | `todo` | 需要真实 Agnet 接入 | + +## M4 · 租户、RBAC 与隔离 + +| DoD | 状态 | 备注 | +|-----|------|------| +| 租户模型(`tenant` 顶层) | `partial` | `new-api` 自身有用户/组/Token 体系;Heicode 维度未与 Agnet 集成 | +| RBAC 角色矩阵 | `partial` | `new-api` 控制台已有基础角色;与 Agnet 设计(`agnet:*` 角色)未对齐 | +| 数据面隔离与跨租户负例 | `todo` | 待联合 Agnet 落地后补测 | +| 凭据写入隔离(Git Token / 云 SA) | `docs-only` | 见 API 设计 §3.2 | +| 审计日志(追加式) | `partial` | `new-api` 自带操作日志;统一 `correlation_id` 字段未规范化 | + +## M5 · 可观测性与可视化 + +| DoD | 状态 | 备注 | +|-----|------|------| +| 实例快照 API | `docs-only` | 字段定义见 API 设计 §6.1 | +| 子 Agnet 输出流(SSE/WS) | `todo` | 客户端 UI 尚未实现订阅 | +| 项目级聚合 / Dashboard | `partial` | `new-api` 控制台具备模型/Token 指标基础 | +| 事件流(含 `Last-Event-ID` 重连) | `docs-only` | 见 API 设计 §7 | +| 与 RBAC 联动 | `todo` | 需在 M4 落地后回填 | +| SLI 指标导出 | `todo` | Prometheus / JSON 端点未配置 | + +## 风险与建议 + +1. **SK 边界要尽早写到自动化校验**:避免后续在 Agnet 控制台或 Manager 误开 SK 写 API +2. **`correlation_id` 与 `tenant_id` 在客户端先注入**:即便 Agnet 还没接,也方便后续审计回看 +3. **Webhook 与回调签名先做规范**:联调时再补会引入兼容包袱 +4. **客户端订阅子 agent 输出的协议** 在 UI 还没动前就该确定多路 `type` 命名 + +## 维护约定 + +- 每次 PR 涉及 M1–M5 任一 DoD 变化时,在本文相应行更新状态并简述 +- 状态从 `docs-only` 升到 `partial` / `done` 时,标注 PR 链接或代码入口 +- 本文不写时间表,避免与里程碑原文重复 diff --git a/docs/onboarding/README.md b/docs/onboarding/README.md new file mode 100644 index 0000000..a9e817d --- /dev/null +++ b/docs/onboarding/README.md @@ -0,0 +1,42 @@ +# 新成员上手指引 + +适合刚加入 Heicode 项目的研发同学:把环境跑起来 → 认识仓库结构 → 知道改哪、看哪。 + +## 推荐阅读顺序 + +1. [`local-dev.md`](./local-dev.md):把 `cc-haha`(客户端)、`new-api`(Manager)、`website`(站点)跑起来;含常见错误与排查 +2. [`env-variables.md`](./env-variables.md):客户端识别的环境变量(base URL、OAuth 配置) +3. 共用骨架:[`../architecture.md`](../architecture.md)、[`../glossary.md`](../glossary.md)、[`../sk-lifecycle.md`](../sk-lifecycle.md) +4. 现状对齐:[`../milestones/STATUS.md`](../milestones/STATUS.md) +5. 子项目细则: + - 客户端约定:[`../../cc-haha/AGENTS.md`](../../cc-haha/AGENTS.md) + - 网关约定:[`../../new-api/CLAUDE.md`](../../new-api/CLAUDE.md) + +## 改代码前的最小心智模型 + +| 你要改什么 | 入口文件 | 备注 | +|------------|----------|------| +| 客户端登录 / Provider | `cc-haha/src/server/api/heicode-auth.ts` | 路由前缀 `/api/heicode-auth/*` | +| 客户端模型发现 | `cc-haha/src/server/services/providerService.ts`、`cc-haha/src/server/api/providers.ts` | `/v1/models` 探活 | +| Provider 预设 | `cc-haha/src/server/config/providerPresets.json` + `providerPresets.ts` | 仅保留 `taijiaicloud` / `clawdrouter` | +| Manager OAuth | `new-api/controller/heicode_oauth.go` | 路由 `new-api/router/heicode-router.go` | +| 桌面端 UI | `cc-haha/desktop/src/` | Tauri + React | + +## 你不需要做的事 + +- **不要** 在 Heicode 客户端里实现计费 / 订阅;这部分归 Manager 与平台 +- **不要** 给 Agnet 平台或 Manager 增加可写 SK 正文的 API(违反 SK 边界,详见 [`../sk-lifecycle.md`](../sk-lifecycle.md)) +- **不要** 引入「客户端 → 模型供应商直连」的捷径;所有模型调用应经 Manager 路由 + +## 提交与协作 + +- 提交风格沿用 Conventional Commits:`feat:` / `fix:` / `docs:` / `chore:` 等 +- 分支前缀:`feat/*`、`fix/*`、`docs/*`(不要新建 `codex/*`) +- PR 描述列出影响面、验证步骤;UI 改动附截图 +- 文档与代码同 PR 提交:避免事后再补 docs + +## 提问与求助 + +- 客户端 TS/React 行为问题:先看 [`../../cc-haha/AGENTS.md`](../../cc-haha/AGENTS.md) +- 网关 Go 行为问题:先看 [`../../new-api/CLAUDE.md`](../../new-api/CLAUDE.md) +- 集成 / Agnet 契约问题:先看 [`../integration/README.md`](../integration/README.md) diff --git a/docs/onboarding/env-variables.md b/docs/onboarding/env-variables.md new file mode 100644 index 0000000..fd26831 --- /dev/null +++ b/docs/onboarding/env-variables.md @@ -0,0 +1,76 @@ +# 环境变量手册(Heicode 客户端) + +仅列出 Heicode 客户端(`cc-haha/`)当前 **代码中已支持** 的环境变量。Manager(`new-api/`)的环境变量请以 `new-api/CLAUDE.md` 与 `new-api/.env.example` 为准。 + +> 来源代码: +> - `cc-haha/src/server/config/providerPresets.ts` +> - `cc-haha/src/server/api/heicode-auth.ts` +> 改动这些变量后 **需要重启** 本地服务才能生效。 + +## 一、Provider Base URL 覆盖 + +让客户端把某个 provider 的 `baseUrl` 指向本地或自部署网关,常用于联调本机 Manager。 + +| 变量 | 作用对象 | 示例 | +|------|----------|------| +| `HEICODE_TAIJIAICLOUD_BASE_URL` | `taijiaicloud` provider | `http://localhost:3000` | +| `HEICODE_CLAWDROUTER_BASE_URL` | `clawdrouter` provider | `http://localhost:4000` | + +行为: +- 模块加载时读取,未设置则用 preset 中的默认 baseUrl +- 末尾斜杠会被自动去除 + +## 二、OAuth 配置 + +客户端浏览器登录会按如下顺序解析授权地址: + +1. 若设置了 `HEICODE__OAUTH_AUTHORIZE_URL`,用其值 +2. 否则使用 `/heicode/oauth/authorize` + +`` 取值范围与 base URL 相同(`TAIJIAICLOUD` / `CLAWDROUTER`)。 + +| 变量 | 用途 | 默认 | +|------|------|------| +| `HEICODE__OAUTH_AUTHORIZE_URL` | OAuth 授权入口 | `/heicode/oauth/authorize` | +| `HEICODE__OAUTH_TOKEN_URL` | OAuth `code → token` 交换端点 | `/heicode/oauth/token` | +| `HEICODE__OAUTH_CLIENT_ID` | OAuth Client ID(启用 PKCE 时必需) | 未设置 | +| `HEICODE__OAUTH_SCOPE` | OAuth Scope(可选,与 `client_id` 一并使用) | 未设置 | + +设置规则: +- **仅设置 AUTHORIZE_URL**:客户端跳转浏览器后,平台必须直接以 `?token=...` 形式回调(适合 Manager 当前的 loopback 实现) +- **同时设置 AUTHORIZE_URL + TOKEN_URL + CLIENT_ID**:启用标准 OAuth2 Authorization Code + PKCE +- **未设置 AUTHORIZE_URL** 时,客户端默认用 `/heicode/oauth/authorize`,与 Manager 默认路由对齐 + +详见 [`../integration/heicode-oauth-flow.md`](../integration/heicode-oauth-flow.md)。 + +## 三、本地服务 + +| 变量 | 用途 | 默认 | +|------|------|------| +| `SERVER_PORT` | 客户端本地 HTTP/WS 服务端口 | `3456` | + +## 四、配置示例 + +### 仅切 baseUrl 到本地 Manager + +```bash +HEICODE_TAIJIAICLOUD_BASE_URL=http://localhost:3000 \ + bun run src/server/index.ts +``` + +### 启用浏览器登录 + 标准 OAuth + +```bash +export HEICODE_TAIJIAICLOUD_BASE_URL=http://localhost:3000 +export HEICODE_TAIJIAICLOUD_OAUTH_AUTHORIZE_URL=http://localhost:3000/heicode/oauth/authorize +export HEICODE_TAIJIAICLOUD_OAUTH_TOKEN_URL=http://localhost:3000/heicode/oauth/token +export HEICODE_TAIJIAICLOUD_OAUTH_CLIENT_ID=heicode-desktop +export HEICODE_TAIJIAICLOUD_OAUTH_SCOPE=models:read,messages:write +bun run src/server/index.ts +``` + +> 注:当前 Manager 的实现仅以 loopback 直接回 `?token=...`,标准 OAuth 等待平台侧补全后再启用。 + +## 五、变更约束 + +新增环境变量时请同步更新本文与代码注释,避免漂移。本文不是 `.env.example` 的替代,仅作为 docs 索引。 diff --git a/docs/onboarding/local-dev.md b/docs/onboarding/local-dev.md new file mode 100644 index 0000000..202ed14 --- /dev/null +++ b/docs/onboarding/local-dev.md @@ -0,0 +1,107 @@ +# 本地联调指引 + +把仓库内三块跑起来:`cc-haha`(客户端)、`new-api`(Manager)、`website`(站点)。下面命令以 macOS / Linux 为主,Windows 仅在差异点提示。 + +> 命令以仓库当前 README 与 package.json 为准;如出现冲突,以代码为最终事实。 +> 客户端工程级别的更细约定在 [`../../cc-haha/AGENTS.md`](../../cc-haha/AGENTS.md)。 + +## 一、前置依赖 + +| 依赖 | 用途 | 检查命令 | +|------|------|----------| +| Bun ≥ 1.x | 客户端 / 站点 / Tauri 前端构建 | `bun --version` | +| Node 22 | 仅 docs 工作流(CI 用 npm) | `node --version` | +| Rust toolchain | Tauri 桌面端 | `cargo --version` | +| Docker / Docker Compose | 起 Manager 与站点容器 | `docker compose version` | +| Go 1.22+ | 直接跑 Manager 源码(可选) | `go version` | + +> Bun 安装:`curl -fsSL https://bun.sh/install | bash`(Windows 用 PowerShell `irm bun.sh/install.ps1 | iex`)。 +> Rust 安装:`curl --proto '=https' https://sh.rustup.rs | sh`(如遇 HTTP/2 报错,去掉 `--http2` 重试)。 + +## 二、最小开发闭环 + +```bash +# 1. 安装客户端依赖 +cd cc-haha && bun install + +# 2. 终端 A:本地 API(桌面端依赖) +bun run src/server/index.ts + +# 3. 终端 B:桌面端 +cd cc-haha/desktop +bun run tauri dev +``` + +服务默认监听 `http://127.0.0.1:3456`(可用 `SERVER_PORT` 覆盖)。 + +## 三、联调本机 Manager(new-api) + +```bash +# 1. 起 Manager(new-api) +cd new-api +docker compose -f docker-compose.yml -f docker-compose.override.yml up --build -d + +# 2. 让客户端把 TaijiAICloud 指向本地 Manager +cd ../cc-haha +HEICODE_TAIJIAICLOUD_BASE_URL=http://localhost:3000 bun run src/server/index.ts +``` + +完整可用变量见 [`env-variables.md`](./env-variables.md)。 + +## 四、桌面端常见排错 + +| 现象 | 原因 / 解决 | +|------|--------------| +| `error: script "tauri" exited with code 1` 提示 `cargo metadata` 找不到 | 缺 Rust toolchain;安装后重开终端 | +| `Could not resolve: "grammy"` / `@larksuiteoapi/node-sdk` | 客户端依赖未装;`cd cc-haha && bun install` | +| `Cannot find module 'lodash-es/sumBy.js'` | 同上,`bun install` 后再启动 | +| 端口 3456 被占 | 用 `SERVER_PORT=3457 bun run src/server/index.ts` | + +## 五、跑客户端测试 + +```bash +cd cc-haha/desktop +bun run test # Vitest 单测 +bun run lint # tsc --noEmit +``` + +桌面端构建产物:`bun run build` 或针对平台用 `bun run build:macos-arm64` / `bun run build:windows-x64`。 + +## 六、Manager(new-api)开发 + +简版命令以 `new-api/CLAUDE.md` 为准,本节只列联调相关: + +```bash +# 用本地 source 构建(覆盖镜像) +cd new-api +docker compose -f docker-compose.yml -f docker-compose.override.yml up --build -d + +# 看日志 +docker compose logs -f new-api +``` + +启动后访问 `http://localhost:3000`,注册管理员,再测试客户端登录链路。 + +## 七、站点(website) + +```bash +cd website +pnpm install +pnpm dev +``` + +或用根目录 `docker-compose.yml` 起静态预览镜像(端口 8888): + +```bash +docker compose up -d --build heicode-www +``` + +## 八、回归三件套 + +每次大改前后至少回归: + +1. 客户端登录(API Key 粘贴 + 浏览器登录二选一) +2. 拉取模型列表(应来自 Provider API,不是硬编码) +3. 发起一次对话或 Anthropic Messages 请求 + +详见 [`../milestones/M2-local-e2e.md`](../milestones/M2-local-e2e.md)。 diff --git a/docs/sk-lifecycle.md b/docs/sk-lifecycle.md new file mode 100644 index 0000000..7cff44a --- /dev/null +++ b/docs/sk-lifecycle.md @@ -0,0 +1,146 @@ +# SK 生命周期(Skill 资产单点真相) + +本文是 Heicode 仓库内 **关于 SK 的唯一权威说明**。其它文档涉及 SK 时请相对链接到本文件,避免规则在多处重复。 + +> 上游契约出处:[`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md) §3.2 / §5.0 / §5.0.1。 +> 名称定义:[`glossary.md#sk(skill-资产)`](./glossary.md)。 + +--- + +## 一、什么是 SK + +SK(Skill)= 给 Agnet 子 agent 在运行时注入的 **只读说明类正文**,承载团队规范、流程提示、领域约束、提示词模板等可被编排消费的「软知识」。 + +它不是: +- 模型权重或微调样本 +- 业务数据或敏感凭据 +- Agnet 控制台可在线编辑的内容 + +--- + +## 二、唯一编辑入口 + +| 来源 | 谁可以写 | 谁不能写 | +|------|----------|----------| +| Git 仓库(事实源) | 经 **Heicode 客户端** 提交,或用户在 Git 远端按授权直接操作 | Manager / Agnet **不得**提供改 SK 正文的 API/UI | +| 上传 MD / 文件(补充源) | 仅经 **Heicode 客户端** 提供的入口 | Manager 仅做登记与透传;Agnet 仅做只读副本 | + +**底线**:若 Agnet 控制台出现可直接改 SK 正文的 API 或 UI,视为 **违背产品边界**,需在评审中拒绝。 + +--- + +## 三、来源(`sk_sources`) + +SK 在部署请求中以 `sk_sources` 数组绑定到指定子 agent。两类来源类型并存: + +```json +{ + "role_template": "sub_reviewer", + "sk_sources": [ + { + "type": "git", + "repo_ref": { + "connection_id": "gitconn_1", + "repo_url": "https://example.com/org/sk-repo.git", + "ref": "main", + "paths": ["policy/review.md"] + } + }, + { + "type": "upload", + "artifact_id": "sk_upl_9f3a", + "mime": "text/markdown" + } + ] +} +``` + +兼容字段: +- `sk_file_refs`(路径数组):可视作 `sk_sources` 的简写,**展开规则需在联合 RFC 中声明**。 + +--- + +## 四、解析、快照、注入 + +```mermaid +flowchart LR + src["sk_sources
(git / upload)"] + fetch["Agnet 解析
fetch + checkout / 拉取制品"] + snapshot["不可变快照
commit_sha · artifact 版本"] + inject["注入子 agent
(运行时只读)"] + + src --> fetch --> snapshot --> inject +``` + +要求: +- 每个 `deployment_id` / `sub_agent_id` 必须能查到对应 **已解析的 SK 快照** +- 运行时 **仅** 使用该快照内容,不得在执行中切换版本 +- 快照锚点: + - `git`:`commit_sha` + 文件路径哈希 + - `upload`:`artifact_id` + 版本 + +Agnet 不需要、也不应该提供针对 SK 正文的 `PUT` / `PATCH`:写操作发生在 Git 远端,或经 Heicode 上传入口。 + +--- + +## 五、刷新策略 + +需要约定何时重新解析 SK 并发布新快照: + +| 触发 | 期望行为 | +|------|----------| +| Git 出现新 commit | 按策略重新解析;可即时或滚动 | +| 用户在 Heicode 触发刷新 | 即时重新解析,并向 Manager 发出事件 | +| 部署新版本 | 必然重新解析 | + +事件示例:`sk_snapshot_refreshed`(可在事件流中下发,Heicode 客户端可提示「已用新版本 SK」)。 + +--- + +## 六、写权与读权矩阵 + +| 行为 | Heicode 客户端 | Heicode Manager | Agnet 平台 / 子 agent | +|------|----------------|-----------------|------------------------| +| 创建 / 修改 / 删除 SK 正文(Git) | 允许(提交到仓库) | **禁止** | **禁止** | +| 创建 / 替换上传类 SK | 允许(专用入口) | 仅登记/透传 | **禁止** | +| 注册 Git 凭据 / 连接 | 发起授权 | 持久化、轮换 | 按租户使用 | +| 读 SK 快照 | 允许(用于展示) | 允许(运营/审计) | 允许(运行时注入) | +| 列出 SK 绑定关系 | 允许 | 允许 | 允许 | + +权限模型在 [`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md) §3 中给出 RBAC 角色: +- `agnet:credential:write`:用于绑定 Git Token / 云 SA +- `heicode:sk:write`(示例命名):仅授予 Heicode 客户端身份 + +--- + +## 七、与一键部署的关系 + +[`integration/agnet-platform-api-design.md`](./integration/agnet-platform-api-design.md) §5.0 要求 Heicode Manager 提供「一键部署 Agnet 团队」单次操作,部署请求体须显式包含: + +- 团队成员列表与组织内角色 +- 各成员所用模型 / `provider_profile_id` +- 子 agent 模板与 `sk_sources` + +部署完成后 Manager 应能展示: + +`团队成员 → 模型 → Agnet 子 agent → SK 源(Git ref / 上传件)→ 快照版本` + +未授权模型 **不得** 在执行路径上静默生效。 + +--- + +## 八、违规判定(评审清单) + +新增能力时,凡命中下列之一,需在评审中明确拒绝: + +- 提供 Agnet 或 Manager 控制台对 SK 正文的在线编辑器 +- 在 Agnet 暴露面向 SK 正文的通用写 API +- 子 agent 在运行中拉取绑定列表外的 SK 路径 +- 跨租户读取 SK 快照 +- 「软隔离」下未带 `tenant_id` 的 SK 查询路径 + +--- + +## 九、与 Heicode 客户端实现的关联 + +当前仓库中 SK 编辑入口由 Heicode 客户端承担。具体逻辑实现以 `cc-haha/` 内代码为准,集成方仅需要遵守本文 SK 边界即可。