feat: KBDB-graph 插件獨立 — 全面改寫成走基本盤 API(API-as-Wall)
按 leo 鐵律(2026-06-14)把插件從「直接 SQL 操作基本盤表」改寫成 「只透過基本盤 arcrun/kbdb HTTP API 讀寫」。零建表、零 migration、零 SQL。 - 新增 src/lib/kbdb-client.ts:唯一對外通道,封裝 entries/templates/records API - 新增 src/lib/templates.ts:triplet/entity template 定義(替代建表) - 改寫 21 個違規 action(triplet/graph/entity/search)→ 走 client,圖在插件層記憶體組裝 - 移除所有 migrations、D1/Vectorize/AI 綁定;embedding/語意搜尋歸基本盤 optional 模組 - index.ts 只掛 triplets/graph/entities/search 路由;基本盤路由歸 arcrun/kbdb - 測試改走 mock client(純 node);裁剪 CLAUDE.md 只留 graph 插件 + 鐵律 - 修正 SDD design.md「讀現狀推翻鐵律」的錯誤判斷(共用 D1 → API-as-Wall) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
// 三元組 CRUD — 走基本盤 API(API-as-Wall,零 SQL)
|
||||
// 寫 triplet = 確保 template='triplet' + POST /records 填 slot。
|
||||
// 查 triplet = GET /records/by-template/triplet → 插件層 filter/組裝。
|
||||
|
||||
import type { Triplet } from '../types';
|
||||
import type { KbdbClient } from '../lib/kbdb-client';
|
||||
import { TPL_TRIPLET, ensurePluginTemplates, recordToTriplet } from '../lib/templates';
|
||||
import { classifyClusters } from './triplet-cluster';
|
||||
|
||||
export type CreateTripletData = {
|
||||
subject: string;
|
||||
predicate: string;
|
||||
object: string;
|
||||
source_block_id?: string;
|
||||
confidence?: number;
|
||||
owner_id?: string;
|
||||
clusters?: string[];
|
||||
bridge_score?: number;
|
||||
subject_entity_type?: string;
|
||||
object_entity_type?: string;
|
||||
};
|
||||
|
||||
/** 建立三元組 → POST /records(template=triplet)。 */
|
||||
export async function createTriplet(
|
||||
client: KbdbClient,
|
||||
data: CreateTripletData,
|
||||
): Promise<{ id: string; subject: string; predicate: string; object: string }> {
|
||||
await ensurePluginTemplates(client);
|
||||
|
||||
const clusters = data.clusters ?? [];
|
||||
const bridgeScore = data.bridge_score ?? Math.max(0, clusters.length - 1);
|
||||
|
||||
const values: Record<string, string> = {
|
||||
subject: data.subject,
|
||||
predicate: data.predicate,
|
||||
object: data.object,
|
||||
confidence: String(data.confidence ?? 1.0),
|
||||
clusters_json: JSON.stringify(clusters),
|
||||
bridge_score: String(bridgeScore),
|
||||
};
|
||||
if (data.source_block_id) values.source_block_id = data.source_block_id;
|
||||
if (data.subject_entity_type) values.subject_entity_type = data.subject_entity_type;
|
||||
if (data.object_entity_type) values.object_entity_type = data.object_entity_type;
|
||||
|
||||
const id = await client.createRecord(TPL_TRIPLET, values, data.owner_id);
|
||||
return { id, subject: data.subject, predicate: data.predicate, object: data.object };
|
||||
}
|
||||
|
||||
export type TripletFilters = {
|
||||
subject?: string;
|
||||
predicate?: string;
|
||||
object?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
owner_id?: string;
|
||||
entity_type?: string;
|
||||
};
|
||||
|
||||
/** 查三元組 → 取 template 全部 record,插件層 filter(base 無複合 slot 查詢)。 */
|
||||
export async function queryTriplets(
|
||||
client: KbdbClient,
|
||||
filters: TripletFilters,
|
||||
): Promise<{ triplets: Triplet[]; count: number }> {
|
||||
const records = await client.listRecordsByTemplate(TPL_TRIPLET, filters.owner_id);
|
||||
let triplets = records.map(recordToTriplet);
|
||||
|
||||
if (filters.subject) triplets = triplets.filter((t) => t.subject === filters.subject);
|
||||
if (filters.predicate) triplets = triplets.filter((t) => t.predicate === filters.predicate);
|
||||
if (filters.object) triplets = triplets.filter((t) => t.object === filters.object);
|
||||
if (filters.entity_type) {
|
||||
triplets = triplets.filter(
|
||||
(t) => t.subject_entity_type === filters.entity_type || t.object_entity_type === filters.entity_type,
|
||||
);
|
||||
}
|
||||
|
||||
const offset = filters.offset ?? 0;
|
||||
const limit = Math.min(filters.limit ?? 50, 2000);
|
||||
const page = triplets.slice(offset, offset + limit);
|
||||
return { triplets: page, count: page.length };
|
||||
}
|
||||
|
||||
/** 取單一三元組 → GET /records/:id。 */
|
||||
export async function getTriplet(client: KbdbClient, id: string): Promise<Triplet | null> {
|
||||
const rec = await client.getRecord(id);
|
||||
if (!rec) return null;
|
||||
return recordToTriplet({ ...rec, template: TPL_TRIPLET });
|
||||
}
|
||||
|
||||
// re-export clusters helper(AI 分群,純函式 + 走 client 無關)
|
||||
export { classifyClusters };
|
||||
Reference in New Issue
Block a user