Files
Arcrun/registry/src/routes/query.ts
T
uncle6me-web 7e631a890a t158 迴歸修復「部署≠發現」:複製路徑回毫秒級純編圖,誠實化只留在 discover
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>
2026-07-31 13:31:33 +08:00

68 lines
2.7 KiB
TypeScript
Raw 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.
// 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;