import { sendCommand } from "./client"; import { pickCase } from "./normalize"; // ── Public types ──────────────────────────────────────────────── export type AiHealthDto = { provider: string; enabled: boolean; healthy: boolean; message: string; }; export type CoachEvidenceDto = { recordId: string | null; text: string; }; export type CoachPatchProposalDto = { kind: string; description: string | null; content: string | null; }; export type CoachPlanDto = { kind: string; title: string; summary: string; questions: string[]; suggestedNextActions: string[]; suggestedTags: string[]; evidence: CoachEvidenceDto[]; patchProposal: CoachPatchProposalDto | null; }; export type CoachPreferencesDto = { maxQuestions?: number; maxNextActions?: number; }; export type CoachSessionPayload = { dateLocal?: string; weekStartLocal?: string; weekEndLocal?: string; recentEntries?: string[]; recentFragments?: string[]; preferences?: CoachPreferencesDto; }; // ── Raw (PascalCase) variants for normalization ───────────────── type AiHealthDtoRaw = { provider?: string; enabled?: boolean; healthy?: boolean; message?: string; Provider?: string; Enabled?: boolean; Healthy?: boolean; Message?: string; }; type CoachEvidenceDtoRaw = { recordId?: string | null; text?: string; RecordId?: string | null; Text?: string; }; type CoachPatchProposalDtoRaw = { kind?: string; description?: string | null; content?: string | null; Kind?: string; Description?: string | null; Content?: string | null; }; type CoachPlanDtoRaw = { kind?: string; title?: string; summary?: string; questions?: string[]; suggestedNextActions?: string[]; suggestedTags?: string[]; evidence?: CoachEvidenceDtoRaw[]; patchProposal?: CoachPatchProposalDtoRaw | null; Kind?: string; Title?: string; Summary?: string; Questions?: string[]; SuggestedNextActions?: string[]; SuggestedTags?: string[]; Evidence?: CoachEvidenceDtoRaw[]; PatchProposal?: CoachPatchProposalDtoRaw | null; }; // ── Normalizers ───────────────────────────────────────────────── function normalizeHealth(raw: AiHealthDtoRaw): AiHealthDto { return { provider: pickCase(raw, "provider", "Provider", ""), enabled: pickCase(raw, "enabled", "Enabled", false), healthy: pickCase(raw, "healthy", "Healthy", false), message: pickCase(raw, "message", "Message", ""), }; } function normalizeEvidence(raw: CoachEvidenceDtoRaw): CoachEvidenceDto { return { recordId: pickCase(raw, "recordId", "RecordId", null as string | null), text: pickCase(raw, "text", "Text", ""), }; } function normalizePatchProposal( raw: CoachPatchProposalDtoRaw | null | undefined, ): CoachPatchProposalDto | null { if (!raw) return null; return { kind: pickCase(raw, "kind", "Kind", ""), description: pickCase( raw, "description", "Description", null as string | null, ), content: pickCase(raw, "content", "Content", null as string | null), }; } function normalizeCoachPlan(raw: CoachPlanDtoRaw): CoachPlanDto { const evidenceRaw = pickCase( raw, "evidence", "Evidence", [] as CoachEvidenceDtoRaw[], ); const patchRaw = pickCase( raw, "patchProposal", "PatchProposal", null as CoachPatchProposalDtoRaw | null, ); return { kind: pickCase(raw, "kind", "Kind", ""), title: pickCase(raw, "title", "Title", ""), summary: pickCase(raw, "summary", "Summary", ""), questions: pickCase(raw, "questions", "Questions", [] as string[]), suggestedNextActions: pickCase( raw, "suggestedNextActions", "SuggestedNextActions", [] as string[], ), suggestedTags: pickCase( raw, "suggestedTags", "SuggestedTags", [] as string[], ), evidence: evidenceRaw.map(normalizeEvidence), patchProposal: normalizePatchProposal(patchRaw), }; } // ── API functions ─────────────────────────────────────────────── export async function aiHealth(): Promise { const data = await sendCommand({ action: "ai.health", payload: {}, }); return normalizeHealth(data); } export async function aiChat(prompt: string): Promise { return sendCommand({ action: "ai.chat", payload: { prompt }, }); } export async function aiSummarizeEntry( content: string, fileStem?: string, ): Promise { return sendCommand({ action: "ai.summarize_entry", payload: { content, fileStem }, }); } export async function coachDaily( payload: CoachSessionPayload = {}, ): Promise { const data = await sendCommand({ action: "ai.coach.daily", payload, }); return normalizeCoachPlan(data); } export async function coachEvening( payload: CoachSessionPayload = {}, ): Promise { const data = await sendCommand({ action: "ai.coach.evening", payload, }); return normalizeCoachPlan(data); } export async function coachWeekly( payload: CoachSessionPayload = {}, ): Promise { const data = await sendCommand({ action: "ai.coach.weekly", payload, }); return normalizeCoachPlan(data); }