@jupyterlite/ai 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/lib/base-completer.d.ts +0 -5
  3. package/lib/chat-handler.d.ts +19 -5
  4. package/lib/chat-handler.js +47 -26
  5. package/lib/completion-provider.d.ts +2 -2
  6. package/lib/completion-provider.js +4 -3
  7. package/lib/components/stop-button.d.ts +0 -1
  8. package/lib/default-providers/Anthropic/completer.d.ts +0 -2
  9. package/lib/default-providers/Anthropic/completer.js +2 -4
  10. package/lib/default-providers/ChromeAI/completer.d.ts +0 -2
  11. package/lib/default-providers/ChromeAI/completer.js +2 -4
  12. package/lib/default-providers/ChromeAI/instructions.d.ts +4 -0
  13. package/lib/default-providers/ChromeAI/instructions.js +18 -0
  14. package/lib/default-providers/MistralAI/completer.d.ts +0 -2
  15. package/lib/default-providers/MistralAI/completer.js +3 -4
  16. package/lib/default-providers/Ollama/completer.d.ts +17 -0
  17. package/lib/default-providers/Ollama/completer.js +49 -0
  18. package/lib/default-providers/Ollama/instructions.d.ts +2 -0
  19. package/lib/default-providers/Ollama/instructions.js +70 -0
  20. package/lib/default-providers/Ollama/settings-schema.json +146 -0
  21. package/lib/default-providers/OpenAI/completer.d.ts +0 -2
  22. package/lib/default-providers/OpenAI/completer.js +2 -4
  23. package/lib/default-providers/WebLLM/completer.d.ts +27 -0
  24. package/lib/default-providers/WebLLM/completer.js +136 -0
  25. package/lib/default-providers/WebLLM/instructions.d.ts +6 -0
  26. package/lib/default-providers/WebLLM/instructions.js +32 -0
  27. package/lib/default-providers/WebLLM/settings-schema.json +21 -0
  28. package/lib/default-providers/index.js +119 -4
  29. package/lib/index.d.ts +2 -2
  30. package/lib/index.js +16 -26
  31. package/lib/provider.d.ts +11 -13
  32. package/lib/provider.js +120 -52
  33. package/lib/settings/index.d.ts +0 -1
  34. package/lib/settings/index.js +0 -1
  35. package/lib/settings/panel.d.ts +37 -8
  36. package/lib/settings/panel.js +225 -131
  37. package/lib/tokens.d.ts +21 -2
  38. package/lib/types/ai-model.d.ts +24 -0
  39. package/lib/types/ai-model.js +5 -0
  40. package/package.json +14 -11
  41. package/schema/provider-registry.json +0 -6
  42. package/src/base-completer.ts +0 -6
  43. package/src/chat-handler.ts +40 -7
  44. package/src/completion-provider.ts +2 -2
  45. package/src/default-providers/Anthropic/completer.ts +0 -5
  46. package/src/default-providers/ChromeAI/completer.ts +0 -5
  47. package/src/default-providers/ChromeAI/instructions.ts +21 -0
  48. package/src/default-providers/MistralAI/completer.ts +0 -5
  49. package/src/default-providers/Ollama/completer.ts +62 -0
  50. package/src/default-providers/Ollama/instructions.ts +70 -0
  51. package/src/default-providers/OpenAI/completer.ts +0 -5
  52. package/src/default-providers/WebLLM/completer.ts +162 -0
  53. package/src/default-providers/WebLLM/instructions.ts +33 -0
  54. package/src/default-providers/index.ts +151 -14
  55. package/src/index.ts +17 -29
  56. package/src/provider.ts +132 -45
  57. package/src/settings/index.ts +0 -1
  58. package/src/settings/panel.tsx +207 -73
  59. package/src/tokens.ts +23 -2
  60. package/src/types/ai-model.ts +37 -0
  61. package/src/types/service-worker.d.ts +6 -0
  62. package/style/base.css +5 -0
  63. package/lib/settings/settings-connector.d.ts +0 -31
  64. package/lib/settings/settings-connector.js +0 -61
  65. package/src/settings/settings-connector.ts +0 -88
@@ -5,14 +5,16 @@
5
5
 
6
6
  import {
7
7
  ChatCommand,
8
- ChatModel,
8
+ AbstractChatContext,
9
+ AbstractChatModel,
9
10
  IChatCommandProvider,
11
+ IChatContext,
10
12
  IChatHistory,
11
13
  IChatMessage,
14
+ IChatModel,
12
15
  IInputModel,
13
16
  INewMessage
14
17
  } from '@jupyter/chat';
