# graph-neighbors ## 解決什麼問題 把 graph plugin 內建的 `GET /graph/neighbors`(同步 request→response 拿鄰居)**改寫成一條 workflow**。 示範「查詢面工作流」:查詢端點不必是框架寫死的 route,可以是一條 `workflow.yaml` —— 撈 triplet 記錄 → 記憶體 BFS → 同步回鄰居。任何唯讀查詢都能這樣泛化成 workflow。 ## 依賴的框架能力(本 PR 補上的) **同步查詢 trigger**(cypher-executor `webhooks-named.ts`):現有 named webhook 的 `/trigger` 回的是 `{success,data,trace,duration_ms}` 信封、且只有 POST。查詢面要 **GET + 直接拿最終節點輸出**。 新端點同步 `await` 執行 graph → 把 `result.data`(最終節點輸出)本身當 response body 回(非 202): - `GET /q/:ns/:name`(namespace 走 path,input 走 query string) - `GET /webhooks/named/:name/query`(X-Arcrun-API-Key header,input 走 query string) - `POST /webhooks/named/:name/query`(header,input 走 body) - `POST /webhooks/named/:ns/:name/query`(namespace 走 path,input 走 body) ## 怎麼觸發 ```bash # GET(最像原本的 /graph/neighbors)——{你的-cypher-domain}/{你的-kbdb-domain} 換成自己的部署 curl "https://{你的-cypher-domain}/q/{namespace}/graph_neighbors?node=Arcrun&depth=2&template=graph_triplet&namespace={namespace}&kbdb_base=https://{你的-kbdb-domain}" # POST(header 認證) curl -X POST https://{你的-cypher-domain}/webhooks/named/graph_neighbors/query \ -H "X-Arcrun-API-Key: {namespace}" \ -d '{"node":"Arcrun","depth":2,"template":"graph_triplet","namespace":"{namespace}","kbdb_base":"https://{你的-kbdb-domain}"}' ``` > ⚠️ **敏感輸入請用 `POST /query`**:`GET /q/` 的參數走 query string,會進 CF / proxy / access log > 各層日誌;node 名、namespace 等若屬敏感,改走 POST body。 回傳(最終節點輸出本身,非信封): ```json { "success": true, "start": "Arcrun", "depth": 2, "directed": false, "neighbors": [ { "node": "cypher-executor", "predicate": "包含", "from": "Arcrun", "depth": 1 } ], "count": 1 } ``` ## 參數 - `node`(必填):BFS 起點節點名 - `depth`(預設 1):最大跳數 - `template`(必填):triplet 記錄的 base template id(⚠️ 以實際部署的 kbdb-graph-plugin triplet template 為準) - `namespace`(必填):租戶 owner_id(self-hosted 明碼 namespace) - `kbdb_base`(必填):**你自己的 KBDB base URL**(如 `https://kbdb.example.com`)。 workflow 不寫死任何一家的庫——抄示範時帶錯(或照抄別人的值)=查詢與資料流向直接打進別人的庫 (KBDB_BASE_URL fallback 同家族坑,勿重蹈)。 - `directed`(預設 false):`true` 只走 subject→object;否則把 triplet 當雙向邊(無向鄰居) ## kbdb_base 該帶哪種 URL(1042) cypher-executor 對 kbdb 發 fetch,若打同 zone URL 會踩 CF 1042(same-zone self-fetch)。兩條路皆可: 1. 帶 KBDB 的 **custom domain**(跨 zone、走公網前門,天然避開 1042); 2. self-hosted 有 **`global_fetch_strictly_public`** compatibility flag(credential-primitives-wasm Phase 7,cypher wrangler.toml),開了之後 **workers.dev URL 亦可**直接帶。 ## ⚠️ 尚未 live 驗(待辦) - **`code` 零件尚未部署到 leo21c**(另線處理)→ 本工作流無法端到端 live 跑。 workflow.yaml 已寫好放這裡待驗。 - **同步查詢 trigger 本身已驗**:`cypher-executor/tests/query-trigger.test.ts`(7 測)用內建零件 (comp_uppercase,純記憶體、無外部 fetch)證明「確實同步回最終節點輸出而非 202」。 - 上線前另需對一次實際 triplet template id(本檔用 `{{input.template}}` 參數化,未寫死)。 ## 對照 記憶體 BFS 對照 `kbdb-graph-plugin` 的 `graph-traverse.ts:23-51`:triplet 當有向邊 `subject --predicate--> object`,從起點逐跳擴張到 depth 上限,收集首次訪到的節點當鄰居。 ## 學到什麼 - 查詢端點可以是 workflow,不必是框架寫死的 route(同步查詢 trigger 讓這件事成立) - `code` 零件(sandbox inline JS)承載「非 call-api 的純計算」(BFS),不必為此鑄 domain 零件 - 單一 `{{ref}}` pass-through 保留陣列型別 → `{{fetch_triplets.data.records}}` 拿到真陣列餵給 code