/** * 分支用法自我說明(SDD workflow-discovery 3.11 / CP arcrun-usable 步驟 5) * * 為什麼需要這一層(leo 08-01 逼出的洞,別刪): * leo:「它也可以不要送整個意圖工作流去查詢,它可以**一一查詢自己手工填寫每個零件, * 就像在 n8n 那樣**,這時它不會每個都寫 code?」 * 取證:逐顆查 `if_control`,回應只有 {status, componentId, input_schema, success_rate…}, * `input_schema` 只說得出 {condition, input}——**沒有任何欄位告訴 AI「判斷完之後兩條路怎麼分岔」** * ⇒ 走 n8n 式逐顆查、自己組圖的 AI 拿到 if_control 後必然卡在「然後呢」,回頭寫 code。 * * 判準(leo 一貫要求:資訊出現在需要它的那一刻): * **AI 只看這一顆的查詢回應,就知道怎麼接下一步**,不必回頭讀 skill。 * * 三顆流程控制零件的 output_schema 都收斂到同一個形狀 `data.branch: string` * ⇒ 引擎只有「依標籤選邊」一個機制(ON_BRANCH),ON_TRUE/ON_FALSE 是布林路的語法糖。 */ export type BranchHint = { /** 這顆零件會輸出哪個欄位當分支標籤 */ branch_field: string; /** 可能的分支標籤(switch 是動態的,故標明由 cases 決定) */ branches: string[] | string; /** 接下游要用哪些邊型 */ edge_types: string[]; /** 一行說明:這顆零件之後怎麼分岔 */ usage: string; /** 可直接照抄的最小範例(意圖語法+對應的邊) */ example: string; }; /** * 零件 → 分支用法。key = canonical_id。 * 只收「本身會分岔」的零件;不分岔的零件不該有 branch_hint(避免噪音)。 */ const BRANCH_HINTS: Record = { if_control: { branch_field: 'data.branch', branches: ['true', 'false'], edge_types: ['ON_TRUE', 'ON_FALSE'], usage: '這顆算完會輸出 data.branch("true"/"false")。下游接兩條邊:ON_TRUE 接條件成立要做的事,' + 'ON_FALSE 接不成立要做的事。**不需要自己寫 code 判斷走哪條**——引擎依 branch 自動選路。', example: '判斷有沒有新資料 >> ON_TRUE >> 傳到 telegram\n' + '判斷有沒有新資料 >> ON_FALSE >> 結束\n' + '(中文語意詞亦可:「成立時」=ON_TRUE、「否則」=ON_FALSE)', }, switch: { branch_field: 'data.branch', branches: '由 input_schema.cases[].branch 與 default_branch 決定(N 路,非固定清單)', edge_types: ['ON_BRANCH'], usage: '這顆依 value 比對 cases,輸出 data.branch=命中那個 case 的 branch 名(都沒中則是 default_branch)。' + '下游**每條路各接一條 ON_BRANCH 邊,並在邊上標 branch 等於你在 cases 裡取的名字**。' + 'default_branch 不需要特別的邊型,照樣用 ON_BRANCH 標它的名字即可。', example: '{"cases":[{"match":"active","branch":"branch_active"}],"default_branch":"branch_default"}\n' + 'edges: [\n' + ' {"from":"my_switch","to":"處理啟用","type":"ON_BRANCH","branch":"branch_active"},\n' + ' {"from":"my_switch","to":"處理其他","type":"ON_BRANCH","branch":"branch_default"}\n' + ']', }, try_catch: { branch_field: 'data.branch', branches: ['try', 'catch'], edge_types: ['ON_BRANCH'], usage: '這顆看上游 error 是否非空,輸出 data.branch("try"=沒錯/"catch"=有錯)。' + '下游接兩條 ON_BRANCH 邊,branch 分別標 "try" 與 "catch"。' + '**錯誤處理不需要寫 code**——把要補救的節點接在 catch 那條邊後面即可。', example: 'edges: [\n' + ' {"from":"my_try_catch","to":"正常流程","type":"ON_BRANCH","branch":"try"},\n' + ' {"from":"my_try_catch","to":"補救流程","type":"ON_BRANCH","branch":"catch"}\n' + ']', }, }; /** 取某零件的分支用法說明;不分岔的零件回 undefined(回應不加噪音)。 */ export function branchHintFor(componentId: string | undefined): BranchHint | undefined { if (!componentId) return undefined; return BRANCH_HINTS[componentId.toLowerCase()]; }