File size: 2,178 Bytes
812d95a
d7cd63b
0bd4051
97c4991
 
1778c9e
 
97c4991
 
812d95a
1778c9e
 
d7cd63b
 
 
 
 
 
 
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
74
75
76
77
78
79
80
import { page } from "$app/state";
import { Provider, 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);

export const structuredForbiddenProviders: Provider[] = [
	Provider.Hyperbolic,
	Provider.Nebius,
	Provider.Novita,
	Provider.Sambanova,
];

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();