Adrien Denat
		
	commited on
		
		
					make sure we allow user to change model if clicking on a link with mo… (#172)
Browse files* make sure we allow user to change model if clicking on a link with model in url param
* typo
* avoid try/catch + abstract weird Zod enum
    	
        src/lib/utils/models.ts
    CHANGED
    
    | @@ -1,4 +1,10 @@ | |
| 1 | 
             
            import type { Model } from "$lib/types/Model";
         | 
|  | |
| 2 |  | 
| 3 | 
             
            export const findCurrentModel = (models: Model[], name?: string) =>
         | 
| 4 | 
             
            	models.find((m) => m.name === name) ?? models[0];
         | 
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
             
            import type { Model } from "$lib/types/Model";
         | 
| 2 | 
            +
            import { z } from "zod";
         | 
| 3 |  | 
| 4 | 
             
            export const findCurrentModel = (models: Model[], name?: string) =>
         | 
| 5 | 
             
            	models.find((m) => m.name === name) ?? models[0];
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            export const validateModel = (models: Model[]) => {
         | 
| 8 | 
            +
            	// Zod enum function requires 2 parameters
         | 
| 9 | 
            +
            	return z.enum([models[0].name, ...models.slice(1).map((m) => m.name)]);
         | 
| 10 | 
            +
            };
         | 
    	
        src/routes/+layout.server.ts
    CHANGED
    
    | @@ -1,14 +1,32 @@ | |
|  | |
|  | |
| 1 | 
             
            import type { LayoutServerLoad } from "./$types";
         | 
| 2 | 
             
            import { collections } from "$lib/server/database";
         | 
| 3 | 
             
            import type { Conversation } from "$lib/types/Conversation";
         | 
| 4 | 
             
            import { UrlDependency } from "$lib/types/UrlDependency";
         | 
| 5 | 
             
            import { defaultModel, models } from "$lib/server/models";
         | 
|  | |
| 6 |  | 
| 7 | 
            -
            export const load: LayoutServerLoad = async ({ locals, depends, url }) => {
         | 
| 8 | 
             
            	const { conversations } = collections;
         | 
|  | |
| 9 |  | 
| 10 | 
             
            	depends(UrlDependency.ConversationList);
         | 
| 11 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 12 | 
             
            	const settings = await collections.settings.findOne({ sessionId: locals.sessionId });
         | 
| 13 |  | 
| 14 | 
             
            	return {
         | 
| @@ -33,7 +51,7 @@ export const load: LayoutServerLoad = async ({ locals, depends, url }) => { | |
| 33 | 
             
            		settings: {
         | 
| 34 | 
             
            			shareConversationsWithModelAuthors: settings?.shareConversationsWithModelAuthors ?? true,
         | 
| 35 | 
             
            			ethicsModalAcceptedAt: settings?.ethicsModalAcceptedAt ?? null,
         | 
| 36 | 
            -
            			activeModel:  | 
| 37 | 
             
            		},
         | 
| 38 | 
             
            		models: models.map((model) => ({
         | 
| 39 | 
             
            			name: model.name,
         | 
|  | |
| 1 | 
            +
            import { base } from "$app/paths";
         | 
| 2 | 
            +
            import { redirect } from "@sveltejs/kit";
         | 
| 3 | 
             
            import type { LayoutServerLoad } from "./$types";
         | 
| 4 | 
             
            import { collections } from "$lib/server/database";
         | 
| 5 | 
             
            import type { Conversation } from "$lib/types/Conversation";
         | 
| 6 | 
             
            import { UrlDependency } from "$lib/types/UrlDependency";
         | 
| 7 | 
             
            import { defaultModel, models } from "$lib/server/models";
         | 
| 8 | 
            +
            import { validateModel } from "$lib/utils/models";
         | 
| 9 |  | 
| 10 | 
            +
            export const load: LayoutServerLoad = async ({ locals, depends, url, request }) => {
         | 
| 11 | 
             
            	const { conversations } = collections;
         | 
| 12 | 
            +
            	const urlModel = url.searchParams.get("model");
         | 
| 13 |  | 
| 14 | 
             
            	depends(UrlDependency.ConversationList);
         | 
| 15 |  | 
| 16 | 
            +
            	if (urlModel) {
         | 
| 17 | 
            +
            		const isValidModel = validateModel(models).safeParse(urlModel).success;
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            		if (isValidModel) {
         | 
| 20 | 
            +
            			await collections.settings.updateOne(
         | 
| 21 | 
            +
            				{ sessionId: locals.sessionId },
         | 
| 22 | 
            +
            				{ $set: { activeModel: urlModel } },
         | 
| 23 | 
            +
            				{ upsert: true }
         | 
| 24 | 
            +
            			);
         | 
| 25 | 
            +
            		}
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            		throw redirect(303, request.headers.get("referer") || base || "/");
         | 
| 28 | 
            +
            	}
         | 
| 29 | 
            +
             | 
| 30 | 
             
            	const settings = await collections.settings.findOne({ sessionId: locals.sessionId });
         | 
| 31 |  | 
| 32 | 
             
            	return {
         | 
|  | |
| 51 | 
             
            		settings: {
         | 
| 52 | 
             
            			shareConversationsWithModelAuthors: settings?.shareConversationsWithModelAuthors ?? true,
         | 
| 53 | 
             
            			ethicsModalAcceptedAt: settings?.ethicsModalAcceptedAt ?? null,
         | 
| 54 | 
            +
            			activeModel: settings?.activeModel ?? defaultModel.name,
         | 
| 55 | 
             
            		},
         | 
| 56 | 
             
            		models: models.map((model) => ({
         | 
| 57 | 
             
            			name: model.name,
         | 
    	
        src/routes/conversation/+server.ts
    CHANGED
    
    | @@ -6,6 +6,7 @@ import { base } from "$app/paths"; | |
| 6 | 
             
            import { z } from "zod";
         | 
| 7 | 
             
            import type { Message } from "$lib/types/Message";
         | 
| 8 | 
             
            import { defaultModel, models } from "$lib/server/models";
         | 
|  | |
| 9 |  | 
| 10 | 
             
            export const POST: RequestHandler = async (input) => {
         | 
| 11 | 
             
            	const body = await input.request.text();
         | 
| @@ -16,9 +17,7 @@ export const POST: RequestHandler = async (input) => { | |
| 16 | 
             
            	const values = z
         | 
| 17 | 
             
            		.object({
         | 
| 18 | 
             
            			fromShare: z.string().optional(),
         | 
| 19 | 
            -
            			model:  | 
| 20 | 
            -
            				.enum([models[0].name, ...models.slice(1).map((m) => m.name)])
         | 
| 21 | 
            -
            				.default(defaultModel.name),
         | 
| 22 | 
             
            		})
         | 
| 23 | 
             
            		.parse(JSON.parse(body));
         | 
| 24 |  | 
|  | |
| 6 | 
             
            import { z } from "zod";
         | 
| 7 | 
             
            import type { Message } from "$lib/types/Message";
         | 
| 8 | 
             
            import { defaultModel, models } from "$lib/server/models";
         | 
| 9 | 
            +
            import { validateModel } from "$lib/utils/models";
         | 
| 10 |  | 
| 11 | 
             
            export const POST: RequestHandler = async (input) => {
         | 
| 12 | 
             
            	const body = await input.request.text();
         | 
|  | |
| 17 | 
             
            	const values = z
         | 
| 18 | 
             
            		.object({
         | 
| 19 | 
             
            			fromShare: z.string().optional(),
         | 
| 20 | 
            +
            			model: validateModel(models).default(defaultModel.name),
         | 
|  | |
|  | |
| 21 | 
             
            		})
         | 
| 22 | 
             
            		.parse(JSON.parse(body));
         | 
| 23 |  | 
    	
        src/routes/settings/+page.server.ts
    CHANGED
    
    | @@ -3,6 +3,7 @@ import { collections } from "$lib/server/database"; | |
| 3 | 
             
            import { redirect } from "@sveltejs/kit";
         | 
| 4 | 
             
            import { z } from "zod";
         | 
| 5 | 
             
            import { defaultModel, models } from "$lib/server/models";
         | 
|  | |
| 6 |  | 
| 7 | 
             
            export const actions = {
         | 
| 8 | 
             
            	default: async function ({ request, locals }) {
         | 
| @@ -12,7 +13,7 @@ export const actions = { | |
| 12 | 
             
            			.object({
         | 
| 13 | 
             
            				shareConversationsWithModelAuthors: z.boolean({ coerce: true }).default(true),
         | 
| 14 | 
             
            				ethicsModalAccepted: z.boolean({ coerce: true }).optional(),
         | 
| 15 | 
            -
            				activeModel:  | 
| 16 | 
             
            			})
         | 
| 17 | 
             
            			.parse({
         | 
| 18 | 
             
            				shareConversationsWithModelAuthors: formData.get("shareConversationsWithModelAuthors"),
         | 
|  | |
| 3 | 
             
            import { redirect } from "@sveltejs/kit";
         | 
| 4 | 
             
            import { z } from "zod";
         | 
| 5 | 
             
            import { defaultModel, models } from "$lib/server/models";
         | 
| 6 | 
            +
            import { validateModel } from "$lib/utils/models.js";
         | 
| 7 |  | 
| 8 | 
             
            export const actions = {
         | 
| 9 | 
             
            	default: async function ({ request, locals }) {
         | 
|  | |
| 13 | 
             
            			.object({
         | 
| 14 | 
             
            				shareConversationsWithModelAuthors: z.boolean({ coerce: true }).default(true),
         | 
| 15 | 
             
            				ethicsModalAccepted: z.boolean({ coerce: true }).optional(),
         | 
| 16 | 
            +
            				activeModel: validateModel(models),
         | 
| 17 | 
             
            			})
         | 
| 18 | 
             
            			.parse({
         | 
| 19 | 
             
            				shareConversationsWithModelAuthors: formData.get("shareConversationsWithModelAuthors"),
         | 
