docs: rewrite CAS structure — flatten refs, named conditions, config.yaml, output naming
This commit is contained in:
+94
-116
@@ -138,30 +138,9 @@ uwf-hermes <thread-id> <role>
|
|||||||
沿用 json-cas 的三层:bootstrap meta-schema → JSON Schema nodes → data nodes。
|
沿用 json-cas 的三层:bootstrap meta-schema → JSON Schema nodes → data nodes。
|
||||||
|
|
||||||
下面所有 CAS 节点都遵循 `{ type: cas_ref, payload: T, timestamp: number }` 的标准格式。
|
下面所有 CAS 节点都遵循 `{ type: cas_ref, payload: T, timestamp: number }` 的标准格式。
|
||||||
|
`cas_ref` 类型的字符串字段在 json-cas 中已内置支持,不需要额外的 `$ref` 包装。
|
||||||
|
|
||||||
### 2.2 Schema 节点
|
### 2.2 数据节点
|
||||||
|
|
||||||
以下每个 schema 本身是一个 CAS 节点(type 指向 meta-schema)。
|
|
||||||
|
|
||||||
#### `RoleSchema`
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# 定义一个 role 的 meta 输出格式
|
|
||||||
# 例:developer role 的输出 schema
|
|
||||||
type: <meta-schema-hash>
|
|
||||||
payload:
|
|
||||||
$id: "role-output-developer"
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
filesChanged:
|
|
||||||
type: array
|
|
||||||
items: { type: string }
|
|
||||||
summary:
|
|
||||||
type: string
|
|
||||||
required: [filesChanged, summary]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2.3 数据节点
|
|
||||||
|
|
||||||
#### `Role`
|
#### `Role`
|
||||||
|
|
||||||
@@ -171,53 +150,62 @@ payload:
|
|||||||
name: "developer"
|
name: "developer"
|
||||||
description: "Implements code changes"
|
description: "Implements code changes"
|
||||||
systemPrompt: "You are a developer agent..."
|
systemPrompt: "You are a developer agent..."
|
||||||
extractPrompt: "Extract the following from the agent output..."
|
outputSchema: "5GWKR8TN1V3JA" # cas_ref → JSON Schema 节点(json-cas 内置)
|
||||||
outputSchema:
|
|
||||||
$ref: "5GWKR8TN1V3JA" # cas_ref → RoleSchema 节点
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `outputSchema` 直接引用 json-cas 的 JSON Schema 节点,不单独定义 RoleSchema
|
||||||
|
- 不需要 `extractPrompt`,extraction 逻辑由 agent-kit 统一处理
|
||||||
|
|
||||||
#### `Moderator`
|
#### `Moderator`
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
type: <moderator-schema-hash>
|
type: <moderator-schema-hash>
|
||||||
payload:
|
payload:
|
||||||
|
conditions:
|
||||||
|
needsClarification: "$exists(output.needsClarification)"
|
||||||
|
notApproved: "output.approved = false"
|
||||||
graph:
|
graph:
|
||||||
- from: "$START"
|
$START:
|
||||||
transitions:
|
- role: "planner"
|
||||||
- to: "planner"
|
condition: null # 无条件(fallback)
|
||||||
condition: null # 无条件(default/fallback)
|
planner:
|
||||||
- from: "planner"
|
- role: "developer"
|
||||||
transitions:
|
condition: "needsClarification" # 引用 conditions 中的名字
|
||||||
- to: "developer"
|
- role: "$END"
|
||||||
condition: "$not($exists(meta.needsClarification))" # JSONata
|
condition: null
|
||||||
- to: "$END"
|
developer:
|
||||||
condition: null # fallback
|
- role: "reviewer"
|
||||||
- from: "developer"
|
condition: null
|
||||||
transitions:
|
reviewer:
|
||||||
- to: "reviewer"
|
- role: "developer"
|
||||||
condition: null
|
condition: "notApproved"
|
||||||
- from: "reviewer"
|
- role: "$END"
|
||||||
transitions:
|
condition: null
|
||||||
- to: "developer"
|
|
||||||
condition: "meta.approved = false" # JSONata
|
|
||||||
- to: "$END"
|
|
||||||
condition: null
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `conditions` — `Record<Name, JSONata>`,命名条件,方便画图描述
|
||||||
|
- `graph` — `Record<Role | "$START", Transition[]>`,每个 Transition = `{ role, condition }`
|
||||||
|
- `condition` 引用 conditions 中的 key,`null` = fallback
|
||||||
|
- 按数组顺序求值,第一个匹配的 transition 胜出
|
||||||
|
|
||||||
JSONata 表达式的求值上下文:
|
JSONata 表达式的求值上下文:
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
"role": "reviewer", // 刚完成的 role
|
"start": { // StartNode 信息
|
||||||
"meta": { "approved": false }, // 刚完成的 role 的 meta
|
"workflow": "4KNM2PXR3B1QW",
|
||||||
"depth": 3, // 当前第几步
|
"prompt": "Fix the login bug..."
|
||||||
"history": [ // 所有历史 steps 的摘要
|
},
|
||||||
{ "role": "planner", "meta": { ... } },
|
"steps": [ // 所有已完成 steps,从旧到新
|
||||||
{ "role": "developer", "meta": { ... } }
|
{ "role": "planner", "output": { ... }, "detail": "...", "agent": "..." },
|
||||||
|
{ "role": "developer", "output": { ... }, "detail": "...", "agent": "..." },
|
||||||
|
{ "role": "reviewer", "output": { "approved": false }, "detail": "...", "agent": "..." }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
当前 step(最后一个)的 output 可直接用 `output` 简写访问(语法糖)。
|
||||||
|
|
||||||
#### `Workflow`
|
#### `Workflow`
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -226,104 +214,94 @@ payload:
|
|||||||
name: "solve-issue"
|
name: "solve-issue"
|
||||||
description: "End-to-end issue resolution"
|
description: "End-to-end issue resolution"
|
||||||
roles:
|
roles:
|
||||||
planner:
|
planner: "3FXJM7QS2A9PB" # cas_ref → Role
|
||||||
$ref: "3FXJM7QS2A9PB" # cas_ref → Role
|
developer: "8CNWT4KR6D1HV" # cas_ref → Role
|
||||||
developer:
|
reviewer: "1VPBG9SM5E7WK" # cas_ref → Role
|
||||||
$ref: "8CNWT4KR6D1HV" # cas_ref → Role
|
moderator: "6HJQX2FN8C4RA" # cas_ref → Moderator
|
||||||
reviewer:
|
|
||||||
$ref: "1VPBG9SM5E7WK" # cas_ref → Role
|
|
||||||
moderator:
|
|
||||||
$ref: "6HJQX2FN8C4RA" # cas_ref → Moderator
|
|
||||||
defaultAgent: "uwf-hermes" # 默认 agent 命令前缀
|
|
||||||
agentOverrides: # per-role override
|
|
||||||
developer: "uwf-cursor"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `AgentConfig`
|
- 不含 agent binding — agent 配置在 `~/.uncaged/workflow/config.yaml` 中管理
|
||||||
|
- roles 和 moderator 都是直接的 cas_ref 字符串
|
||||||
```yaml
|
|
||||||
type: <agent-config-schema-hash>
|
|
||||||
payload:
|
|
||||||
command: "uwf-hermes"
|
|
||||||
# 不存 env(从运行环境继承)
|
|
||||||
# 不存 thread-id(运行时变量)
|
|
||||||
# → 相同 command 的 steps 自然共享同一个 CAS hash
|
|
||||||
```
|
|
||||||
|
|
||||||
为什么只存 command?因为 env 从运行环境继承,不进 CAS。这样同一个 agent 命令在不同 step 间去重为同一个 hash。如果需要记录实际运行时的 env snapshot 用于审计,可以单独存一个 `AgentExecContext` 节点,但不作为默认行为。
|
|
||||||
|
|
||||||
#### `StartNode`(Thread 起点)
|
#### `StartNode`(Thread 起点)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
type: <start-node-schema-hash>
|
type: <start-node-schema-hash>
|
||||||
payload:
|
payload:
|
||||||
workflow:
|
workflow: "4KNM2PXR3B1QW" # cas_ref → Workflow
|
||||||
$ref: "4KNM2PXR3B1QW" # cas_ref → Workflow
|
|
||||||
prompt: "Fix the login bug..."
|
prompt: "Fix the login bug..."
|
||||||
agentBinding: # 启动时确定的 agent 分配
|
|
||||||
planner:
|
|
||||||
$ref: "9DSVW3KM7B2PA" # cas_ref → AgentConfig
|
|
||||||
developer:
|
|
||||||
$ref: "5RTJN8FQ1H6WC" # cas_ref → AgentConfig
|
|
||||||
reviewer:
|
|
||||||
$ref: "9DSVW3KM7B2PA" # cas_ref → AgentConfig
|
|
||||||
```
|
```
|
||||||
|
|
||||||
没有 thread-id 在 payload 里 — thread-id 是索引层面的事,不进 CAS 内容。
|
- 没有 thread-id — thread-id 是索引层面的事,不进 CAS 内容
|
||||||
|
- 没有 agent binding — 运行时从 config.yaml 解析
|
||||||
|
|
||||||
#### `StepNode`(Thread 每一步)
|
#### `StepNode`(Thread 每一步)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
type: <step-node-schema-hash>
|
type: <step-node-schema-hash>
|
||||||
payload:
|
payload:
|
||||||
|
start: "4TNVW8KR2B3MA" # cas_ref → StartNode(每个 step 都引用)
|
||||||
|
prev: "2MXBG6PN4A8JR" # cas_ref → 前一个 StepNode,第一步为 null
|
||||||
role: "developer"
|
role: "developer"
|
||||||
meta:
|
output: # 结构化输出,符合 role 的 outputSchema
|
||||||
filesChanged: ["src/auth.ts"]
|
filesChanged: ["src/auth.ts"]
|
||||||
summary: "Fixed redirect loop"
|
summary: "Fixed redirect loop"
|
||||||
content:
|
detail: "7BQST3VW9F2MA" # cas_ref → 原始 agent 输出(content node)
|
||||||
$ref: "7BQST3VW9F2MA" # cas_ref → 原始 agent 输出(content node)
|
agent: "uwf-cursor" # 实际使用的 agent 命令(纯字符串)
|
||||||
agent:
|
|
||||||
$ref: "5RTJN8FQ1H6WC" # cas_ref → 实际使用的 AgentConfig
|
|
||||||
prev:
|
|
||||||
$ref: "2MXBG6PN4A8JR" # cas_ref → 前一个 StepNode 或 StartNode
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.4 链式结构
|
- `start` — 每个 StepNode 都直接引用 StartNode,方便随机访问
|
||||||
|
- `prev` — 前一个 StepNode 的 cas_ref,第一步为 `null`(不指向 StartNode)
|
||||||
|
- `output` — 对应 role 的 `outputSchema`,内联存储
|
||||||
|
- `detail` — 原始 agent 输出的 cas_ref
|
||||||
|
- `agent` — 纯字符串,不是 CAS 节点
|
||||||
|
|
||||||
|
### 2.3 链式结构
|
||||||
|
|
||||||
```
|
```
|
||||||
threads.json: { "01J7K9M2XNPQR5VWBCDF8G3H4T": "8FWKR3TN5V1QA" }
|
threads.yaml: { "01J7K9M2XNPQR5VWBCDF8G3H4T": "8FWKR3TN5V1QA" }
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
StepNode (step 3)
|
StepNode (step 3)
|
||||||
|
├── start ──→ StartNode
|
||||||
|
│ ├── workflow → CAS(Workflow)
|
||||||
|
│ └── prompt: "Fix..."
|
||||||
|
├── prev ──→ StepNode (step 2)
|
||||||
|
│ ├── start ──→ (same StartNode)
|
||||||
|
│ ├── prev ──→ StepNode (step 1)
|
||||||
|
│ │ ├── start ──→ (same StartNode)
|
||||||
|
│ │ ├── prev: null
|
||||||
|
│ │ ├── role: "planner"
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── role: "developer"
|
||||||
|
│ └── ...
|
||||||
├── role: "reviewer"
|
├── role: "reviewer"
|
||||||
├── meta: { approved: true }
|
├── output: { approved: true }
|
||||||
├── content → CAS(raw output)
|
├── detail → CAS(raw output)
|
||||||
├── agent → CAS(AgentConfig)
|
└── agent: "uwf-hermes"
|
||||||
└── prev ──→ StepNode (step 2)
|
|
||||||
├── role: "developer"
|
|
||||||
├── ...
|
|
||||||
└── prev ──→ StepNode (step 1)
|
|
||||||
├── role: "planner"
|
|
||||||
├── ...
|
|
||||||
└── prev ──→ StartNode
|
|
||||||
├── workflow → CAS(Workflow)
|
|
||||||
├── prompt: "Fix..."
|
|
||||||
└── agentBinding: {...}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.5 可变状态
|
### 2.4 可变状态
|
||||||
|
|
||||||
整个系统唯一的可变文件:
|
系统两个顶层 YAML 文件:
|
||||||
|
|
||||||
```jsonc
|
```yaml
|
||||||
// ~/.uncaged/workflow/threads.json
|
# ~/.uncaged/workflow/config.yaml — 全局配置
|
||||||
{
|
defaultAgent: "uwf-hermes"
|
||||||
"01J7K9M2XNPQR5VWBCDF8G3H4T": "8FWKR3TN5V1QA", // active thread → 链头
|
agentOverrides:
|
||||||
"01J8AB3QRMSTV6WKXZ2C4DF7GN": "3CNWT9KR6D2HV"
|
solve-issue: # per-workflow
|
||||||
}
|
developer: "uwf-cursor"
|
||||||
|
review-code:
|
||||||
|
reviewer: "uwf-hermes"
|
||||||
```
|
```
|
||||||
|
|
||||||
Thread 结束时从这个文件移除。可选:追加一行到 `history.jsonl` 做归档。
|
```yaml
|
||||||
|
# ~/.uncaged/workflow/threads.yaml — active thread 链头指针
|
||||||
|
01J7K9M2XNPQR5VWBCDF8G3H4T: "8FWKR3TN5V1QA"
|
||||||
|
01J8AB3QRMSTV6WKXZ2C4DF7GN: "3CNWT9KR6D2HV"
|
||||||
|
```
|
||||||
|
|
||||||
|
Thread 结束时从 threads.yaml 移除。可选:追加到 `history.jsonl` 做归档。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user