From d8e839efe2f20b687d6c32a541a1e78ffea1d730 Mon Sep 17 00:00:00 2001 From: Nathan Sarrazin Date: Tue, 27 Feb 2024 18:39:09 +0100 Subject: [PATCH] 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 #868 --- package-lock.json | 20 +++++++++++++++++++ package.json | 2 ++ src/lib/types/Message.ts | 3 ++- src/lib/utils/tree/addChildren.ts | 5 +++-- src/lib/utils/tree/addSibling.ts | 3 ++- .../utils/tree/convertLegacyConversation.ts | 3 ++- src/lib/utils/tree/isMessageId.spec.ts | 3 ++- src/routes/conversation/+server.ts | 3 ++- src/routes/conversation/[id]/+page.svelte | 3 ++- vite.config.ts | 2 +- 10 files changed, 38 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6583c52b..dd1e9a91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "sharp": "^0.33.2", "tailwind-scrollbar": "^3.0.0", "tailwindcss": "^3.4.0", + "uuid": "^9.0.1", "zod": "^3.22.3" }, "devDependencies": { @@ -46,6 +47,7 @@ "@types/jsdom": "^21.1.1", "@types/marked": "^4.0.8", "@types/parquetjs": "^0.10.3", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^6.x", "@typescript-eslint/parser": "^6.x", "eslint": "^8.28.0", @@ -1847,6 +1849,12 @@ "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", "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": { "version": "7.0.0", "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", "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": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", diff --git a/package.json b/package.json index 0c2484b9..fb0f47fa 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@types/jsdom": "^21.1.1", "@types/marked": "^4.0.8", "@types/parquetjs": "^0.10.3", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^6.x", "@typescript-eslint/parser": "^6.x", "eslint": "^8.28.0", @@ -71,6 +72,7 @@ "sharp": "^0.33.2", "tailwind-scrollbar": "^3.0.0", "tailwindcss": "^3.4.0", + "uuid": "^9.0.1", "zod": "^3.22.3" }, "optionalDependencies": { diff --git a/src/lib/types/Message.ts b/src/lib/types/Message.ts index 2c4b4762..68f9d6b2 100644 --- a/src/lib/types/Message.ts +++ b/src/lib/types/Message.ts @@ -1,10 +1,11 @@ import type { MessageUpdate } from "./MessageUpdate"; import type { Timestamps } from "./Timestamps"; import type { WebSearch } from "./WebSearch"; +import type { v4 } from "uuid"; export type Message = Partial & { from: "user" | "assistant" | "system"; - id: ReturnType; + id: ReturnType; content: string; updates?: MessageUpdate[]; webSearchId?: WebSearch["_id"]; // legacy version diff --git a/src/lib/utils/tree/addChildren.ts b/src/lib/utils/tree/addChildren.ts index c35ff426..e8149a1f 100644 --- a/src/lib/utils/tree/addChildren.ts +++ b/src/lib/utils/tree/addChildren.ts @@ -1,5 +1,6 @@ import type { Conversation } from "$lib/types/Conversation"; import type { Message } from "$lib/types/Message"; +import { v4 } from "uuid"; export function addChildren( conv: Pick, @@ -8,7 +9,7 @@ export function addChildren( ): Message["id"] { // if this is the first message we just push it if (conv.messages.length === 0) { - const messageId = crypto.randomUUID(); + const messageId = v4(); conv.rootMessageId = messageId; conv.messages.push({ ...message, @@ -22,7 +23,7 @@ export function addChildren( 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 there is no parentId we just push the message if (!!parentId && parentId !== conv.messages[conv.messages.length - 1].id) { diff --git a/src/lib/utils/tree/addSibling.ts b/src/lib/utils/tree/addSibling.ts index 4d04026d..8371ffcf 100644 --- a/src/lib/utils/tree/addSibling.ts +++ b/src/lib/utils/tree/addSibling.ts @@ -1,5 +1,6 @@ import type { Conversation } from "$lib/types/Conversation"; import type { Message } from "$lib/types/Message"; +import { v4 } from "uuid"; export function addSibling( conv: Pick, @@ -23,7 +24,7 @@ export function addSibling( 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({ ...message, diff --git a/src/lib/utils/tree/convertLegacyConversation.ts b/src/lib/utils/tree/convertLegacyConversation.ts index 583fb8d0..4b14468a 100644 --- a/src/lib/utils/tree/convertLegacyConversation.ts +++ b/src/lib/utils/tree/convertLegacyConversation.ts @@ -1,5 +1,6 @@ import type { Conversation } from "$lib/types/Conversation"; import type { Message } from "$lib/types/Message"; +import { v4 } from "uuid"; export function convertLegacyConversation( conv: Pick @@ -12,7 +13,7 @@ export function convertLegacyConversation( content: conv.preprompt ?? "", createdAt: new Date(), updatedAt: new Date(), - id: crypto.randomUUID(), + id: v4(), } satisfies Message, ...conv.messages, ]; diff --git a/src/lib/utils/tree/isMessageId.spec.ts b/src/lib/utils/tree/isMessageId.spec.ts index aa709979..91b2baef 100644 --- a/src/lib/utils/tree/isMessageId.spec.ts +++ b/src/lib/utils/tree/isMessageId.spec.ts @@ -1,9 +1,10 @@ import { describe, expect, it } from "vitest"; import { isMessageId } from "./isMessageId"; +import { v4 } from "uuid"; describe("isMessageId", () => { 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", () => { expect(isMessageId("1-2-3-4")).toBe(false); diff --git a/src/routes/conversation/+server.ts b/src/routes/conversation/+server.ts index e7f4c8a7..df3787b2 100644 --- a/src/routes/conversation/+server.ts +++ b/src/routes/conversation/+server.ts @@ -7,6 +7,7 @@ import { z } from "zod"; import type { Message } from "$lib/types/Message"; import { models, validateModel } from "$lib/server/models"; import { defaultEmbeddingModel } from "$lib/server/embeddingModels"; +import { v4 } from "uuid"; export const POST: RequestHandler = async ({ locals, request }) => { const body = await request.text(); @@ -24,7 +25,7 @@ export const POST: RequestHandler = async ({ locals, request }) => { let messages: Message[] = [ { - id: crypto.randomUUID(), + id: v4(), from: "system", content: values.preprompt ?? "", createdAt: new Date(), diff --git a/src/routes/conversation/[id]/+page.svelte b/src/routes/conversation/[id]/+page.svelte index fd5d18f0..868a799b 100644 --- a/src/routes/conversation/[id]/+page.svelte +++ b/src/routes/conversation/[id]/+page.svelte @@ -18,6 +18,7 @@ import { addChildren } from "$lib/utils/tree/addChildren"; import { addSibling } from "$lib/utils/tree/addSibling"; import { createConvTreeStore } from "$lib/stores/convTree"; + import type { v4 } from "uuid"; export let data; @@ -72,7 +73,7 @@ isContinue = false, }: { prompt?: string; - messageId?: ReturnType; + messageId?: ReturnType; isRetry?: boolean; isContinue?: boolean; }): Promise { diff --git a/vite.config.ts b/vite.config.ts index 54405234..0ffbd048 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -26,6 +26,6 @@ export default defineConfig({ loadTTFAsArrayBuffer(), ], optimizeDeps: { - include: ["browser-image-resizer"], + include: ["browser-image-resizer", "uuid"], }, });