LLM integration with App on TypeScript

This article will guide you through the process of integrating a Large Language Model Integration (LLM integration) with your web app using TypeScript. We’ll demonstrate how to leverage LLMs to add sophisticated natural language processing features to your application. Whether you’re looking to build a smart chatbot, enhance content generation, or improve user interactions, this integration can open up a world of possibilities. Let’s dive in and see how you can harness the power of LLM integration to take your web app to the next level! Elinext company offers LLM Integration Services so this article is based on our practical experience.

WebLLM

WebLLM is a high-performance, in-browser language model inference engine designed to run directly within web browsers without the need for server-side processing. Leveraging WebGPU for hardware acceleration, WebLLM supports a variety of models, including Llama, Phi, and Mistral, among others. It is fully compatible with the OpenAI API, allowing seamless integration into applications for tasks such as streaming chat completions and real-time interactions. This makes WebLLM a versatile tool for building AI-powered web applications and enhancing user privacy by keeping computations on the client. Elinext offers LLM integration services for web applications, contact us to get details.

Dependencies

Here is an example of the package.json dependencies for LLM integration into your app:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
"devDependencies": {
"buffer": "^5.7.1",
"parcel": "^2.8.3",
"process": "^0.11.10",
"tslib": "^2.3.1",
"typescript": "^4.9.5",
"url": "^0.11.3"
},
"dependencies": {
"@mlc-ai/web-llm": "^0.2.73"
}
"devDependencies": { "buffer": "^5.7.1", "parcel": "^2.8.3", "process": "^0.11.10", "tslib": "^2.3.1", "typescript": "^4.9.5", "url": "^0.11.3" }, "dependencies": { "@mlc-ai/web-llm": "^0.2.73" }
"devDependencies": {
  "buffer": "^5.7.1",
  "parcel": "^2.8.3",
  "process": "^0.11.10",
  "tslib": "^2.3.1",
  "typescript": "^4.9.5",
  "url": "^0.11.3"
},
"dependencies": {
  "@mlc-ai/web-llm": "^0.2.73"
}

Adding LLM configuration file

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { prebuiltAppConfig } from "@mlc-ai/web-llm";
export default {
model_list: prebuiltAppConfig.model_list,
use_web_worker: true,
};
import { prebuiltAppConfig } from "@mlc-ai/web-llm"; export default { model_list: prebuiltAppConfig.model_list, use_web_worker: true, };
import { prebuiltAppConfig } from "@mlc-ai/web-llm";
 
export default {
 model_list: prebuiltAppConfig.model_list,
 use_web_worker: true,
};

This code configures the application to use a predefined list of models and enables the use of web workers:

  • model_list: This property is set to the model_list from the prebuiltAppConfig. It contains a list of models that the application can use. Here are the primary families of models currently supported:

Llama: Llama 3, Llama 2, Hermes-2-Pro-Llama-3

Phi: Phi 3, Phi 2, Phi 1.5

Gemma: Gemma-2B

Mistral: Mistral-7B-v0.3, Hermes-2-Pro-Mistral-7B, NeuralHermes-2.5-Mistral-7B, OpenHermes-2.5-Mistral-7B

Qwen: Qwen2 0.5B, 1.5B, 7B

  • use_web_worker: This property is set to true, indicating that the application should use a web worker for running tasks. Web workers allow for running scripts in background threads, which can improve performance by offloading tasks from the main thread.

Instantiate the Engine

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import * as webllm from "@mlc-ai/web-llm";
const useWebWorker = appConfig.use_web_worker;
let engine: webllm.MLCEngineInterface;
if (useWebWorker) {
engine = new webllm.WebWorkerMLCEngine(
new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
{ appConfig, logLevel: "INFO" },
);
} else {
engine = new webllm.MLCEngine({ appConfig });
}
import * as webllm from "@mlc-ai/web-llm"; const useWebWorker = appConfig.use_web_worker; let engine: webllm.MLCEngineInterface; if (useWebWorker) { engine = new webllm.WebWorkerMLCEngine( new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }), { appConfig, logLevel: "INFO" }, ); } else { engine = new webllm.MLCEngine({ appConfig }); }
import * as webllm from "@mlc-ai/web-llm";
 
  const useWebWorker = appConfig.use_web_worker;
  let engine: webllm.MLCEngineInterface;
 
  if (useWebWorker) {
   engine = new webllm.WebWorkerMLCEngine(
     new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
 	{ appConfig, logLevel: "INFO" },
   );
  } else {
   engine = new webllm.MLCEngine({ appConfig });
  }

This code performs followed three steps: 

Step 1.  Importing all the exported members

The first line imports all the exported members (functions, classes, constants, etc.) from the @mlc-ai/web-llm package and makes them available under the namespace webllm.

Step 2. Determine Whether to Use a Web Worker

