"use client"; import { createNotesApiClient } from "@/lib/api-helpers"; import type { PromptTemplate, RunPromptInput, RunPromptOutput, SimilarNote, KnowledgeGap, } from "@/lib/types"; // ── Template CRUD ───────────────────────────────────────────── export async function listPromptTemplates(): Promise { const api = createNotesApiClient(); const res = await api.fetch<{ items: PromptTemplate[] }>("/note-prompts"); return res.items; } export async function getPromptTemplate(id: string): Promise { const api = createNotesApiClient(); return api.fetch(`/note-prompts/${encodeURIComponent(id)}`); } export async function createPromptTemplate( input: Omit, ): Promise { const api = createNotesApiClient(); return api.fetch("/note-prompts", { method: "POST", body: JSON.stringify(input), }); } export async function deletePromptTemplate(id: string): Promise { const api = createNotesApiClient(); await api.fetch(`/note-prompts/${encodeURIComponent(id)}`, { method: "DELETE" }); } // ── Run prompts ─────────────────────────────────────────────── export async function runPrompt(input: RunPromptInput): Promise { const api = createNotesApiClient(); return api.fetch("/note-prompts/run", { method: "POST", body: JSON.stringify(input), }); } // ── Run prompts (streaming) ─────────────────────────────────── export async function runPromptStream( input: RunPromptInput, onToken: (content: string) => void, onDone: (meta: Partial) => void, onError?: (message: string) => void, ): Promise { const api = createNotesApiClient(); const baseUrl = (api as unknown as { baseUrl?: string }).baseUrl ?? ""; const token = typeof window !== "undefined" ? localStorage.getItem("access_token") : null; const headers: Record = { "Content-Type": "application/json" }; if (token) headers["Authorization"] = `Bearer ${token}`; const res = await fetch(`${baseUrl}/note-prompts/run-stream`, { method: "POST", headers, body: JSON.stringify(input), }); if (!res.ok || !res.body) { onError?.(res.statusText || "Stream failed"); return; } const reader = res.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n\n"); buffer = lines.pop() ?? ""; for (const line of lines) { if (!line.startsWith("data: ")) continue; try { const payload = JSON.parse(line.slice(6)); if (payload.type === "token") onToken(payload.content); else if (payload.type === "done") onDone(payload); else if (payload.type === "error") onError?.(payload.message); } catch { /* skip malformed */ } } } } // ── History ────────────────────────────────────────────────── export interface PromptHistoryItem { id: string; noteId: string; workspaceId: string; toolName?: string; state: string; reason?: string; afterSummary?: string; createdAt: string; } export async function listPromptHistory( workspaceId: string, limit = 20, ): Promise<{ items: PromptHistoryItem[]; total: number }> { const api = createNotesApiClient(); return api.fetch(`/note-prompts/history?workspaceId=${encodeURIComponent(workspaceId)}&limit=${limit}`); } // ── Intelligence endpoints ──────────────────────────────────── export async function suggestTags( noteId: string, workspaceId: string, ): Promise { const api = createNotesApiClient(); const res = await api.fetch<{ tags: string[] }>( `/notes/${encodeURIComponent(noteId)}/suggest-tags`, { method: "POST", body: JSON.stringify({ workspaceId }) }, ); return res.tags; } export async function checkDuplicates( noteId: string, workspaceId: string, threshold = 0.85, ): Promise { const api = createNotesApiClient(); const res = await api.fetch<{ duplicates: SimilarNote[] }>( `/notes/${encodeURIComponent(noteId)}/check-duplicates`, { method: "POST", body: JSON.stringify({ workspaceId, threshold }) }, ); return res.duplicates; } export async function suggestLinks( noteId: string, workspaceId: string, threshold = 0.6, ): Promise { const api = createNotesApiClient(); const res = await api.fetch<{ suggestions: SimilarNote[] }>( `/notes/${encodeURIComponent(noteId)}/suggest-links`, { method: "POST", body: JSON.stringify({ workspaceId, threshold }) }, ); return res.suggestions; } export async function getReadingTime( noteId: string, workspaceId: string, ): Promise<{ wordCount: number; readingTimeMinutes: number }> { const api = createNotesApiClient(); return api.fetch(`/notes/${encodeURIComponent(noteId)}/reading-time?workspaceId=${encodeURIComponent(workspaceId)}`); } export async function compareNotes( noteIds: string[], workspaceId: string, ): Promise { const api = createNotesApiClient(); return api.fetch("/notes/compare", { method: "POST", body: JSON.stringify({ noteIds, workspaceId }), }); } export async function mergeNotes( noteIds: string[], workspaceId: string, ): Promise { const api = createNotesApiClient(); return api.fetch("/notes/merge", { method: "POST", body: JSON.stringify({ noteIds, workspaceId }), }); } export async function getKnowledgeGaps( workspaceId: string, ): Promise<{ gaps: KnowledgeGap[]; topicMap: Record }> { const api = createNotesApiClient(); return api.fetch(`/workspaces/${encodeURIComponent(workspaceId)}/knowledge-gaps`, { method: "POST", }); }