Merge branch 'renovate/all-minor-patch' into 'main'
[ProtonMail-WebClient.git] / packages / llm / lib / types.ts
blob5ce6415293ef3993ed33c7554e2047b4bb80d1fb
1 /* eslint-disable @typescript-eslint/lines-between-class-members */
3 /* eslint-disable @typescript-eslint/no-unused-vars */
5 /* eslint-disable @typescript-eslint/no-use-before-define */
6 import type { CacheId, DownloadResult, LlmFile } from '@proton/llm/lib/downloader';
8 export type PromiseResolve = (value: PromiseLike<void> | void) => void;
10 export type PromiseReject = (reason?: any) => void;
12 export interface LlmManager {
13     // prefer passing a canvas, it will allow us to get some info using WebGL
14     startDownload: (updateProgress: DownloadProgressCallback, assistantConfig: AssistantConfig) => Promise<boolean>; // returns whether it completed
15     cancelDownload: () => void;
16     loadOnGpu: (assistantConfig: AssistantConfig) => Promise<LlmModel>;
17     isDownloaded: (assistantConfig: AssistantConfig, setLlmStatus?: boolean) => Promise<boolean>;
20 export interface LlmModel {
21     unload: () => Promise<void>;
22     performAction: (action: Action, callback: GenerationCallback) => Promise<RunningAction>;
25 export interface RunningAction {
26     isRunning: () => boolean;
27     isDone: () => boolean;
28     isCancelled: () => boolean;
29     action: () => Action;
30     cancel: () => boolean;
31     waitForCompletion(): Promise<void>;
34 export type GenerationCallbackDetails = {
35     slow: boolean;
36     harmful: boolean;
38 export type GenerationCallback = (fulltext: string, details?: GenerationCallbackDetails) => void;
40 /** ACTION TYPES
41  *
42  * Here is the classification for the different actions:
43  *
44  * writeFullEmail
45  * proofread         } "predefined           }
46  * shorten           }  refine actions"      }  "refine actions"
47  * customRefine                              }
48  *
49  * The types below indicate this hierarchy, along with optional info
50  * like the refine location.
51  */
53 type ActionOptions = {
54     userInputFormat?: 'plaintext' | 'markdown';
55     assistantOutputFormat?: 'plaintext' | 'markdown';
58 // "Write Full Email": initial generation of an email based on a user prompt.
59 export type WriteFullEmailAction = {
60     type: 'writeFullEmail';
61     prompt: string;
62     recipient?: string;
63     sender?: string;
64     locale?: string;
65 } & ActionOptions;
67 // Identifies a substring to refine along with its context. Only for refine actions.
68 // Usually, this will be a selection inside the generated text.
69 export type RefineLocation = {
70     fullEmail: string; // `fullEmail.slice(idxStart, idxEnd)` is the part to rephrase
71     idxStart: number; // beginning of part to rephrase
72     idxEnd: number; // end of part to rephrase
73 } & ActionOptions;
75 // "Custom Refine" refers to the reformulation of an already-generated email, or part of it,
76 // with a custom request written by the user (e.g. "make it formal").
77 export type CustomRefineAction = PartialCustomRefineAction & RefineLocation;
78 export type PartialCustomRefineAction = {
79     type: 'customRefine';
80     prompt: string; // user-submitted instruction of what to do with this text
81 } & ActionOptions;
83 // "Proofread" action button.
84 export type ProofreadAction = PartialProofreadAction & RefineLocation;
85 export type PartialProofreadAction = {
86     type: 'proofread';
89 // "Shorten" action button.
90 export type ShortenAction = PartialShortenAction & RefineLocation;
91 export type PartialShortenAction = {
92     type: 'shorten';
95 // "Formal" action button.
96 export type FormalAction = PartialFormalAction & RefineLocation;
97 export type PartialFormalAction = {
98     type: 'formal';
101 // "Friendly" action button.
102 export type FriendlyAction = PartialFriendlyAction & RefineLocation;
103 export type PartialFriendlyAction = {
104     type: 'friendly';
107 // "Expand" action button.
108 export type ExpandAction = PartialExpandAction & RefineLocation;
109 export type PartialExpandAction = {
110     type: 'expand';
113 export type PartialRefineAction =
114     | PartialProofreadAction
115     | PartialShortenAction
116     | PartialFormalAction
117     | PartialFriendlyAction
118     | PartialExpandAction
119     | PartialCustomRefineAction;
120 export type RefineAction = PartialRefineAction & RefineLocation;
121 export type PredefinedRefineAction = ProofreadAction | ShortenAction | FormalAction | FriendlyAction | ExpandAction;
122 export type Action = WriteFullEmailAction | RefineAction;
124 export type PredefinedRefineActionType = PredefinedRefineAction['type'];
125 export type RefineActionType = RefineAction['type'];
126 export type ActionType = Action['type'];
128 export function isPredefinedRefineActionType(value: any): value is PredefinedRefineActionType {
129     return (
130         value === 'shorten' || value === 'proofread' || value === 'formal' || value === 'friendly' || value === 'expand'
131     );
134 export function isRefineActionType(value: any): value is RefineActionType {
135     return value === 'customRefine' || isPredefinedRefineActionType(value);
138 // A function to monitor the overall download progress.
140 // `info.estimatedTotalBytes` can change over time, because there are a few
141 // files whose size is unknown until we start downloading them. That said,
142 // it shouldn't be far from reality anyway, because we know the size of the
143 // biggest files upfront.
145 // If the download is stopped and then resume, this progress will take into
146 // account the files already cached and start from that number, not from zero.
147 export type DownloadProgressCallback = (info: DownloadProgressInfo) => void;
148 export type DownloadProgressInfo = {
149     receivedFiles: number;
150     totalFiles: number;
151     receivedBytes: number;
152     estimatedTotalBytes: number;
155 export interface AssistantModel {
156     ModelID: string;
157     Priority: number;
158     ModelURL: string;
159     ModelLibURL: string;
160     VRAMRequiredMB: number;
161     LowResourceRequired: boolean;
162     RequiredFeatures: string[];
165 export interface AssistantConfigModel {
166     model_url: string;
167     model_download_url: string;
168     model_id: string;
169     model_lib_url: string;
170     vram_required_MB: number;
171     low_resource_required: boolean;
172     required_features: string[];
175 export interface AssistantConfig {
176     model_list: AssistantConfigModel[];
177     use_web_worker: boolean;
180 export enum OpenedAssistantStatus {
181     EXPANDED = 'expanded',
182     COLLAPSED = 'collapsed',
185 export type OpenedAssistant = {
186     id: string;
187     status: OpenedAssistantStatus;
191  * Events sent from or to the assistant iframe
192  */
193 export enum AssistantEvent {
194     // Messages from parent to iframe
195     START_DOWNLOAD = 'start-download',
196     PAUSE_DOWNLOAD = 'pause-download',
198     // Messages from iframe to parent
199     IFRAME_READY = 'iframe-ready',
200     DOWNLOAD_DATA = 'download-data',
201     DOWNLOAD_PROGRESS = 'download-progress',
202     DOWNLOAD_ERROR = 'download-error',
205 interface StartDownloadMessage {
206     type: AssistantEvent.START_DOWNLOAD;
207     payload: {
208         config: AssistantConfig;
209         modelVariant: string;
210         filesToIgnore: LlmFile[];
211     };
214 interface PauseDownloadMessage {
215     type: AssistantEvent.PAUSE_DOWNLOAD;
218 interface IframeReady {
219     type: AssistantEvent.IFRAME_READY;
222 interface DownloadedChunkMessage {
223     type: AssistantEvent.DOWNLOAD_DATA;
224     payload: {
225         downloadResult: DownloadResult;
226         cacheId: CacheId;
227         cacheUrl: string;
228         expectedMd5?: string;
229         terminate: boolean;
230     };
233 interface DownloadProgressMessage {
234     type: AssistantEvent.DOWNLOAD_PROGRESS;
235     payload: {
236         progress: DownloadProgressInfo;
237     };
240 interface DownloadErrorMessage {
241     type: AssistantEvent.DOWNLOAD_ERROR;
242     payload: {
243         error: any;
244     };
247 export type ParentToIframeMessage = StartDownloadMessage | PauseDownloadMessage;
249 export type IframeToParentMessage =
250     | IframeReady
251     | DownloadedChunkMessage
252     | DownloadProgressMessage
253     | DownloadErrorMessage;