@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 6.21 kB
Source Map (JSON)
{"version":3,"file":"webllm.cjs","names":["SimpleChatModel","webllm","ChatGenerationChunk","AIMessageChunk"],"sources":["../../src/chat_models/webllm.ts"],"sourcesContent":["import {\n SimpleChatModel,\n type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { BaseLanguageModelCallOptions } from \"@langchain/core/language_models/base\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { BaseMessage, AIMessageChunk } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk } from \"@langchain/core/outputs\";\nimport * as webllm from \"@mlc-ai/web-llm\";\nimport { ChatCompletionMessageParam } from \"@mlc-ai/web-llm/lib/openai_api_protocols\";\n\nexport interface WebLLMInputs extends BaseChatModelParams {\n appConfig?: webllm.AppConfig;\n chatOptions?: webllm.ChatOptions;\n temperature?: number;\n model: string;\n}\n\nexport interface WebLLMCallOptions extends BaseLanguageModelCallOptions {}\n\n/**\n * To use this model you need to have the `@mlc-ai/web-llm` module installed.\n * This can be installed using `npm install -S @mlc-ai/web-llm`.\n *\n * You can see a list of available model records here:\n * https://github.com/mlc-ai/web-llm/blob/main/src/config.ts\n * @example\n * ```typescript\n * // Initialize the ChatWebLLM model with the model record.\n * const model = new ChatWebLLM({\n * model: \"Phi-3-mini-4k-instruct-q4f16_1-MLC\",\n * chatOptions: {\n * temperature: 0.5,\n * },\n * });\n *\n * // Call the model with a message and await the response.\n * const response = await model.invoke([\n * new HumanMessage({ content: \"My name is John.\" }),\n * ]);\n * ```\n */\nexport class ChatWebLLM extends SimpleChatModel<WebLLMCallOptions> {\n static inputs: WebLLMInputs;\n\n protected engine: webllm.MLCEngine;\n\n appConfig?: webllm.AppConfig;\n\n chatOptions?: webllm.ChatOptions;\n\n temperature?: number;\n\n model: string;\n\n static lc_name() {\n return \"ChatWebLLM\";\n }\n\n constructor(inputs: WebLLMInputs) {\n super(inputs);\n this.appConfig = inputs.appConfig;\n this.chatOptions = inputs.chatOptions;\n this.model = inputs.model;\n this.temperature = inputs.temperature;\n this.engine = new webllm.MLCEngine({\n appConfig: this.appConfig,\n });\n }\n\n _llmType() {\n return \"web-llm\";\n }\n\n async initialize(progressCallback?: webllm.InitProgressCallback) {\n if (progressCallback !== undefined) {\n this.engine.setInitProgressCallback(progressCallback);\n }\n await this.reload(this.model, this.chatOptions);\n }\n\n async reload(modelId: string, newChatOpts?: webllm.ChatOptions) {\n await this.engine.reload(modelId, newChatOpts);\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const messagesInput: ChatCompletionMessageParam[] = messages.map(\n (message) => {\n if (typeof message.content !== \"string\") {\n throw new Error(\n \"ChatWebLLM does not support non-string message content in sessions.\"\n );\n }\n const langChainType = message._getType();\n let role;\n if (langChainType === \"ai\") {\n role = \"assistant\" as const;\n } else if (langChainType === \"human\") {\n role = \"user\" as const;\n } else if (langChainType === \"system\") {\n role = \"system\" as const;\n } else {\n throw new Error(\n \"Function, tool, and generic messages are not supported.\"\n );\n }\n return {\n role,\n content: message.content,\n };\n }\n );\n\n const stream = await this.engine.chat.completions.create({\n stream: true,\n messages: messagesInput,\n stop: options.stop,\n logprobs: true,\n });\n for await (const chunk of stream) {\n // Last chunk has undefined content\n const text = chunk.choices[0].delta.content ?? \"\";\n yield new ChatGenerationChunk({\n text,\n message: new AIMessageChunk({\n content: text,\n additional_kwargs: {\n logprobs: chunk.choices[0].logprobs,\n finish_reason: chunk.choices[0].finish_reason,\n },\n }),\n });\n await runManager?.handleLLMNewToken(text);\n }\n }\n\n async _call(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<string> {\n const chunks = [];\n for await (const chunk of this._streamResponseChunks(\n messages,\n options,\n runManager\n )) {\n chunks.push(chunk.text);\n }\n return chunks.join(\"\");\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,aAAb,cAAgCA,4CAAAA,gBAAmC;CACjE,OAAO;CAEP;CAEA;CAEA;CAEA;CAEA;CAEA,OAAO,UAAU;AACf,SAAO;;CAGT,YAAY,QAAsB;AAChC,QAAM,OAAO;AACb,OAAK,YAAY,OAAO;AACxB,OAAK,cAAc,OAAO;AAC1B,OAAK,QAAQ,OAAO;AACpB,OAAK,cAAc,OAAO;AAC1B,OAAK,SAAS,IAAIC,gBAAO,UAAU,EACjC,WAAW,KAAK,WACjB,CAAC;;CAGJ,WAAW;AACT,SAAO;;CAGT,MAAM,WAAW,kBAAgD;AAC/D,MAAI,qBAAqB,KAAA,EACvB,MAAK,OAAO,wBAAwB,iBAAiB;AAEvD,QAAM,KAAK,OAAO,KAAK,OAAO,KAAK,YAAY;;CAGjD,MAAM,OAAO,SAAiB,aAAkC;AAC9D,QAAM,KAAK,OAAO,OAAO,SAAS,YAAY;;CAGhD,OAAO,sBACL,UACA,SACA,YACqC;EACrC,MAAM,gBAA8C,SAAS,KAC1D,YAAY;AACX,OAAI,OAAO,QAAQ,YAAY,SAC7B,OAAM,IAAI,MACR,sEACD;GAEH,MAAM,gBAAgB,QAAQ,UAAU;GACxC,IAAI;AACJ,OAAI,kBAAkB,KACpB,QAAO;YACE,kBAAkB,QAC3B,QAAO;YACE,kBAAkB,SAC3B,QAAO;OAEP,OAAM,IAAI,MACR,0DACD;AAEH,UAAO;IACL;IACA,SAAS,QAAQ;IAClB;IAEJ;EAED,MAAM,SAAS,MAAM,KAAK,OAAO,KAAK,YAAY,OAAO;GACvD,QAAQ;GACR,UAAU;GACV,MAAM,QAAQ;GACd,UAAU;GACX,CAAC;AACF,aAAW,MAAM,SAAS,QAAQ;GAEhC,MAAM,OAAO,MAAM,QAAQ,GAAG,MAAM,WAAW;AAC/C,SAAM,IAAIC,wBAAAA,oBAAoB;IAC5B;IACA,SAAS,IAAIC,yBAAAA,eAAe;KAC1B,SAAS;KACT,mBAAmB;MACjB,UAAU,MAAM,QAAQ,GAAG;MAC3B,eAAe,MAAM,QAAQ,GAAG;MACjC;KACF,CAAC;IACH,CAAC;AACF,SAAM,YAAY,kBAAkB,KAAK;;;CAI7C,MAAM,MACJ,UACA,SACA,YACiB;EACjB,MAAM,SAAS,EAAE;AACjB,aAAW,MAAM,SAAS,KAAK,sBAC7B,UACA,SACA,WACD,CACC,QAAO,KAAK,MAAM,KAAK;AAEzB,SAAO,OAAO,KAAK,GAAG"}