15
- import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
16
18
  import {
17
19
  AIMessage,
18
20
  HumanMessage,
@@ -20,9 +22,11 @@ import {
20
22
  SystemMessage
21
23
  } from '@langchain/core/messages';
22
24
  import { UUID } from '@lumino/coreutils';
25
+
26
+ import { jupyternautLiteIcon } from './icons';
23
27
  import { chatSystemPrompt } from './provider';
24
28
  import { IAIProviderRegistry } from './tokens';
25
- import { jupyternautLiteIcon } from './icons';
29
+ import { AIChatModel } from './types/ai-model';
26
30
 
27
31
  /**
28
32
  * The base64 encoded SVG string of the jupyternaut lite icon.
@@ -31,12 +35,24 @@ import { jupyternautLiteIcon } from './icons';
31
35
  const AI_AVATAR_BASE64 = btoa(jupyternautLiteIcon.svgstr);
32
36
  const AI_AVATAR = `data:image/svg+xml;base64,${AI_AVATAR_BASE64}`;
33
37
 
38
+ export const welcomeMessage = (providers: string[]) => `
39
+ #### Ask JupyterLite AI
40
+
41
+
42
+ The provider to use can be set in the settings editor, by selecting it from
43
+ the <img src="${AI_AVATAR}" width="16" height="16"> _AI provider_ settings.
44
+
45
+ The current providers that are available are _${providers.sort().join('_, _')}_.
46
+
47
+ To clear the chat, you can use the \`/clear\` command from the chat input.
48
+ `;
49
+
34
50
  export type ConnectionMessage = {
35
51
  type: 'connection';
36
52
  client_id: string;
37
53
  };
38
54
 
39
- export class ChatHandler extends ChatModel {
55
+ export class ChatHandler extends AbstractChatModel {
40
56
  constructor(options: ChatHandler.IOptions) {
41
57
  super(options);
42
58
  this._providerRegistry = options.providerRegistry;
@@ -52,7 +68,7 @@ export class ChatHandler extends ChatModel {
52
68
  });
53
69
  }
54
70
 
55
- get provider(): BaseChatModel | null {
71
+ get provider(): AIChatModel | null {
56
72
  return this._providerRegistry.currentChatModel;
57
73
  }
58
74
 
@@ -126,7 +142,7 @@ export class ChatHandler extends ChatModel {
126
142
  );
127
143
 
128
144
  const sender = { username: this._personaName, avatar_url: AI_AVATAR };
129
- this.updateWriters([sender]);
145
+ this.updateWriters([{ user: sender }]);
130
146
 
131
147
  // create an empty message to be filled by the AI provider
132
148
  const botMsg: IChatMessage = {
@@ -184,6 +200,10 @@ export class ChatHandler extends ChatModel {
184
200
  this._controller?.abort();
185
201
  }
186
202
 
203
+ createChatContext(): IChatContext {
204
+ return new ChatHandler.ChatContext({ model: this });
205
+ }
206
+
187
207
  private _providerRegistry: IAIProviderRegistry;
188
208
  private _personaName = 'AI';
189
209
  private _prompt: string;
@@ -194,10 +214,23 @@ export class ChatHandler extends ChatModel {
194
214
  }
195
215
 
196
216
  export namespace ChatHandler {
197
- export interface IOptions extends ChatModel.IOptions {
217
+ /**
218
+ * The options used to create a chat handler.
219
+ */
220
+ export interface IOptions extends IChatModel.IOptions {
198
221
  providerRegistry: IAIProviderRegistry;
199
222
  }
200
223
 
224
+ /**
225
+ * The minimal chat context.
226
+ */
227
+ export class ChatContext extends AbstractChatContext {
228
+ users = [];
229
+ }
230
+
231
+ /**
232
+ * The chat command provider for the chat.
233
+ */
201
234
  export class ClearCommandProvider implements IChatCommandProvider {
202
235
  public id: string = '@jupyterlite/ai:clear-commands';
203
236
  private _slash_commands: ChatCommand[] = [
@@ -4,8 +4,8 @@ import {
4
4
  IInlineCompletionProvider
5
5
  } from '@jupyterlab/completer';
6
6
 
7
- import { IBaseCompleter } from './base-completer';
8
7
  import { IAIProviderRegistry } from './tokens';
8
+ import { AICompleter } from './types/ai-model';
9
9
 
10
10
  /**
11
11
  * The generic completion provider to register to the completion provider manager.
@@ -34,7 +34,7 @@ export class CompletionProvider implements IInlineCompletionProvider {
34
34
  /**
35
35
  * Get the current completer.
36
36
  */
37
- get completer(): IBaseCompleter | null {
37
+ get completer(): AICompleter | null {
38
38
  return this._providerRegistry.currentCompleter;
39
39
  }
40
40
 
@@ -3,7 +3,6 @@ import {
3
3
  IInlineCompletionContext
4
4
  } from '@jupyterlab/completer';
5
5
  import { ChatAnthropic } from '@langchain/anthropic';
6
- import { BaseChatModel } from '@langchain/core/language_models/chat_models';
7
6
  import { AIMessage, SystemMessage } from '@langchain/core/messages';
8
7
 
9
8
  import { BaseCompleter, IBaseCompleter } from '../../base-completer';
@@ -14,10 +13,6 @@ export class AnthropicCompleter implements IBaseCompleter {
14
13
  this._completer = new ChatAnthropic({ ...options.settings });
15
14
  }
16
15
 
17
- get completer(): BaseChatModel {
18
- return this._completer;
19
- }
20
-
21
16
  /**
22
17
  * Getter and setter for the initial prompt.
23
18
  */
@@ -3,7 +3,6 @@ import {
3
3
  IInlineCompletionContext
4
4
  } from '@jupyterlab/completer';
5
5
  import { ChromeAI } from '@langchain/community/experimental/llms/chrome_ai';
6
- import { LLM } from '@langchain/core/language_models/llms';
7
6
  import { HumanMessage, SystemMessage } from '@langchain/core/messages';
8
7
 
9
8
  import { BaseCompleter, IBaseCompleter } from '../../base-completer';
@@ -45,10 +44,6 @@ export class ChromeCompleter implements IBaseCompleter {
45
44
  this._prompt = value;
46
45
  }
47
46
 
48
- get completer(): LLM {
49
- return this._completer;
50
- }
51
-
52
47
  async fetch(
53
48
  request: CompletionHandler.IRequest,
54
49
  context: IInlineCompletionContext
@@ -22,3 +22,24 @@ During the download, ChromeAI may not be available via the extension.
22
22
 
23
23
  <i class="fa fa-info-circle" aria-hidden="true"></i> For more information about Chrome Built-in AI: <https://developer.chrome.com/docs/ai/get-started>
24
24
  `;
25
+
26
+ /**
27
+ * Check if the browser supports ChromeAI and the model is available.
28
+ */
29
+ export async function compatibilityCheck(): Promise<string | null> {
30
+ // Check if the browser supports the ChromeAI model
31
+ if (
32
+ typeof window === 'undefined' ||
33
+ !('LanguageModel' in window) ||
34
+ window.LanguageModel === undefined ||
35
+ (window.LanguageModel as any).availability === undefined
36
+ ) {
37
+ return 'Your browser does not support ChromeAI. Please use an updated chrome based browser like Google Chrome, and follow the instructions in settings to enable it.';
38
+ }
39
+ const languageModel = window.LanguageModel as any;
40
+ if (!(await languageModel.availability())) {
41
+ return 'The ChromeAI model is not available in your browser. Please ensure you have enabled the necessary flags in Google Chrome as described in the instructions in settings.';
42
+ }
43
+ // If the model is available, return null to indicate compatibility
44
+ return null;
45
+ }
@@ -2,7 +2,6 @@ import {
2
2
  CompletionHandler,
3
3
  IInlineCompletionContext
4
4
  } from '@jupyterlab/completer';
5
- import { BaseChatModel } from '@langchain/core/language_models/chat_models';
6
5
  import {
7
6
  BaseMessage,
8
7
  HumanMessage,
@@ -47,10 +46,6 @@ export class CodestralCompleter implements IBaseCompleter {
47
46
  );
48
47
  }
49
48
 
50
- get completer(): BaseChatModel {
51
- return this._completer;
52
- }
53
-
54
49
  /**
55
50
  * Getter and setter for the initial prompt.
56
51
  */
@@ -0,0 +1,62 @@
1
+ import {
2
+ CompletionHandler,
3
+ IInlineCompletionContext
4
+ } from '@jupyterlab/completer';
5
+ import { AIMessage, SystemMessage } from '@langchain/core/messages';
6
+ import { ChatOllama } from '@langchain/ollama';
7
+
8
+ import { BaseCompleter, IBaseCompleter } from '../../base-completer';
9
+ import { COMPLETION_SYSTEM_PROMPT } from '../../provider';
10
+
11
+ export class OllamaCompleter implements IBaseCompleter {
12
+ constructor(options: BaseCompleter.IOptions) {
13
+ this._completer = new ChatOllama({ ...options.settings });
14
+ }
15
+
16
+ /**
17
+ * Getter and setter for the initial prompt.
18
+ */
19
+ get prompt(): string {
20
+ return this._prompt;
21
+ }
22
+ set prompt(value: string) {
23
+ this._prompt = value;
24
+ }
25
+
26
+ async fetch(
27
+ request: CompletionHandler.IRequest,
28
+ context: IInlineCompletionContext
29
+ ) {
30
+ const { text, offset: cursorOffset } = request;
31
+ const prompt = text.slice(0, cursorOffset);
32
+
33
+ const messages = [new SystemMessage(this._prompt), new AIMessage(prompt)];
34
+
35
+ try {
36
+ const response = await this._completer.invoke(messages);
37
+ const items = [];
38
+ if (typeof response.content === 'string') {
39
+ items.push({
40
+ insertText: response.content
41
+ });
42
+ } else {
43
+ response.content.forEach(content => {
44
+ if (content.type !== 'text') {
45
+ return;
46
+ }
47
+ items.push({
48
+ insertText: content.text,
49
+ filterText: prompt.substring(prompt.length)
50
+ });
51
+ });
52
+ }
53
+ return { items };
54
+ } catch (error) {
55
+ console.error('Error fetching completions', error);
56
+ return { items: [] };
57
+ }
58
+ }
59
+
60
+ private _completer: ChatOllama;
61
+ private _prompt: string = COMPLETION_SYSTEM_PROMPT;
62
+ }
@@ -0,0 +1,70 @@
1
+ export default `
2
+ Ollama allows to run large language models locally on your machine.
3
+ To use it you need to install the Ollama CLI and pull the model you want to use.
4
+
5
+ 1. Install the Ollama CLI by following the instructions at <https://ollama.com/download>
6
+
7
+ 2. Pull the model you want to use by running the following command in your terminal:
8
+
9
+ \`\`\`bash
10
+ ollama pull <model-name>
11
+ \`\`\`
12
+
13
+ For example, to pull the Llama 2 model, run:
14
+
15
+ \`\`\`bash
16
+ ollama pull llama2
17
+ \`\`\`
18
+
19
+ 3. Once the model is pulled, you can use it in your application by running the following command:
20
+
21
+ \`\`\`bash
22
+ ollama serve
23
+ \`\`\`
24
+
25
+ 4. This model will be available in the extension, using the model name you used in the command above.
26
+
27
+ <details>
28
+ <summary>Deploying Lite/Lab on external server</summary>
29
+
30
+ See https://objectgraph.com/blog/ollama-cors/ for more details.
31
+
32
+ On Linux, you can run the following commands:
33
+
34
+ 1. Check if CORS is enabled on the server. You can do this by running the following command in your terminal:
35
+
36
+ \`\`\`bash
37
+ curl -X OPTIONS http://localhost:11434 -H "Origin: http://example.com" -H "Access-Control-Request-Method: GET" -I
38
+ \`\`\`
39
+
40
+ If CORS is disabled, you will see a response like this:
41
+
42
+ \`\`\`bash
43
+ HTTP/1.1 403 Forbidden
44
+ Date: Wed, 09 Oct 2024 10:12:15 GMT
45
+ Content-Length: 0
46
+ \`\`\`
47
+
48
+ 2. If CORS is not enabled, update _/etc/systemd/system/ollama.service_ with:
49
+
50
+ \`\`\`bash
51
+ [Service]
52
+ Environment="OLLAMA_HOST=0.0.0.0"
53
+ Environment="OLLAMA_ORIGINS=*"
54
+ \`\`\`
55
+
56
+ 3. Restart the service:
57
+
58
+ \`\`\`bash
59
+ sudo systemctl daemon-reload
60
+ sudo systemctl restart ollama
61
+ \`\`\`
62
+
63
+ 4. Check if CORS is enabled on the server again by running the following command in your terminal:
64
+
65
+ \`\`\`bash
66
+ curl -X OPTIONS http://localhost:11434 -H "Origin: http://example.com" -H "Access-Control-Request-Method: GET" -I
67
+ \`\`\`
68
+
69
+ </details>
70
+ `;
@@ -2,7 +2,6 @@ import {
2
2
  CompletionHandler,
3
3
  IInlineCompletionContext
4
4
  } from '@jupyterlab/completer';
5
- import { BaseChatModel } from '@langchain/core/language_models/chat_models';
6
5
  import { AIMessage, SystemMessage } from '@langchain/core/messages';
7
6
  import { ChatOpenAI } from '@langchain/openai';
8
7
 
@@ -14,10 +13,6 @@ export class OpenAICompleter implements IBaseCompleter {
14
13
  this._completer = new ChatOpenAI({ ...options.settings });
15
14
  }
16
15
 
17
- get completer(): BaseChatModel {
18
- return this._completer;
19
- }
20
-
21
16
  /**
22
17
  * Getter and setter for the initial prompt.
23
18
  */
@@ -0,0 +1,162 @@
1
+ import {
2
+ CompletionHandler,
3
+ IInlineCompletionContext
4
+ } from '@jupyterlab/completer';
5
+ import { HumanMessage, SystemMessage } from '@langchain/core/messages';
6
+ import { ChatWebLLM } from '@langchain/community/chat_models/webllm';
7
+
8
+ import { BaseCompleter, IBaseCompleter } from '../../base-completer';
9
+ import { COMPLETION_SYSTEM_PROMPT } from '../../provider';
10
+
11
+ /**
12
+ * Regular expression to match the '```' string at the start of a string.
13
+ * So the completions returned by the LLM can still be kept after removing the code block formatting.
14
+ *
15
+ * For example, if the response contains the following content after typing `import pandas`:
16
+ *
17
+ * ```python
18
+ * as pd
19
+ * ```
20
+ *
21
+ * The formatting string after removing the code block delimiters will be:
22
+ *
23
+ * as pd
24
+ */
25
+ const CODE_BLOCK_START_REGEX = /^```(?:[a-zA-Z]+)?\n?/;
26
+
27
+ /**
28
+ * Regular expression to match the '```' string at the end of a string.
29
+ */
30
+ const CODE_BLOCK_END_REGEX = /```$/;
31
+
32
+ export class WebLLMCompleter implements IBaseCompleter {
33
+ constructor(options: BaseCompleter.IOptions) {
34
+ const model = options.settings.model as string;
35
+ // provide model separately since ChatWebLLM expects it
36
+ this._completer = new ChatWebLLM({
37
+ ...options.settings,
38
+ model
39
+ });
40
+
41
+ // Initialize the model and track its status
42
+ this._isInitialized = false;
43
+ this._isInitializing = false;
44
+ this._initError = null;
45
+ void this._initializeModel();
46
+ }
47
+
48
+ /**
49
+ * Initialize the WebLLM model
50
+ */
51
+ private async _initializeModel(): Promise<void> {
52
+ if (this._isInitialized || this._isInitializing) {
53
+ return;
54
+ }
55
+
56
+ this._isInitializing = true;
57
+ try {
58
+ await this._completer.initialize((progress: any) => {
59
+ console.log('WebLLM initialization progress:', progress);
60
+ });
61
+ this._isInitialized = true;
62
+ this._isInitializing = false;
63
+ console.log('WebLLM model successfully initialized');
64
+ } catch (error) {
65
+ this._initError =
66
+ error instanceof Error ? error : new Error(String(error));
67
+ this._isInitializing = false;
68
+ console.error('Failed to initialize WebLLM model:', error);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Getter and setter for the initial prompt.
74
+ */
75
+ get prompt(): string {
76
+ return this._prompt;
77
+ }
78
+ set prompt(value: string) {
79
+ this._prompt = value;
80
+ }
81
+
82
+ get provider(): ChatWebLLM {
83
+ return this._completer;
84
+ }
85
+
86
+ async fetch(
87
+ request: CompletionHandler.IRequest,
88
+ context: IInlineCompletionContext
89
+ ) {
90
+ // Abort any pending request
91
+ if (this._abortController) {
92
+ this._abortController.abort();
93
+ }
94
+
95
+ // Create a new abort controller for this request
96
+ this._abortController = new AbortController();
97
+ const signal = this._abortController.signal;
98
+
99
+ if (!this._isInitialized) {
100
+ if (this._initError) {
101
+ console.error('WebLLM model failed to initialize:', this._initError);
102
+ return { items: [] };
103
+ }
104
+
105
+ if (!this._isInitializing) {
106
+ // Try to initialize again if it's not currently initializing
107
+ await this._initializeModel();
108
+ } else {
109
+ console.log(
110
+ 'WebLLM model is still initializing, please try again later'
111
+ );
112
+ return { items: [] };
113
+ }
114
+
115
+ // Return empty if still not initialized
116
+ if (!this._isInitialized) {
117
+ return { items: [] };
118
+ }
119
+ }
120
+
121
+ const { text, offset: cursorOffset } = request;
122
+ const prompt = text.slice(0, cursorOffset);
123
+ const trimmedPrompt = prompt.trim();
124
+
125
+ const messages = [
126
+ new SystemMessage(this._prompt),
127
+ new HumanMessage(trimmedPrompt)
128
+ ];
129
+
130
+ try {
131
+ console.log('Trigger invoke');
132
+ const response = await this._completer.invoke(messages, { signal });
133
+ let content = response.content as string;
134
+ console.log('Response content:', content);
135
+
136
+ if (CODE_BLOCK_START_REGEX.test(content)) {
137
+ content = content
138
+ .replace(CODE_BLOCK_START_REGEX, '')
139
+ .replace(CODE_BLOCK_END_REGEX, '');
140
+ }
141
+
142
+ const items = [{ insertText: content }];
143
+ return {
144
+ items
145
+ };
146
+ } catch (error) {
147
+ if (error instanceof Error) {
148
+ console.error('Error fetching completion from WebLLM:', error.message);
149
+ } else {
150
+ console.error('Unknown error fetching completion from WebLLM:', error);
151
+ }
152
+ return { items: [] };
153
+ }
154
+ }
155
+
156
+ private _completer: ChatWebLLM;
157
+ private _prompt: string = COMPLETION_SYSTEM_PROMPT;
158
+ private _isInitialized: boolean = false;
159
+ private _isInitializing: boolean = false;
160
+ private _initError: Error | null = null;
161
+ private _abortController: AbortController | null = null;
162
+ }
@@ -0,0 +1,33 @@
1
+ export default `
2
+ WebLLM enables running LLMs directly in your browser, making it possible to use AI features without sending data to external servers.
3
+
4
+ <i class="fas fa-info-circle"></i> WebLLM runs models entirely in your browser, so initial model download may be large (100MB-2GB depending on the model).
5
+
6
+ <i class="fas fa-exclamation-triangle"></i> <strong>Requirements:</strong> WebLLM requires a browser with WebGPU support (Chrome 113+, Edge 113+, or Safari 17+). It will not work on older browsers or browsers without WebGPU enabled.
7
+
8
+ 1. Enter a model in the JupyterLab settings under the **Ai providers** section. Select the \`WebLLM\` provider and type the model you want to use.
9
+ 2. When you first use WebLLM, your browser will download the model. A progress notification will appear:
10
+ 3. Once loaded, use the chat
11
+ 4. Example of available models:
12
+ - Llama-3.2-1B-Instruct-q4f32_1-MLC
13
+ - Mistral-7B-Instruct-v0.3-q4f32_1-MLC
14
+ - Qwen3-0.6B-q4f32_1-MLC
15
+ 5. See the full list of models: https://github.com/mlc-ai/web-llm/blob/632d34725629b480b5b2772379ef5c150b1286f0/src/config.ts#L303-L309
16
+
17
+ <i class="fas fa-exclamation-triangle"></i> Model performance depends on your device's hardware capabilities. More powerful devices will run models faster. Some larger models may not work well on devices with limited GPU memory or may experience slow response times.
18
+ `;
19
+
20
+ /**
21
+ * Check if the browser supports WebLLM.
22
+ */
23
+ export async function compatibilityCheck(): Promise<string | null> {
24
+ // Check if the browser supports the ChromeAI model
25
+ if (typeof navigator === 'undefined' || !('gpu' in navigator)) {
26
+ return 'Your browser does not support WebLLM, it does not support required WebGPU.';
27
+ }
28
+ if ((await navigator.gpu.requestAdapter()) === null) {
29
+ return 'You may need to enable WebGPU, `await navigator.gpu.requestAdapter()` is null.';
30
+ }
31
+ // If the model is available, return null to indicate compatibility
32
+ return null;
33
+ }