diff --git a/.env.template b/.env.template
index 09c63f50d47..a7e33c0b8ff 100644
--- a/.env.template
+++ b/.env.template
@@ -92,35 +92,6 @@ MODELS=`[
"max_new_tokens": 4096
}
},
- {
- "name": "tiiuae/falcon-180B-chat",
- "displayName": "tiiuae/falcon-180B-chat",
- "description": "Falcon-180B is a 180B parameters causal decoder-only model built by TII and trained on 3,500B tokens.",
- "websiteUrl": "https://www.tii.ae/news/technology-innovation-institute-introduces-worlds-most-powerful-open-llm-falcon-180b",
- "preprompt": " ",
- "chatPromptTemplate": "System: {{preprompt}}\nUser:{{#each messages}}{{#ifUser}}{{content}}\nFalcon:{{/ifUser}}{{#ifAssistant}}{{content}}\nUser:{{/ifAssistant}}{{/each}}",
- "parameters": {
- "temperature": 0.1,
- "top_p": 0.95,
- "repetition_penalty": 1.2,
- "top_k": 50,
- "truncate": 1024,
- "max_new_tokens": 1024,
- "stop": ["User:"]
- },
- "promptExamples": [
- {
- "title": "Write an email from bullet list",
- "prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
- }, {
- "title": "Code a snake game",
- "prompt": "Code a basic snake game in python, give explanations for each step."
- }, {
- "title": "Assist in a task",
- "prompt": "How do I make a delicious lemon cheesecake?"
- }
- ]
- },
{
"name": "mistralai/Mistral-7B-Instruct-v0.1",
"displayName": "mistralai/Mistral-7B-Instruct-v0.1",
@@ -215,7 +186,9 @@ OLD_MODELS=`[
{"name":"bigcode/starcoder"},
{"name":"OpenAssistant/oasst-sft-6-llama-30b-xor"},
{"name":"HuggingFaceH4/zephyr-7b-alpha"},
- {"name":"openchat/openchat_3.5"}]`
+ {"name":"openchat/openchat_3.5"},
+ {"name": "tiiuae/falcon-180B-chat"}
+]`
TASK_MODEL='mistralai/Mistral-7B-Instruct-v0.2'
# TASK_MODEL=`{
diff --git a/package-lock.json b/package-lock.json
index e3f4c44b7ce..371731efac3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "chat-ui",
- "version": "0.6.0",
+ "version": "0.7.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "chat-ui",
- "version": "0.6.0",
+ "version": "0.7.0",
"dependencies": {
"@huggingface/hub": "^0.5.1",
"@huggingface/inference": "^2.6.3",
@@ -20,6 +20,7 @@
"highlight.js": "^11.7.0",
"image-size": "^1.0.2",
"jsdom": "^22.0.0",
+ "json5": "^2.2.3",
"marked": "^4.3.0",
"mongodb": "^5.8.0",
"nanoid": "^4.0.2",
@@ -3597,6 +3598,17 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
diff --git a/package.json b/package.json
index 998987d9978..d389bc13d31 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "chat-ui",
- "version": "0.6.0",
+ "version": "0.7.0",
"private": true,
"packageManager": "npm@9.5.0",
"scripts": {
@@ -55,6 +55,7 @@
"highlight.js": "^11.7.0",
"image-size": "^1.0.2",
"jsdom": "^22.0.0",
+ "json5": "^2.2.3",
"marked": "^4.3.0",
"mongodb": "^5.8.0",
"nanoid": "^4.0.2",
diff --git a/src/lib/components/chat/ChatIntroduction.svelte b/src/lib/components/chat/ChatIntroduction.svelte
index d5667732008..8cc746fd522 100644
--- a/src/lib/components/chat/ChatIntroduction.svelte
+++ b/src/lib/components/chat/ChatIntroduction.svelte
@@ -10,6 +10,7 @@
import { findCurrentModel } from "$lib/utils/models";
import { base } from "$app/paths";
import { useSettingsStore } from "$lib/stores/settings";
+ import JSON5 from "json5";
export let currentModel: Model;
export let models: Model[];
@@ -19,7 +20,7 @@
$: currentModelMetadata = findCurrentModel(models, $settings.activeModel);
const announcementBanners = PUBLIC_ANNOUNCEMENT_BANNERS
- ? JSON.parse(PUBLIC_ANNOUNCEMENT_BANNERS)
+ ? JSON5.parse(PUBLIC_ANNOUNCEMENT_BANNERS)
: [];
const dispatch = createEventDispatcher<{ message: string }>();
diff --git a/src/lib/components/chat/ChatWindow.svelte b/src/lib/components/chat/ChatWindow.svelte
index e123de67a15..66e6e78d635 100644
--- a/src/lib/components/chat/ChatWindow.svelte
+++ b/src/lib/components/chat/ChatWindow.svelte
@@ -1,11 +1,12 @@
@@ -220,12 +241,19 @@
{#if messages.length}
{/if}
diff --git a/src/lib/server/auth.ts b/src/lib/server/auth.ts
index 2e66a4ce49a..8f021425833 100644
--- a/src/lib/server/auth.ts
+++ b/src/lib/server/auth.ts
@@ -15,6 +15,7 @@ import { z } from "zod";
import { dev } from "$app/environment";
import type { Cookies } from "@sveltejs/kit";
import { collections } from "./database";
+import JSON5 from "json5";
export interface OIDCSettings {
redirectURI: string;
@@ -40,7 +41,7 @@ const OIDConfig = z
TOLERANCE: stringWithDefault(OPENID_TOLERANCE),
RESOURCE: stringWithDefault(OPENID_RESOURCE),
})
- .parse(JSON.parse(OPENID_CONFIG));
+ .parse(JSON5.parse(OPENID_CONFIG));
export const requiresUser = !!OIDConfig.CLIENT_ID && !!OIDConfig.CLIENT_SECRET;
diff --git a/src/lib/server/models.ts b/src/lib/server/models.ts
index 58d05bd7a9b..0e6e5320b68 100644
--- a/src/lib/server/models.ts
+++ b/src/lib/server/models.ts
@@ -13,6 +13,8 @@ import endpoints, { endpointSchema, type Endpoint } from "./endpoints/endpoints"
import endpointTgi from "./endpoints/tgi/endpointTgi";
import { sum } from "$lib/utils/sum";
+import JSON5 from "json5";
+
type Optional = Pick, K> & Omit;
const modelConfig = z.object({
@@ -68,7 +70,7 @@ const modelConfig = z.object({
unlisted: z.boolean().default(false),
});
-const modelsRaw = z.array(modelConfig).parse(JSON.parse(MODELS));
+const modelsRaw = z.array(modelConfig).parse(JSON5.parse(MODELS));
const processModel = async (m: z.infer) => ({
...m,
@@ -138,7 +140,7 @@ export const oldModels = OLD_MODELS
displayName: z.string().min(1).optional(),
})
)
- .parse(JSON.parse(OLD_MODELS))
+ .parse(JSON5.parse(OLD_MODELS))
.map((m) => ({ ...m, id: m.id || m.name, displayName: m.displayName || m.name }))
: [];
@@ -151,7 +153,7 @@ export const validateModel = (_models: BackendModel[]) => {
export const smallModel = TASK_MODEL
? (models.find((m) => m.name === TASK_MODEL) ||
- (await processModel(modelConfig.parse(JSON.parse(TASK_MODEL))).then((m) =>
+ (await processModel(modelConfig.parse(JSON5.parse(TASK_MODEL))).then((m) =>
addEndpoint(m)
))) ??
defaultModel
diff --git a/src/lib/server/websearch/generateQuery.ts b/src/lib/server/websearch/generateQuery.ts
index 69d0c1ce40b..cdff0c7b937 100644
--- a/src/lib/server/websearch/generateQuery.ts
+++ b/src/lib/server/websearch/generateQuery.ts
@@ -3,11 +3,12 @@ import { format } from "date-fns";
import { generateFromDefaultEndpoint } from "../generateFromDefaultEndpoint";
import { WEBSEARCH_ALLOWLIST, WEBSEARCH_BLOCKLIST } from "$env/static/private";
import { z } from "zod";
+import JSON5 from "json5";
const listSchema = z.array(z.string()).default([]);
-const allowList = listSchema.parse(JSON.parse(WEBSEARCH_ALLOWLIST));
-const blockList = listSchema.parse(JSON.parse(WEBSEARCH_BLOCKLIST));
+const allowList = listSchema.parse(JSON5.parse(WEBSEARCH_ALLOWLIST));
+const blockList = listSchema.parse(JSON5.parse(WEBSEARCH_BLOCKLIST));
const queryModifier = [
...allowList.map((item) => "site:" + item),
diff --git a/src/lib/server/websearch/runWebSearch.ts b/src/lib/server/websearch/runWebSearch.ts
index e91b87fd7e9..c37512cbe52 100644
--- a/src/lib/server/websearch/runWebSearch.ts
+++ b/src/lib/server/websearch/runWebSearch.ts
@@ -45,11 +45,17 @@ export async function runWebSearch(
webSearch.results =
(results.organic_results &&
results.organic_results.map((el: { title?: string; link: string; text?: string }) => {
- const { title, link, text } = el;
- const { hostname } = new URL(link);
- return { title, link, hostname, text };
+ try {
+ const { title, link, text } = el;
+ const { hostname } = new URL(link);
+ return { title, link, hostname, text };
+ } catch (e) {
+ // Ignore Errors
+ return null;
+ }
})) ??
[];
+ webSearch.results = webSearch.results.filter((value) => value !== null);
webSearch.results = webSearch.results
.filter(({ link }) => !DOMAIN_BLOCKLIST.some((el) => link.includes(el))) // filter out blocklist links
.slice(0, MAX_N_PAGES_SCRAPE); // limit to first 10 links only
diff --git a/src/lib/shareConversation.ts b/src/lib/shareConversation.ts
index 0086fcaf5d4..064a586a596 100644
--- a/src/lib/shareConversation.ts
+++ b/src/lib/shareConversation.ts
@@ -8,7 +8,7 @@ export async function shareConversation(id: string, title: string) {
try {
if (id.length === 7) {
const url = get(page).url;
- share(getShareUrl(url, id), title);
+ await share(getShareUrl(url, id), title);
} else {
const res = await fetch(`${base}/conversation/${id}/share`, {
method: "POST",
@@ -24,7 +24,7 @@ export async function shareConversation(id: string, title: string) {
}
const { url } = await res.json();
- share(url, title);
+ await share(url, title);
}
} catch (err) {
error.set(ERROR_MESSAGES.default);
diff --git a/src/lib/stores/settings.ts b/src/lib/stores/settings.ts
index 51dab38dda2..18c55ce6e54 100644
--- a/src/lib/stores/settings.ts
+++ b/src/lib/stores/settings.ts
@@ -1,5 +1,7 @@
import { browser } from "$app/environment";
+import { invalidate } from "$app/navigation";
import { base } from "$app/paths";
+import { UrlDependency } from "$lib/types/UrlDependency";
import { getContext, setContext } from "svelte";
import { type Writable, writable, get } from "svelte/store";
@@ -53,6 +55,7 @@ export function createSettingsStore(initialValue: Omit {
updatedAt: 1,
createdAt: 1,
})
- .map((conv) => ({
- id: conv._id.toString(),
- title: settings?.hideEmojiOnSidebar ? conv.title.replace(/\p{Emoji}/gu, "") : conv.title,
- model: conv.model ?? defaultModel,
- updatedAt: conv.updatedAt,
- }))
+ .map((conv) => {
+ // remove emojis if settings say so
+ if (settings?.hideEmojiOnSidebar) {
+ conv.title = conv.title.replace(/\p{Emoji}/gu, "");
+ }
+
+ // remove invalid unicode and trim whitespaces
+ conv.title = conv.title.replace(/\uFFFD/gu, "").trimStart();
+ return {
+ id: conv._id.toString(),
+ title: settings?.hideEmojiOnSidebar ? conv.title.replace(/\p{Emoji}/gu, "") : conv.title,
+ model: conv.model ?? defaultModel,
+ updatedAt: conv.updatedAt,
+ };
+ })
.toArray(),
settings: {
searchEnabled: !!(