{
+ if (data.settings.assistants.includes(assistant._id.toString())) {
+ settings.instantSet({ activeModel: assistant._id.toString() });
+ goto(`${base}` || "/");
+ } else {
+ goto(`${base}/assistant/${assistant._id}`);
+ }
+ }}
>
{#if assistant.userCount && assistant.userCount > 1}
{/if}
-
+
{:else}
No assistants found
{/each}
diff --git a/src/routes/conversation/+server.ts b/src/routes/conversation/+server.ts
index e7f4c8a7e24..df3787b25d2 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 b19001ed165..97b730ebf04 100644
--- a/src/routes/conversation/[id]/+page.svelte
+++ b/src/routes/conversation/[id]/+page.svelte
@@ -4,10 +4,9 @@
import { isAborted } from "$lib/stores/isAborted";
import { onMount } from "svelte";
import { page } from "$app/stores";
- import { goto, invalidate } from "$app/navigation";
+ import { goto, invalidateAll } from "$app/navigation";
import { base } from "$app/paths";
import { shareConversation } from "$lib/shareConversation";
- import { UrlDependency } from "$lib/types/UrlDependency";
import { ERROR_MESSAGES, error } from "$lib/stores/errors";
import { findCurrentModel } from "$lib/utils/models";
import { webSearchParameters } from "$lib/stores/webSearchParameters";
@@ -18,17 +17,11 @@
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;
- let messages = data.messages;
- let lastLoadedMessages = data.messages;
-
- // Since we modify the messages array locally, we don't want to reset it if an old version is passed
- $: if (data.messages !== lastLoadedMessages) {
- messages = data.messages;
- lastLoadedMessages = data.messages;
- }
+ $: ({ messages } = data);
let loading = false;
let pending = false;
@@ -72,7 +65,7 @@
isContinue = false,
}: {
prompt?: string;
- messageId?: ReturnType
;
+ messageId?: ReturnType;
isRetry?: boolean;
isContinue?: boolean;
}): Promise {
@@ -231,9 +224,16 @@
// this is a bit ugly
// we read the stream until we get the final answer
+
+ let readerClosed = false;
+
+ reader.closed.then(() => {
+ readerClosed = true;
+ });
+
while (finalAnswer === "") {
// check for abort
- if ($isAborted) {
+ if ($isAborted || $error || readerClosed) {
reader?.cancel();
break;
}
@@ -243,7 +243,6 @@
// we read, if it's done we cancel
if (done) {
reader.cancel();
- return;
}
if (!value) {
@@ -264,10 +263,8 @@
if (update.type === "finalAnswer") {
finalAnswer = update.text;
- reader.cancel();
loading = false;
pending = false;
- invalidate(UrlDependency.Conversation);
} else if (update.type === "stream") {
pending = false;
messageToWriteTo.content += update.token;
@@ -306,7 +303,6 @@
}
messageToWriteTo.updates = messageUpdates;
- await invalidate(UrlDependency.ConversationList);
} catch (err) {
if (err instanceof Error && err.message.includes("overloaded")) {
$error = "Too much traffic, please try again.";
@@ -321,7 +317,7 @@
} finally {
loading = false;
pending = false;
- await invalidate(UrlDependency.Conversation);
+ await invalidateAll();
}
}
diff --git a/src/routes/conversation/[id]/+server.ts b/src/routes/conversation/[id]/+server.ts
index ed7c2ec2969..7aeda860c8a 100644
--- a/src/routes/conversation/[id]/+server.ts
+++ b/src/routes/conversation/[id]/+server.ts
@@ -72,18 +72,17 @@ export async function POST({ request, locals, params, getClientAddress }) {
ip: getClientAddress(),
});
+ const messagesBeforeLogin = MESSAGES_BEFORE_LOGIN ? parseInt(MESSAGES_BEFORE_LOGIN) : 0;
+
// guest mode check
- if (
- !locals.user?._id &&
- requiresUser &&
- (MESSAGES_BEFORE_LOGIN ? parseInt(MESSAGES_BEFORE_LOGIN) : 0) > 0
- ) {
+ if (!locals.user?._id && requiresUser && messagesBeforeLogin) {
const totalMessages =
(
await collections.conversations
.aggregate([
- { $match: authCondition(locals) },
+ { $match: { ...authCondition(locals), "messages.from": "assistant" } },
{ $project: { messages: 1 } },
+ { $limit: messagesBeforeLogin + 1 },
{ $unwind: "$messages" },
{ $match: { "messages.from": "assistant" } },
{ $count: "messages" },
@@ -91,7 +90,7 @@ export async function POST({ request, locals, params, getClientAddress }) {
.toArray()
)[0]?.messages ?? 0;
- if (totalMessages > parseInt(MESSAGES_BEFORE_LOGIN)) {
+ if (totalMessages > messagesBeforeLogin) {
throw error(429, "Exceeded number of messages before login");
}
}
@@ -325,6 +324,7 @@ export async function POST({ request, locals, params, getClientAddress }) {
// inject websearch result & optionally images into the messages
const processedMessages = await preprocessMessages(
messagesForPrompt,
+ messageToWriteTo.webSearch,
model.multimodal,
convId
);
@@ -377,6 +377,15 @@ export async function POST({ request, locals, params, getClientAddress }) {
}
} catch (e) {
update({ type: "status", status: "error", message: (e as Error).message });
+ } finally {
+ // check if no output was generated
+ if (messageToWriteTo.content === previousText) {
+ update({
+ type: "status",
+ status: "error",
+ message: "No output was generated. Something went wrong.",
+ });
+ }
}
await collections.conversations.updateOne(
diff --git a/src/routes/login/callback/updateUser.ts b/src/routes/login/callback/updateUser.ts
index 94062d4aa69..f2fac350531 100644
--- a/src/routes/login/callback/updateUser.ts
+++ b/src/routes/login/callback/updateUser.ts
@@ -18,6 +18,12 @@ export async function updateUser(params: {
}) {
const { userData, locals, cookies, userAgent, ip } = params;
+ // Microsoft Entra v1 tokens do not provide preferred_username, instead the username is provided in the upn
+ // claim. See https://learn.microsoft.com/en-us/entra/identity-platform/access-token-claims-reference
+ if (!userData.preferred_username && userData.upn) {
+ userData.preferred_username = userData.upn as string;
+ }
+
const {
preferred_username: username,
name,
@@ -28,7 +34,7 @@ export async function updateUser(params: {
.object({
preferred_username: z.string().optional(),
name: z.string(),
- picture: z.string(),
+ picture: z.string().optional(),
sub: z.string(),
email: z.string().email().optional(),
})
diff --git a/src/routes/models/+page.svelte b/src/routes/models/+page.svelte
new file mode 100644
index 00000000000..6c92f19b973
--- /dev/null
+++ b/src/routes/models/+page.svelte
@@ -0,0 +1,72 @@
+
+
+
+ {#if isHuggingChat}
+ HuggingChat - Models
+
+
+
+
+ {/if}
+
+
+
diff --git a/src/routes/settings/+layout.server.ts b/src/routes/settings/+layout.server.ts
index 63daa415ad8..140b1a7e149 100644
--- a/src/routes/settings/+layout.server.ts
+++ b/src/routes/settings/+layout.server.ts
@@ -1,17 +1,9 @@
import { collections } from "$lib/server/database";
-import { ObjectId } from "mongodb";
import type { LayoutServerLoad } from "./$types";
import type { Report } from "$lib/types/Report";
export const load = (async ({ locals, parent }) => {
- const { settings } = await parent();
-
- // find assistants matching the settings assistants
- const assistants = await collections.assistants
- .find({
- _id: { $in: settings.assistants.map((el) => new ObjectId(el)) },
- })
- .toArray();
+ const { assistants } = await parent();
let reportsByUser: string[] = [];
const createdBy = locals.user?._id ?? locals.sessionId;
@@ -25,10 +17,7 @@ export const load = (async ({ locals, parent }) => {
return {
assistants: assistants.map((el) => ({
...el,
- _id: el._id.toString(),
- createdById: undefined,
- createdByMe: el.createdById.toString() === (locals.user?._id ?? locals.sessionId).toString(),
- reported: reportsByUser.includes(el._id.toString()),
+ reported: reportsByUser.includes(el._id),
})),
};
}) satisfies LayoutServerLoad;
diff --git a/src/routes/settings/+layout.svelte b/src/routes/settings/+layout.svelte
index 05b5c87fac1..48b8850e9bd 100644
--- a/src/routes/settings/+layout.svelte
+++ b/src/routes/settings/+layout.svelte
@@ -34,7 +34,7 @@