323ccc8475
問題(「全變成 code」的根):if_control 回 {result, branch} 卻沒有邊讀得懂它,
圖的邊只有 ON_SUCCESS/IF/FOREACH ⇒ 就算照規矩用零件,仍得寫 code 判斷走哪條。
leo 08-01 追問「你改了 if,有改 switch 嗎?switch 更嚴重」——確認 switch(N 路)
與 try_catch(try/catch) 同病,故一次做成通用機制,不留「為 switch 再改一次」的債。
設計:三顆流程控制零件的 output_schema 本來就都收斂到同一形狀 data.branch: string
(if_control→true/false;switch→case 名或 default_branch;try_catch→try/catch)
⇒ 引擎只需「依標籤選邊」一個機制 ON_BRANCH;ON_TRUE/ON_FALSE 是布林路的語法糖,
底層同一條路(測試已證等價)。讀不出分支=不走(誠實,不亂挑一條)。
- types/schemas/constants:新增三邊型(純新增,既有列舉不動)+ GraphEdge.branch
- graph-executor:readBranch() 依 data.branch → branch → data.result → result 四層相容
- 中文語意詞:成立時/為真時=ON_TRUE,不成立時/為假時/否則=ON_FALSE,BRANCH=ON_BRANCH
分支用法要「查得到」(leo 08-01:AI 可能像 n8n 那樣逐顆查、自己組圖):
新增 lib/branch-hints.ts,讓 if_control/switch/try_catch 的查詢回應自帶 branch_hint
(branch_field/branches/edge_types/usage/example)——只看這一顆的回應就知道怎麼接下一步,
不必回頭讀 skill。四條回應路徑全wire:catalog found/legacy 逐顆/步驟4 substitution/
target=component 名字搜尋(=n8n 式那條)。不分岔的零件不加此欄,避免噪音。
測試(先寫測試再改引擎,紅線要求):tests/conditional-edges.test.ts 16 項全綠
——if 兩路/switch 多路+default/try_catch 成功與失敗路/語法糖等價/
context 傳遞/同分支 fan-out/無匹配不走/混合邊時 PIPE 不受影響/schema 放行。
零變化保證:195 passed(前 179 +16 新),失敗數維持既有 9 筆未變(console/portal
HTML 資產未建置+executor 斷言字串漂移,皆與本次無關);tsc --noEmit 綠。
現存 workflow/example 用到新邊型=0 筆(grep 實查)⇒ 既有行為不可能被改動。
SDD: workflow-discovery task 3.11|CP: arcrun-usable 步驟 5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
28 lines
932 B
TypeScript
28 lines
932 B
TypeScript
import { z } from 'zod';
|
||
|
||
// 圖定義的 Zod Schema
|
||
export const graphSchema = z.object({
|
||
id: z.string().min(1),
|
||
name: z.string().min(1),
|
||
nodes: z.array(z.object({
|
||
id: z.string(),
|
||
type: z.enum(['Input', 'Component', 'Output']),
|
||
componentId: z.string().optional(),
|
||
label: z.string().optional(),
|
||
data: z.record(z.unknown()).optional(),
|
||
})),
|
||
edges: z.array(z.object({
|
||
from: z.string(),
|
||
to: z.string(),
|
||
type: z.enum(['PIPE', 'IF', 'FOREACH', 'CONTINUE', 'IS_A', 'ON_SUCCESS', 'ON_FAIL', 'ON_TRUE', 'ON_FALSE', 'ON_BRANCH', 'ON_CLICK', 'CALLS_SUBFLOW', 'CONTAINS', 'HAS_STYLE', 'HAS_BEHAVIOR']),
|
||
condition: z.string().optional(),
|
||
iterator: z.string().optional(),
|
||
branch: z.string().optional(), // ON_BRANCH 的具名分支(SDD workflow-discovery 3.11)
|
||
})),
|
||
});
|
||
|
||
export const executeSchema = z.object({
|
||
graph: graphSchema,
|
||
context: z.record(z.unknown()).default({}),
|
||
});
|