MCPcopy
hub / github.com/afar1/fieldtheory-cli / classifyDomainsWithLlm

Function classifyDomainsWithLlm

src/bookmark-classify-llm.ts:285–356  ·  view source on GitHub ↗
(
  options: { engine: ResolvedEngine; all?: boolean; onBatch?: (done: number, total: number) => void },
)

Source from the content-addressed store, hash-verified

283}
284
285export async function classifyDomainsWithLlm(
286 options: { engine: ResolvedEngine; all?: boolean; onBatch?: (done: number, total: number) => void },
287): Promise<LlmClassifyResult> {
288 const { engine } = options;
289
290 const dbPath = twitterBookmarksIndexPath();
291 const db = await openDb(dbPath);
292
293 // Ensure domain columns exist (migration from schema v2)
294 try { db.run('ALTER TABLE bookmarks ADD COLUMN domains TEXT'); } catch { /* already exists */ }
295 try { db.run('ALTER TABLE bookmarks ADD COLUMN primary_domain TEXT'); } catch { /* already exists */ }
296
297 try {
298 const where = options.all
299 ? '1=1'
300 : 'primary_domain IS NULL';
301 const rows = db.exec(
302 `SELECT id, text, author_handle, categories FROM bookmarks
303 WHERE ${where} ORDER BY RANDOM()`
304 );
305
306 if (!rows.length || !rows[0].values.length) {
307 return { engine: engine.name, totalUnclassified: 0, classified: 0, failed: 0, batches: 0 };
308 }
309
310 const bookmarks: DomainBookmark[] = rows[0].values.map(r => ({
311 id: r[0] as string,
312 text: r[1] as string,
313 authorHandle: r[2] as string | null,
314 categories: r[3] as string | null,
315 }));
316
317 const total = bookmarks.length;
318 let classified = 0;
319 let failed = 0;
320 let batchCount = 0;
321
322 for (let i = 0; i < bookmarks.length; i += BATCH_SIZE) {
323 const batch = bookmarks.slice(i, i + BATCH_SIZE);
324 const batchIds = new Set(batch.map(b => b.id));
325 batchCount++;
326
327 options.onBatch?.(i, total);
328
329 try {
330 const prompt = buildDomainPrompt(batch);
331 const raw = invokeEngine(engine, prompt);
332 // Reuse the same parse logic — structure is identical
333 const results = parseResponse(raw, batchIds);
334
335 const stmt = db.prepare(
336 `UPDATE bookmarks SET domains = ?, primary_domain = ? WHERE id = ?`
337 );
338 for (const r of results) {
339 stmt.run([r.categories.join(','), r.primary, r.id]);
340 }
341 stmt.free();
342

Callers 2

classifyNewFunction · 0.85
buildCliFunction · 0.85

Calls 8

openDbFunction · 0.85
buildDomainPromptFunction · 0.85
invokeEngineFunction · 0.85
parseResponseFunction · 0.85
saveDbFunction · 0.85
writeMethod · 0.80
closeMethod · 0.65

Tested by

no test coverage detected