Monorepo with centralized build props, npm workspaces, LlamaSharp AI, SQLite/SQLCipher storage, Svelte frontend, and unified smoke tests. Co-Authored-By: Oz <oz-agent@warp.dev>
196 lines
4.4 KiB
TypeScript
196 lines
4.4 KiB
TypeScript
import { sendCommand } from "./client";
|
|
import { pickCase } from "./normalize";
|
|
|
|
//#region 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;
|
|
};
|
|
//#endregion
|
|
|
|
//#region PascalCase Normalizers
|
|
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;
|
|
};
|
|
//#endregion
|
|
|
|
//#region 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),
|
|
};
|
|
}
|
|
//#endregion
|
|
|
|
//#region API Functions
|
|
export async function listConversations(): Promise<ConversationDto[]> {
|
|
const data = await sendCommand<ConversationDtoRaw[]>({
|
|
action: "conversations.list",
|
|
payload: {},
|
|
});
|
|
return (data ?? []).map(normalizeConversation);
|
|
}
|
|
|
|
export async function getConversation(
|
|
id: string,
|
|
): Promise<ConversationDetailDto> {
|
|
const data = await sendCommand<ConversationDetailDtoRaw>({
|
|
action: "conversations.get",
|
|
id,
|
|
payload: {},
|
|
});
|
|
return normalizeDetail(data);
|
|
}
|
|
|
|
export async function createConversation(
|
|
title: string,
|
|
): Promise<ConversationDto> {
|
|
const data = await sendCommand<ConversationDtoRaw>({
|
|
action: "conversations.create",
|
|
payload: { title },
|
|
});
|
|
return normalizeConversation(data);
|
|
}
|
|
|
|
export async function updateConversation(
|
|
id: string,
|
|
title: string,
|
|
): Promise<boolean> {
|
|
return sendCommand<boolean>({
|
|
action: "conversations.update",
|
|
id,
|
|
payload: { title },
|
|
});
|
|
}
|
|
|
|
export async function deleteConversation(id: string): Promise<boolean> {
|
|
return sendCommand<boolean>({
|
|
action: "conversations.delete",
|
|
id,
|
|
payload: {},
|
|
});
|
|
}
|
|
|
|
export async function conversationChat(
|
|
conversationId: string,
|
|
prompt: string,
|
|
): Promise<ConversationChatResult> {
|
|
const data = await sendCommand<ConversationChatResultRaw>({
|
|
action: "conversations.chat",
|
|
payload: { conversationId, prompt },
|
|
});
|
|
return normalizeChatResult(data);
|
|
}
|
|
//#endregion
|