The second line retrieves the use_web_worker setting from the appConfig object. This setting determines whether the application should use a web worker for running tasks.

Step 3. Declare the Engine Variable 

The third line declares a variable engine of type webllm.MLCEngineInterface. This variable will hold the instance of the machine learning engine.

Step 4. Instantiate the Engine:

If useWebWorker is true:

  • It creates an instance of webllm.WebWorkerMLCEngine.
  • This instance is initialized with a new web worker, created from the worker.ts file.
  • The web worker is set up to run as a module.
  • The engine is also configured with appConfig and a log level of “INFO”.

If useWebWorker is false: 

  • It creates an instance of webllm.MLCEngine directly, without using a web worker.
  • This instance is also configured with appConfig.

Main Entry Point

The entry point in this example is the asynchronous CreateAsync method, which initializes the ChatUI class, passing the engine instance as an argument. This method sets up UI elements with the specified engine, and registers event handlers:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public static CreateAsync = async (engine: webllm.MLCEngineInterface) => {
//logic
}
ChatUI.CreateAsync(engine);
public static CreateAsync = async (engine: webllm.MLCEngineInterface) => { //logic } ChatUI.CreateAsync(engine);
public static CreateAsync = async (engine: webllm.MLCEngineInterface) => {
    //logic
  }
  ChatUI.CreateAsync(engine);

Chat Completion

Once the engine is successfully initialized, you can utilize the engine.chat.completions interface to call chat completions in the OpenAI style:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const messages = [
{ content: "Hi, I’m your personal Artificial intelligence helper.", role: "system", },
{ content: "Hi!", role: "user" },
]
const reply = await engine.chat.completions.create({
messages,
});
console.log(reply.choices[0].message);
console.log(reply.usage);
const messages = [ { content: "Hi, I’m your personal Artificial intelligence helper.", role: "system", }, { content: "Hi!", role: "user" }, ] const reply = await engine.chat.completions.create({ messages, }); console.log(reply.choices[0].message); console.log(reply.usage);
 
const messages = [
 { content: "Hi, I’m your personal Artificial intelligence helper.", role: "system", },
 { content: "Hi!", role: "user" },
]
 
const reply = await engine.chat.completions.create({
 messages,
});
console.log(reply.choices[0].message);
console.log(reply.usage);

Streaming

WebLLM also supports streaming chat completion generating. To utilize it, just include stream: true in the engine.chat.completions.create call.:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const messages = [
{ content: "Hi, I’m your personal Artificial intelligence helper.", role: "system", },
{ content: "Hi!", role: "user" },
]
const chunks = await engine.chat.completions.create({
messages,
temperature: 1,
stream: true, // <-- Enable streaming
stream_options: { include_usage: true },
});
let reply = "";
for await (const chunk of chunks) {
reply += chunk.choices[0]?.delta.content || "";
console.log(reply);
if (chunk.usage) {
console.log(chunk.usage); // only last chunk has usage
}
}
const fullReply = await engine.getMessage();
console.log(fullReply);
const messages = [ { content: "Hi, I’m your personal Artificial intelligence helper.", role: "system", }, { content: "Hi!", role: "user" }, ] const chunks = await engine.chat.completions.create({ messages, temperature: 1, stream: true, // <-- Enable streaming stream_options: { include_usage: true }, }); let reply = ""; for await (const chunk of chunks) { reply += chunk.choices[0]?.delta.content || ""; console.log(reply); if (chunk.usage) { console.log(chunk.usage); // only last chunk has usage } } const fullReply = await engine.getMessage(); console.log(fullReply);
const messages = [
 { content: "Hi, I’m your personal Artificial intelligence helper.", role: "system", },
 { content: "Hi!", role: "user" },
]
const chunks = await engine.chat.completions.create({
 messages,
 temperature: 1,
 stream: true, // <-- Enable streaming
 stream_options: { include_usage: true },
});
 
let reply = "";
for await (const chunk of chunks) {
 reply += chunk.choices[0]?.delta.content || "";
 console.log(reply);
 if (chunk.usage) {
   console.log(chunk.usage); // only last chunk has usage
 }
}
 
const fullReply = await engine.getMessage();
console.log(fullReply);

Testing

Run `npm install`and `npm start` in CMD or PowerShell to start the application. In our case, the system automatically selected the Llama-3.2-1B-Instruct-q4f32_1-MLC model for work. Also, in our case, a chatbot client had already been developed, which only needed to be integrated with the above-described interface of the WebLLM interface functionality.

As we can see, LLM integration copes well with abstract questions from the knowledge base on which it was trained. But model might not have real-time data access or the capability to provide specific weather updates.

The example demonstrates how to invoke chat completions using OpenAI-style chat APIs and how to enable streaming for real-time responses. These make the chat experience more dynamic and responsive.

Conclusion for LLM Integration into Your App

Druzik Aliaksei Nikolaevich, Senior Software Engineer, LLM Integration Specialist:

LLM integration with your web app using TypeScript can significantly enhance your application’s capabilities, providing sophisticated natural language processing features. By following the steps outlined in this article, you can build a smart chatbot, enhance content generation, and improve user interactions, opening up a world of possibilities for your web application using LLM integration.”

In case, you want a smooth  LLM integration guaranteed, the Elinext team offers LLM integration services that meet your expectations.

Contact Us
Contact Us

    • United States+1
    • United Kingdom+44
    • Afghanistan (‫افغانستان‬‎)+93
    • Albania (Shqipëri)+355
    • Algeria (‫الجزائر‬‎)+213
    • American Samoa+1
    • Andorra+376
    • Angola+244
    • Anguilla+1
    • Antigua and Barbuda+1
    • Argentina+54
    • Armenia (Հայաստան)+374
    • Aruba+297
    • Ascension Island+247
    • Australia+61
    • Austria (Österreich)+43
    • Azerbaijan (Azərbaycan)+994
    • Bahamas+1
    • Bahrain (‫البحرين‬‎)+973
    • Bangladesh (বাংলাদেশ)+880
    • Barbados+1
    • Belarus (Беларусь)+375
    • Belgium (België)+32
    • Belize+501
    • Benin (Bénin)+229
    • Bermuda+1
    • Bhutan (འབྲུག)+975
    • Bolivia+591
    • Bosnia and Herzegovina (Босна и Херцеговина)+387
    • Botswana+267
    • Brazil (Brasil)+55
    • British Indian Ocean Territory+246
    • British Virgin Islands+1
    • Brunei+673
    • Bulgaria (България)+359
    • Burkina Faso+226
    • Burundi (Uburundi)+257
    • Cambodia (កម្ពុជា)+855
    • Cameroon (Cameroun)+237
    • Canada+1
    • Cape Verde (Kabu Verdi)+238
    • Caribbean Netherlands+599
    • Cayman Islands+1
    • Central African Republic (République centrafricaine)+236
    • Chad (Tchad)+235
    • Chile+56
    • China (中国)+86
    • Christmas Island+61
    • Cocos (Keeling) Islands+61
    • Colombia+57
    • Comoros (‫جزر القمر‬‎)+269
    • Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)+243
    • Congo (Republic) (Congo-Brazzaville)+242
    • Cook Islands+682
    • Costa Rica+506
    • Côte d’Ivoire+225
    • Croatia (Hrvatska)+385
    • Cuba+53
    • Curaçao+599
    • Cyprus (Κύπρος)+357
    • Czech Republic (Česká republika)+420
    • Denmark (Danmark)+45
    • Djibouti+253
    • Dominica+1
    • Dominican Republic (República Dominicana)+1
    • Ecuador+593
    • Egypt (‫مصر‬‎)+20
    • El Salvador+503
    • Equatorial Guinea (Guinea Ecuatorial)+240
    • Eritrea+291
    • Estonia (Eesti)+372
    • Eswatini+268
    • Ethiopia+251
    • Falkland Islands (Islas Malvinas)+500
    • Faroe Islands (Føroyar)+298
    • Fiji+679
    • Finland (Suomi)+358
    • France+33
    • French Guiana (Guyane française)+594
    • French Polynesia (Polynésie française)+689
    • Gabon+241
    • Gambia+220
    • Georgia (საქართველო)+995
    • Germany (Deutschland)+49
    • Ghana (Gaana)+233
    • Gibraltar+350
    • Greece (Ελλάδα)+30
    • Greenland (Kalaallit Nunaat)+299
    • Grenada+1
    • Guadeloupe+590
    • Guam+1
    • Guatemala+502
    • Guernsey+44
    • Guinea (Guinée)+224
    • Guinea-Bissau (Guiné Bissau)+245
    • Guyana+592
    • Haiti+509
    • Honduras+504
    • Hong Kong (香港)+852
    • Hungary (Magyarország)+36
    • Iceland (Ísland)+354
    • India (भारत)+91
    • Indonesia+62
    • Iran (‫ایران‬‎)+98
    • Iraq (‫العراق‬‎)+964
    • Ireland+353
    • Isle of Man+44
    • Israel (‫ישראל‬‎)+972
    • Italy (Italia)+39
    • Jamaica+1
    • Japan (日本)+81
    • Jersey+44
    • Jordan (‫الأردن‬‎)+962
    • Kazakhstan (Казахстан)+7
    • Kenya+254
    • Kiribati+686
    • Kosovo+383
    • Kuwait (‫الكويت‬‎)+965
    • Kyrgyzstan (Кыргызстан)+996
    • Laos (ລາວ)+856
    • Latvia (Latvija)+371
    • Lebanon (‫لبنان‬‎)+961
    • Lesotho+266
    • Liberia+231
    • Libya (‫ليبيا‬‎)+218
    • Liechtenstein+423
    • Lithuania (Lietuva)+370
    • Luxembourg+352
    • Macau (澳門)+853
    • Macedonia (FYROM) (Македонија)+389
    • Madagascar (Madagasikara)+261
    • Malawi+265
    • Malaysia+60
    • Maldives+960
    • Mali+223
    • Malta+356
    • Marshall Islands+692
    • Martinique+596
    • Mauritania (‫موريتانيا‬‎)+222
    • Mauritius (Moris)+230
    • Mayotte+262
    • Mexico (México)+52
    • Micronesia+691
    • Moldova (Republica Moldova)+373
    • Monaco+377
    • Mongolia (Монгол)+976
    • Montenegro (Crna Gora)+382
    • Montserrat+1
    • Morocco (‫المغرب‬‎)+212
    • Mozambique (Moçambique)+258
    • Myanmar (Burma) (မြန်မာ)+95
    • Namibia (Namibië)+264
    • Nauru+674
    • Nepal (नेपाल)+977
    • Netherlands (Nederland)+31
    • New Caledonia (Nouvelle-Calédonie)+687
    • New Zealand+64
    • Nicaragua+505
    • Niger (Nijar)+227
    • Nigeria+234
    • Niue+683
    • Norfolk Island+672
    • North Korea (조선 민주주의 인민 공화국)+850
    • Northern Mariana Islands+1
    • Norway (Norge)+47
    • Oman (‫عُمان‬‎)+968
    • Pakistan (‫پاکستان‬‎)+92
    • Palau+680
    • Palestine (‫فلسطين‬‎)+970
    • Panama (Panamá)+507
    • Papua New Guinea+675
    • Paraguay+595
    • Peru (Perú)+51
    • Philippines+63
    • Poland (Polska)+48
    • Portugal+351
    • Puerto Rico+1
    • Qatar (‫قطر‬‎)+974
    • Réunion (La Réunion)+262
    • Romania (România)+40
    • Russia (Россия)+7
    • Rwanda+250
    • Saint Barthélemy+590
    • Saint Helena+290
    • Saint Kitts and Nevis+1
    • Saint Lucia+1
    • Saint Martin (Saint-Martin (partie française))+590
    • Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)+508
    • Saint Vincent and the Grenadines+1
    • Samoa+685
    • San Marino+378
    • São Tomé and Príncipe (São Tomé e Príncipe)+239
    • Saudi Arabia (‫المملكة العربية السعودية‬‎)+966
    • Senegal (Sénégal)+221
    • Serbia (Србија)+381
    • Seychelles+248
    • Sierra Leone+232
    • Singapore+65
    • Sint Maarten+1
    • Slovakia (Slovensko)+421
    • Slovenia (Slovenija)+386
    • Solomon Islands+677
    • Somalia (Soomaaliya)+252
    • South Africa+27
    • South Korea (대한민국)+82
    • South Sudan (‫جنوب السودان‬‎)+211
    • Spain (España)+34
    • Sri Lanka (ශ්‍රී ලංකාව)+94
    • Sudan (‫السودان‬‎)+249
    • Suriname+597
    • Svalbard and Jan Mayen+47
    • Sweden (Sverige)+46
    • Switzerland (Schweiz)+41
    • Syria (‫سوريا‬‎)+963
    • Taiwan (台灣)+886
    • Tajikistan+992
    • Tanzania+255
    • Thailand (ไทย)+66
    • Timor-Leste+670
    • Togo+228
    • Tokelau+690
    • Tonga+676
    • Trinidad and Tobago+1
    • Tunisia (‫تونس‬‎)+216
    • Turkey (Türkiye)+90
    • Turkmenistan+993
    • Turks and Caicos Islands+1
    • Tuvalu+688
    • U.S. Virgin Islands+1
    • Uganda+256
    • Ukraine (Україна)+380
    • United Arab Emirates (‫الإمارات العربية المتحدة‬‎)+971
    • United Kingdom+44
    • United States+1
    • Uruguay+598
    • Uzbekistan (Oʻzbekiston)+998
    • Vanuatu+678
    • Vatican City (Città del Vaticano)+39
    • Venezuela+58
    • Vietnam (Việt Nam)+84
    • Wallis and Futuna (Wallis-et-Futuna)+681
    • Western Sahara (‫الصحراء الغربية‬‎)+212
    • Yemen (‫اليمن‬‎)+967
    • Zambia+260
    • Zimbabwe+263
    • Åland Islands+358

    Insert math as
    Block
    Inline
    Additional settings
    Formula color
    Text color
    #333333
    Type math using LaTeX
    Preview
    Nothing to preview
    Insert