import { sendCommand } from "./client"; import { pickCase } from "./normalize"; // ── Public types ──────────────────────────────────────────────── export type ConversationDto = { id: string; title: string; createdAt: string; updatedAt: string; }; export type ConversationMessageDto = { id: string; role: string; text: string; createdAt: string; }; export type ConversationDetailDto = { id: string; title: string; messages: ConversationMessageDto[]; createdAt: string; updatedAt: string; }; export type ConversationChatResult = { userMessage: ConversationMessageDto; assistantMessage: ConversationMessageDto; }; // ── Raw (PascalCase) variants ─────────────────────────────────── type ConversationDtoRaw = { id?: string; title?: string; createdAt?: string; updatedAt?: string; Id?: string; Title?: string; CreatedAt?: string; UpdatedAt?: string; }; type ConversationMessageDtoRaw = { id?: string; role?: string; text?: string; createdAt?: string; Id?: string; Role?: string; Text?: string; CreatedAt?: string; }; type ConversationDetailDtoRaw = { id?: string; title?: string; messages?: ConversationMessageDtoRaw[]; createdAt?: string; updatedAt?: string; Id?: string; Title?: string; Messages?: ConversationMessageDtoRaw[]; CreatedAt?: string; UpdatedAt?: string; }; type ConversationChatResultRaw = { userMessage?: ConversationMessageDtoRaw; assistantMessage?: ConversationMessageDtoRaw; UserMessage?: ConversationMessageDtoRaw; AssistantMessage?: ConversationMessageDtoRaw; }; // ── Normalizers ───────────────────────────────────────────────── function normalizeMessage( raw: ConversationMessageDtoRaw, ): ConversationMessageDto { return { id: pickCase(raw, "id", "Id", ""), role: pickCase(raw, "role", "Role", ""), text: pickCase(raw, "text", "Text", ""), createdAt: pickCase(raw, "createdAt", "CreatedAt", ""), }; } function normalizeConversation(raw: ConversationDtoRaw): ConversationDto { return { id: pickCase(raw, "id", "Id", ""), title: pickCase(raw, "title", "Title", ""), createdAt: pickCase(raw, "createdAt", "CreatedAt", ""), updatedAt: pickCase(raw, "updatedAt", "UpdatedAt", ""), }; } function normalizeDetail(raw: ConversationDetailDtoRaw): ConversationDetailDto { const msgs = pickCase( raw, "messages", "Messages", [] as ConversationMessageDtoRaw[], ); return { id: pickCase(raw, "id", "Id", ""), title: pickCase(raw, "title", "Title", ""), messages: msgs.map(normalizeMessage), createdAt: pickCase(raw, "createdAt", "CreatedAt", ""), updatedAt: pickCase(raw, "updatedAt", "UpdatedAt", ""), }; } function normalizeChatResult( raw: ConversationChatResultRaw, ): ConversationChatResult { const userRaw = pickCase( raw, "userMessage", "UserMessage", {} as ConversationMessageDtoRaw, ); const assistantRaw = pickCase( raw, "assistantMessage", "AssistantMessage", {} as ConversationMessageDtoRaw, ); return { userMessage: normalizeMessage(userRaw), assistantMessage: normalizeMessage(assistantRaw), }; } // ── API functions ─────────────────────────────────────────────── export async function listConversations(): Promise { const data = await sendCommand({ action: "conversations.list", payload: {}, }); return (data ?? []).map(normalizeConversation); } export async function getConversation( id: string, ): Promise { const data = await sendCommand({ action: "conversations.get", id, payload: {}, }); return normalizeDetail(data); } export async function createConversation( title: string, ): Promise { const data = await sendCommand({ action: "conversations.create", payload: { title }, }); return normalizeConversation(data); } export async function updateConversation( id: string, title: string, ): Promise { return sendCommand({ action: "conversations.update", id, payload: { title }, }); } export async function deleteConversation(id: string): Promise { return sendCommand({ action: "conversations.delete", id, payload: {}, }); } export async function conversationChat( conversationId: string, prompt: string, ): Promise { const data = await sendCommand({ action: "conversations.chat", payload: { conversationId, prompt }, }); return normalizeChatResult(data); }