7e631a890a
leo 07-31 定調:「這裡只是複製一些工作流的 data 過去,沒有要在這裡驗證,難怪這麼慢。
就算是我自己寫了錯的工作流,也可以跑跑看,如果錯誤就修改,
沒有說有錯誤還要一個個驗證這回事。」
定性=迴歸非新設計:部署路徑純複製是既有設計(arcrun-rag installer/src/index.js:13
「workflows.json 是既有 workflows/*.local.yaml 的搬運(打包期抽 flow/config)」+
arcrun-rag wiki「workflow 打包期預編成 workflows.json(worker 免帶 parser)」)。
5cadc60 起誠實化漏進 /cypher/search ⇒ 複製路徑也逐節點跑兩庫查詢+相似搜尋
(每 missing 節點 1+9 次 HTTP+recipe KV 掃)⇒ 冷實例 8 節點實測 25.7s、
安裝器 15s timeout 必炸(leo stage 實走 rag_takedown_direct aborted)。
改動:
- /cypher/search 加 mode:compile=純編圖零查詢(安裝器/acr push 複製路徑);
discover=誠實查詢預設(AI 問「有沒有」的既有契約,not_found+分型指路全保留)
- /cypher/execute 一律 compile(存在性由 component-loader 執行時決定=原權威)
- compile 的節點 status 標 unchecked(誠實「沒查」,不回假 found)
- discover 批次化:registry 新增 GET /components/catalog(一次回全目錄含
input_schema,補 CP2-B「沒有列表端點」缺口)+recipe 清單一次抓,
存在判定與相似度全記憶體比對;舊 registry 無 catalog 端點 → 退回逐顆(相容);
registry 整個查不通 → unknown 照舊(不誤判 not_found)
- cli push 帶 mode:compile+拔 missing 擋(push 不看 missing;要問有沒有走 validate)
驗(本地 wrangler dev 誠實環境,registry 種 20 合約):
- compile 編圖:graph_neighbors 39ms/rag_chat(11節點) 3ms/rag_ingest_card 2ms/
rag_takedown_direct(8節點) 3ms——回迴歸前毫秒級
- 安裝器 pushWorkflowTo(mode:compile)4/4 ok(44/7/7/5ms)
- 故意引用不存在零件的 workflow:部署 ok=true,trigger 執行時誠實報
「找不到零件…」+可用零件清單(部署≠發現實證)
- discover 契約:邏輯名 missing=2+not_found+suggestion(21ms);
頂層 verify.sh 01 組 5/5+03 組 4/4 全綠
- cypher+registry tsc 全綠;vitest 9 failed/179 passed=5cadc60 基線完全相同
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
68 lines
2.7 KiB
TypeScript
68 lines
2.7 KiB
TypeScript
// GET /components/:id — 取得零件最優版本合約
|
||
// GET /components/:id/versions — 取得所有版本清單(含評分)
|
||
// GET /components/search?q=... — 語意搜尋零件
|
||
// Requirements: 12.2, 12.3
|
||
|
||
import { Hono } from 'hono';
|
||
import type { Bindings } from '../types';
|
||
import { getComponent, getComponentVersions, searchComponents, toComponentRecord } from '../actions/queryComponents';
|
||
import type { ComponentRecord } from '../actions/queryComponents';
|
||
|
||
const app = new Hono<{ Bindings: Bindings }>();
|
||
|
||
// 全清單(t158 批次化):/cypher/search discover 一次抓走整份目錄,
|
||
// 節點存在判定+相似度全在 cypher 記憶體內比對——取代「每個 missing 節點
|
||
// 各打 1+8 次查詢」的疊爆模式(冷實例 8 節點實測 25.7s 的病根)。
|
||
// 也補上 CP2-B 記載的「registry 沒有列表端點」缺口。
|
||
// 必須在 /:id 之前,避免 "catalog" 被當作 id。
|
||
app.get('/catalog', async c => {
|
||
const list = await c.env.SUBMISSIONS_KV.list({ prefix: 'comp:' });
|
||
const seen = new Set<string>();
|
||
const components: ComponentRecord[] = [];
|
||
for (const key of list.keys) {
|
||
const raw = await c.env.SUBMISSIONS_KV.get(key.name);
|
||
if (!raw) continue;
|
||
let v: Record<string, unknown>;
|
||
try { v = JSON.parse(raw) as Record<string, unknown>; } catch { continue; }
|
||
if (v.status === 'tombstone' || v.visibility !== 'public') continue;
|
||
const dedup = `${String(v.component_hash_id ?? '')}:${String(v.version ?? '')}`;
|
||
if (seen.has(dedup)) continue;
|
||
seen.add(dedup);
|
||
components.push(toComponentRecord(v));
|
||
}
|
||
return c.json({ success: true, data: { components, count: components.length } });
|
||
});
|
||
|
||
// 語意搜尋(必須在 /:id 之前,避免 "search" 被當作 id)
|
||
app.get('/search', async c => {
|
||
const q = c.req.query('q');
|
||
if (!q || q.trim() === '') {
|
||
return c.json({ success: false, error: 'q 參數必填' }, 400);
|
||
}
|
||
|
||
const results = await searchComponents(q.trim(), c.env);
|
||
return c.json({ success: true, data: { results, count: results.length } });
|
||
});
|
||
|
||
// 取得所有版本
|
||
app.get('/:id/versions', async c => {
|
||
const id = c.req.param('id');
|
||
const versions = await getComponentVersions(id, c.env);
|
||
if (versions.length === 0) {
|
||
return c.json({ success: false, error: `零件 ${id} 不存在` }, 404);
|
||
}
|
||
return c.json({ success: true, data: { versions, count: versions.length } });
|
||
});
|
||
|
||
// 取得最優版本
|
||
app.get('/:id', async c => {
|
||
const id = c.req.param('id');
|
||
const component = await getComponent(id, c.env);
|
||
if (!component) {
|
||
return c.json({ success: false, error: `零件 ${id} 不存在` }, 404);
|
||
}
|
||
return c.json({ success: true, data: component });
|
||
});
|
||
|
||
export default app;
|