From 137efb8828e0958bc93becdf0ff85df88fdd5b28 Mon Sep 17 00:00:00 2001 From: Taekmin Kim Date: Sun, 1 Dec 2024 20:20:23 -0800 Subject: [PATCH 1/4] Add chrome extension example built with plasmo --- chrome-extension-plasmo/.env | 1 + chrome-extension-plasmo/.env.example | 1 + chrome-extension-plasmo/.gitignore | 35 + chrome-extension-plasmo/.prettierrc.mjs | 26 + chrome-extension-plasmo/LICENSE | 201 + chrome-extension-plasmo/README.md | 122 + chrome-extension-plasmo/assets/icon.png | Bin 0 -> 87478 bytes chrome-extension-plasmo/components.json | 21 + .../components/ChangeModelForm.tsx | 76 + chrome-extension-plasmo/components/Chat.tsx | 226 + .../components/ChatCopyButton.tsx | 27 + .../components/ChatExamples.tsx | 52 + .../components/ChatHeader.tsx | 210 + .../components/ChatMessages.tsx | 97 + .../components/ChatProgress.tsx | 30 + .../components/GenerationConfigForm.tsx | 139 + .../components/ModelRegistryForm.tsx | 88 + .../components/ui/accordion.tsx | 55 + .../components/ui/alert.tsx | 59 + .../components/ui/badge.tsx | 36 + .../components/ui/breadcrumb.tsx | 115 + .../components/ui/button.tsx | 57 + .../components/ui/context-menu.tsx | 198 + .../components/ui/dialog.tsx | 122 + .../components/ui/dropdown-menu.tsx | 199 + .../components/ui/input.tsx | 22 + .../components/ui/label.tsx | 24 + .../components/ui/scroll-area.tsx | 46 + .../components/ui/separator.tsx | 29 + .../components/ui/sheet.tsx | 140 + .../components/ui/sidebar.tsx | 761 ++ .../components/ui/skeleton.tsx | 15 + .../components/ui/switch.tsx | 27 + .../components/ui/table.tsx | 120 + .../components/ui/tooltip.tsx | 32 + .../docs/example-summarize.jpg | Bin 0 -> 226658 bytes .../docs/example-write-code.jpg | Bin 0 -> 202639 bytes .../docs/inspect-views.jpg | Bin 0 -> 158647 bytes .../docs/local-storage.jpg | Bin 0 -> 329880 bytes chrome-extension-plasmo/docs/task-manager.jpg | Bin 0 -> 55575 bytes chrome-extension-plasmo/hooks/use-mobile.tsx | 19 + chrome-extension-plasmo/lib/formatter.ts | 9 + chrome-extension-plasmo/lib/utils.ts | 6 + chrome-extension-plasmo/llm/default-config.ts | 22 + chrome-extension-plasmo/llm/model-list.ts | 69 + chrome-extension-plasmo/llm/pipeline.ts | 78 + .../llm/stopping-criteria.ts | 39 + chrome-extension-plasmo/package.json | 71 + chrome-extension-plasmo/pnpm-lock.yaml | 8161 +++++++++++++++++ chrome-extension-plasmo/postbuild/sed.js | 38 + chrome-extension-plasmo/postcss.config.js | 9 + chrome-extension-plasmo/src/background.ts | 154 + chrome-extension-plasmo/src/index.css | 204 + chrome-extension-plasmo/src/popup.tsx | 17 + chrome-extension-plasmo/src/sidepanel.tsx | 9 + chrome-extension-plasmo/src/types.ts | 26 + chrome-extension-plasmo/tailwind.config.js | 83 + chrome-extension-plasmo/tsconfig.json | 22 + 58 files changed, 12445 insertions(+) create mode 100644 chrome-extension-plasmo/.env create mode 100644 chrome-extension-plasmo/.env.example create mode 100644 chrome-extension-plasmo/.gitignore create mode 100644 chrome-extension-plasmo/.prettierrc.mjs create mode 100644 chrome-extension-plasmo/LICENSE create mode 100644 chrome-extension-plasmo/README.md create mode 100644 chrome-extension-plasmo/assets/icon.png create mode 100644 chrome-extension-plasmo/components.json create mode 100644 chrome-extension-plasmo/components/ChangeModelForm.tsx create mode 100644 chrome-extension-plasmo/components/Chat.tsx create mode 100644 chrome-extension-plasmo/components/ChatCopyButton.tsx create mode 100644 chrome-extension-plasmo/components/ChatExamples.tsx create mode 100644 chrome-extension-plasmo/components/ChatHeader.tsx create mode 100644 chrome-extension-plasmo/components/ChatMessages.tsx create mode 100644 chrome-extension-plasmo/components/ChatProgress.tsx create mode 100644 chrome-extension-plasmo/components/GenerationConfigForm.tsx create mode 100644 chrome-extension-plasmo/components/ModelRegistryForm.tsx create mode 100644 chrome-extension-plasmo/components/ui/accordion.tsx create mode 100644 chrome-extension-plasmo/components/ui/alert.tsx create mode 100644 chrome-extension-plasmo/components/ui/badge.tsx create mode 100644 chrome-extension-plasmo/components/ui/breadcrumb.tsx create mode 100644 chrome-extension-plasmo/components/ui/button.tsx create mode 100644 chrome-extension-plasmo/components/ui/context-menu.tsx create mode 100644 chrome-extension-plasmo/components/ui/dialog.tsx create mode 100644 chrome-extension-plasmo/components/ui/dropdown-menu.tsx create mode 100644 chrome-extension-plasmo/components/ui/input.tsx create mode 100644 chrome-extension-plasmo/components/ui/label.tsx create mode 100644 chrome-extension-plasmo/components/ui/scroll-area.tsx create mode 100644 chrome-extension-plasmo/components/ui/separator.tsx create mode 100644 chrome-extension-plasmo/components/ui/sheet.tsx create mode 100644 chrome-extension-plasmo/components/ui/sidebar.tsx create mode 100644 chrome-extension-plasmo/components/ui/skeleton.tsx create mode 100644 chrome-extension-plasmo/components/ui/switch.tsx create mode 100644 chrome-extension-plasmo/components/ui/table.tsx create mode 100644 chrome-extension-plasmo/components/ui/tooltip.tsx create mode 100644 chrome-extension-plasmo/docs/example-summarize.jpg create mode 100644 chrome-extension-plasmo/docs/example-write-code.jpg create mode 100644 chrome-extension-plasmo/docs/inspect-views.jpg create mode 100644 chrome-extension-plasmo/docs/local-storage.jpg create mode 100644 chrome-extension-plasmo/docs/task-manager.jpg create mode 100644 chrome-extension-plasmo/hooks/use-mobile.tsx create mode 100644 chrome-extension-plasmo/lib/formatter.ts create mode 100644 chrome-extension-plasmo/lib/utils.ts create mode 100644 chrome-extension-plasmo/llm/default-config.ts create mode 100644 chrome-extension-plasmo/llm/model-list.ts create mode 100644 chrome-extension-plasmo/llm/pipeline.ts create mode 100644 chrome-extension-plasmo/llm/stopping-criteria.ts create mode 100644 chrome-extension-plasmo/package.json create mode 100644 chrome-extension-plasmo/pnpm-lock.yaml create mode 100644 chrome-extension-plasmo/postbuild/sed.js create mode 100644 chrome-extension-plasmo/postcss.config.js create mode 100644 chrome-extension-plasmo/src/background.ts create mode 100644 chrome-extension-plasmo/src/index.css create mode 100644 chrome-extension-plasmo/src/popup.tsx create mode 100644 chrome-extension-plasmo/src/sidepanel.tsx create mode 100644 chrome-extension-plasmo/src/types.ts create mode 100644 chrome-extension-plasmo/tailwind.config.js create mode 100644 chrome-extension-plasmo/tsconfig.json diff --git a/chrome-extension-plasmo/.env b/chrome-extension-plasmo/.env new file mode 100644 index 00000000..6c176842 --- /dev/null +++ b/chrome-extension-plasmo/.env @@ -0,0 +1 @@ +POST_BUILD_SCRIPT=postbuild/sed.js \ No newline at end of file diff --git a/chrome-extension-plasmo/.env.example b/chrome-extension-plasmo/.env.example new file mode 100644 index 00000000..6c176842 --- /dev/null +++ b/chrome-extension-plasmo/.env.example @@ -0,0 +1 @@ +POST_BUILD_SCRIPT=postbuild/sed.js \ No newline at end of file diff --git a/chrome-extension-plasmo/.gitignore b/chrome-extension-plasmo/.gitignore new file mode 100644 index 00000000..590de907 --- /dev/null +++ b/chrome-extension-plasmo/.gitignore @@ -0,0 +1,35 @@ + +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +out/ +build/ +dist/ + +# plasmo +.plasmo + +# typescript +.tsbuildinfo + +.vscode \ No newline at end of file diff --git a/chrome-extension-plasmo/.prettierrc.mjs b/chrome-extension-plasmo/.prettierrc.mjs new file mode 100644 index 00000000..77f84c21 --- /dev/null +++ b/chrome-extension-plasmo/.prettierrc.mjs @@ -0,0 +1,26 @@ +/** + * @type {import('prettier').Options} + */ +export default { + printWidth: 80, + tabWidth: 2, + useTabs: false, + semi: false, + singleQuote: false, + trailingComma: "none", + bracketSpacing: true, + bracketSameLine: true, + plugins: ["@ianvs/prettier-plugin-sort-imports"], + importOrder: [ + "", // Node.js built-in modules + "", // Imports not matched by other special words or groups. + "", // Empty line + "^@plasmo/(.*)$", + "", + "^@plasmohq/(.*)$", + "", + "^~(.*)$", + "", + "^[./]" + ] +} diff --git a/chrome-extension-plasmo/LICENSE b/chrome-extension-plasmo/LICENSE new file mode 100644 index 00000000..f49a4e16 --- /dev/null +++ b/chrome-extension-plasmo/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/chrome-extension-plasmo/README.md b/chrome-extension-plasmo/README.md new file mode 100644 index 00000000..3f850f83 --- /dev/null +++ b/chrome-extension-plasmo/README.md @@ -0,0 +1,122 @@ +# Transformers.js Chrome Extension + +This is an example Chrome extension for [Transformers.js](https://github.com/huggingface/transformers.js), a library for running LLMs in the browser, built on top of [Plasmo](https://plasmo.com/). + +Please note that this project is still under development. The chrome extension process could be stopped by the browser anytime. Please refer to the [tantara/transformers.js-chrome](https://github.com/tantara/transformers.js-chrome) repo for the latest updates. + +## Examples + +Here is the link to the [demo video](https://www.youtube.com/watch?v=yXZQ8FHtSes). Each example will be updated below. + +| Task | Example | +| ------------------- | ----------------------------------------------------------- | +| Text Summarization | ![Example Text Summarization](./docs/example-summarize.jpg) | +| Code Generation | ![Example Code Generation](./docs/example-write-code.jpg) | +| Multi Modal LLM | WIP | +| Text Classification | WIP | +| Speech to Text | WIP | +| Image Segmentation | WIP | +| Remove Background | WIP | +| Image Generation | WIP | + +## Features + +- [x] Integrate Transformers.js with Chrome extension +- [x] Use modern web development tooling (TypeScript, Parcel, Tailwind CSS, Shadcn, etc.) +- [x] Change generation parameters (e.g. max_tokens, temperature, top_p etc.) +- [x] Load LLaMA variants +- [x] Load other LLM models +- [ ] Release extension to Chrome Web Store +- [ ] Load multi modal LLM models +- [ ] Load Whisper (Speech-to-Text), SAM (Segment Anything Model), etc. +- [ ] Chat history (save to local storage, export to CSV) +- [ ] Call 3rd party LLM APIs +- [ ] Error handling +- [ ] Resource management (e.g. orchestrate and stop generations, unload models) + +## Performance + +All the numbers below are measured on a MacBook Pro M1 Max with 32GB RAM. + +Prompt: "Write python code to compute the nth fibonacci number." + +| Model | Throughput | +| ----------------------------------------------------------------------------------------------- | --------------- | +| [Llama-3.2-1B](https://huggingface.co/onnx-community/Llama-3.2-1B-Instruct-q4f16) (q4f16) | 40.3 tokens/sec | +| [Phi-3.5-mini](https://huggingface.co/onnx-community/Phi-3.5-mini-instruct-onnx-web) (q4f16) | 32.9 tokens/sec | +| [SmolLM2-1.7B](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct) (q4f16) | 46.2 tokens/sec | +| [Qwen2.5-Coder-1.5B](https://huggingface.co/onnx-community/Qwen2.5-Coder-1.5B-Instruct) (q4f16) | 36.1 tokens/sec | + + +## Installation + +### Chrome Web Store + +Work in progress. + +### From source + +You should install `node` and `pnpm` to build the project. + +First, install the dependencies: + +```bash +pnpm install +``` + +Then, start the development server: + +```bash +pnpm dev +``` + +Open your Chrome browser (i.e. `chrome://extensions`) and load the appropriate development build. For example, if you are developing for the chrome browser, using manifest v3, use: `build/chrome-mv3-dev`. + +For further guidance, [visit Plasmo's Documentation](https://docs.plasmo.com/) or create an issue. + +## Deployment + +### Making production build + +Run the following: + +```bash +pnpm build +``` + +This should create a production bundle for your extension, ready to be zipped and published to the stores. + +### Submit to the webstores + +The easiest way to deploy your Plasmo extension is to use the built-in [bpp](https://bpp.browser.market) GitHub action. Prior to using this action however, make sure to build your extension and upload the first version to the store to establish the basic credentials. Then, simply follow [this setup instruction](https://docs.plasmo.com/framework/workflows/submit) and you should be on your way for automated submission! + +## Debugging + +### Debug service worker + +Open `chrome://extensions` and find the "Inspect views" section for the extension. + +![Inspect views](./docs/inspect-views.jpg) + +### Memory usage for inference + +Open Chrome > More Tools > Task Manager. + +![Task manager](./docs/task-manager.jpg) + +### Local storage for cached checkpoints + +Run Chrome extension, open `inspect`, go to `Application` tab, find `Local Storage` section, and find the `transformers-cache` entry. + +![Local storage](./docs/local-storage.jpg) + +## References + +- [Transformers.js Example](https://github.com/huggingface/transformers.js-examples) +- [Transformers.js V2 Chrome Extension](https://github.com/huggingface/transformers.js/tree/main/examples/extension) +- [Plasmo Documentation](https://docs.plasmo.com/) +- [WebLLM](https://webllm.mlc.ai/) and its [Chrome Extension](https://github.com/mlc-ai/web-llm/tree/main/examples/chrome-extension-webgpu-service-worker) +- [gpu.cpp](https://github.com/AnswerDotAI/gpu.cpp) +- https://github.com/huggingface/transformers.js/issues/986 +- https://github.com/microsoft/onnxruntime/issues/20876 +- https://github.com/ggaabe/extension diff --git a/chrome-extension-plasmo/assets/icon.png b/chrome-extension-plasmo/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2e4f723d4b52fe94040900c61d0e4ccd0b4221f0 GIT binary patch literal 87478 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 literal 0 HcmV?d00001 diff --git a/chrome-extension-plasmo/components.json b/chrome-extension-plasmo/components.json new file mode 100644 index 00000000..61fcdd93 --- /dev/null +++ b/chrome-extension-plasmo/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "~/components", + "utils": "~/lib/utils", + "ui": "~/components/ui", + "lib": "~/lib", + "hooks": "~/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/chrome-extension-plasmo/components/ChangeModelForm.tsx b/chrome-extension-plasmo/components/ChangeModelForm.tsx new file mode 100644 index 00000000..4a0c7795 --- /dev/null +++ b/chrome-extension-plasmo/components/ChangeModelForm.tsx @@ -0,0 +1,76 @@ +import { useStorage } from "@plasmohq/storage/hook" + +import { DEFAULT_MODEL_CONFIG } from "~/llm/default-config" +import { modelList } from "~/llm/model-list" +import type { ModelConfig } from "~/src/types" + +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger +} from "./ui/accordion" +import { Alert, AlertDescription } from "./ui/alert" +import { Button } from "./ui/button" + +function ChangeModelForm() { + const [config, setConfig] = useStorage( + "model_config", + DEFAULT_MODEL_CONFIG + ) + const availableModels = modelList + + const handleChange = async (model: ModelConfig) => { + await setConfig(model) + alert("Model changed. Please refresh the page to apply the changes.") + chrome.runtime.reload() + } + + return ( +
+ + {availableModels.map((model) => ( + + {model.model_id} + + {config.model_id == model.model_id && ( + + + You're using this model {model.model_id}. + + + )} +
+ {JSON.stringify(model, null, 2)} +
+
+ + +
+
+
+ ))} +
+
+ ) +} + +export default ChangeModelForm diff --git a/chrome-extension-plasmo/components/Chat.tsx b/chrome-extension-plasmo/components/Chat.tsx new file mode 100644 index 00000000..000a17eb --- /dev/null +++ b/chrome-extension-plasmo/components/Chat.tsx @@ -0,0 +1,226 @@ +import { ArrowUp } from "lucide-react" +import { useCallback, useEffect, useRef, useState } from "react" + +import { useStorage } from "@plasmohq/storage/hook" + +import ChatExamples from "~/components/ChatExamples" +import ChatHeader from "~/components/ChatHeader" +import ChatMessages from "~/components/ChatMessages" +import ChatProgress from "~/components/ChatProgress" +import { Button } from "~/components/ui/button" +import { Input } from "~/components/ui/input" +import { DEFAULT_MODEL_CONFIG } from "~/llm/default-config" +import type { Message, ModelConfig, ProgressItem } from "~/src/types" + +function Chat() { + const [inputText, setInputText] = useState("") + const [messages, setMessages] = useState([]) + const messagesEndRef = useRef(null) + const [progressItems, setProgressItems] = useState([]) + + const [modelConfig, setModelConfig] = useStorage( + "model_config", + DEFAULT_MODEL_CONFIG + ) + + const [isLoading, setIsLoading] = useState(false) + + useEffect(() => { + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.status === "initiate") { + console.log("Model initiate:", message) + setProgressItems((prev) => [...prev, message.data]) + + setMessages((prev) => + prev.map((m) => { + if (m.content === "Thinking...") { + return { ...m, content: "Loading model..." } + } + return m + }) + ) + } else if (message.status === "progress") { + // Handle model progress + setProgressItems((prev) => + prev.map((item) => { + if (item.file === message.data.file) { + return { ...item, ...message.data } + } + return item + }) + ) + } else if (message.status === "done") { + // Handle model done + console.log("Model done:", message) + setProgressItems((prev) => { + const newItems = prev.filter( + (item) => item.file !== message.data.file + ) + if (newItems.length === 0) { + setMessages((prev) => + prev.map((m) => { + if (["Thinking...", "Loading model..."].includes(m.content)) { + return { ...m, content: "Thinking..." } + } + return m + }) + ) + } + return newItems + }) + } else if (message.status === "assistant") { + console.log("Assistant:", message) + setMessages((prev) => + prev.map((m) => { + if (["Thinking...", "Loading model..."].includes(m.content)) { + return { ...m, content: message.data.text } + } + return m + }) + ) + } else if (message.status === "update") { + setMessages((prev) => { + const response = message.data + const metadata = `${response.numTokens} tokens in ${response.latency.toFixed(0)} ms (${response.tps.toFixed(1)} tokens/sec)` + const last = prev[prev.length - 1] + const content = ["Thinking...", "Loading model..."].includes( + last.content + ) + ? response.output + : last.content + response.output + return [ + ...prev.slice(0, -1), + { + ...last, + content: content, + role: "assistant", + metadata + } + ] + }) + } + }) + }, []) + + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }) + }, [messages]) + + const handleInputChange = useCallback( + (event: React.ChangeEvent) => { + setInputText(event.target.value) + }, + [] + ) + + const handleSubmitOnText = (text: string) => { + setIsLoading(true) + + const promptMessages = messages + .map((m) => ({ + role: m.role, + content: m.content + })) + .concat([ + { + role: "user", + content: text + } + ]) + const message = { + action: "generate", + messages: promptMessages + } + + const pendingMessages = promptMessages.concat([ + { role: "assistant", content: "Thinking..." } + ]) + setMessages(pendingMessages) + setInputText("") + + chrome.runtime.sendMessage(message, (response) => { + setIsLoading(false) + }) + } + + const handleSubmit = useCallback(() => { + if (!inputText.trim()) return + if (isLoading) return + + handleSubmitOnText(inputText) + }, [inputText]) + + const handleKeyPress = useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "Enter") { + handleSubmit() + } + }, + [handleSubmit] + ) + + return ( +
+ {/* Fixed Header */} + { + setMessages([]) + setInputText("") + }} + hasChat={messages.length > 0} + /> + + {/* Fixed Progress Bar */} + {progressItems.length > 0 && ( + + )} + + {/* Scrollable Messages Container */} + {messages.length > 0 ? ( + + ) : ( + { + setInputText(example) + handleSubmitOnText(example) + }} + /> + )} + + {/* Fixed Footer */} +
+ + +
+
+ ) +} + +export default Chat diff --git a/chrome-extension-plasmo/components/ChatCopyButton.tsx b/chrome-extension-plasmo/components/ChatCopyButton.tsx new file mode 100644 index 00000000..34d721cd --- /dev/null +++ b/chrome-extension-plasmo/components/ChatCopyButton.tsx @@ -0,0 +1,27 @@ +import { Check, Copy } from "lucide-react" +import { useState } from "react" + +function ChatCopyButton({ text }: { text: string }) { + const [copied, setCopied] = useState(false) + + const handleCopy = async (text: string) => { + setCopied(true) + await navigator.clipboard.writeText(text) + setTimeout(() => setCopied(false), 1000) + } + + return ( + + ) +} + +export default ChatCopyButton diff --git a/chrome-extension-plasmo/components/ChatExamples.tsx b/chrome-extension-plasmo/components/ChatExamples.tsx new file mode 100644 index 00000000..27492200 --- /dev/null +++ b/chrome-extension-plasmo/components/ChatExamples.tsx @@ -0,0 +1,52 @@ +import { Terminal } from "lucide-react" +import { useState } from "react" + +import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert" + +function ChatExamples({ + onExampleClick +}: { + onExampleClick: (example: string) => void +}) { + const [examples, setExamples] = useState([ + "Give me some tips to improve my time management skills.", + "What is the difference between AI and ML?", + "Write python code to compute the nth fibonacci number." + ]) + + const handleExampleClick = (example: string) => { + onExampleClick(example) + } + + return ( +
+ + + Hello Local World! + + You can chat with large language models locally. No internet + connection needed. + + + {examples.map((example, index) => ( +
handleExampleClick(example)} + className="text-sm bg-blue-100 rounded-md p-2 cursor-pointer hover:bg-blue-200"> + {example} +
+ ))} +
+ ) +} + +export default ChatExamples diff --git a/chrome-extension-plasmo/components/ChatHeader.tsx b/chrome-extension-plasmo/components/ChatHeader.tsx new file mode 100644 index 00000000..5bf88ccd --- /dev/null +++ b/chrome-extension-plasmo/components/ChatHeader.tsx @@ -0,0 +1,210 @@ +import { + ArrowLeftRight, + Bot, + EllipsisVertical, + Eraser, + Github, + History, + Logs, + Milestone, + Pencil, + Power, + Settings2 +} from "lucide-react" +import React, { useEffect, useState } from "react" + +import { Button } from "~/components/ui/button" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger +} from "~/components/ui/dropdown-menu" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from "~/components/ui/tooltip" + +import ChangeModelForm from "./ChangeModelForm" +import GenerationConfigForm from "./GenerationConfigForm" +import ModelRegistryForm from "./ModelRegistryForm" +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger +} from "./ui/dialog" + +function ChatHeader({ + modelName, + onNewChat, + hasChat +}: { + modelName: string + onNewChat: () => void + hasChat: boolean +}) { + const [version, setVersion] = useState("0.0.0") + const [dialogMode, setDialogMode] = useState< + "generation_settings" | "change_model" | "model_registry" + >("generation_settings") + + useEffect(() => { + if (chrome?.runtime?.getManifest) { + const manifest = chrome.runtime.getManifest() + setVersion(manifest.version) + } + }, []) + + return ( +
+

+ Chat with{" "} + + {modelName.split("/")[1]} + +

+
+ + + + + + New Chat + + + + + + + + + Generation + + + { + event.preventDefault() + setDialogMode("generation_settings") + }}> + + Change Settings + + + Model + + { + chrome.runtime.reload() + }}> + + Restart Model + + + { + event.preventDefault() + setDialogMode("change_model") + }}> + + Change Model + + + + { + event.preventDefault() + setDialogMode("model_registry") + }}> + + Model Registry + + + Others + + + + Version {version} + + + window.open( + "https://github.com/tantara/transformers.js-chrome", + "_blank" + ) + }> + + Change Logs + + + window.open( + "https://github.com/tantara/transformers.js-chrome", + "_blank" + ) + }> + + Repository + + + + + {dialogMode === "generation_settings" && ( + + Generation Settings + + + + + )} + {dialogMode === "change_model" && ( + + Change Model + + + + + )} + {dialogMode === "model_registry" && ( + + Model Registry + + + + + )} + + +
+
+ ) +} + +export default ChatHeader diff --git a/chrome-extension-plasmo/components/ChatMessages.tsx b/chrome-extension-plasmo/components/ChatMessages.tsx new file mode 100644 index 00000000..ff34c855 --- /dev/null +++ b/chrome-extension-plasmo/components/ChatMessages.tsx @@ -0,0 +1,97 @@ +import DOMPurify from "dompurify" +import { marked } from "marked" + +import ChatCopyButton from "~/components/ChatCopyButton" +import { cn } from "~/lib/utils" +import type { Message } from "~/src/types" + +function ChatMessages({ + messages, + messagesEndRef +}: { + messages: Message[] + messagesEndRef: React.RefObject +}) { + const render = (text: string) => { + return DOMPurify.sanitize(marked.parse(text, { async: false })) + } + + return ( +
+ {messages.map((msg, index) => ( +
+
+
+

+ +

+
+ {msg.role === "assistant" && } +
+ {msg.metadata && ( +
+ {msg.metadata} +
+ )} +
+ ))} +
+
+ ) +} + +export default ChatMessages diff --git a/chrome-extension-plasmo/components/ChatProgress.tsx b/chrome-extension-plasmo/components/ChatProgress.tsx new file mode 100644 index 00000000..98e9daf9 --- /dev/null +++ b/chrome-extension-plasmo/components/ChatProgress.tsx @@ -0,0 +1,30 @@ +import { formatBytes } from "~/lib/formatter" +import type { ProgressItem } from "~/src/types" + +function Progress({ file, progress, total }) { + progress ??= 0 + return ( +
+
+ {file} ({progress.toFixed(2)}% + {isNaN(total) ? "" : ` of ${formatBytes(total)}`}) +
+
+ ) +} + +function ChatProgress({ progressItems }: { progressItems: ProgressItem[] }) { + return ( +
+
+ {progressItems.map((item) => ( + + ))} +
+
+ ) +} + +export default ChatProgress diff --git a/chrome-extension-plasmo/components/GenerationConfigForm.tsx b/chrome-extension-plasmo/components/GenerationConfigForm.tsx new file mode 100644 index 00000000..9f5cf142 --- /dev/null +++ b/chrome-extension-plasmo/components/GenerationConfigForm.tsx @@ -0,0 +1,139 @@ +import type { GenerationConfig } from "@huggingface/transformers/types/generation/configuration_utils" +import { useState } from "react" + +import { useStorage } from "@plasmohq/storage/hook" + +import { DEFAULT_GENERATION_CONFIG } from "~/llm/default-config" + +import { Alert, AlertDescription } from "./ui/alert" +import { Input } from "./ui/input" +import { Label } from "./ui/label" +import { Switch } from "./ui/switch" + +function GenerationConfigForm() { + const [config, setConfig] = useStorage( + "generation_config", + DEFAULT_GENERATION_CONFIG + ) + const [updated, setUpdated] = useState(false) + + const handleChange = async ( + field: keyof GenerationConfig, + value: number | boolean + ) => { + await setConfig({ + ...config, + [field]: value + }) + setUpdated(true) + } + + return ( +
+
+ + handleChange("do_sample", checked)} + /> +
+ +
+ + handleChange("top_k", Number(e.target.value))} + className="max-w-24" + /> +
+ +
+ + handleChange("temperature", Number(e.target.value))} + className="max-w-24" + /> +
+ +
+ + handleChange("top_p", Number(e.target.value))} + className="max-w-24" + /> +
+ +
+ + + handleChange("max_new_tokens", Number(e.target.value)) + } + className="max-w-24" + /> +
+ +
+ + + handleChange("repetition_penalty", Number(e.target.value)) + } + className="max-w-24" + /> +
+ + {updated && ( + + + Generation config updated. Please send a message to see the changes. + + + )} +
+ ) +} + +export default GenerationConfigForm diff --git a/chrome-extension-plasmo/components/ModelRegistryForm.tsx b/chrome-extension-plasmo/components/ModelRegistryForm.tsx new file mode 100644 index 00000000..bb77fd03 --- /dev/null +++ b/chrome-extension-plasmo/components/ModelRegistryForm.tsx @@ -0,0 +1,88 @@ +import { TrashIcon } from "lucide-react" +import { useEffect, useState } from "react" + +import { formatBytes } from "~/lib/formatter" + +import { Badge } from "./ui/badge" +import { Button } from "./ui/button" +import { ScrollArea } from "./ui/scroll-area" +import { Separator } from "./ui/separator" + +function ModelRegistryForm() { + const targetCacheName = "transformers-cache" + const listCacheStorage = async (targetCacheName: string) => { + try { + const cacheNames = await caches.keys() + + for (const cacheName of cacheNames) { + const cache = await caches.open(cacheName) + const requests = await cache.keys() + console.log(`Cache: ${cacheName}`) + + if (cacheName === targetCacheName) { + const cacheDetails = await Promise.all( + requests.map(async (request) => { + const response = await cache.match(request) + const blob = await response.blob() + return { + url: request.url, + size: blob.size, + sizeFormatted: formatBytes(blob.size) + } + }) + ) + return cacheDetails + } + } + + return [] + } catch (error) { + console.error("Error accessing cache:", error) + } + } + + const [cachedFiles, setCachedFiles] = useState< + { url: string; size: number; sizeFormatted: string }[] + >([]) + + useEffect(() => { + listCacheStorage(targetCacheName).then((requests) => + setCachedFiles(requests) + ) + }, []) + + const handleDelete = async (url: string) => { + const cache = await caches.open(targetCacheName) + await cache.delete(url) + setCachedFiles((prev) => prev.filter((file) => file.url !== url)) + } + + return ( + +

+ {cachedFiles.length} files cached.{" "} + {formatBytes(cachedFiles.reduce((acc, file) => acc + file.size, 0))} in + total. +

+ +
+ {cachedFiles.map((file) => ( + <> +
+ {file.url} {file.sizeFormatted}{" "} + +
+ + + ))} +
+
+ ) +} + +export default ModelRegistryForm diff --git a/chrome-extension-plasmo/components/ui/accordion.tsx b/chrome-extension-plasmo/components/ui/accordion.tsx new file mode 100644 index 00000000..d718c907 --- /dev/null +++ b/chrome-extension-plasmo/components/ui/accordion.tsx @@ -0,0 +1,55 @@ +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDown } from "lucide-react" + +import { cn } from "~/lib/utils" + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)) +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/chrome-extension-plasmo/components/ui/alert.tsx b/chrome-extension-plasmo/components/ui/alert.tsx new file mode 100644 index 00000000..6c72a38b --- /dev/null +++ b/chrome-extension-plasmo/components/ui/alert.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "~/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)) +Alert.displayName = "Alert" + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertTitle.displayName = "AlertTitle" + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertDescription.displayName = "AlertDescription" + +export { Alert, AlertTitle, AlertDescription } diff --git a/chrome-extension-plasmo/components/ui/badge.tsx b/chrome-extension-plasmo/components/ui/badge.tsx new file mode 100644 index 00000000..5e2b7aca --- /dev/null +++ b/chrome-extension-plasmo/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "~/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/chrome-extension-plasmo/components/ui/breadcrumb.tsx b/chrome-extension-plasmo/components/ui/breadcrumb.tsx new file mode 100644 index 00000000..2ca8b012 --- /dev/null +++ b/chrome-extension-plasmo/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "~/lib/utils" + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode + } +>(({ ...props }, ref) =>