Spaces:
Sleeping
Sleeping
File size: 3,903 Bytes
fc69895 |
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
<script lang="ts">
import { page } from "$app/state";
import { base } from "$app/paths";
import { goto, replaceState } from "$app/navigation";
import { onMount, tick } from "svelte";
import { usePublicConfig } from "$lib/utils/PublicConfig.svelte";
import ChatWindow from "$lib/components/chat/ChatWindow.svelte";
import { findCurrentModel } from "$lib/utils/models";
import { useSettingsStore } from "$lib/stores/settings";
import { ERROR_MESSAGES, error } from "$lib/stores/errors";
import { pendingMessage } from "$lib/stores/pendingMessage";
import { sanitizeUrlParam } from "$lib/utils/urlParams";
import { loadAttachmentsFromUrls } from "$lib/utils/loadAttachmentsFromUrls";
let { data } = $props();
let loading = $state(false);
let files: File[] = $state([]);
let draft = $state("");
const settings = useSettingsStore();
const modelId = page.params.model;
const publicConfig = usePublicConfig();
async function createConversation(message: string) {
try {
loading = true;
const res = await fetch(`${base}/conversation`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
model: modelId,
preprompt: $settings.customPrompts[modelId],
}),
});
if (!res.ok) {
error.set("Error while creating conversation, try again.");
console.error("Error while creating conversation: " + (await res.text()));
return;
}
const { conversationId } = await res.json();
// Ugly hack to use a store as temp storage, feel free to improve ^^
pendingMessage.set({
content: message,
files,
});
// invalidateAll to update list of conversations
await goto(`${base}/conversation/${conversationId}`, { invalidateAll: true });
} catch (err) {
error.set(ERROR_MESSAGES.default);
console.error(err);
} finally {
loading = false;
}
}
onMount(async () => {
try {
// Handle attachments parameter first
if (page.url.searchParams.has("attachments")) {
const result = await loadAttachmentsFromUrls(page.url.searchParams);
files = result.files;
// Show errors if any
if (result.errors.length > 0) {
console.error("Failed to load some attachments:", result.errors);
error.set(
`Failed to load ${result.errors.length} attachment(s). Check console for details.`
);
}
// Clean up URL
const url = new URL(page.url);
url.searchParams.delete("attachments");
history.replaceState({}, "", url);
}
const query = sanitizeUrlParam(page.url.searchParams.get("q"));
if (query) {
void createConversation(query);
const url = new URL(page.url);
url.searchParams.delete("q");
tick().then(() => {
replaceState(url, page.state);
});
return;
}
const promptQuery = sanitizeUrlParam(page.url.searchParams.get("prompt"));
if (promptQuery && !draft) {
draft = promptQuery;
const url = new URL(page.url);
url.searchParams.delete("prompt");
tick().then(() => {
replaceState(url, page.state);
});
}
} catch (err) {
console.error("Failed to process URL parameters:", err);
}
settings.instantSet({ activeModel: modelId });
});
</script>
<svelte:head>
<meta property="og:title" content={modelId + " - " + publicConfig.PUBLIC_APP_NAME} />
<meta property="og:type" content="link" />
<meta property="og:description" content={`Use ${modelId} with ${publicConfig.PUBLIC_APP_NAME}`} />
<meta
property="og:image"
content="{publicConfig.PUBLIC_ORIGIN || page.url.origin}{base}/models/{modelId}/thumbnail.png"
/>
<meta property="og:url" content={page.url.href} />
<meta name="twitter:card" content="summary_large_image" />
</svelte:head>
<ChatWindow
onmessage={(message) => createConversation(message)}
{loading}
currentModel={findCurrentModel(data.models, data.oldModels, modelId)}
models={data.models}
bind:files
bind:draft
/>
|