File size: 2,027 Bytes
812d95a
1778c9e
0bd4051
97c4991
 
1778c9e
 
97c4991
 
812d95a
1778c9e
 
73a8db9
1778c9e
97c4991
 
0bd4051
97c4991
0bd4051
97c4991
 
0bd4051
97c4991
 
 
 
 
 
 
 
 
0bd4051
 
97c4991
 
 
 
0bd4051
 
 
 
 
 
 
 
 
97c4991
 
 
0bd4051
97c4991
 
 
 
 
 
 
 
0bd4051
97c4991
 
 
 
0bd4051
1778c9e
97c4991
1778c9e
97c4991
 
73a8db9
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { page } from "$app/state";
import { type CustomModel } from "$lib/types.js";
import { edit, randomPick } from "$lib/utils/array.js";
import { safeParse } from "$lib/utils/json.js";
import typia from "typia";
import type { PageData } from "../../routes/$types.js";
import { conversations } from "./conversations.svelte";

const LOCAL_STORAGE_KEY = "hf_inference_playground_custom_models";

const pageData = $derived(page.data as PageData);

class Models {
	remote = $derived(pageData.models);
	trending = $derived(this.remote.toSorted((a, b) => b.trendingScore - a.trendingScore).slice(0, 5));
	nonTrending = $derived(this.remote.filter(m => !this.trending.includes(m)));
	all = $derived([...this.remote, ...this.custom]);

	constructor() {
		const savedData = localStorage.getItem(LOCAL_STORAGE_KEY);
		if (!savedData) return;

		const parsed = safeParse(savedData);
		const res = typia.validate<CustomModel[]>(parsed);
		if (res.success) {
			this.#custom = parsed;
		} else {
			localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify([]));
		}
	}

	#custom = $state.raw<CustomModel[]>([]);

	get custom() {
		return this.#custom;
	}

	set custom(models: CustomModel[]) {
		this.#custom = models;

		try {
			localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(models));
		} catch (e) {
			console.error("Failed to save session to localStorage:", e);
		}
	}

	addCustom(model: CustomModel) {
		if (this.#custom.find(m => m.id === model.id)) return null;
		this.custom = [...this.custom, model];
		return model;
	}

	upsertCustom(model: CustomModel) {
		const index = this.#custom.findIndex(m => m._id === model._id);
		if (index === -1) {
			this.addCustom(model);
		} else {
			this.custom = edit(this.custom, index, model);
		}
	}

	removeCustom(uuid: CustomModel["_id"]) {
		this.custom = this.custom.filter(m => m._id !== uuid);
		conversations.active.forEach(c => {
			if (c.model._id !== uuid) return;
			c.update({ modelId: randomPick(models.trending)?.id });
		});
	}
}

export const models = new Models();