a0b98a944f
* feat: introducing TextToDiagram v2 feature * fix: eslint issue * debug mermaid bundle size * tests: covering the utils * fix: import mock chunks dynamically to shrink the bundle size * fix: removing replay feature * fix: removing unused prop * fix: bumping workbox cache limit * snapshots + yarn.lock * bump mermaid-to-excalidraw@2 and split into its own chunk * bump node@20 * css tweaks * move files around & rewrite stream chunk schema * random naming & file structure refactor + some tweaks * fix preview theme * support custom warning renderer * label and css fix * fix and rwrite 429 handling * fix label --------- Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
659 lines
16 KiB
TypeScript
659 lines
16 KiB
TypeScript
import {
|
|
addMessages,
|
|
getLastAssistantMessage,
|
|
getMessagesForLLM,
|
|
removeLastAssistantMessage,
|
|
updateAssistantContent,
|
|
} from "./chat";
|
|
|
|
import type { TChat } from "../types";
|
|
|
|
describe("chat utils", () => {
|
|
describe("updateAssistantContent", () => {
|
|
it("should update the last assistant message with new payload", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Hello",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "assistant",
|
|
content: "Hi there",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = updateAssistantContent(chatHistory, {
|
|
content: "Hi there, how can I help?",
|
|
});
|
|
|
|
expect(result.messages[1].content).toBe("Hi there, how can I help?");
|
|
expect(result.messages[1].id).toBe("2"); // ID should remain the same
|
|
});
|
|
|
|
it("should update only the last assistant message when multiple exist", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "First assistant message",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "user",
|
|
content: "User message",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: "assistant",
|
|
content: "Second assistant message",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = updateAssistantContent(chatHistory, {
|
|
content: "Updated second message",
|
|
});
|
|
|
|
expect(result.messages[0].content).toBe("First assistant message");
|
|
expect(result.messages[2].content).toBe("Updated second message");
|
|
});
|
|
|
|
it("should update isGenerating flag", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "Message",
|
|
timestamp: new Date("2024-01-01"),
|
|
isGenerating: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = updateAssistantContent(chatHistory, {
|
|
isGenerating: true,
|
|
});
|
|
|
|
expect(result.messages[0].isGenerating).toBe(true);
|
|
});
|
|
|
|
it("should update error information", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "Message",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = updateAssistantContent(chatHistory, {
|
|
error: "Something went wrong",
|
|
errorType: "network",
|
|
});
|
|
|
|
expect(result.messages[0].error).toBe("Something went wrong");
|
|
expect(result.messages[0].errorType).toBe("network");
|
|
});
|
|
|
|
it("should return unchanged chatHistory if no assistant message exists", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Hello",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = updateAssistantContent(chatHistory, {
|
|
content: "New content",
|
|
});
|
|
|
|
expect(result).toEqual(chatHistory);
|
|
});
|
|
|
|
it("should not mutate original chatHistory", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "Original",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = updateAssistantContent(chatHistory, {
|
|
content: "Updated",
|
|
});
|
|
|
|
expect(chatHistory.messages[0].content).toBe("Original");
|
|
expect(result.messages[0].content).toBe("Updated");
|
|
});
|
|
});
|
|
|
|
describe("getLastAssistantMessage", () => {
|
|
it("should return the last assistant message", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Hello",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "assistant",
|
|
content: "Hi there",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getLastAssistantMessage(chatHistory);
|
|
|
|
expect(result).toEqual({
|
|
id: "2",
|
|
type: "assistant",
|
|
content: "Hi there",
|
|
timestamp: new Date("2024-01-01"),
|
|
});
|
|
});
|
|
|
|
it("should return the last assistant message when multiple exist", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "First",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "user",
|
|
content: "User",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: "assistant",
|
|
content: "Second",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getLastAssistantMessage(chatHistory);
|
|
|
|
expect(result.id).toBe("3");
|
|
expect(result.content).toBe("Second");
|
|
});
|
|
|
|
it("should return undefined if no assistant message exists", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Hello",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getLastAssistantMessage(chatHistory);
|
|
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it("should return undefined for empty messages array", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = getLastAssistantMessage(chatHistory);
|
|
|
|
expect(result).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("addMessages", () => {
|
|
it("should add a single message with id and timestamp", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "user",
|
|
content: "Hello",
|
|
},
|
|
]);
|
|
|
|
expect(result.messages).toHaveLength(1);
|
|
expect(result.messages[0]).toMatchObject({
|
|
type: "user",
|
|
content: "Hello",
|
|
});
|
|
expect(result.messages[0].id).toBeDefined();
|
|
expect(result.messages[0].timestamp).toBeInstanceOf(Date);
|
|
});
|
|
|
|
it("should add multiple messages", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "user",
|
|
content: "Hello",
|
|
},
|
|
{
|
|
type: "assistant",
|
|
content: "Hi there",
|
|
},
|
|
]);
|
|
|
|
expect(result.messages).toHaveLength(2);
|
|
expect(result.messages[0].type).toBe("user");
|
|
expect(result.messages[1].type).toBe("assistant");
|
|
});
|
|
|
|
it("should append to existing messages", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Existing",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "assistant",
|
|
content: "New message",
|
|
},
|
|
]);
|
|
|
|
expect(result.messages).toHaveLength(2);
|
|
expect(result.messages[0].content).toBe("Existing");
|
|
expect(result.messages[1].content).toBe("New message");
|
|
});
|
|
|
|
it("should add warning messages", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "warning",
|
|
},
|
|
]);
|
|
|
|
expect(result.messages).toHaveLength(1);
|
|
expect(result.messages[0].type).toBe("warning");
|
|
});
|
|
|
|
it("should preserve additional message properties", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "assistant",
|
|
content: "Message",
|
|
isGenerating: true,
|
|
error: "Error text",
|
|
errorType: "parse",
|
|
},
|
|
]);
|
|
|
|
expect(result.messages[0].isGenerating).toBe(true);
|
|
expect(result.messages[0].error).toBe("Error text");
|
|
expect(result.messages[0].errorType).toBe("parse");
|
|
});
|
|
|
|
it("should not mutate original chatHistory", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "user",
|
|
content: "Hello",
|
|
},
|
|
]);
|
|
|
|
expect(chatHistory.messages).toHaveLength(0);
|
|
expect(result.messages).toHaveLength(1);
|
|
});
|
|
|
|
it("should generate unique IDs for each message", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = addMessages(chatHistory, [
|
|
{
|
|
type: "user",
|
|
content: "Message 1",
|
|
},
|
|
{
|
|
type: "assistant",
|
|
content: "Message 2",
|
|
},
|
|
]);
|
|
|
|
expect(result.messages[0].id).not.toBe(result.messages[1].id);
|
|
});
|
|
});
|
|
|
|
describe("removeLastAssistantMessage", () => {
|
|
it("should remove the last assistant message", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Hello",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "assistant",
|
|
content: "Hi there",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: "user",
|
|
content: "How are you?",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = removeLastAssistantMessage(chatHistory);
|
|
|
|
expect(result.messages).toHaveLength(2);
|
|
expect(result.messages[0].id).toBe("1");
|
|
expect(result.messages[1].id).toBe("3");
|
|
});
|
|
|
|
it("should remove only the last assistant message when multiple exist", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "First",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "user",
|
|
content: "User",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: "assistant",
|
|
content: "Second",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = removeLastAssistantMessage(chatHistory);
|
|
|
|
expect(result.messages).toHaveLength(2);
|
|
expect(result.messages[0].id).toBe("1");
|
|
expect(result.messages[1].id).toBe("2");
|
|
});
|
|
|
|
it("should return unchanged chatHistory if no assistant message exists", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Hello",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = removeLastAssistantMessage(chatHistory);
|
|
|
|
expect(result).toEqual(chatHistory);
|
|
});
|
|
|
|
it("should handle empty messages array", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = removeLastAssistantMessage(chatHistory);
|
|
|
|
expect(result).toEqual(chatHistory);
|
|
});
|
|
|
|
it("should not mutate original chatHistory", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "Message",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = removeLastAssistantMessage(chatHistory);
|
|
|
|
expect(chatHistory.messages).toHaveLength(1);
|
|
expect(result.messages).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe("getMessagesForApi", () => {
|
|
it("should filter out messages with empty content", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "user",
|
|
content: "Valid question",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: "assistant",
|
|
content: "",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "4",
|
|
type: "assistant",
|
|
content: "Valid answer",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getMessagesForLLM(chatHistory);
|
|
|
|
expect(result).toHaveLength(2);
|
|
expect(result[0].content).toBe("Valid question");
|
|
expect(result[1].content).toBe("Valid answer");
|
|
});
|
|
|
|
it("should return only user message if no assistant messages", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Question",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getMessagesForLLM(chatHistory);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toEqual({
|
|
role: "user",
|
|
content: "Question",
|
|
});
|
|
});
|
|
|
|
it("should return only assistant messages if no user message", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "assistant",
|
|
content: "Answer",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getMessagesForLLM(chatHistory);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toEqual({
|
|
role: "assistant",
|
|
content: "Answer",
|
|
});
|
|
});
|
|
|
|
it("should return empty array for empty messages", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [],
|
|
};
|
|
|
|
const result = getMessagesForLLM(chatHistory);
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
|
|
it("should filter out warning messages", () => {
|
|
const chatHistory: TChat.ChatHistory = {
|
|
id: "chat-1",
|
|
currentPrompt: "",
|
|
messages: [
|
|
{
|
|
id: "1",
|
|
type: "user",
|
|
content: "Question",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: "warning",
|
|
content: "warning",
|
|
timestamp: new Date("2024-01-01"),
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = getMessagesForLLM(chatHistory);
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toEqual(
|
|
expect.objectContaining({
|
|
role: "user",
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
});
|