1 import type { LlmFile } from '@proton/llm/lib/downloader';
2 import { downloadModel } from '@proton/llm/lib/downloader';
3 import { isAssistantPostMessage, postMessageIframeToParent } from '@proton/llm/lib/helpers';
4 import type { AssistantConfig } from '@proton/llm/lib/types';
5 import { AssistantEvent } from '@proton/llm/lib/types';
7 window.addEventListener('load', async () => {
8 let abortController: AbortController | undefined; // defined if status === 'loading'
11 const handleDownloadModel = async (
12 assistantConfig: AssistantConfig,
14 filesToIgnore: LlmFile[]
17 if (!abortController) {
18 abortController = new AbortController();
19 await downloadModel(modelVariant, assistantConfig, abortController, filesToIgnore, parentURL);
20 abortController = undefined;
22 } catch (error: any) {
23 postMessageIframeToParent(
25 type: AssistantEvent.DOWNLOAD_ERROR,
33 abortController = undefined;
37 // Request to cancel an ongoing download.
39 // This will return immediately, but the cancellation will be complete when the startDownload() promise is
40 // resolved, which shouldn't take long.
41 const cancelDownload = () => {
42 if (abortController) {
43 abortController.abort();
44 abortController = undefined;
48 const handleReceivedEvent = async (event: MessageEvent) => {
49 if (!isAssistantPostMessage(event)) {
53 switch (event.data.type) {
54 case AssistantEvent.START_DOWNLOAD:
56 // If we passed all the validations and receive a start download event,
57 // we assume the parent url is the origin of the received event
58 parentURL = event.origin;
60 postMessageIframeToParent(
62 type: AssistantEvent.IFRAME_READY,
67 const { config, modelVariant, filesToIgnore } = event.data.payload;
68 await handleDownloadModel(config, modelVariant, filesToIgnore);
71 case AssistantEvent.PAUSE_DOWNLOAD:
79 window.addEventListener('message', handleReceivedEvent);