Use `uuid` for message ID generation instead of crypto method (#882)
Because `crypto.randomUUID()` is not available on non-secure contexts (for example `http` versions of chat-ui), this would break on non-https deployments of chat-ui. This should fix #870 and fix #868pull/884/head
parent
00443e1098
commit
d8e839efe2
|
@ -35,6 +35,7 @@
|
||||||
"sharp": "^0.33.2",
|
"sharp": "^0.33.2",
|
||||||
"tailwind-scrollbar": "^3.0.0",
|
"tailwind-scrollbar": "^3.0.0",
|
||||||
"tailwindcss": "^3.4.0",
|
"tailwindcss": "^3.4.0",
|
||||||
|
"uuid": "^9.0.1",
|
||||||
"zod": "^3.22.3"
|
"zod": "^3.22.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
"@types/jsdom": "^21.1.1",
|
"@types/jsdom": "^21.1.1",
|
||||||
"@types/marked": "^4.0.8",
|
"@types/marked": "^4.0.8",
|
||||||
"@types/parquetjs": "^0.10.3",
|
"@types/parquetjs": "^0.10.3",
|
||||||
|
"@types/uuid": "^9.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.x",
|
"@typescript-eslint/eslint-plugin": "^6.x",
|
||||||
"@typescript-eslint/parser": "^6.x",
|
"@typescript-eslint/parser": "^6.x",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.28.0",
|
||||||
|
@ -1847,6 +1849,12 @@
|
||||||
"integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==",
|
"integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/uuid": {
|
||||||
|
"version": "9.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||||
|
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/webidl-conversions": {
|
"node_modules/@types/webidl-conversions": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||||
|
@ -7249,6 +7257,18 @@
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/v8-compile-cache-lib": {
|
"node_modules/v8-compile-cache-lib": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
"@types/jsdom": "^21.1.1",
|
"@types/jsdom": "^21.1.1",
|
||||||
"@types/marked": "^4.0.8",
|
"@types/marked": "^4.0.8",
|
||||||
"@types/parquetjs": "^0.10.3",
|
"@types/parquetjs": "^0.10.3",
|
||||||
|
"@types/uuid": "^9.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.x",
|
"@typescript-eslint/eslint-plugin": "^6.x",
|
||||||
"@typescript-eslint/parser": "^6.x",
|
"@typescript-eslint/parser": "^6.x",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.28.0",
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
"sharp": "^0.33.2",
|
"sharp": "^0.33.2",
|
||||||
"tailwind-scrollbar": "^3.0.0",
|
"tailwind-scrollbar": "^3.0.0",
|
||||||
"tailwindcss": "^3.4.0",
|
"tailwindcss": "^3.4.0",
|
||||||
|
"uuid": "^9.0.1",
|
||||||
"zod": "^3.22.3"
|
"zod": "^3.22.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import type { MessageUpdate } from "./MessageUpdate";
|
import type { MessageUpdate } from "./MessageUpdate";
|
||||||
import type { Timestamps } from "./Timestamps";
|
import type { Timestamps } from "./Timestamps";
|
||||||
import type { WebSearch } from "./WebSearch";
|
import type { WebSearch } from "./WebSearch";
|
||||||
|
import type { v4 } from "uuid";
|
||||||
|
|
||||||
export type Message = Partial<Timestamps> & {
|
export type Message = Partial<Timestamps> & {
|
||||||
from: "user" | "assistant" | "system";
|
from: "user" | "assistant" | "system";
|
||||||
id: ReturnType<typeof crypto.randomUUID>;
|
id: ReturnType<typeof v4>;
|
||||||
content: string;
|
content: string;
|
||||||
updates?: MessageUpdate[];
|
updates?: MessageUpdate[];
|
||||||
webSearchId?: WebSearch["_id"]; // legacy version
|
webSearchId?: WebSearch["_id"]; // legacy version
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { Conversation } from "$lib/types/Conversation";
|
import type { Conversation } from "$lib/types/Conversation";
|
||||||
import type { Message } from "$lib/types/Message";
|
import type { Message } from "$lib/types/Message";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
export function addChildren(
|
export function addChildren(
|
||||||
conv: Pick<Conversation, "messages" | "rootMessageId">,
|
conv: Pick<Conversation, "messages" | "rootMessageId">,
|
||||||
|
@ -8,7 +9,7 @@ export function addChildren(
|
||||||
): Message["id"] {
|
): Message["id"] {
|
||||||
// if this is the first message we just push it
|
// if this is the first message we just push it
|
||||||
if (conv.messages.length === 0) {
|
if (conv.messages.length === 0) {
|
||||||
const messageId = crypto.randomUUID();
|
const messageId = v4();
|
||||||
conv.rootMessageId = messageId;
|
conv.rootMessageId = messageId;
|
||||||
conv.messages.push({
|
conv.messages.push({
|
||||||
...message,
|
...message,
|
||||||
|
@ -22,7 +23,7 @@ export function addChildren(
|
||||||
throw new Error("You need to specify a parentId if this is not the first message");
|
throw new Error("You need to specify a parentId if this is not the first message");
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageId = crypto.randomUUID();
|
const messageId = v4();
|
||||||
if (!conv.rootMessageId) {
|
if (!conv.rootMessageId) {
|
||||||
// if there is no parentId we just push the message
|
// if there is no parentId we just push the message
|
||||||
if (!!parentId && parentId !== conv.messages[conv.messages.length - 1].id) {
|
if (!!parentId && parentId !== conv.messages[conv.messages.length - 1].id) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { Conversation } from "$lib/types/Conversation";
|
import type { Conversation } from "$lib/types/Conversation";
|
||||||
import type { Message } from "$lib/types/Message";
|
import type { Message } from "$lib/types/Message";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
export function addSibling(
|
export function addSibling(
|
||||||
conv: Pick<Conversation, "messages" | "rootMessageId">,
|
conv: Pick<Conversation, "messages" | "rootMessageId">,
|
||||||
|
@ -23,7 +24,7 @@ export function addSibling(
|
||||||
throw new Error("The sibling message is the root message, therefore we can't add a sibling");
|
throw new Error("The sibling message is the root message, therefore we can't add a sibling");
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageId = crypto.randomUUID();
|
const messageId = v4();
|
||||||
|
|
||||||
conv.messages.push({
|
conv.messages.push({
|
||||||
...message,
|
...message,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { Conversation } from "$lib/types/Conversation";
|
import type { Conversation } from "$lib/types/Conversation";
|
||||||
import type { Message } from "$lib/types/Message";
|
import type { Message } from "$lib/types/Message";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
export function convertLegacyConversation(
|
export function convertLegacyConversation(
|
||||||
conv: Pick<Conversation, "messages" | "rootMessageId" | "preprompt">
|
conv: Pick<Conversation, "messages" | "rootMessageId" | "preprompt">
|
||||||
|
@ -12,7 +13,7 @@ export function convertLegacyConversation(
|
||||||
content: conv.preprompt ?? "",
|
content: conv.preprompt ?? "",
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
id: crypto.randomUUID(),
|
id: v4(),
|
||||||
} satisfies Message,
|
} satisfies Message,
|
||||||
...conv.messages,
|
...conv.messages,
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { isMessageId } from "./isMessageId";
|
import { isMessageId } from "./isMessageId";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
describe("isMessageId", () => {
|
describe("isMessageId", () => {
|
||||||
it("should return true for a valid message id", () => {
|
it("should return true for a valid message id", () => {
|
||||||
expect(isMessageId(crypto.randomUUID())).toBe(true);
|
expect(isMessageId(v4())).toBe(true);
|
||||||
});
|
});
|
||||||
it("should return false for an invalid message id", () => {
|
it("should return false for an invalid message id", () => {
|
||||||
expect(isMessageId("1-2-3-4")).toBe(false);
|
expect(isMessageId("1-2-3-4")).toBe(false);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { z } from "zod";
|
||||||
import type { Message } from "$lib/types/Message";
|
import type { Message } from "$lib/types/Message";
|
||||||
import { models, validateModel } from "$lib/server/models";
|
import { models, validateModel } from "$lib/server/models";
|
||||||
import { defaultEmbeddingModel } from "$lib/server/embeddingModels";
|
import { defaultEmbeddingModel } from "$lib/server/embeddingModels";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
export const POST: RequestHandler = async ({ locals, request }) => {
|
export const POST: RequestHandler = async ({ locals, request }) => {
|
||||||
const body = await request.text();
|
const body = await request.text();
|
||||||
|
@ -24,7 +25,7 @@ export const POST: RequestHandler = async ({ locals, request }) => {
|
||||||
|
|
||||||
let messages: Message[] = [
|
let messages: Message[] = [
|
||||||
{
|
{
|
||||||
id: crypto.randomUUID(),
|
id: v4(),
|
||||||
from: "system",
|
from: "system",
|
||||||
content: values.preprompt ?? "",
|
content: values.preprompt ?? "",
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
import { addChildren } from "$lib/utils/tree/addChildren";
|
import { addChildren } from "$lib/utils/tree/addChildren";
|
||||||
import { addSibling } from "$lib/utils/tree/addSibling";
|
import { addSibling } from "$lib/utils/tree/addSibling";
|
||||||
import { createConvTreeStore } from "$lib/stores/convTree";
|
import { createConvTreeStore } from "$lib/stores/convTree";
|
||||||
|
import type { v4 } from "uuid";
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@
|
||||||
isContinue = false,
|
isContinue = false,
|
||||||
}: {
|
}: {
|
||||||
prompt?: string;
|
prompt?: string;
|
||||||
messageId?: ReturnType<typeof crypto.randomUUID>;
|
messageId?: ReturnType<typeof v4>;
|
||||||
isRetry?: boolean;
|
isRetry?: boolean;
|
||||||
isContinue?: boolean;
|
isContinue?: boolean;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
|
|
|
@ -26,6 +26,6 @@ export default defineConfig({
|
||||||
loadTTFAsArrayBuffer(),
|
loadTTFAsArrayBuffer(),
|
||||||
],
|
],
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ["browser-image-resizer"],
|
include: ["browser-image-resizer", "uuid"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue