55a47d7c18
embed 模組原本只有 embedOnWrite(寫入即嵌),對「開 Vectorize binding 之前就寫入」或 embed-on-write 當時漏掉的既有 entry 沒有回填路徑 → is_embedded=0 永遠補不回,語義查詢回 0 筆。 新增(base,對 entries 做;embedding 是 base 唯一職責,非 graph 插件): - embed.ts: backfillEmbeddings()——找 is_embedded=0 且 isEmbeddable(metadata.embed===true) 的 entry, 批次補嵌(單次 AI.run 陣列 + 單次 VECTORIZE.upsert 陣列 + 單次 UPDATE IN,一批≈3 subrequest)、 設 is_embedded=1,冪等、分批(limit 1-100,回傳 processed/remaining,可重複呼叫直到清零)。 模組未開誠實回 enabled:false(不假綠)。backfillStatus() 回 pending/embedded 計數。 - routes/embed.ts: POST /embed/backfill、GET /embed/backfill/status;模組未開回 409 + capability_hint。 - index.ts: mount /embed。 - tests/embed-backfill.test.ts: 5 vitest(off no-op / 補嵌+標記 / 冪等 / 分批 remaining / status)。 base 維持對內容語意無知(只認通用 embed 旗標,不知 triplet/wiki)。tsc exit 0、vitest 5/5。 端到端(leo21c,wrangler 直推、非 acr update):pending 5→processed 5→remaining 0, Vectorize vectorCount 0→5,/entries/search?mode=semantic 由 0 筆→5 筆(語義排序命中)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDtnGPJpAzp8UqHfAo8o1s
28 lines
1.2 KiB
TypeScript
28 lines
1.2 KiB
TypeScript
// KBDB Base — atomic universal table worker (arcrun self-hosted data layer + official core).
|
|
// SDD: .agents/specs/arcrun/kbdb-base/design.md
|
|
//
|
|
// Base = D1 only (free, no credit card): entries / templates / records + LIKE search + recipe-stats.
|
|
// Optional modules (NOT in this base): embed (Vectorize+AI binding, semantic search), triplet (separate repo).
|
|
import { Hono } from 'hono';
|
|
import type { Bindings } from './types';
|
|
import { entryRoutes } from './routes/entries';
|
|
import { templateRoutes } from './routes/templates';
|
|
import { recordRoutes } from './routes/records';
|
|
import { recipeStatRoutes } from './routes/recipe-stats';
|
|
import { embedRoutes } from './routes/embed';
|
|
|
|
const app = new Hono<{ Bindings: Bindings }>();
|
|
|
|
app.get('/', (c) => c.json({ service: 'arcrun-kbdb', tier: 'base', status: 'ok' }));
|
|
app.get('/health', (c) => c.json({ ok: true }));
|
|
|
|
app.route('/entries', entryRoutes);
|
|
app.route('/templates', templateRoutes);
|
|
app.route('/records', recordRoutes);
|
|
app.route('/recipe-stats', recipeStatRoutes);
|
|
// Optional embed module admin (backfill). Route mounts unconditionally; the handler
|
|
// honestly 409s when the embed binding is off (base 對內容語意無知,只認通用 embed 旗標)。
|
|
app.route('/embed', embedRoutes);
|
|
|
|
export default app;
|