Files
Arcrun/cypher-executor/src/actions/webhook-graph-resolver.ts
Leo 5cadc60e36 feat(workflow-discovery): /cypher/search 改為真查 registry——修「查詢回假信號」
📋 SDD:workflow-discovery(本 commit 同時執行 D35 交接:portal-auth 26/26 完成 → closed
   superseded_by workflow-discovery;workflow-discovery paused → active。單一活性已驗=1 份)
🎯 對應 task:3.x 搜尋端誠實化(CP2-B)

病灶(leo 2026-07-30 定性「腹語術」):
search-nodes.ts 無條件回 status:'found'、missingNodes 永遠 []——
型別宣告了 'missing' 但程式碼從不使用。實測「完全不存在的東西xyz」也回 found。
⇒ AI 拿到假信號 → 以為零件存在 → 部署才發現沒有 → 改寫 code
⇒ 正式 workflow 只用 2 個零件、8 個 code 節點含 if×61。

修法:
- 查 registry 判真實存在(走 HTTP,守 D28 禁新增 service binding;
  URL 用既有 wasmWorkerUrl() 慣例組,不自創)
- found 時附 input_schema/success_rate/stability
  ⇒ AI 才填得出 payload、才看得到「測過幾次」(leo:AI 只要填 payload)
- 查不通回 'unknown' 而非 'missing'——**誠實限制**:
  不能因查詢失敗就宣告零件不存在(那會讓 AI 誤判而重寫 code)
- missing 真的回傳出去(原本寫死 [])

⚠️ 實測發現 registry **沒有列表端點**(GET /components → 404,只有 /components/<id>)
⇒ 改為逐個查(節點數通常 <10、5s timeout)。補列表端點後可改抓一次=CP2-B 待辦。

驗:tsc 零錯誤;vitest 9 failed/179 passed=**與改動前 stash 對帳完全相同**(既有債非本次造成)。
 待部署到實例後跑 arcrun-usable/verify.sh 驗 01 那組轉綠。
2026-07-30 20:41:53 +08:00

61 lines
2.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Bindings } from '../types';
import { graphSchema } from '../lib/schemas';
import { parseTriplets } from './triplet-parser';
import { searchNodes } from './search-nodes';
import { buildExecutionGraph } from './graph-builder';
export async function resolveWebhookGraph(
body: Record<string, unknown>,
description: string,
env: Bindings,
): Promise<{ resolvedGraph: Record<string, unknown>; error?: string }> {
// 路徑 Atriplets 格式
if (Array.isArray(body.triplets) && body.triplets.length > 0) {
const parsed = parseTriplets(body.triplets as unknown[]);
if (!parsed) return { resolvedGraph: {}, error: '無法解析 triplets' };
const { nodeResults } = await searchNodes(parsed);
const graphId = `webhook-${Date.now()}`;
const graphName = description || `Webhook ${new Date().toISOString()}`;
const graph = buildExecutionGraph(parsed, nodeResults, graphId, graphName) as Record<string, unknown>;
const parseResult = graphSchema.safeParse(graph);
if (!parseResult.success) {
return { resolvedGraph: {}, error: '圖定義產生失敗' };
}
return { resolvedGraph: graph };
}
// 路徑 Bgraph 格式
if (body.graph && typeof body.graph === 'object') {
const graphWithDefaults = {
id: `webhook-${Date.now()}`,
name: description || `Webhook ${new Date().toISOString()}`,
...(body.graph as Record<string, unknown>),
};
const parsed = graphSchema.safeParse(graphWithDefaults);
if (!parsed.success) {
return { resolvedGraph: {}, error: '圖定義驗證失敗' };
}
return { resolvedGraph: graphWithDefaults };
}
// 路徑 Cbody 直接就是 graph
if (body.nodes && body.edges) {
const graphWithDefaults = {
id: `webhook-${Date.now()}`,
name: description || `Webhook ${new Date().toISOString()}`,
...body,
};
const parsed = graphSchema.safeParse(graphWithDefaults);
if (!parsed.success) {
return { resolvedGraph: {}, error: '圖定義驗證失敗' };
}
return { resolvedGraph: graphWithDefaults };
}
return { resolvedGraph: {}, error: '需提供 graph 物件或 triplets 陣列' };
}