├── .github └── workflows │ └── build-and-lint.yml ├── .gitignore ├── .prettierrc ├── ATTRIBUTION.md ├── LICENSE ├── README.md ├── SECURITY.md ├── assets └── demo.mp4 ├── docs ├── next.config.mjs ├── package-lock.json ├── package.json ├── pages │ ├── _app.jsx │ ├── _meta.jsx │ ├── advanced │ │ ├── _meta.jsx │ │ ├── database_options.mdx │ │ ├── speech_recognition_options.mdx │ │ ├── structured_generation.mdx │ │ ├── text_generation_options.mdx │ │ ├── text_to_speech_options.mdx │ │ └── web_worker.mdx │ ├── api_reference │ │ ├── _meta.jsx │ │ ├── browserai_class.mdx │ │ ├── database.mdx │ │ ├── error_handling.mdx │ │ ├── events.mdx │ │ ├── generate_text.mdx │ │ ├── start_recording.mdx │ │ ├── stop_recording.mdx │ │ ├── text_to_speech.mdx │ │ └── transcribe_audio.mdx │ ├── contributing.mdx │ ├── demo │ │ ├── _meta.jsx │ │ ├── audio_demo.mdx │ │ └── text_demo.mdx │ ├── feature_requests.mdx │ ├── getting_started │ │ ├── _meta.jsx │ │ ├── core_features_and_usage.mdx │ │ └── installation.mdx │ ├── index.mdx │ ├── supported_models.mdx │ └── troubleshooting.mdx └── theme.config.jsx ├── eslint.config.js ├── eslintrc.config.js ├── examples ├── WIP-browser-agent-demo │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── components │ │ │ ├── AgentChat.css │ │ │ ├── AgentChat.tsx │ │ │ ├── BrowserView.css │ │ │ └── BrowserView.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tailwind.config.js │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── audio-demo │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ │ ├── _headers │ │ ├── _routes.json │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── components │ │ │ └── ChatInterface.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── chat-demo │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── _headers │ │ ├── _routes.json │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ ├── Browserai-logo.png │ │ │ └── react.svg │ │ ├── components │ │ │ ├── ChatInterface.tsx │ │ │ ├── EnhancedChatInterface.tsx │ │ │ ├── MessageContent.tsx │ │ │ └── MessageFormatting │ │ │ │ ├── CodeBlock.tsx │ │ │ │ ├── Latex.tsx │ │ │ │ └── index.ts │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tailwind.config.js │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── database-demos │ └── indexeddb-demo │ │ ├── .gitignore │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ └── vite.svg │ │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── components │ │ │ ├── DatabaseDemo.css │ │ │ └── DatabaseDemo.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ ├── types.ts │ │ └── vite-env.d.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts ├── realtime-chat-demo │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── _headers │ │ ├── _routes.json │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── components │ │ │ ├── chat-message.tsx │ │ │ └── info-banner.tsx │ │ ├── index.css │ │ ├── lib │ │ │ └── utils.ts │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tailwind.config.js │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── schema-llm │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── examples.ts │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── tts-demo │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts └── voice-demo │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ └── vite.svg │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── index.css │ ├── main.tsx │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── extensions └── chrome │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── background.js │ ├── content-script.css │ ├── content-script.js │ ├── icons │ │ ├── icon128.png │ │ ├── icon16.png │ │ ├── icon32.png │ │ └── icon64.png │ ├── manifest.json │ ├── sidepanel.html │ └── vite.svg │ ├── sidepanel.html │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── components │ │ ├── HTMLCleanerTest.tsx │ │ ├── Header.tsx │ │ └── ui │ │ │ ├── accordion.tsx │ │ │ ├── alert-dialog.tsx │ │ │ ├── alert.tsx │ │ │ ├── aspect-ratio.tsx │ │ │ ├── avatar.tsx │ │ │ ├── badge.tsx │ │ │ ├── breadcrumb.tsx │ │ │ ├── button.tsx │ │ │ ├── card.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── collapsible.tsx │ │ │ ├── command.tsx │ │ │ ├── context-menu.tsx │ │ │ ├── dialog.tsx │ │ │ ├── drawer.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── form.tsx │ │ │ ├── hover-card.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── menubar.tsx │ │ │ ├── navigation-menu.tsx │ │ │ ├── pagination.tsx │ │ │ ├── popover.tsx │ │ │ ├── progress.tsx │ │ │ ├── radio-group.tsx │ │ │ ├── resizable.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── select.tsx │ │ │ ├── separator.tsx │ │ │ ├── sheet.tsx │ │ │ ├── sidebar.tsx │ │ │ ├── skeleton.tsx │ │ │ ├── slider.tsx │ │ │ ├── switch.tsx │ │ │ ├── table.tsx │ │ │ ├── tabs.tsx │ │ │ ├── textarea.tsx │ │ │ ├── toast.tsx │ │ │ ├── toaster.tsx │ │ │ ├── toggle-group.tsx │ │ │ ├── toggle.tsx │ │ │ ├── tooltip.tsx │ │ │ ├── use-mobile.tsx │ │ │ └── use-toast.ts │ ├── core │ │ ├── browser-actions-api.ts │ │ └── browser-actions.ts │ ├── helpers │ │ └── executors.tsx │ ├── hooks │ │ ├── use-mobile.tsx │ │ └── use-toast.ts │ ├── index.css │ ├── lib │ │ └── utils.ts │ ├── main.tsx │ ├── popup │ │ ├── chat-interface.tsx │ │ ├── header.tsx │ │ ├── navigation.tsx │ │ ├── popup.tsx │ │ ├── workflow-list.tsx │ │ └── workflow-view.tsx │ ├── sidepanel.tsx │ ├── sidepanel │ │ ├── content-identifier-test.tsx │ │ └── workflow-runner.tsx │ └── vite-env.d.ts │ ├── tailwind.config.js │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── package.json ├── src ├── config │ └── models │ │ ├── mlc-models.json │ │ ├── transformers-models.json │ │ └── types.ts ├── core │ ├── agent │ │ ├── browser-actions.ts │ │ ├── browser-agent.ts │ │ ├── content-identifier.ts │ │ ├── dom-analyzer.ts │ │ ├── html-cleaner.test.ts │ │ ├── html-cleaner.ts │ │ ├── index.ts │ │ └── types.ts │ ├── common │ │ └── grammar.ts │ ├── database │ │ ├── implementation │ │ │ ├── indexeddb.ts │ │ │ └── sqlite.ts │ │ ├── index.ts │ │ ├── storage.ts │ │ ├── types.ts │ │ └── vectorstore.ts │ ├── llm │ │ └── index.ts │ └── parsers │ │ ├── csv.ts │ │ ├── docx.ts │ │ ├── image.ts │ │ └── pdf.ts ├── engines │ ├── mlc-engine-wrapper.ts │ ├── transformer-engine-wrapper.ts │ └── tts-engine.ts ├── index.ts ├── libs │ └── transformers │ │ ├── Huggingface-LICENSE │ │ ├── backends │ │ ├── onnx.ts │ │ └── ort-wasm-simd-threaded.jsep.wasm │ │ ├── base │ │ ├── feature_extraction_utils.ts │ │ ├── image_processors_utils.ts │ │ └── processing_utils.ts │ │ ├── configs.ts │ │ ├── env.ts │ │ ├── generation │ │ ├── configuration_utils.ts │ │ ├── logits_process.ts │ │ ├── logits_sampler.ts │ │ ├── parameters.ts │ │ ├── stopping_criteria.ts │ │ └── streamers.ts │ │ ├── models.ts │ │ ├── models │ │ ├── audio_spectrogram_transformer │ │ │ └── feature_extraction_audio_spectrogram_transformer.ts │ │ ├── auto │ │ │ ├── feature_extraction_auto.ts │ │ │ ├── image_processing_auto.ts │ │ │ └── processing_auto.ts │ │ ├── bit │ │ │ └── image_processing_bit.ts │ │ ├── chinese_clip │ │ │ └── image_processing_chinese_clip.ts │ │ ├── clap │ │ │ └── feature_extraction_clap.ts │ │ ├── clip │ │ │ └── image_processing_clip.ts │ │ ├── convnext │ │ │ └── image_processing_convnext.ts │ │ ├── deit │ │ │ └── image_processing_deit.ts │ │ ├── donut │ │ │ └── image_processing_donut.ts │ │ ├── feature_extractors.ts │ │ ├── florence2 │ │ │ └── processing_florence2.ts │ │ ├── idefics3 │ │ │ ├── image_processing_idefics3.ts │ │ │ └── processing_idefics3.ts │ │ ├── image_processors.ts │ │ ├── janus │ │ │ ├── image_processing_janus.ts │ │ │ └── processing_janus.ts │ │ ├── jina_clip │ │ │ ├── image_processing_jina_clip.ts │ │ │ └── processing_jina_clip.ts │ │ ├── llava_onevision │ │ │ └── image_processing_llava_onevision.ts │ │ ├── mgp_str │ │ │ └── processing_mgp_str.ts │ │ ├── moonshine │ │ │ ├── feature_extraction_moonshine.ts │ │ │ └── processing_moonshine.ts │ │ ├── paligemma │ │ │ └── processing_paligemma.ts │ │ ├── phi3_v │ │ │ ├── image_processing_phi3_v.ts │ │ │ └── processing_phi3_v.ts │ │ ├── processors.ts │ │ ├── pyannote │ │ │ ├── feature_extraction_pyannote.ts │ │ │ └── processing_pyannote.ts │ │ ├── qwen2_vl │ │ │ ├── image_processing_qwen2_vl.ts │ │ │ └── processing_qwen2_vl.ts │ │ ├── sam │ │ │ ├── image_processing_sam.ts │ │ │ └── processing_sam.ts │ │ ├── seamless_m4t │ │ │ └── feature_extraction_seamless_m4t.ts │ │ ├── siglip │ │ │ └── image_processing_siglip.ts │ │ ├── speecht5 │ │ │ ├── feature_extraction_speecht5.ts │ │ │ └── processing_speecht5.ts │ │ ├── swin2sr │ │ │ └── image_processing_swin2sr.ts │ │ ├── vitmatte │ │ │ └── image_processing_vitmatte.ts │ │ ├── vitpose │ │ │ └── image_processing_vitpose.ts │ │ ├── wav2vec2 │ │ │ ├── feature_extraction_wav2vec2.ts │ │ │ └── processing_wav2vec2.ts │ │ ├── wespeaker │ │ │ └── feature_extraction_wespeaker.ts │ │ └── whisper │ │ │ ├── common_whisper.ts │ │ │ ├── feature_extraction_whisper.ts │ │ │ ├── generation_whisper.ts │ │ │ └── processing_whisper.ts │ │ ├── ops │ │ └── registry.ts │ │ ├── pipelines.ts │ │ ├── tokenizers.ts │ │ ├── transformers.ts │ │ ├── types.ts │ │ └── utils │ │ ├── audio.ts │ │ ├── constants.d.ts │ │ ├── constants.ts │ │ ├── core.ts │ │ ├── data-structures.ts │ │ ├── devices.ts │ │ ├── dtypes.ts │ │ ├── generic.ts │ │ ├── hub.ts │ │ ├── image.ts │ │ ├── maths.ts │ │ ├── phonemize.ts │ │ ├── pipelines.ts │ │ ├── tensor.ts │ │ └── voices.ts └── types │ ├── backends.d.ts │ ├── base.d.ts │ ├── generation.d.ts │ ├── models.d.ts │ ├── ops.d.ts │ └── utils.d.ts ├── tsconfig.json ├── tsup.config.ts ├── vite.config.js └── vite.config.ts /.github/workflows/build-and-lint.yml: -------------------------------------------------------------------------------- 1 | name: Build and Lint 2 | 3 | on: 4 | push: 5 | branches: [ '**' ] # Runs on all branches 6 | pull_request: 7 | branches: [ '**' ] # Runs on PRs targeting any branch 8 | 9 | jobs: 10 | build-and-lint: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [18.x, 20.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | 25 | # Main project build and lint 26 | - name: Install main dependencies 27 | run: npm install 28 | 29 | - name: Run tests 30 | run: npm run test 31 | 32 | - name: Build main project 33 | run: npm run build 34 | 35 | # Need to fix linting issues first 36 | # - name: Lint main project 37 | # run: npm run lint 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | .pnp 4 | .pnp.js 5 | 6 | # Production 7 | dist/ 8 | build/ 9 | 10 | # Testing 11 | coverage/ 12 | 13 | # IDE 14 | .vscode/ 15 | .idea/ 16 | *.swp 17 | *.swo 18 | 19 | # Misc 20 | .DS_Store 21 | .env 22 | .env.local 23 | .env.development.local 24 | .env.test.local 25 | .env.production.local 26 | 27 | # Logs 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | 32 | # Cache 33 | .cache/ 34 | .npm/ 35 | 36 | # Docs 37 | .next 38 | out 39 | 40 | # Build 41 | .next 42 | out 43 | *package-lock.json 44 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "printWidth": 120, 6 | "tabWidth": 2 7 | } -------------------------------------------------------------------------------- /ATTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # Attribution Notice 2 | 3 | This project incorporates code and functionality from the following sources: 4 | 5 | ## Transformers.js 6 | - **Source**: [Transformers.js](https://github.com/xenova/transformers.js) 7 | - **Author**: Xenova 8 | - **License**: Apache License 2.0 9 | - **Usage**: We utilize Transformers.js for running machine learning models in the browser. The original code has been modified to work in a browser environment and converted to TypeScript. 10 | 11 | ## Hugging Face 12 | - **Source**: [Hugging Face](https://huggingface.co/) 13 | - **License**: Apache License 2.0 14 | - **Usage**: We use models and technologies from Hugging Face's ecosystem through Transformers.js. 15 | 16 | Both Transformers.js and Hugging Face's components are licensed under the Apache License 2.0, which is included in this directory as `Huggingface-LICENSE`. We gratefully acknowledge these projects and their contributions to the open-source community. 17 | 18 | For full terms and conditions, please refer to the Apache License 2.0 in the accompanying `Huggingface-LICENSE` file. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Cloud Code AI Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /assets/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/assets/demo.mp4 -------------------------------------------------------------------------------- /docs/next.config.mjs: -------------------------------------------------------------------------------- 1 | import nextra from 'nextra' 2 | 3 | const withNextra = nextra({ 4 | defaultShowCopyCode: true, 5 | staticImage: true, 6 | theme: 'nextra-theme-docs' 7 | }) 8 | 9 | // Add Cloudflare Pages specific configuration 10 | export default withNextra({ 11 | output: 'export', 12 | images: { 13 | unoptimized: true 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "next": "^14.2.26", 4 | "nextra": "^3.3.1", 5 | "nextra-theme-docs": "^3.3.1", 6 | "react": "^18.2.0", 7 | "react-dom": "^18.2.0" 8 | }, 9 | "optionalDependencies": { 10 | "@napi-rs/simple-git-darwin-arm64": "latest", 11 | "@napi-rs/simple-git-linux-x64-gnu": "latest" 12 | }, 13 | "scripts": { 14 | "dev": "next", 15 | "build": "next build", 16 | "start": "next start" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/pages/_app.jsx: -------------------------------------------------------------------------------- 1 | export default function App({ Component, pageProps }) { 2 | return 3 | } -------------------------------------------------------------------------------- /docs/pages/_meta.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | "index": "Welcome to BrowserAI", 3 | "getting_started": "Getting Started", 4 | "supported_models": "Supported Models", 5 | "advanced": "Advanced", 6 | "api_reference": "API Reference", 7 | "demo": "Demo", 8 | "troubleshooting": "Troubleshooting", 9 | "contributing": "Contributing", 10 | "feature_requests": "Feature Requests" 11 | } -------------------------------------------------------------------------------- /docs/pages/advanced/_meta.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | "text_generation_options": "Text Generation Options", 3 | "structured_generation": "Structured Generation", 4 | "web_worker": "Web Worker Support", 5 | "speech_recognition_options": "Speech Recognition Options", 6 | "text_to_speech_options": "Text to Speech Options" 7 | } -------------------------------------------------------------------------------- /docs/pages/advanced/web_worker.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Web Worker Support' 3 | description: 'Guide for using web workers with BrowserAI' 4 | --- 5 | 6 | # Web Worker Support 7 | 8 | Run model inference in a separate thread for better performance. 9 | 10 | ## Enabling Web Workers 11 | 12 | ```javascript copy 13 | const response = await browserAI.generateText('Hello', { 14 | useWorker: true 15 | }); 16 | ``` 17 | 18 | ## Benefits 19 | - Non-blocking UI 20 | - Parallel processing 21 | - Better resource utilization 22 | 23 | ## Worker Status Monitoring 24 | 25 | ```javascript copy 26 | browserAI.on('workerStatus', (status) => { 27 | console.log('Worker status:', status); 28 | }); 29 | ``` 30 | 31 | export const metadata = { 32 | title: 'Web Worker Support', 33 | description: 'Guide for using web workers with BrowserAI' 34 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/_meta.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | "browserai_class": "BrowserAI Class", 3 | "generate_text": "Generate Text", 4 | "start_recording": "Start Recording", 5 | "stop_recording": "Stop Recording", 6 | "transcribe_audio": "Transcribe Audio", 7 | "text_to_speech": "Text to Speech", 8 | "database": "Database", 9 | "error_handling": "Error Handling", 10 | "events": "Events" 11 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/browserai_class.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'BrowserAI Class Reference' 3 | description: 'Documentation for the main BrowserAI class and its core methods' 4 | --- 5 | 6 | # BrowserAI Class 7 | 8 | The main class that provides access to all AI capabilities. 9 | 10 | ## Constructor 11 | 12 | ```javascript copy 13 | const browserAI = new BrowserAI(); 14 | ``` 15 | 16 | Creates a new instance of the BrowserAI class. No parameters required. 17 | 18 | ## loadModel(modelIdentifier: string, options?: ModelOptions) 19 | 20 | Loads an AI model for use. 21 | 22 | ```javascript copy 23 | await browserAI.loadModel('smollm2-135m-instruct', { 24 | quantization: 'q4f16_1', 25 | onProgress: (progress) => console.log(`Loading: ${progress.progress}%`) 26 | }); 27 | ``` 28 | 29 | ### Parameters 30 | 31 | | Parameter | Type | Required | Description | 32 | |-----------|------|----------|-------------| 33 | | modelIdentifier | string | Yes | Name of the model to load | 34 | | options | ModelOptions | No | Configuration options | 35 | 36 | ### ModelOptions 37 | 38 | | Option | Type | Default | Description | 39 | |--------|------|---------|-------------| 40 | | quantization | string | 'q4f16_1' | Model quantization level | 41 | | onProgress | function | - | Progress callback | 42 | | onComplete | function | - | Completion callback | 43 | | onError | function | - | Error callback | 44 | 45 | ### Returns 46 | `Promise` 47 | 48 | export const metadata = { 49 | title: 'BrowserAI Class Reference', 50 | description: 'Documentation for the main BrowserAI class and its core methods' 51 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/error_handling.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Error Handling' 3 | description: 'Documentation for handling errors in BrowserAI operations' 4 | --- 5 | 6 | # Error Handling 7 | 8 | All methods can throw errors that should be handled. 9 | 10 | ```javascript copy 11 | try { 12 | await browserAI.loadModel('smollm2-135m-instruct'); 13 | } catch (error) { 14 | console.error('Error:', error.message); 15 | } 16 | ``` 17 | 18 | ## Common Error Types 19 | 20 | | Error Type | Description | 21 | |------------|-------------| 22 | | ModelLoadError | Failed to load model | 23 | | GenerationError | Text generation failed | 24 | | AudioError | Audio processing failed | 25 | | TranscriptionError | Speech recognition failed | 26 | 27 | ### Best Practices 28 | 29 | It's recommended to wrap all BrowserAI operations in try-catch blocks to handle potential errors gracefully. You can also use the `onError` callback in configuration options for specific error handling: 30 | 31 | ```javascript copy 32 | await browserAI.loadModel('smollm2-135m-instruct', { 33 | onError: (error) => { 34 | console.error('Model loading failed:', error.message); 35 | // Handle error appropriately 36 | } 37 | }); 38 | ``` 39 | 40 | export const metadata = { 41 | title: 'Error Handling', 42 | description: 'Documentation for handling errors in BrowserAI operations' 43 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/events.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Events' 3 | description: 'Documentation for event handling and callbacks in BrowserAI' 4 | --- 5 | 6 | # Events 7 | 8 | The BrowserAI instance emits events you can listen to: 9 | 10 | ```javascript copy 11 | browserAI.on('modelLoaded', (modelInfo) => { 12 | console.log(`Model ${modelInfo.name} loaded successfully`); 13 | }); 14 | 15 | browserAI.on('error', (error) => { 16 | console.error('An error occurred:', error); 17 | }); 18 | ``` 19 | 20 | ## Available Events 21 | 22 | | Event | Description | 23 | |-------|-------------| 24 | | modelLoaded | Triggered when a model is successfully loaded | 25 | | modelUnloaded | Triggered when a model is unloaded | 26 | | error | Triggered when an error occurs | 27 | | progress | Triggered during loading operations with progress updates | 28 | 29 | ### Example Usage 30 | 31 | ```javascript copy 32 | // Listen for loading progress 33 | browserAI.on('progress', (progress) => { 34 | console.log(`Loading progress: ${progress.progress}%`); 35 | }); 36 | 37 | // Handle model loading completion 38 | browserAI.on('modelLoaded', (modelInfo) => { 39 | console.log(`Model ${modelInfo.name} is ready to use`); 40 | }); 41 | 42 | // Global error handling 43 | browserAI.on('error', (error) => { 44 | console.error('BrowserAI error:', error.message); 45 | }); 46 | ``` 47 | 48 | export const metadata = { 49 | title: 'Events', 50 | description: 'Documentation for event handling and callbacks in BrowserAI' 51 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/start_recording.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Audio Recording' 3 | description: 'Documentation for starting audio recording in BrowserAI' 4 | --- 5 | 6 | # Start Recording 7 | 8 | ## startRecording(options?: RecordingOptions) 9 | 10 | Starts audio recording for speech recognition. 11 | 12 | ```javascript copy 13 | await browserAI.startRecording({ 14 | sampleRate: 16000, 15 | channels: 1 16 | }); 17 | ``` 18 | 19 | ### Parameters 20 | 21 | | Parameter | Type | Required | Description | 22 | |-----------|------|----------|-------------| 23 | | options | RecordingOptions | No | Recording configuration | 24 | 25 | ### RecordingOptions 26 | 27 | | Option | Type | Default | Description | 28 | |--------|------|---------|-------------| 29 | | sampleRate | number | 16000 | Audio sample rate | 30 | | channels | number | 1 | Number of channels | 31 | 32 | ### Returns 33 | `Promise` 34 | 35 | export const metadata = { 36 | title: 'Audio Recording', 37 | description: 'Documentation for audio recording functionality in BrowserAI' 38 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/stop_recording.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Stop Recording' 3 | description: 'Documentation for stopping audio recording in BrowserAI' 4 | --- 5 | 6 | # Stop Recording 7 | 8 | ## stopRecording() 9 | 10 | Stops the current recording and returns the audio data. 11 | 12 | ```javascript copy 13 | const audioBlob = await browserAI.stopRecording(); 14 | ``` 15 | 16 | ### Returns 17 | `Promise` 18 | 19 | The returned Blob contains the recorded audio data that can be used for transcription or other audio processing. 20 | 21 | export const metadata = { 22 | title: 'Stop Recording', 23 | description: 'Documentation for stopping audio recording in BrowserAI' 24 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/text_to_speech.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Text-to-Speech' 3 | description: 'Documentation for text-to-speech conversion capabilities' 4 | --- 5 | 6 | # Text-to-Speech 7 | 8 | ## textToSpeech(text: string, options?: TTSOptions) 9 | 10 | Converts text to speech. 11 | 12 | ```javascript copy 13 | const audioBuffer = await browserAI.textToSpeech('Hello world', { 14 | voice: 'female_a', 15 | speed: 1.0 16 | }); 17 | ``` 18 | 19 | ### Parameters 20 | 21 | | Parameter | Type | Required | Description | 22 | |-----------|------|----------|-------------| 23 | | text | string | Yes | Text to convert | 24 | | options | TTSOptions | No | TTS settings | 25 | 26 | ### TTSOptions 27 | 28 | | Option | Type | Default | Description | 29 | |--------|------|---------|-------------| 30 | | voice | string | 'female_a' | Voice selection | 31 | | speed | number | 1.0 | Speech rate | 32 | | pitch | number | 1.0 | Voice pitch | 33 | | quality | string | 'medium' | Audio quality | 34 | 35 | ### Returns 36 | `Promise` 37 | 38 | export const metadata = { 39 | title: 'Text-to-Speech', 40 | description: 'Documentation for text-to-speech conversion capabilities' 41 | } -------------------------------------------------------------------------------- /docs/pages/api_reference/transcribe_audio.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Transcribe Audio' 3 | description: 'Documentation for audio transcription capabilities' 4 | --- 5 | 6 | # Transcribe Audio 7 | 8 | ## transcribeAudio(audio: Blob | Float32Array, options?: TranscriptionOptions) 9 | 10 | Transcribes audio to text. 11 | 12 | ```javascript copy 13 | const transcription = await browserAI.transcribeAudio(audioBlob, { 14 | return_timestamps: true, 15 | language: 'en' 16 | }); 17 | ``` 18 | 19 | ### Parameters 20 | 21 | | Parameter | Type | Required | Description | 22 | |-----------|------|----------|-------------| 23 | | audio | Blob\|Float32Array | Yes | Audio data | 24 | | options | TranscriptionOptions | No | Transcription settings | 25 | 26 | ### TranscriptionOptions 27 | 28 | | Option | Type | Default | Description | 29 | |--------|------|---------|-------------| 30 | | return_timestamps | boolean | false | Include word timing | 31 | | language | string | 'en' | Target language | 32 | | chunk_length_s | number | 30 | Chunk size in seconds | 33 | 34 | ### Returns 35 | `Promise` 36 | 37 | export const metadata = { 38 | title: 'Transcribe Audio', 39 | description: 'Documentation for audio transcription capabilities' 40 | } -------------------------------------------------------------------------------- /docs/pages/demo/_meta.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | "audio_demo": "Audio Demo", 3 | "text_demo": "Text Demo" 4 | } -------------------------------------------------------------------------------- /docs/pages/demo/audio_demo.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Audio Demo' 3 | description: 'Interactive demonstration of BrowserAI speech and conversation capabilities' 4 | --- 5 | 6 | # Audio Demo 7 | 8 | Experience the full power of BrowserAI's speech capabilities in this interactive demo. 9 | 10 | [See it in action here](https://voice-demo.browserai.dev/) 11 | 12 | ## What You Can Do 13 | 14 | ### 🗣️ Voice Conversations 15 | - Speak naturally to the AI 16 | - Get real-time transcriptions 17 | - Hear AI responses in natural speech 18 | 19 | ### 💬 Text Chat 20 | - Type messages if you prefer 21 | - Switch between voice and text 22 | - See your conversation history 23 | 24 | ### 🎯 Key Features 25 | - Real-time voice recognition 26 | - Natural text-to-speech responses 27 | - Seamless conversation flow 28 | - Multi-modal interaction 29 | 30 | ## How to Use 31 | 32 | ### Start a Voice Chat 33 | 1. Click the microphone icon 34 | 2. Speak your message 35 | 3. Listen to AI's response 36 | 37 | ### Text Chat 38 | 1. Type in the message box 39 | 2. Press enter or click send 40 | 3. Click the speaker icon to hear responses 41 | 42 | ## Demo Settings 43 | 44 | Customize your experience: 45 | - Choose different AI voices 46 | - Adjust speech speed 47 | - Toggle between models 48 | - Control response length 49 | 50 | ## Tips 51 | 52 | - Use Chrome/Edge Canary for best performance 53 | - Speak clearly for better recognition 54 | - Try both voice and text for different experiences 55 | 56 | export const metadata = { 57 | title: 'Audio Demo', 58 | description: 'Interactive demonstration of BrowserAI speech and conversation capabilities' 59 | } -------------------------------------------------------------------------------- /docs/pages/demo/text_demo.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Chat Demo' 3 | description: 'Interactive demonstration of BrowserAI natural language capabilities' 4 | --- 5 | 6 | # Chat Demo 7 | 8 | A streamlined demo showcasing BrowserAI's natural language capabilities. 9 | 10 | [See it in action here](https://chat.browserai.dev/) 11 | 12 | ## What You Can Do 13 | 14 | ### 💭 Natural Conversations 15 | - Chat with AI naturally 16 | - Get thoughtful responses 17 | - Maintain context in conversations 18 | 19 | ### 🎯 Key Features 20 | - Real-time responses 21 | - Context awareness 22 | - Memory of conversation 23 | - Clean, intuitive interface 24 | 25 | ## How to Use 26 | 27 | ### Start Chatting 28 | 1. Type your message 29 | 2. Get instant responses 30 | 3. Continue the conversation naturally 31 | 32 | ### Try Different Topics 33 | - Ask questions 34 | - Request explanations 35 | - Creative writing 36 | - Problem solving 37 | 38 | ## Demo Settings 39 | 40 | Customize the experience: 41 | - Switch between models 42 | - Adjust response length 43 | - Control AI creativity 44 | - Change chat themes 45 | 46 | ## Tips 47 | 48 | - Start with simple questions 49 | - Build on previous responses 50 | - Try different conversation styles 51 | - Experiment with different models 52 | 53 | export const metadata = { 54 | title: 'Chat Demo', 55 | description: 'Interactive demonstration of BrowserAI natural language capabilities' 56 | } -------------------------------------------------------------------------------- /docs/pages/getting_started/_meta.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | "installation": "Installation", 3 | "core_features_and_usage": "Core Features & Usage" 4 | } -------------------------------------------------------------------------------- /docs/pages/getting_started/installation.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Installation' 3 | description: 'Getting started with BrowserAI installation and setup' 4 | --- 5 | 6 | # Installation 7 | 8 | Getting started with BrowserAI is quick and easy! Choose your preferred package manager to install: 9 | 10 | ## Using NPM 11 | 12 | ```bash copy 13 | npm install @browserai/browserai 14 | ``` 15 | 16 | ## Using Yarn 17 | 18 | ```bash copy 19 | yarn add @browserai/browserai 20 | ``` 21 | 22 | ## Quick Start 23 | 24 | Once installed, you can import BrowserAI into your project: 25 | 26 | ```javascript copy 27 | import { BrowserAI } from '@browserai/browserai'; 28 | ``` 29 | 30 | ## Basic Example 31 | 32 | Here's a simple example to get you up and running in seconds: 33 | 34 | ```javascript copy 35 | // Initialize BrowserAI 36 | const browserAI = new BrowserAI(); 37 | 38 | // Load a model and generate text 39 | async function quickStart() { 40 | // Load a small, efficient model 41 | await browserAI.loadModel('llama-3.2-1b-instruct'); 42 | 43 | // Generate your first AI response! 44 | const response = await browserAI.generateText('Hello, BrowserAI!'); 45 | console.log(response.choices[0].message.content); 46 | } 47 | 48 | quickStart(); 49 | ``` 50 | 51 | ## Requirements 52 | 53 | - Modern web browser with WebGPU support (Chrome Canary, Edge Canary, or other browsers with WebGPU enabled) 54 | - Node.js version 16 or higher (for development) 55 | 56 | export const metadata = { 57 | title: 'BrowserAI Installation Guide', 58 | description: 'Step-by-step guide for installing and setting up BrowserAI' 59 | } -------------------------------------------------------------------------------- /docs/theme.config.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | logo: ( 3 | 4 | BrowserAI 5 | 6 | ), 7 | project: { 8 | link: "https://github.com/sauravpanda/BrowserAI", 9 | }, 10 | docsRepositoryBase: "https://github.com/sauravpanda/BrowserAI/tree/main/docs", 11 | footer: { 12 | text: ( 13 | 14 | MIT {new Date().getFullYear()} ©{" "} 15 | 16 | Cloud Code AI 17 | 18 | . 19 | 20 | ), 21 | }, 22 | // head: ( 23 | // 24 | // 25 | // 26 | // 27 | // ), 28 | }; 29 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import tsParser from '@typescript-eslint/parser'; 2 | import tsPlugin from '@typescript-eslint/eslint-plugin'; 3 | 4 | export default [ 5 | { 6 | files: ['**/*.ts', '**/*.tsx'], 7 | languageOptions: { 8 | parser: tsParser, 9 | parserOptions: { 10 | ecmaVersion: 'latest', 11 | sourceType: 'module', 12 | }, 13 | }, 14 | plugins: { 15 | '@typescript-eslint': tsPlugin, 16 | }, 17 | rules: { 18 | // TypeScript specific rules 19 | '@typescript-eslint/no-explicit-any': 'warn', 20 | '@typescript-eslint/explicit-function-return-type': 'off', 21 | '@typescript-eslint/no-unused-vars': 'warn', 22 | 23 | // General ESLint rules 24 | 'no-console': 'warn', 25 | 'no-unused-vars': 'off', // turned off in favor of @typescript-eslint/no-unused-vars 26 | 'quotes': ['error', 'single'], 27 | 'semi': ['error', 'always'], 28 | }, 29 | }, 30 | ]; -------------------------------------------------------------------------------- /eslintrc.config.js: -------------------------------------------------------------------------------- 1 | import tsParser from '@typescript-eslint/parser'; 2 | import tsPlugin from '@typescript-eslint/eslint-plugin'; 3 | 4 | export default [ 5 | { 6 | languageOptions: { 7 | parser: tsParser, 8 | parserOptions: { 9 | ecmaVersion: 'latest', 10 | }, 11 | }, 12 | plugins: { 13 | '@typescript-eslint': tsPlugin, 14 | }, 15 | extends: [ 16 | 'eslint:recommended', 17 | 'plugin:@typescript-eslint/recommended', 18 | 'prettier' 19 | ], 20 | rules: { 21 | '@typescript-eslint/no-explicit-any': 'off', 22 | } 23 | } 24 | ]; -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Browser Agent WIP 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-agent-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.18", 14 | "lucide-react": "^0.474.0", 15 | "react": "^18.3.1", 16 | "react-dom": "^18.3.1" 17 | }, 18 | "devDependencies": { 19 | "@eslint/js": "^9.17.0", 20 | "@types/react": "^18.3.18", 21 | "@types/react-dom": "^18.3.5", 22 | "@vitejs/plugin-react": "^4.3.4", 23 | "autoprefixer": "^10.4.20", 24 | "eslint": "^9.17.0", 25 | "eslint-plugin-react-hooks": "^5.0.0", 26 | "eslint-plugin-react-refresh": "^0.4.16", 27 | "globals": "^15.14.0", 28 | "postcss": "^8.4.35", 29 | "tailwindcss": "^3.4.1", 30 | "typescript": "~5.6.2", 31 | "typescript-eslint": "^8.18.2", 32 | "vite": "^5.4.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/App.css: -------------------------------------------------------------------------------- 1 | .app-container { 2 | display: flex; 3 | height: 100vh; 4 | background: #f5f5f5; 5 | width: 100%; 6 | } 7 | 8 | .browser-container { 9 | border-right: 1px solid #ddd; 10 | background: white; 11 | } 12 | 13 | .chat-container { 14 | min-width: 320px; 15 | max-width: 450px; 16 | background: white; 17 | box-shadow: -2px 0 5px rgba(0,0,0,0.1); 18 | } -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import BrowserView from './components/BrowserView' 3 | import AgentChat from './components/AgentChat' 4 | import './App.css' 5 | 6 | function App() { 7 | const [currentUrl, setCurrentUrl] = useState('https://example.com') 8 | 9 | return ( 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default App 18 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/components/AgentChat.css: -------------------------------------------------------------------------------- 1 | .agent-chat { 2 | display: flex; 3 | flex-direction: column; 4 | height: 100%; 5 | } 6 | 7 | .chat-messages { 8 | flex: 1; 9 | overflow-y: auto; 10 | padding: 20px; 11 | } 12 | 13 | .message { 14 | margin-bottom: 12px; 15 | padding: 8px 12px; 16 | border-radius: 8px; 17 | max-width: 80%; 18 | } 19 | 20 | .message.user { 21 | background: #007AFF; 22 | color: white; 23 | margin-left: auto; 24 | } 25 | 26 | .message.agent { 27 | background: #F0F0F0; 28 | color: #333; 29 | } 30 | 31 | .chat-input { 32 | padding: 15px; 33 | border-top: 1px solid #ddd; 34 | display: flex; 35 | gap: 8px; 36 | } 37 | 38 | .chat-input input { 39 | flex: 1; 40 | padding: 8px; 41 | border: 1px solid #ddd; 42 | border-radius: 4px; 43 | } 44 | 45 | .chat-input button { 46 | padding: 8px 16px; 47 | background: #007AFF; 48 | color: white; 49 | border: none; 50 | border-radius: 4px; 51 | cursor: pointer; 52 | } 53 | 54 | .chat-input button:disabled { 55 | background: #ccc; 56 | } -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/components/BrowserView.css: -------------------------------------------------------------------------------- 1 | .browser-view { 2 | display: flex; 3 | flex-direction: column; 4 | height: 100%; 5 | } 6 | 7 | .browser-toolbar { 8 | padding: 10px; 9 | border-bottom: 1px solid #ddd; 10 | } 11 | 12 | .url-input { 13 | width: 100%; 14 | padding: 8px; 15 | border: 1px solid #ddd; 16 | border-radius: 4px; 17 | } 18 | 19 | .browser-iframe { 20 | flex: 1; 21 | width: 100%; 22 | border: none; 23 | } -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ], 7 | "compilerOptions": { 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["src/*"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/WIP-browser-agent-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | 8 | }) 9 | -------------------------------------------------------------------------------- /examples/audio-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/audio-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/audio-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/audio-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Browser AI Voice and Chat Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/audio-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-ai-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build && cp public/_headers dist/", 9 | "lint": "eslint .", 10 | "preview": "vite preview", 11 | "predeploy": "npm run build", 12 | "deploy": "gh-pages -d dist" 13 | }, 14 | "dependencies": { 15 | "@browserai/browserai": "^1.0.18", 16 | "@emotion/styled": "^11.14.0", 17 | "@huggingface/transformers": "^3.2.4", 18 | "@mlc-ai/web-llm": "^0.2.77", 19 | "posthog-js": "^1.205.0", 20 | "react": "^18.3.1", 21 | "react-dom": "^18.3.1" 22 | }, 23 | "devDependencies": { 24 | "@eslint/js": "^9.17.0", 25 | "@types/react": "^18.3.18", 26 | "@types/react-dom": "^18.3.5", 27 | "@vitejs/plugin-react": "^4.3.4", 28 | "eslint": "^9.17.0", 29 | "eslint-plugin-react-hooks": "^5.0.0", 30 | "eslint-plugin-react-refresh": "^0.4.16", 31 | "gh-pages": "^6.3.0", 32 | "globals": "^15.14.0", 33 | "typescript": "~5.6.2", 34 | "typescript-eslint": "^8.18.2", 35 | "vite": "^6.0.5" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/audio-demo/public/_headers: -------------------------------------------------------------------------------- 1 | /* 2 | Access-Control-Allow-Origin: * 3 | Cross-Origin-Opener-Policy: same-origin 4 | Cross-Origin-Embedder-Policy: require-corp 5 | Access-Control-Allow-Origin: * -------------------------------------------------------------------------------- /examples/audio-demo/public/_routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "include": ["/*"], 4 | "exclude": [ 5 | "/assets/*", 6 | "/_next/*", 7 | "/_next/static/*", 8 | "/api/*", 9 | "/*.js", 10 | "/*.css" 11 | ] 12 | } -------------------------------------------------------------------------------- /examples/audio-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/audio-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /examples/audio-demo/src/App.tsx: -------------------------------------------------------------------------------- 1 | import ChatInterface from './components/ChatInterface'; 2 | 3 | function App() { 4 | return ( 5 | 6 | 7 | 8 | ); 9 | } 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /examples/audio-demo/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | color-scheme: light dark; 6 | background-color: #1a1a1a; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | padding: 0; 12 | min-width: 320px; 13 | min-height: 100vh; 14 | } 15 | 16 | #root { 17 | width: 100%; 18 | min-height: 100vh; 19 | } 20 | -------------------------------------------------------------------------------- /examples/audio-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /examples/audio-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/audio-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/audio-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/audio-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/audio-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | base: './', 7 | plugins: [react()], 8 | build: { 9 | ssrManifest: true, 10 | rollupOptions: { 11 | output: { 12 | manualChunks: undefined 13 | } 14 | }, 15 | commonjsOptions: { 16 | include: [/@browserai\/browserai/, /node_modules/] 17 | }, 18 | outDir: 'dist', 19 | assetsDir: 'assets', 20 | sourcemap: true 21 | }, 22 | optimizeDeps: { 23 | include: ['@browserai/browserai'] 24 | }, 25 | server: { 26 | middlewareMode: false, 27 | fs: { 28 | strict: true 29 | } 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /examples/chat-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/chat-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/chat-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/chat-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Browser AI Chat Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/chat-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-ai-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build && cp public/_headers dist/", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.37", 14 | "@emotion/react": "^11.14.0", 15 | "@emotion/styled": "^11.14.0", 16 | "@huggingface/jinja": "^0.3.2", 17 | "@huggingface/transformers": "^3.2.4", 18 | "@mlc-ai/web-llm": "^0.2.77", 19 | "@types/markdown-it": "^14.1.2", 20 | "katex": "^0.16.20", 21 | "lucide-react": "^0.473.0", 22 | "markdown-it": "^14.1.0", 23 | "posthog-js": "^1.205.0", 24 | "react": "^18.3.1", 25 | "react-dom": "^18.3.1" 26 | }, 27 | "devDependencies": { 28 | "@eslint/js": "^9.17.0", 29 | "@types/react": "^18.3.18", 30 | "@types/react-dom": "^18.3.5", 31 | "@vitejs/plugin-react": "^4.3.4", 32 | "autoprefixer": "^10.4.20", 33 | "eslint": "^9.17.0", 34 | "eslint-plugin-react-hooks": "^5.0.0", 35 | "eslint-plugin-react-refresh": "^0.4.16", 36 | "globals": "^15.14.0", 37 | "postcss": "^8.5.1", 38 | "tailwindcss": "^3.4.17", 39 | "typescript": "~5.6.2", 40 | "typescript-eslint": "^8.18.2", 41 | "vite": "^6.0.5" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/chat-demo/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /examples/chat-demo/public/_headers: -------------------------------------------------------------------------------- 1 | /* 2 | Access-Control-Allow-Origin: * 3 | Cross-Origin-Opener-Policy: same-origin 4 | Cross-Origin-Embedder-Policy: require-corp 5 | 6 | /*.js 7 | Content-Type: application/javascript 8 | Access-Control-Allow-Origin: * 9 | 10 | /*.css 11 | Content-Type: text/css 12 | Access-Control-Allow-Origin: * 13 | 14 | /*.html 15 | Content-Type: text/html 16 | Access-Control-Allow-Origin: * -------------------------------------------------------------------------------- /examples/chat-demo/public/_routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "include": ["/*"], 4 | "exclude": [ 5 | "/assets/*", 6 | "/_next/*", 7 | "/_next/static/*", 8 | "/api/*", 9 | "/*.js", 10 | "/*.css" 11 | ] 12 | } -------------------------------------------------------------------------------- /examples/chat-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/chat-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /examples/chat-demo/src/App.tsx: -------------------------------------------------------------------------------- 1 | import ChatInterface from './components/ChatInterface' 2 | import React from 'react' 3 | 4 | function App() { 5 | return ; 6 | } 7 | 8 | export default App; 9 | -------------------------------------------------------------------------------- /examples/chat-demo/src/assets/Browserai-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/examples/chat-demo/src/assets/Browserai-logo.png -------------------------------------------------------------------------------- /examples/chat-demo/src/components/MessageFormatting/CodeBlock.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from '@emotion/styled'; 3 | 4 | const CodeBlockContainer = styled.div` 5 | margin: 8px 0; 6 | position: relative; 7 | font-family: 'Courier New', Courier, monospace; 8 | `; 9 | 10 | const CodeHeader = styled.div` 11 | display: flex; 12 | justify-content: space-between; 13 | align-items: center; 14 | padding: 8px 16px; 15 | background: #2d2d2d; 16 | border: 1px solid #404040; 17 | border-bottom: none; 18 | border-radius: 4px 4px 0 0; 19 | `; 20 | 21 | const CodeContent = styled.pre` 22 | margin: 0; 23 | padding: 16px; 24 | background: #1a1a1a; 25 | border: 1px solid #404040; 26 | border-radius: 0 0 4px 4px; 27 | overflow-x: auto; 28 | color: #ffffff; 29 | `; 30 | 31 | const CopyButton = styled.button` 32 | background: #3b82f6; 33 | color: white; 34 | border: none; 35 | border-radius: 4px; 36 | padding: 4px 8px; 37 | cursor: pointer; 38 | font-size: 12px; 39 | 40 | &:hover { 41 | background: #2563eb; 42 | } 43 | `; 44 | 45 | interface CodeBlockProps { 46 | code: string; 47 | language?: string; 48 | } 49 | 50 | export const CodeBlock: React.FC = ({ code, language = 'plaintext' }) => { 51 | const [copied, setCopied] = React.useState(false); 52 | 53 | const handleCopy = async () => { 54 | await navigator.clipboard.writeText(code); 55 | setCopied(true); 56 | setTimeout(() => setCopied(false), 2000); 57 | }; 58 | 59 | return ( 60 | 61 | 62 | {language} 63 | 64 | {copied ? 'Copied!' : 'Copy'} 65 | 66 | 67 | {code} 68 | 69 | ); 70 | }; -------------------------------------------------------------------------------- /examples/chat-demo/src/components/MessageFormatting/Latex.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import katex from 'katex'; 3 | import styled from '@emotion/styled'; 4 | 5 | const LatexBlock = styled.div` 6 | margin: 8px 0; 7 | overflow-x: auto; 8 | color: #ffffff; 9 | 10 | .katex-display { 11 | margin: 0; 12 | padding: 8px 0; 13 | } 14 | `; 15 | 16 | interface LatexProps { 17 | formula: string; 18 | display?: boolean; 19 | } 20 | 21 | export const Latex: React.FC = ({ formula, display = false }) => { 22 | const [html, setHtml] = useState(''); 23 | 24 | useEffect(() => { 25 | try { 26 | const rendered = katex.renderToString(formula, { 27 | displayMode: display, 28 | throwOnError: false 29 | }); 30 | setHtml(rendered); 31 | } catch (error) { 32 | console.error('LaTeX rendering error:', error); 33 | setHtml(formula); 34 | } 35 | }, [formula, display]); 36 | 37 | return ( 38 | 41 | ); 42 | }; -------------------------------------------------------------------------------- /examples/chat-demo/src/components/MessageFormatting/index.ts: -------------------------------------------------------------------------------- 1 | export { CodeBlock } from './CodeBlock'; 2 | export { Latex } from './Latex'; 3 | export { MessageContent } from '../MessageContent'; -------------------------------------------------------------------------------- /examples/chat-demo/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 7 | line-height: 1.5; 8 | font-weight: 400; 9 | color-scheme: dark; 10 | background-color: #1a1a1a; 11 | color: #ffffff; 12 | } 13 | 14 | body { 15 | margin: 0; 16 | min-width: 320px; 17 | min-height: 100vh; 18 | } 19 | 20 | h1 { 21 | font-size: 24px; 22 | line-height: 1.1; 23 | margin: 0; 24 | font-weight: 600; 25 | } 26 | -------------------------------------------------------------------------------- /examples/chat-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React, { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | if (!rootElement) throw new Error('Failed to find the root element'); 8 | 9 | createRoot(rootElement).render( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /examples/chat-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.png' { 4 | const value: string; 5 | export default value; 6 | } 7 | -------------------------------------------------------------------------------- /examples/chat-demo/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}" // This tells Tailwind to scan these file types in src folder 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | darkMode: 'class', // Enable dark mode if needed 12 | } -------------------------------------------------------------------------------- /examples/chat-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | 14 | /* Output configuration */ 15 | "composite": true, 16 | "outDir": "./dist", 17 | "noEmit": true, 18 | 19 | /* Linting */ 20 | "strict": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noFallthroughCasesInSwitch": true, 24 | "noUncheckedSideEffectImports": true, 25 | 26 | "esModuleInterop": true, 27 | "allowSyntheticDefaultImports": true, 28 | "types": ["node"] 29 | }, 30 | "include": ["vite.config.ts"] 31 | } -------------------------------------------------------------------------------- /examples/chat-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "skipLibCheck": true, 7 | "composite": true 8 | }, 9 | "files": [], 10 | "references": [ 11 | { "path": "./tsconfig.app.json" }, 12 | { "path": "./tsconfig.node.json" } 13 | ] 14 | } -------------------------------------------------------------------------------- /examples/chat-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023", "DOM", "DOM.Iterable"], // Added DOM libraries 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true, 22 | 23 | /* Added configurations */ 24 | "composite": true, 25 | "esModuleInterop": true, 26 | "allowSyntheticDefaultImports": true, 27 | "types": ["node"] 28 | }, 29 | "include": ["vite.config.ts"] 30 | } -------------------------------------------------------------------------------- /examples/chat-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | base:'/', 7 | plugins: [react()], 8 | build: { 9 | ssrManifest: true, 10 | rollupOptions: { 11 | output: { 12 | manualChunks: undefined 13 | } 14 | }, 15 | commonjsOptions: { 16 | include: [/@browserai\/browserai/, /node_modules/] 17 | }, 18 | outDir: 'dist', 19 | assetsDir: 'assets', 20 | sourcemap: true 21 | }, 22 | optimizeDeps: { 23 | include: ['@browserai/browserai'] 24 | }, 25 | server: { 26 | middlewareMode: false, 27 | fs: { 28 | strict: true 29 | } 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "indexeddb-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.18", 14 | "react": "^18.3.1", 15 | "react-dom": "^18.3.1" 16 | }, 17 | "devDependencies": { 18 | "@eslint/js": "^9.17.0", 19 | "@types/react": "^18.3.18", 20 | "@types/react-dom": "^18.3.5", 21 | "@vitejs/plugin-react": "^4.3.4", 22 | "eslint": "^9.17.0", 23 | "eslint-plugin-react-hooks": "^5.0.0", 24 | "eslint-plugin-react-refresh": "^0.4.16", 25 | "globals": "^15.14.0", 26 | "typescript": "~5.6.2", 27 | "typescript-eslint": "^8.18.2", 28 | "vite": "^6.0.5" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | } 6 | 7 | .database-demo { 8 | text-align: left; 9 | } 10 | 11 | .logs { 12 | background: #f0f0f0; 13 | padding: 1rem; 14 | border-radius: 8px; 15 | max-height: 500px; 16 | overflow-y: auto; 17 | } 18 | 19 | .logs pre { 20 | margin: 0.5rem 0; 21 | white-space: pre-wrap; 22 | word-wrap: break-word; 23 | } -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { DatabaseDemo } from './components/DatabaseDemo' 2 | import './App.css' 3 | 4 | function App() { 5 | return ( 6 | 7 | 8 | 9 | ) 10 | } 11 | 12 | export default App -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/components/DatabaseDemo.css: -------------------------------------------------------------------------------- 1 | .database-demo { 2 | padding: 20px; 3 | max-width: 800px; 4 | margin: 0 auto; 5 | } 6 | 7 | .input-section { 8 | margin: 20px 0; 9 | display: flex; 10 | gap: 10px; 11 | } 12 | 13 | .input-section input { 14 | padding: 8px; 15 | border: 1px solid #ccc; 16 | border-radius: 4px; 17 | flex: 1; 18 | } 19 | 20 | .button-section { 21 | display: flex; 22 | gap: 10px; 23 | margin-bottom: 20px; 24 | flex-wrap: wrap; 25 | } 26 | 27 | .button-section button { 28 | padding: 8px 16px; 29 | background-color: #007bff; 30 | color: white; 31 | border: none; 32 | border-radius: 4px; 33 | cursor: pointer; 34 | } 35 | 36 | .button-section button:hover { 37 | background-color: #0056b3; 38 | } 39 | 40 | .documents-section { 41 | margin: 20px 0; 42 | padding: 20px; 43 | border: 1px solid #eee; 44 | border-radius: 4px; 45 | } 46 | 47 | .documents-list { 48 | display: grid; 49 | gap: 10px; 50 | } 51 | 52 | .document-item { 53 | padding: 10px; 54 | background-color: #f8f9fa; 55 | border-radius: 4px; 56 | color: #333; 57 | } 58 | 59 | .document-item strong { 60 | display: block; 61 | margin-bottom: 5px; 62 | color: #333; 63 | } 64 | 65 | .logs-section { 66 | margin-top: 20px; 67 | } 68 | 69 | .logs { 70 | background-color: #f8f9fa; 71 | padding: 10px; 72 | border-radius: 4px; 73 | max-height: 300px; 74 | overflow-y: auto; 75 | } 76 | 77 | .logs pre { 78 | margin: 5px 0; 79 | white-space: pre-wrap; 80 | color: #333; 81 | } -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: #646cff; 19 | text-decoration: inherit; 20 | } 21 | a:hover { 22 | color: #535bf2; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | display: flex; 28 | place-items: center; 29 | min-width: 320px; 30 | min-height: 100vh; 31 | } 32 | 33 | h1 { 34 | font-size: 3.2em; 35 | line-height: 1.1; 36 | } 37 | 38 | button { 39 | border-radius: 8px; 40 | border: 1px solid transparent; 41 | padding: 0.6em 1.2em; 42 | font-size: 1em; 43 | font-weight: 500; 44 | font-family: inherit; 45 | background-color: #1a1a1a; 46 | cursor: pointer; 47 | transition: border-color 0.25s; 48 | } 49 | button:hover { 50 | border-color: #646cff; 51 | } 52 | button:focus, 53 | button:focus-visible { 54 | outline: 4px auto -webkit-focus-ring-color; 55 | } 56 | 57 | @media (prefers-color-scheme: light) { 58 | :root { 59 | color: #213547; 60 | background-color: #ffffff; 61 | } 62 | a:hover { 63 | color: #747bff; 64 | } 65 | button { 66 | background-color: #f9f9f9; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Storable { 2 | id: string; 3 | } 4 | 5 | export interface Document extends Storable { 6 | text: string; 7 | } 8 | 9 | export interface DatabaseConfig { 10 | databaseName?: string; 11 | } -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/database-demos/indexeddb-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Browser AI Chat Demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-ai-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build && cp public/_headers dist/", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.29", 14 | "@emotion/react": "^11.14.0", 15 | "@emotion/styled": "^11.14.0", 16 | "@huggingface/jinja": "^0.3.2", 17 | "@huggingface/transformers": "^3.2.4", 18 | "@mlc-ai/web-llm": "^0.2.77", 19 | "@types/markdown-it": "^14.1.2", 20 | "clsx": "^2.1.1", 21 | "framer-motion": "^12.4.1", 22 | "katex": "^0.16.20", 23 | "lucide-react": "^0.473.0", 24 | "markdown-it": "^14.1.0", 25 | "posthog-js": "^1.205.0", 26 | "react": "^18.3.1", 27 | "react-dom": "^18.3.1", 28 | "tailwind-merge": "^3.0.1" 29 | }, 30 | "devDependencies": { 31 | "@eslint/js": "^9.17.0", 32 | "@types/react": "^18.3.18", 33 | "@types/react-dom": "^18.3.5", 34 | "@vitejs/plugin-react": "^4.3.4", 35 | "autoprefixer": "^10.4.20", 36 | "eslint": "^9.17.0", 37 | "eslint-plugin-react-hooks": "^5.0.0", 38 | "eslint-plugin-react-refresh": "^0.4.16", 39 | "globals": "^15.14.0", 40 | "postcss": "^8.5.1", 41 | "tailwindcss": "^3.4.17", 42 | "typescript": "~5.6.2", 43 | "typescript-eslint": "^8.18.2", 44 | "vite": "^6.0.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/public/_headers: -------------------------------------------------------------------------------- 1 | /* 2 | Access-Control-Allow-Origin: * 3 | Cross-Origin-Opener-Policy: same-origin 4 | Cross-Origin-Embedder-Policy: require-corp 5 | 6 | /*.js 7 | Content-Type: application/javascript 8 | Access-Control-Allow-Origin: * 9 | 10 | /*.css 11 | Content-Type: text/css 12 | Access-Control-Allow-Origin: * 13 | 14 | /*.html 15 | Content-Type: text/html 16 | Access-Control-Allow-Origin: * -------------------------------------------------------------------------------- /examples/realtime-chat-demo/public/_routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "include": ["/*"], 4 | "exclude": [ 5 | "/assets/*", 6 | "/_next/*", 7 | "/_next/static/*", 8 | "/api/*", 9 | "/*.js", 10 | "/*.css" 11 | ] 12 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 7 | line-height: 1.5; 8 | font-weight: 400; 9 | color-scheme: dark; 10 | background-color: #1a1a1a; 11 | color: #ffffff; 12 | } 13 | 14 | body { 15 | margin: 0; 16 | min-width: 320px; 17 | min-height: 100vh; 18 | } 19 | 20 | h1 { 21 | font-size: 24px; 22 | line-height: 1.1; 23 | margin: 0; 24 | font-weight: 600; 25 | } 26 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React, { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const rootElement = document.getElementById('root'); 7 | if (!rootElement) throw new Error('Failed to find the root element'); 8 | 9 | createRoot(rootElement).render( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/realtime-chat-demo/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}" // This tells Tailwind to scan these file types in src folder 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | darkMode: 'class', // Enable dark mode if needed 12 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | 14 | /* Output configuration */ 15 | "composite": true, 16 | "outDir": "./dist", 17 | "noEmit": true, 18 | 19 | /* Linting */ 20 | "strict": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noFallthroughCasesInSwitch": true, 24 | "noUncheckedSideEffectImports": true, 25 | 26 | "esModuleInterop": true, 27 | "allowSyntheticDefaultImports": true, 28 | "types": ["node"] 29 | }, 30 | "include": ["vite.config.ts"] 31 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "skipLibCheck": true, 7 | "composite": true 8 | }, 9 | "files": [], 10 | "references": [ 11 | { "path": "./tsconfig.app.json" }, 12 | { "path": "./tsconfig.node.json" } 13 | ] 14 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023", "DOM", "DOM.Iterable"], // Added DOM libraries 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true, 22 | 23 | /* Added configurations */ 24 | "composite": true, 25 | "esModuleInterop": true, 26 | "allowSyntheticDefaultImports": true, 27 | "types": ["node"] 28 | }, 29 | "include": ["vite.config.ts"] 30 | } -------------------------------------------------------------------------------- /examples/realtime-chat-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | base:'/', 7 | plugins: [react()], 8 | build: { 9 | ssrManifest: true, 10 | rollupOptions: { 11 | output: { 12 | manualChunks: undefined 13 | } 14 | }, 15 | commonjsOptions: { 16 | include: [/@browserai\/browserai/, /node_modules/] 17 | }, 18 | outDir: 'dist', 19 | assetsDir: 'assets', 20 | sourcemap: true 21 | }, 22 | optimizeDeps: { 23 | include: ['@browserai/browserai'] 24 | }, 25 | server: { 26 | middlewareMode: false, 27 | fs: { 28 | strict: true 29 | } 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /examples/schema-llm/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/schema-llm/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/schema-llm/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/schema-llm/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Schema LLM Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/schema-llm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "schema-llm", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.26", 14 | "react": "^19.0.0", 15 | "react-dom": "^19.0.0" 16 | }, 17 | "devDependencies": { 18 | "@eslint/js": "^9.19.0", 19 | "@types/react": "^19.0.8", 20 | "@types/react-dom": "^19.0.3", 21 | "@vitejs/plugin-react": "^4.3.4", 22 | "eslint": "^9.19.0", 23 | "eslint-plugin-react-hooks": "^5.0.0", 24 | "eslint-plugin-react-refresh": "^0.4.18", 25 | "globals": "^15.14.0", 26 | "typescript": "~5.7.2", 27 | "typescript-eslint": "^8.22.0", 28 | "vite": "^6.1.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/schema-llm/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/schema-llm/src/App.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 800px; 3 | margin: 0 auto; 4 | padding: 20px; 5 | } 6 | 7 | .input-group { 8 | margin-bottom: 20px; 9 | } 10 | 11 | .input-group label { 12 | display: block; 13 | margin-bottom: 5px; 14 | font-weight: bold; 15 | } 16 | 17 | input, textarea { 18 | width: 100%; 19 | padding: 8px; 20 | border: 1px solid #ccc; 21 | border-radius: 4px; 22 | } 23 | 24 | textarea { 25 | min-height: 100px; 26 | font-family: monospace; 27 | } 28 | 29 | button { 30 | background-color: #4CAF50; 31 | color: white; 32 | padding: 10px 20px; 33 | border: none; 34 | border-radius: 4px; 35 | cursor: pointer; 36 | } 37 | 38 | button:disabled { 39 | background-color: #cccccc; 40 | cursor: not-allowed; 41 | } 42 | 43 | .output { 44 | margin-top: 20px; 45 | } 46 | 47 | .output pre { 48 | background-color: black; 49 | padding: 15px; 50 | border-radius: 4px; 51 | overflow-x: auto; 52 | white-space: pre-wrap; 53 | word-wrap: break-word; 54 | } 55 | 56 | .examples { 57 | margin: 20px 0; 58 | } 59 | 60 | .example-button { 61 | margin-right: 10px; 62 | background-color: #2196F3; 63 | } 64 | 65 | .example-button:hover { 66 | background-color: #1976D2; 67 | } -------------------------------------------------------------------------------- /examples/schema-llm/src/examples.ts: -------------------------------------------------------------------------------- 1 | export const sampleSchemas = { 2 | colors: `{ 3 | "type": "object", 4 | "properties": { 5 | "colors": { 6 | "type": "array", 7 | "items": { 8 | "type": "object", 9 | "properties": { 10 | "name": { "type": "string" }, 11 | "hex": { "type": "string" } 12 | } 13 | } 14 | } 15 | } 16 | }`, 17 | 18 | person: `{ 19 | "type": "object", 20 | "properties": { 21 | "name": { "type": "string" }, 22 | "age": { "type": "number" }, 23 | "hobbies": { 24 | "type": "array", 25 | "items": { "type": "string" } 26 | } 27 | } 28 | }` 29 | }; 30 | 31 | export const samplePrompts = { 32 | colors: "List 3 popular colors with their hex codes", 33 | person: "Create a profile for a fictional person named John" 34 | }; -------------------------------------------------------------------------------- /examples/schema-llm/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: #646cff; 19 | text-decoration: inherit; 20 | } 21 | a:hover { 22 | color: #535bf2; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | display: flex; 28 | place-items: center; 29 | min-width: 320px; 30 | min-height: 100vh; 31 | } 32 | 33 | h1 { 34 | font-size: 3.2em; 35 | line-height: 1.1; 36 | } 37 | 38 | button { 39 | border-radius: 8px; 40 | border: 1px solid transparent; 41 | padding: 0.6em 1.2em; 42 | font-size: 1em; 43 | font-weight: 500; 44 | font-family: inherit; 45 | background-color: #1a1a1a; 46 | cursor: pointer; 47 | transition: border-color 0.25s; 48 | } 49 | button:hover { 50 | border-color: #646cff; 51 | } 52 | button:focus, 53 | button:focus-visible { 54 | outline: 4px auto -webkit-focus-ring-color; 55 | } 56 | 57 | @media (prefers-color-scheme: light) { 58 | :root { 59 | color: #213547; 60 | background-color: #ffffff; 61 | } 62 | a:hover { 63 | color: #747bff; 64 | } 65 | button { 66 | background-color: #f9f9f9; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /examples/schema-llm/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /examples/schema-llm/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/schema-llm/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/schema-llm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/schema-llm/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/schema-llm/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /examples/tts-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/tts-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/tts-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/tts-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/tts-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tts-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.29", 14 | "@emotion/styled": "^11.14.0", 15 | "react": "^18.3.1", 16 | "react-dom": "^18.3.1" 17 | }, 18 | "devDependencies": { 19 | "@eslint/js": "^9.17.0", 20 | "@types/react": "^18.3.18", 21 | "@types/react-dom": "^18.3.5", 22 | "@vitejs/plugin-react": "^4.3.4", 23 | "eslint": "^9.17.0", 24 | "eslint-plugin-react-hooks": "^5.0.0", 25 | "eslint-plugin-react-refresh": "^0.4.16", 26 | "globals": "^15.14.0", 27 | "typescript": "~5.6.2", 28 | "typescript-eslint": "^8.18.2", 29 | "vite": "^6.0.5" 30 | } 31 | } -------------------------------------------------------------------------------- /examples/tts-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/tts-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /examples/tts-demo/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | color-scheme: light dark; 6 | color: rgba(255, 255, 255, 0.87); 7 | background-color: #1a1a1a; 8 | } 9 | 10 | body { 11 | margin: 0; 12 | min-width: 320px; 13 | min-height: 100vh; 14 | } -------------------------------------------------------------------------------- /examples/tts-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ); -------------------------------------------------------------------------------- /examples/tts-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/tts-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/tts-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/tts-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/tts-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /examples/voice-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/voice-demo/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /examples/voice-demo/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /examples/voice-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/voice-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "voice-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@browserai/browserai": "^1.0.29", 14 | "@emotion/styled": "^11.14.0", 15 | "react": "^19.0.0", 16 | "react-dom": "^19.0.0" 17 | }, 18 | "devDependencies": { 19 | "@eslint/js": "^9.19.0", 20 | "@types/react": "^19.0.8", 21 | "@types/react-dom": "^19.0.3", 22 | "@vitejs/plugin-react": "^4.3.4", 23 | "eslint": "^9.19.0", 24 | "eslint-plugin-react-hooks": "^5.0.0", 25 | "eslint-plugin-react-refresh": "^0.4.18", 26 | "globals": "^15.14.0", 27 | "typescript": "~5.7.2", 28 | "typescript-eslint": "^8.22.0", 29 | "vite": "^6.1.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/voice-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/voice-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /examples/voice-demo/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | color-scheme: light dark; 6 | background-color: #1a1a1a; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | padding: 0; 12 | min-width: 320px; 13 | min-height: 100vh; 14 | } 15 | 16 | #root { 17 | width: 100%; 18 | min-height: 100vh; 19 | } 20 | 21 | a { 22 | font-weight: 500; 23 | color: #646cff; 24 | text-decoration: inherit; 25 | } 26 | a:hover { 27 | color: #535bf2; 28 | } 29 | 30 | h1 { 31 | font-size: 3.2em; 32 | line-height: 1.1; 33 | } 34 | 35 | button { 36 | border-radius: 8px; 37 | border: 1px solid transparent; 38 | padding: 0.6em 1.2em; 39 | font-size: 1em; 40 | font-weight: 500; 41 | font-family: inherit; 42 | background-color: #1a1a1a; 43 | cursor: pointer; 44 | transition: border-color 0.25s; 45 | } 46 | button:hover { 47 | border-color: #646cff; 48 | } 49 | button:focus, 50 | button:focus-visible { 51 | outline: 4px auto -webkit-focus-ring-color; 52 | } 53 | 54 | @media (prefers-color-scheme: light) { 55 | :root { 56 | color: #213547; 57 | background-color: #ffffff; 58 | } 59 | a:hover { 60 | color: #747bff; 61 | } 62 | button { 63 | background-color: #f9f9f9; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /examples/voice-demo/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /examples/voice-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/voice-demo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /examples/voice-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/voice-demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/voice-demo/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /extensions/chrome/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default tseslint.config({ 18 | languageOptions: { 19 | // other options... 20 | parserOptions: { 21 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 22 | tsconfigRootDir: import.meta.dirname, 23 | }, 24 | }, 25 | }) 26 | ``` 27 | 28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` 29 | - Optionally add `...tseslint.configs.stylisticTypeChecked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: 31 | 32 | ```js 33 | // eslint.config.js 34 | import react from 'eslint-plugin-react' 35 | 36 | export default tseslint.config({ 37 | // Set the react version 38 | settings: { react: { version: '18.3' } }, 39 | plugins: { 40 | // Add the react plugin 41 | react, 42 | }, 43 | rules: { 44 | // other rules... 45 | // Enable its recommended rules 46 | ...react.configs.recommended.rules, 47 | ...react.configs['jsx-runtime'].rules, 48 | }, 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /extensions/chrome/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /extensions/chrome/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Browser AI 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /extensions/chrome/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /extensions/chrome/public/content-script.css: -------------------------------------------------------------------------------- 1 | .floating-button { 2 | position: fixed; 3 | right: 20px; 4 | bottom: 20px; 5 | width: 50px; 6 | height: 50px; 7 | border-radius: 25px; 8 | background: #4F46E5; 9 | color: white; 10 | border: none; 11 | cursor: pointer; 12 | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); 13 | z-index: 9999; 14 | font-size: 24px; 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | transition: transform 0.2s; 19 | } 20 | 21 | .floating-button:hover { 22 | transform: scale(1.1); 23 | } -------------------------------------------------------------------------------- /extensions/chrome/public/content-script.js: -------------------------------------------------------------------------------- 1 | console.log('Content script loaded!'); 2 | 3 | // Create and inject the floating button 4 | function createFloatingButton() { 5 | const button = document.createElement('button'); 6 | button.innerHTML = '🤖'; // You can replace this with an SVG icon 7 | button.className = 'floating-button'; 8 | 9 | button.addEventListener('click', () => { 10 | console.log('Button clicked!'); 11 | chrome.runtime.sendMessage({ action: 'openSidePanel' }); 12 | }); 13 | 14 | document.body.appendChild(button); 15 | } 16 | 17 | createFloatingButton(); 18 | 19 | // Listen for the custom event 20 | window.addEventListener('workflowData', function(event) { 21 | // Forward the data to the background script 22 | chrome.runtime.sendMessage({ 23 | action: 'workflowDataReceived', 24 | data: event.detail 25 | }); 26 | }); 27 | 28 | // Listen for action execution messages 29 | chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { 30 | if (request.action === 'executeAction') { 31 | // Import the executor dynamically 32 | import(chrome.runtime.getURL('src/core/browser-actions.js')) 33 | .then(module => { 34 | return module.executeAction({ 35 | type: request.type, 36 | params: request.params 37 | }); 38 | }) 39 | .then(result => { 40 | sendResponse({ success: true, result }); 41 | }) 42 | .catch(error => { 43 | sendResponse({ success: false, error: error.message }); 44 | }); 45 | 46 | return true; // Required for async sendResponse 47 | } 48 | }); -------------------------------------------------------------------------------- /extensions/chrome/public/icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/extensions/chrome/public/icons/icon128.png -------------------------------------------------------------------------------- /extensions/chrome/public/icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/extensions/chrome/public/icons/icon16.png -------------------------------------------------------------------------------- /extensions/chrome/public/icons/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/extensions/chrome/public/icons/icon32.png -------------------------------------------------------------------------------- /extensions/chrome/public/icons/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/extensions/chrome/public/icons/icon64.png -------------------------------------------------------------------------------- /extensions/chrome/public/sidepanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Browser AI Side Panel 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /extensions/chrome/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extensions/chrome/sidepanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Browser AI Side Panel 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /extensions/chrome/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 0; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /extensions/chrome/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense, lazy } from 'react' 2 | import './App.css' 3 | import './index.css' 4 | 5 | const Popup = lazy(() => import('./popup/popup')) 6 | 7 | function App() { 8 | return ( 9 | 10 | Loading...}> 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default App 18 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/Header.tsx: -------------------------------------------------------------------------------- 1 | export function Header({ currentSection }: { currentSection: string }) { 2 | return ( 3 | 4 | {currentSection} 5 | 6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AvatarPrimitive from "@radix-ui/react-avatar" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Avatar = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | )) 21 | Avatar.displayName = AvatarPrimitive.Root.displayName 22 | 23 | const AvatarImage = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 32 | )) 33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 34 | 35 | const AvatarFallback = React.forwardRef< 36 | React.ElementRef, 37 | React.ComponentPropsWithoutRef 38 | >(({ className, ...props }, ref) => ( 39 | 47 | )) 48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 49 | 50 | export { Avatar, AvatarImage, AvatarFallback } 51 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "../../lib/utils" 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-full 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", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ) 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 | 33 | ) 34 | } 35 | 36 | export { Badge, badgeVariants } 37 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox" 5 | import { Check } from "lucide-react" 6 | 7 | import { cn } from "../../lib/utils" 8 | 9 | const Checkbox = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => ( 13 | 21 | 24 | 25 | 26 | 27 | )) 28 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 29 | 30 | export { Checkbox } 31 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/hover-card.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as HoverCardPrimitive from "@radix-ui/react-hover-card" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const HoverCard = HoverCardPrimitive.Root 9 | 10 | const HoverCardTrigger = HoverCardPrimitive.Trigger 11 | 12 | const HoverCardContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 16 | 26 | )) 27 | HoverCardContent.displayName = HoverCardPrimitive.Content.displayName 28 | 29 | export { HoverCard, HoverCardTrigger, HoverCardContent } 30 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "../../lib/utils" 4 | 5 | const Input = React.forwardRef>( 6 | ({ className, type, ...props }, ref) => { 7 | return ( 8 | 17 | ) 18 | } 19 | ) 20 | Input.displayName = "Input" 21 | 22 | export { Input } 23 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "../../lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/popover.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as PopoverPrimitive from "@radix-ui/react-popover" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Popover = PopoverPrimitive.Root 9 | 10 | const PopoverTrigger = PopoverPrimitive.Trigger 11 | 12 | const PopoverContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 16 | 17 | 27 | 28 | )) 29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 30 | 31 | export { Popover, PopoverTrigger, PopoverContent } 32 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/radio-group.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" 5 | import { Circle } from "lucide-react" 6 | 7 | import { cn } from "../../lib/utils" 8 | 9 | const RadioGroup = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => { 13 | return ( 14 | 19 | ) 20 | }) 21 | RadioGroup.displayName = RadioGroupPrimitive.Root.displayName 22 | 23 | const RadioGroupItem = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => { 27 | return ( 28 | 36 | 37 | 38 | 39 | 40 | ) 41 | }) 42 | RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName 43 | 44 | export { RadioGroup, RadioGroupItem } 45 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Separator = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >( 12 | ( 13 | { className, orientation = "horizontal", decorative = true, ...props }, 14 | ref 15 | ) => ( 16 | 27 | ) 28 | ) 29 | Separator.displayName = SeparatorPrimitive.Root.displayName 30 | 31 | export { Separator } 32 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "../../lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 | 12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/slider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SliderPrimitive from "@radix-ui/react-slider" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Slider = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | 21 | 22 | 23 | 24 | 25 | )) 26 | Slider.displayName = SliderPrimitive.Root.displayName 27 | 28 | export { Slider } 29 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/switch.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SwitchPrimitives from "@radix-ui/react-switch" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Switch = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | 25 | 26 | )) 27 | Switch.displayName = SwitchPrimitives.Root.displayName 28 | 29 | export { Switch } 30 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "../../lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 | 19 | ) 20 | } 21 | ) 22 | Textarea.displayName = "Textarea" 23 | 24 | export { Textarea } 25 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/toaster.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useToast } from "../../hooks/use-toast" 4 | import { 5 | Toast, 6 | ToastClose, 7 | ToastDescription, 8 | ToastProps, 9 | ToastProvider, 10 | ToastTitle, 11 | ToastViewport, 12 | } from "./toast" 13 | 14 | // Add this interface to extend ToastProps 15 | type ToasterToast = ToastProps & { 16 | id: string; 17 | title?: React.ReactNode; 18 | description?: React.ReactNode; 19 | action?: React.ReactNode; 20 | } 21 | 22 | export function Toaster() { 23 | const { toasts } = useToast() 24 | 25 | return ( 26 | 27 | {toasts.map(function ({ id, title, description, action, ...props }: ToasterToast) { 28 | return ( 29 | 30 | 31 | {title && {title}} 32 | {description && ( 33 | {description} 34 | )} 35 | 36 | {action} 37 | 38 | 39 | ) 40 | })} 41 | 42 | 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/toggle.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as TogglePrimitive from "@radix-ui/react-toggle" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "../../lib/utils" 8 | 9 | const toggleVariants = cva( 10 | "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2", 11 | { 12 | variants: { 13 | variant: { 14 | default: "bg-transparent", 15 | outline: 16 | "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", 17 | }, 18 | size: { 19 | default: "h-10 px-3 min-w-10", 20 | sm: "h-9 px-2.5 min-w-9", 21 | lg: "h-11 px-5 min-w-11", 22 | }, 23 | }, 24 | defaultVariants: { 25 | variant: "default", 26 | size: "default", 27 | }, 28 | } 29 | ) 30 | 31 | const Toggle = React.forwardRef< 32 | React.ElementRef, 33 | React.ComponentPropsWithoutRef & 34 | VariantProps 35 | >(({ className, variant, size, ...props }, ref) => ( 36 | 41 | )) 42 | 43 | Toggle.displayName = TogglePrimitive.Root.displayName 44 | 45 | export { Toggle, toggleVariants } 46 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/tooltip.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const TooltipProvider = TooltipPrimitive.Provider 9 | 10 | const Tooltip = TooltipPrimitive.Root 11 | 12 | const TooltipTrigger = TooltipPrimitive.Trigger 13 | 14 | const TooltipContent = React.forwardRef< 15 | React.ElementRef, 16 | React.ComponentPropsWithoutRef 17 | >(({ className, sideOffset = 4, ...props }, ref) => ( 18 | 27 | )) 28 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 29 | 30 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } 31 | -------------------------------------------------------------------------------- /extensions/chrome/src/components/ui/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /extensions/chrome/src/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /extensions/chrome/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /extensions/chrome/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /extensions/chrome/src/popup/header.tsx: -------------------------------------------------------------------------------- 1 | 2 | export function Header() { 3 | return ( 4 | 5 | 6 | 7 | BrowserAgent 8 | 9 | 10 | Powered by BrowserAI 11 | 12 | ) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /extensions/chrome/src/sidepanel.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import './App.css' 4 | import './index.css' 5 | import { Button } from './components/ui/button' 6 | import { HTMLCleanerTest } from './components/HTMLCleanerTest' 7 | 8 | function SidePanel() { 9 | const [currentView, setCurrentView] = useState<'main' | 'htmlCleaner'>('main') 10 | 11 | return ( 12 | 13 | 14 | Browser AI 15 | 16 | 17 | 18 | setCurrentView('main')} 22 | > 23 | Main 24 | 25 | setCurrentView('htmlCleaner')} 29 | > 30 | HTML Cleaner 31 | 32 | 33 | 34 | 35 | {currentView === 'main' && ( 36 | 37 | Browser AI 38 | Use this panel to interact with your AI assistant. 39 | 40 | )} 41 | 42 | {currentView === 'htmlCleaner' && } 43 | 44 | 45 | ) 46 | } 47 | 48 | ReactDOM.createRoot(document.getElementById('side-panel-root')!).render( 49 | 50 | 51 | , 52 | ) -------------------------------------------------------------------------------- /extensions/chrome/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /extensions/chrome/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./sidepanel.html", 6 | "./src/**/*.{js,ts,jsx,tsx}", 7 | ], 8 | darkMode: 'media', // or 'class' if you're using class-based dark mode 9 | theme: { 10 | extend: { 11 | colors: { 12 | border: "hsl(var(--border))", 13 | background: "hsl(var(--background))", 14 | foreground: "hsl(var(--foreground))", 15 | muted: { 16 | DEFAULT: "hsl(var(--muted))", 17 | foreground: "hsl(var(--muted-foreground))", 18 | }, 19 | 'input-dark': 'hsl(240 10% 4% / 1)', 20 | }, 21 | }, 22 | }, 23 | plugins: [], 24 | } -------------------------------------------------------------------------------- /extensions/chrome/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /extensions/chrome/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /extensions/chrome/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /extensions/chrome/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import { viteStaticCopy } from 'vite-plugin-static-copy'; 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | react(), 8 | viteStaticCopy({ 9 | targets: [ 10 | { 11 | src: 'public/manifest.json', 12 | dest: '.', 13 | }, 14 | { 15 | src: 'public/icons', 16 | dest: 'icons', 17 | }, 18 | { 19 | src: 'public/content-script.js', 20 | dest: '.', 21 | }, 22 | ], 23 | }), 24 | ], 25 | base: './', 26 | build: { 27 | outDir: 'build', 28 | rollupOptions: { 29 | input: { 30 | main: 'index.html', 31 | sidepanel: 'sidepanel.html' 32 | }, 33 | }, 34 | }, 35 | }); -------------------------------------------------------------------------------- /src/config/models/types.ts: -------------------------------------------------------------------------------- 1 | export interface BaseModelConfig { 2 | modelName: string; 3 | modelType: ModelType; 4 | repo: string; 5 | pipeline: string; 6 | defaultQuantization: string; 7 | supportedDTypes?: string[]; 8 | contextLength?: number; 9 | defaultParams?: Record; 10 | quantizations?: string[]; 11 | requiredFeatures?: string[]; 12 | modelLibrary?: string; 13 | metadata?: Record; 14 | } 15 | 16 | export type ModelType = 17 | | 'text-generation' 18 | | 'sentiment-analysis' 19 | | 'feature-extraction' 20 | | 'automatic-speech-recognition' 21 | | 'multimodal' 22 | | 'text-to-speech'; 23 | 24 | export interface MLCConfig extends BaseModelConfig { 25 | engine: 'mlc'; 26 | quantized?: boolean; 27 | threads?: number; 28 | overrides?: Record; 29 | } 30 | 31 | export interface TransformersConfig extends BaseModelConfig { 32 | engine: 'transformers'; 33 | revision?: string; 34 | } 35 | 36 | export type ModelConfig = MLCConfig | TransformersConfig; 37 | -------------------------------------------------------------------------------- /src/core/agent/html-cleaner.test.ts: -------------------------------------------------------------------------------- 1 | import { HTMLCleaner } from './html-cleaner'; 2 | 3 | describe('HTMLCleaner', () => { 4 | let cleaner: HTMLCleaner; 5 | 6 | beforeEach(() => { 7 | cleaner = new HTMLCleaner(); 8 | }); 9 | 10 | test('cleanForInteractive extracts interactive elements', () => { 11 | const html = ` 12 | 13 | Click me 14 | Link 15 | 16 | Custom Button 17 | 18 | `; 19 | const result = cleaner.cleanForInteractive(html); 20 | expect(result).toContain('[button] Click me'); 21 | expect(result).toContain('[a] Link'); 22 | expect(result).toContain('[input] Input'); 23 | expect(result).toContain('[div] Custom Button'); 24 | }); 25 | 26 | test('preserveSemanticHierarchy maintains heading structure', () => { 27 | const html = ` 28 | 29 | Main Title 30 | Subtitle 31 | Paragraph 1 32 | Another Section 33 | Paragraph 2 34 | 35 | `; 36 | const result = cleaner.preserveSemanticHierarchy(html); 37 | expect(result).toContain('h1: Main Title'); 38 | expect(result).toContain('h2: Subtitle'); 39 | expect(result).toContain('Paragraph 1'); 40 | expect(result).toContain('h2: Another Section'); 41 | expect(result).toContain('Paragraph 2'); 42 | }); 43 | 44 | }); -------------------------------------------------------------------------------- /src/core/agent/index.ts: -------------------------------------------------------------------------------- 1 | export * from './html-cleaner'; 2 | export * from './content-identifier'; 3 | export * from './types'; 4 | export * from './browser-agent'; 5 | export * from './dom-analyzer'; 6 | export * from './browser-actions'; 7 | 8 | -------------------------------------------------------------------------------- /src/core/agent/types.ts: -------------------------------------------------------------------------------- 1 | export interface BrowserAgentAction { 2 | type: 'click' | 'scroll' | 'navigate' | 'extract' | 'read' | 'wait' | 3 | 'think' | 'analyze' | 'classify' | 'summarize'; 4 | target?: string; 5 | value?: any; 6 | taskType?: AgentModelConfig['taskType']; 7 | } 8 | 9 | export interface PageMetadata { 10 | title: string; 11 | url: string; 12 | description: string; 13 | keywords: string; 14 | timestamp: string; 15 | } 16 | 17 | export interface RetryConfig { 18 | maxRetries: number; 19 | delay: number; 20 | backoffFactor: number; 21 | } 22 | 23 | export class ActionError extends Error { 24 | constructor( 25 | public action: BrowserAgentAction, 26 | message: string 27 | ) { 28 | super(`Failed to execute ${action.type}: ${message}`); 29 | this.name = 'ActionError'; 30 | } 31 | } 32 | 33 | export interface AgentState { 34 | currentUrl: string; 35 | lastAction: BrowserAgentAction | null; 36 | actionHistory: BrowserAgentAction[]; 37 | errors: ActionError[]; 38 | } 39 | 40 | export interface AgentModelConfig { 41 | taskType: 'navigation' | 'analysis' | 'extraction' | 'decision' | 'conversation'; 42 | modelId: string; 43 | options?: Record; 44 | } 45 | 46 | export interface AgentConfig { 47 | models: { 48 | [key in AgentModelConfig['taskType']]?: AgentModelConfig; 49 | }; 50 | defaultModel?: string; 51 | } 52 | -------------------------------------------------------------------------------- /src/core/database/storage.ts: -------------------------------------------------------------------------------- 1 | import { Storable, DatabaseConfig } from './types'; 2 | 3 | export interface Storage { 4 | store(data: T): Promise; 5 | get(id: string): Promise; 6 | getAll(): Promise; 7 | update(data: T): Promise; 8 | delete(id: string): Promise; 9 | clear(): Promise; 10 | close(): void; 11 | } 12 | 13 | export interface StorageFactory { 14 | createStorage(type: string, config: DatabaseConfig): Promise> 15 | } -------------------------------------------------------------------------------- /src/core/database/types.ts: -------------------------------------------------------------------------------- 1 | export interface Storable { 2 | id: string; 3 | } 4 | 5 | export interface DatabaseConfig { 6 | databaseName: string; 7 | version?: number; 8 | storeName?: string; 9 | } 10 | 11 | export interface Database { 12 | store(data: T): Promise; 13 | get(id: string): Promise; 14 | getAll(): Promise; 15 | update(data: T): Promise; 16 | delete(id: string): Promise; 17 | clear(): Promise; 18 | close(): void; 19 | } 20 | 21 | export interface VectorStore { 22 | add(id: string, vector: number[]): Promise; 23 | search(vector: number[], topK: number): Promise; 24 | } 25 | 26 | 27 | export interface DatabaseFactory{ 28 | create(config: DatabaseConfig): Database; 29 | } 30 | 31 | export type DatabaseType = 'indexeddb' | 'sqlite'; 32 | 33 | export interface DatabaseOptions { 34 | type: DatabaseType; 35 | config: DatabaseConfig; 36 | } -------------------------------------------------------------------------------- /src/core/database/vectorstore.ts: -------------------------------------------------------------------------------- 1 | import { VectorStore } from './types'; 2 | 3 | export interface VectorStoreFactory { 4 | createVectorStore(type: string): VectorStore; 5 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Import BrowserAI first 2 | import { BrowserAI } from './core/llm'; 3 | 4 | // Export everything as named exports 5 | export { BrowserAI }; 6 | export { MLCEngineWrapper } from './engines/mlc-engine-wrapper'; 7 | export { TransformersEngineWrapper } from './engines/transformer-engine-wrapper'; 8 | export { default as mlcModels } from './config/models/mlc-models.json'; 9 | export { default as transformersModels } from './config/models/transformers-models.json'; 10 | 11 | export { DatabaseImpl } from './core/database'; 12 | export * from './core/agent'; 13 | 14 | // Export PDF parser 15 | export { 16 | PDFParser, 17 | extractTextFromPdf, 18 | extractStructuredTextFromPdf, 19 | processPdfFile, 20 | pdfToText, 21 | type PDFParseOptions, 22 | type PDFParseResult 23 | } from './core/parsers/pdf'; 24 | 25 | // Export CSV parser 26 | export { 27 | CSVParser, 28 | extractDataFromCSV, 29 | extractTextFromCSV, 30 | processCSVFile, 31 | csvToText, 32 | type CSVParseOptions, 33 | type CSVParseResult 34 | } from './core/parsers/csv'; 35 | 36 | // Export DOCX parser 37 | export { 38 | DOCXParser, 39 | extractTextFromDOCX, 40 | processDOCXFile, 41 | docxToText, 42 | type DOCXParseOptions, 43 | type DOCXParseResult 44 | } from './core/parsers/docx'; 45 | 46 | // Export image parser 47 | export { 48 | ImageParser, 49 | extractTextFromImage, 50 | processImageFile, 51 | imageToText 52 | } from './core/parsers/image'; 53 | export type { ImageParseOptions, ImageParseResult } from './core/parsers/image'; 54 | -------------------------------------------------------------------------------- /src/libs/transformers/backends/ort-wasm-simd-threaded.jsep.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/src/libs/transformers/backends/ort-wasm-simd-threaded.jsep.wasm -------------------------------------------------------------------------------- /src/libs/transformers/models/auto/feature_extraction_auto.ts: -------------------------------------------------------------------------------- 1 | import { FEATURE_EXTRACTOR_NAME, GITHUB_ISSUE_URL } from '../../utils/constants.js'; 2 | import { getModelJSON } from '../../utils/hub.js'; 3 | import { FeatureExtractor } from '../../base/feature_extraction_utils.js'; 4 | import * as AllFeatureExtractors from '../feature_extractors.js'; 5 | 6 | export class AutoFeatureExtractor { 7 | /** @type {typeof FeatureExtractor.from_pretrained} */ 8 | static async from_pretrained(pretrained_model_name_or_path: string, options = {}) { 9 | const preprocessorConfig = await getModelJSON(pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME, true, options); 10 | 11 | // Determine feature extractor class 12 | const key = preprocessorConfig.feature_extractor_type; 13 | const feature_extractor_class = AllFeatureExtractors[key as keyof typeof AllFeatureExtractors]; 14 | 15 | if (!feature_extractor_class) { 16 | throw new Error(`Unknown feature_extractor_type: '${key}'. Please report this at ${GITHUB_ISSUE_URL}.`); 17 | } 18 | 19 | // Instantiate feature extractor 20 | return new feature_extractor_class(preprocessorConfig); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/transformers/models/auto/image_processing_auto.ts: -------------------------------------------------------------------------------- 1 | import { GITHUB_ISSUE_URL, IMAGE_PROCESSOR_NAME } from '../../utils/constants'; 2 | import { getModelJSON } from '../../utils/hub'; 3 | import { ImageProcessor } from '../../base/image_processors_utils'; 4 | import { VLMImageProcessor } from '../janus/image_processing_janus'; 5 | 6 | // Map of processor types to their implementations 7 | const PROCESSOR_MAPPING = { 8 | 'VLMImageProcessor': VLMImageProcessor, 9 | 'ImageProcessor': ImageProcessor, 10 | }; 11 | 12 | export class AutoImageProcessor { 13 | /** @type {typeof ImageProcessor.from_pretrained} */ 14 | static async from_pretrained(pretrained_model_name_or_path: string, options: Record = {}) { 15 | const preprocessorConfig = await getModelJSON(pretrained_model_name_or_path, IMAGE_PROCESSOR_NAME, true, options); 16 | 17 | // Determine image processor class 18 | const key = preprocessorConfig.image_processor_type ?? preprocessorConfig.feature_extractor_type; 19 | let image_processor_class = ImageProcessor; 20 | 21 | if (key && key in PROCESSOR_MAPPING) { 22 | image_processor_class = PROCESSOR_MAPPING[key as keyof typeof PROCESSOR_MAPPING]; 23 | } else if (key !== undefined) { 24 | console.warn( 25 | `Image processor type '${key}' not found, assuming base ImageProcessor. Please report this at ${GITHUB_ISSUE_URL}.` 26 | ); 27 | } 28 | 29 | // Instantiate image processor 30 | return new image_processor_class(preprocessorConfig); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/libs/transformers/models/bit/image_processing_bit.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils'; 2 | 3 | export class BitImageProcessor extends ImageProcessor {} 4 | -------------------------------------------------------------------------------- /src/libs/transformers/models/chinese_clip/image_processing_chinese_clip.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils'; 2 | 3 | export class ChineseCLIPFeatureExtractor extends ImageProcessor {} 4 | -------------------------------------------------------------------------------- /src/libs/transformers/models/clip/image_processing_clip.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class CLIPImageProcessor extends ImageProcessor {} 4 | export class CLIPFeatureExtractor extends CLIPImageProcessor {} 5 | -------------------------------------------------------------------------------- /src/libs/transformers/models/convnext/image_processing_convnext.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class ConvNextImageProcessor extends ImageProcessor { 4 | constructor(config: any) { 5 | super(config); 6 | 7 | /** 8 | * Percentage of the image to crop. Only has an effect if this.size < 384. 9 | */ 10 | // @ts-expect-error TS2339 11 | this.crop_pct = this.config.crop_pct ?? 224 / 256; 12 | } 13 | 14 | async resize(image: any) { 15 | const shortest_edge = this.size?.shortest_edge; 16 | if (shortest_edge === undefined) { 17 | throw new Error(`Size dictionary must contain 'shortest_edge' key.`); 18 | } 19 | 20 | if (shortest_edge < 384) { 21 | // maintain same ratio, resizing shortest edge to shortest_edge/crop_pct 22 | const resize_shortest_edge = Math.floor(shortest_edge / this.crop_pct); 23 | 24 | const [newWidth, newHeight] = this.get_resize_output_image_size(image, { 25 | shortest_edge: resize_shortest_edge, 26 | }); 27 | 28 | image = await image.resize(newWidth, newHeight, { 29 | resample: this.resample, 30 | }); 31 | 32 | // then crop to (shortest_edge, shortest_edge) 33 | image = await image.center_crop(shortest_edge, shortest_edge); 34 | } else { 35 | // warping (no cropping) when evaluated at 384 or larger 36 | image = await image.resize(shortest_edge, shortest_edge, { 37 | resample: this.resample, 38 | }); 39 | } 40 | 41 | return image; 42 | } 43 | } 44 | export class ConvNextFeatureExtractor extends ConvNextImageProcessor {} 45 | -------------------------------------------------------------------------------- /src/libs/transformers/models/deit/image_processing_deit.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class DeiTImageProcessor extends ImageProcessor {} 4 | export class DeiTFeatureExtractor extends DeiTImageProcessor {} 5 | -------------------------------------------------------------------------------- /src/libs/transformers/models/donut/image_processing_donut.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils'; 2 | 3 | export class DonutImageProcessor extends ImageProcessor { 4 | pad_image(pixelData: any, imgDims: any, padSize: any, options = {}) { 5 | const [imageHeight, imageWidth, imageChannels] = imgDims; 6 | 7 | let image_mean = this.image_mean ?? [0.5, 0.5, 0.5]; 8 | if (!Array.isArray(this.image_mean)) { 9 | image_mean = new Array(imageChannels).fill(image_mean); 10 | } 11 | 12 | let image_std = this.image_std; 13 | if (!Array.isArray(image_std)) { 14 | image_std = new Array(imageChannels).fill(image_mean); 15 | } 16 | 17 | const constant_values = image_mean.map((x, i) => -x / image_std[i]); 18 | 19 | return super.pad_image(pixelData, imgDims, padSize, constant_values, 'constant', true); 20 | } 21 | } 22 | export class DonutFeatureExtractor extends DonutImageProcessor {} 23 | -------------------------------------------------------------------------------- /src/libs/transformers/models/feature_extractors.ts: -------------------------------------------------------------------------------- 1 | export * from './audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer'; 2 | export * from './clap/feature_extraction_clap'; 3 | export * from './moonshine/feature_extraction_moonshine'; 4 | export * from './pyannote/feature_extraction_pyannote'; 5 | export * from './seamless_m4t/feature_extraction_seamless_m4t'; 6 | export * from './speecht5/feature_extraction_speecht5'; 7 | export * from './wav2vec2/feature_extraction_wav2vec2'; 8 | export * from './wespeaker/feature_extraction_wespeaker'; 9 | export * from './whisper/feature_extraction_whisper'; 10 | 11 | // For legacy support, ImageFeatureExtractor is an alias for ImageProcessor 12 | export { ImageProcessor as ImageFeatureExtractor } from '../base/image_processors_utils'; 13 | -------------------------------------------------------------------------------- /src/libs/transformers/models/image_processors.ts: -------------------------------------------------------------------------------- 1 | export * from './bit/image_processing_bit'; 2 | export * from './chinese_clip/image_processing_chinese_clip'; 3 | export * from './clip/image_processing_clip'; 4 | export * from './convnext/image_processing_convnext'; 5 | export * from './deit/image_processing_deit'; 6 | export * from './idefics3/image_processing_idefics3'; 7 | export * from './janus/image_processing_janus'; 8 | export * from './jina_clip/image_processing_jina_clip'; 9 | export * from './llava_onevision/image_processing_llava_onevision'; 10 | export * from './phi3_v/image_processing_phi3_v'; 11 | export * from './qwen2_vl/image_processing_qwen2_vl'; 12 | export * from './sam/image_processing_sam'; 13 | export * from './siglip/image_processing_siglip'; 14 | export * from './swin2sr/image_processing_swin2sr'; 15 | export * from './vitmatte/image_processing_vitmatte'; 16 | export * from './vitpose/image_processing_vitpose'; 17 | -------------------------------------------------------------------------------- /src/libs/transformers/models/janus/image_processing_janus.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class VLMImageProcessor extends ImageProcessor { 4 | constructor(config) { 5 | super({ 6 | do_pad: true, 7 | pad_size: { 8 | width: config.image_size, 9 | height: config.image_size, 10 | }, 11 | ...config, 12 | }); 13 | // @ts-expect-error TS2339 14 | this.constant_values = this.config.background_color.map((x) => x * this.rescale_factor); 15 | } 16 | 17 | pad_image(pixelData, imgDims, padSize, options) { 18 | return super.pad_image(pixelData, imgDims, padSize, { 19 | constant_values: this.constant_values, 20 | center: true, 21 | ...options, 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/libs/transformers/models/jina_clip/image_processing_jina_clip.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class JinaCLIPImageProcessor extends ImageProcessor { 4 | constructor(config) { 5 | // JinaCLIPImageProcessor uses a custom preprocessor_config.json, so we configure it here 6 | const { resize_mode, fill_color, interpolation, size, ...other } = config; 7 | 8 | const new_size = 9 | resize_mode === 'squash' 10 | ? { width: size, height: size } 11 | : resize_mode === 'shortest' 12 | ? { shortest_edge: size } 13 | : { longest_edge: size }; 14 | 15 | const resample = interpolation === 'bicubic' ? 3 : 2; 16 | super({ 17 | ...other, 18 | size: new_size, 19 | resample, 20 | do_center_crop: true, 21 | crop_size: size, 22 | do_normalize: true, 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/libs/transformers/models/jina_clip/processing_jina_clip.ts: -------------------------------------------------------------------------------- 1 | import { Processor } from '../../base/processing_utils.js'; 2 | import { AutoImageProcessor } from '../auto/image_processing_auto.js'; 3 | import { AutoTokenizer } from '../../tokenizers.js'; 4 | 5 | export class JinaCLIPProcessor extends Processor { 6 | static tokenizer_class = AutoTokenizer; 7 | static image_processor_class = AutoImageProcessor; 8 | 9 | async _call(text = null, images = null, kwargs = {}) { 10 | if (!text && !images) { 11 | throw new Error('Either text or images must be provided'); 12 | } 13 | 14 | const text_inputs = text ? this.tokenizer(text, kwargs) : {}; 15 | const image_inputs = images ? await this.image_processor(images, kwargs) : {}; 16 | 17 | return { 18 | ...text_inputs, 19 | ...image_inputs, 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/transformers/models/llava_onevision/image_processing_llava_onevision.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class LlavaOnevisionImageProcessor extends ImageProcessor {} 4 | -------------------------------------------------------------------------------- /src/libs/transformers/models/moonshine/feature_extraction_moonshine.ts: -------------------------------------------------------------------------------- 1 | import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js'; 2 | import { Tensor } from '../../utils/tensor.js'; 3 | 4 | export class MoonshineFeatureExtractor extends FeatureExtractor { 5 | /** 6 | * Asynchronously extracts input values from a given audio using the provided configuration. 7 | * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array. 8 | * @returns {Promise<{ input_values: Tensor; }>} The extracted input values. 9 | */ 10 | async _call(audio) { 11 | validate_audio_inputs(audio, 'MoonshineFeatureExtractor'); 12 | 13 | if (audio instanceof Float64Array) { 14 | audio = new Float32Array(audio); 15 | } 16 | 17 | const shape = [1 /* batch_size */, audio.length /* num_samples */]; 18 | return { 19 | input_values: new Tensor('float32', audio, shape), 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/transformers/models/moonshine/processing_moonshine.ts: -------------------------------------------------------------------------------- 1 | import { AutoFeatureExtractor } from '../auto/feature_extraction_auto.js'; 2 | import { AutoTokenizer } from '../../tokenizers.js'; 3 | import { Processor } from '../../base/processing_utils.js'; 4 | 5 | /** 6 | * Represents a MoonshineProcessor that extracts features from an audio input. 7 | */ 8 | export class MoonshineProcessor extends Processor { 9 | static tokenizer_class = AutoTokenizer; 10 | static feature_extractor_class = AutoFeatureExtractor; 11 | 12 | /** 13 | * Calls the feature_extractor function with the given audio input. 14 | * @param {any} audio The audio input to extract features from. 15 | * @returns {Promise} A Promise that resolves with the extracted features. 16 | */ 17 | async _call(audio) { 18 | return await this.feature_extractor(audio); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/libs/transformers/models/processors.ts: -------------------------------------------------------------------------------- 1 | export * from './florence2/processing_florence2'; 2 | export * from './idefics3/processing_idefics3'; 3 | export * from './mgp_str/processing_mgp_str'; 4 | export * from './moonshine/processing_moonshine'; 5 | export * from './janus/processing_janus'; 6 | export * from './jina_clip/processing_jina_clip'; 7 | export * from './phi3_v/processing_phi3_v'; 8 | export * from './paligemma/processing_paligemma'; 9 | export * from './pyannote/processing_pyannote'; 10 | export * from './qwen2_vl/processing_qwen2_vl'; 11 | export * from './sam/processing_sam'; 12 | export * from './speecht5/processing_speecht5'; 13 | export * from './wav2vec2/processing_wav2vec2'; 14 | export * from './whisper/processing_whisper'; 15 | -------------------------------------------------------------------------------- /src/libs/transformers/models/pyannote/processing_pyannote.ts: -------------------------------------------------------------------------------- 1 | import { Processor } from '../../base/processing_utils.js'; 2 | import { PyAnnoteFeatureExtractor } from './feature_extraction_pyannote.js'; 3 | 4 | export class PyAnnoteProcessor extends Processor { 5 | static feature_extractor_class = PyAnnoteFeatureExtractor; 6 | 7 | /** 8 | * Calls the feature_extractor function with the given audio input. 9 | * @param {any} audio The audio input to extract features from. 10 | * @returns {Promise} A Promise that resolves with the extracted features. 11 | */ 12 | async _call(audio) { 13 | return await this.feature_extractor(audio); 14 | } 15 | 16 | /** @type {PyAnnoteFeatureExtractor['post_process_speaker_diarization']} */ 17 | post_process_speaker_diarization(...args) { 18 | return /** @type {PyAnnoteFeatureExtractor} */ this.feature_extractor.post_process_speaker_diarization(...args); 19 | } 20 | 21 | get sampling_rate() { 22 | return this.feature_extractor.config.sampling_rate; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/libs/transformers/models/qwen2_vl/image_processing_qwen2_vl.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | import { cat, Tensor } from '../../utils/tensor.js'; 3 | 4 | export class Qwen2VLImageProcessor extends ImageProcessor { 5 | async _call(images, ...args) { 6 | const { pixel_values, original_sizes, reshaped_input_sizes } = await super._call(images, ...args); 7 | 8 | let patches = pixel_values; 9 | 10 | // @ts-ignore 11 | const { temporal_patch_size, merge_size, patch_size } = this.config; 12 | if (patches.dims[0] === 1) { 13 | // Equivalent to np.tile(patches, (self.temporal_patch_size, 1, 1, 1)) 14 | patches = cat( 15 | Array.from({ length: temporal_patch_size }, () => patches), 16 | 0, 17 | ); 18 | } 19 | 20 | const grid_t = patches.dims[0] / temporal_patch_size; 21 | const channel = patches.dims[1]; 22 | const grid_h = Math.floor(patches.dims[2] / patch_size); 23 | const grid_w = Math.floor(patches.dims[3] / patch_size); 24 | 25 | const flatten_patches = patches 26 | .view( 27 | grid_t, 28 | temporal_patch_size, 29 | channel, 30 | Math.floor(grid_h / merge_size), 31 | merge_size, 32 | patch_size, 33 | Math.floor(grid_w / merge_size), 34 | merge_size, 35 | patch_size, 36 | ) 37 | .permute(0, 3, 6, 4, 7, 2, 1, 5, 8) 38 | .view(grid_t * grid_h * grid_w, channel * temporal_patch_size * patch_size * patch_size); 39 | 40 | const image_grid_thw = new Tensor('int64', [grid_t, grid_h, grid_w], [1, 3]); 41 | 42 | return { 43 | pixel_values: flatten_patches, 44 | image_grid_thw, 45 | original_sizes, 46 | reshaped_input_sizes, 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/libs/transformers/models/qwen2_vl/processing_qwen2_vl.ts: -------------------------------------------------------------------------------- 1 | import { Processor } from '../../base/processing_utils.js'; 2 | import { AutoImageProcessor } from '../auto/image_processing_auto.js'; 3 | import { AutoTokenizer } from '../../tokenizers.js'; 4 | import { RawImage } from '../../utils/image.js'; 5 | 6 | export class Qwen2VLProcessor extends Processor { 7 | static image_processor_class = AutoImageProcessor; 8 | static tokenizer_class = AutoTokenizer; 9 | 10 | /** 11 | * 12 | * @param {string|string[]} text 13 | * @param {RawImage|RawImage[]} images 14 | * @param {...any} args 15 | * @returns {Promise} 16 | */ 17 | async _call(text, images = null, ...args) { 18 | if (!Array.isArray(text)) { 19 | text = [text]; 20 | } 21 | 22 | let image_inputs, image_grid_thw; 23 | 24 | if (images) { 25 | image_inputs = await this.image_processor(images); 26 | image_grid_thw = image_inputs.image_grid_thw; 27 | } 28 | 29 | if (image_grid_thw) { 30 | // @ts-expect-error TS2551 31 | let merge_length = this.image_processor.config.merge_size ** 2; 32 | let index = 0; 33 | 34 | const image_grid_thw_list = image_grid_thw.tolist(); 35 | text = text.map((t) => { 36 | while (t.includes('<|image_pad|>')) { 37 | const prod = Number(image_grid_thw_list[index++].reduce((a, b) => a * b, 1n)); 38 | t = t.replace('<|image_pad|>', '<|placeholder|>'.repeat(Math.floor(prod / merge_length))); 39 | } 40 | return t.replaceAll('<|placeholder|>', '<|image_pad|>'); 41 | }); 42 | } 43 | 44 | const text_inputs = this.tokenizer(text); 45 | 46 | return { 47 | ...text_inputs, 48 | ...image_inputs, 49 | // TODO: ...videos_inputs, 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/libs/transformers/models/sam/processing_sam.ts: -------------------------------------------------------------------------------- 1 | import { Processor } from '../../base/processing_utils.js'; 2 | import { AutoImageProcessor } from '../auto/image_processing_auto.js'; 3 | 4 | export class SamProcessor extends Processor { 5 | static image_processor_class = AutoImageProcessor; 6 | 7 | async _call(...args) { 8 | return await this.image_processor(...args); 9 | } 10 | 11 | post_process_masks(...args) { 12 | // @ts-ignore 13 | return this.image_processor.post_process_masks(...args); 14 | } 15 | 16 | reshape_input_points(...args) { 17 | // @ts-ignore 18 | return this.image_processor.reshape_input_points(...args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/libs/transformers/models/siglip/image_processing_siglip.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class SiglipImageProcessor extends ImageProcessor {} 4 | -------------------------------------------------------------------------------- /src/libs/transformers/models/speecht5/feature_extraction_speecht5.ts: -------------------------------------------------------------------------------- 1 | import { FeatureExtractor } from '../../base/feature_extraction_utils.js'; 2 | 3 | export class SpeechT5FeatureExtractor extends FeatureExtractor {} 4 | -------------------------------------------------------------------------------- /src/libs/transformers/models/speecht5/processing_speecht5.ts: -------------------------------------------------------------------------------- 1 | import { Processor } from '../../base/processing_utils.js'; 2 | import { AutoTokenizer } from '../../tokenizers.js'; 3 | import { AutoFeatureExtractor } from '../auto/feature_extraction_auto.js'; 4 | 5 | export class SpeechT5Processor extends Processor { 6 | static tokenizer_class = AutoTokenizer; 7 | static feature_extractor_class = AutoFeatureExtractor; 8 | 9 | /** 10 | * Calls the feature_extractor function with the given input. 11 | * @param {any} input The input to extract features from. 12 | * @returns {Promise} A Promise that resolves with the extracted features. 13 | */ 14 | async _call(input) { 15 | return await this.feature_extractor(input); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/libs/transformers/models/swin2sr/image_processing_swin2sr.ts: -------------------------------------------------------------------------------- 1 | import { ImageProcessor } from '../../base/image_processors_utils.js'; 2 | 3 | export class Swin2SRImageProcessor extends ImageProcessor { 4 | pad_image(pixelData, imgDims, padSize, options = {}) { 5 | // NOTE: In this case, `padSize` represents the size of the sliding window for the local attention. 6 | // In other words, the image is padded so that its width and height are multiples of `padSize`. 7 | const [imageHeight, imageWidth, imageChannels] = imgDims; 8 | 9 | return super.pad_image( 10 | pixelData, 11 | imgDims, 12 | { 13 | // NOTE: For Swin2SR models, the original python implementation adds padding even when the image's width/height is already 14 | // a multiple of `pad_size`. However, this is most likely a bug (PR: https://github.com/mv-lab/swin2sr/pull/19). 15 | // For this reason, we only add padding when the image's width/height is not a multiple of `pad_size`. 16 | width: imageWidth + ((padSize - (imageWidth % padSize)) % padSize), 17 | height: imageHeight + ((padSize - (imageHeight % padSize)) % padSize), 18 | }, 19 | { 20 | mode: 'symmetric', 21 | center: false, 22 | constant_values: -1, 23 | ...options, 24 | }, 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/libs/transformers/models/wav2vec2/processing_wav2vec2.ts: -------------------------------------------------------------------------------- 1 | import { Processor } from '../../base/processing_utils.js'; 2 | import { AutoFeatureExtractor } from '../auto/feature_extraction_auto.js'; 3 | 4 | export class Wav2Vec2ProcessorWithLM extends Processor { 5 | static feature_extractor_class = AutoFeatureExtractor; 6 | 7 | /** 8 | * Calls the feature_extractor function with the given audio input. 9 | * @param {any} audio The audio input to extract features from. 10 | * @returns {Promise} A Promise that resolves with the extracted features. 11 | */ 12 | async _call(audio) { 13 | return await this.feature_extractor(audio); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/libs/transformers/models/whisper/processing_whisper.ts: -------------------------------------------------------------------------------- 1 | import { AutoFeatureExtractor } from '../auto/feature_extraction_auto'; 2 | import { AutoTokenizer } from '../../tokenizers'; 3 | import { Processor } from '../../base/processing_utils'; 4 | 5 | /** 6 | * Represents a WhisperProcessor that extracts features from an audio input. 7 | */ 8 | export class WhisperProcessor extends Processor { 9 | static tokenizer_class = AutoTokenizer; 10 | static feature_extractor_class = AutoFeatureExtractor; 11 | 12 | /** 13 | * Calls the feature_extractor function with the given audio input. 14 | * @param {any} audio The audio input to extract features from. 15 | * @returns {Promise} A Promise that resolves with the extracted features. 16 | */ 17 | async _call(audio) { 18 | return await this.feature_extractor(audio); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/libs/transformers/transformers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Entry point for the Transformers.js library. Only the exports from this file 3 | * are available to the end user, and are grouped as follows: 4 | * 5 | * 1. [Pipelines](./pipelines) 6 | * 2. [Environment variables](./env) 7 | * 3. [Models](./models) 8 | * 4. [Tokenizers](./tokenizers) 9 | * 5. [Processors](./processors) 10 | * 11 | * @module transformers 12 | */ 13 | 14 | export { env } from './env'; 15 | 16 | export * from './pipelines.js'; 17 | export * from './models.js'; 18 | export * from './tokenizers.js'; 19 | export * from './configs.js'; 20 | 21 | export * from './utils/audio.js'; 22 | export * from './utils/image.js'; 23 | export * from './utils/tensor.js'; 24 | export * from './utils/maths.js'; 25 | 26 | export { FeatureExtractor } from './base/feature_extraction_utils.js'; 27 | export * from './models/feature_extractors.js'; 28 | export * from './models/auto/feature_extraction_auto.js'; 29 | 30 | export { ImageProcessor } from './base/image_processors_utils.js'; 31 | export * from './models/image_processors.js'; 32 | export * from './models/auto/image_processing_auto.js'; 33 | 34 | export { Processor } from './base/processing_utils.js'; 35 | export * from './models/processors.js'; 36 | export * from './models/auto/processing_auto.js'; 37 | 38 | export * from './generation/streamers.js'; 39 | export * from './generation/stopping_criteria.js'; 40 | export * from './generation/logits_process.js'; 41 | export * from './types'; -------------------------------------------------------------------------------- /src/libs/transformers/utils/constants.d.ts: -------------------------------------------------------------------------------- 1 | export const GITHUB_ISSUE_URL: string; 2 | export const FEATURE_EXTRACTOR_NAME: string; 3 | export const IMAGE_PROCESSOR_NAME: string; 4 | export const CONFIG_NAME: string; 5 | export const PROCESSOR_NAME: string; 6 | export const CHAT_TEMPLATE_NAME: string; 7 | export const GENERATION_CONFIG_NAME: string; 8 | -------------------------------------------------------------------------------- /src/libs/transformers/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const GITHUB_ISSUE_URL = 'https://github.com/sauravpanda/browserai/issues'; 2 | 3 | export const CONFIG_NAME = 'config.json'; 4 | export const FEATURE_EXTRACTOR_NAME = 'preprocessor_config.json'; 5 | export const IMAGE_PROCESSOR_NAME = 'preprocessor_config.json'; 6 | 7 | export const PROCESSOR_NAME = 'processor_config.json'; 8 | export const CHAT_TEMPLATE_NAME = 'chat_template.json'; 9 | export const GENERATION_CONFIG_NAME = 'generation_config.json'; 10 | -------------------------------------------------------------------------------- /src/libs/transformers/utils/devices.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The list of devices supported by Transformers.js 3 | */ 4 | export const DEVICE_TYPES = Object.freeze({ 5 | auto: 'auto', // Auto-detect based on device and environment 6 | gpu: 'gpu', // Auto-detect GPU 7 | cpu: 'cpu', // CPU 8 | wasm: 'wasm', // WebAssembly 9 | webgpu: 'webgpu', // WebGPU 10 | cuda: 'cuda', // CUDA 11 | dml: 'dml', // DirectML 12 | 13 | webnn: 'webnn', // WebNN (default) 14 | 'webnn-npu': 'webnn-npu', // WebNN NPU 15 | 'webnn-gpu': 'webnn-gpu', // WebNN GPU 16 | 'webnn-cpu': 'webnn-cpu', // WebNN CPU 17 | }); 18 | 19 | /** 20 | * @typedef {keyof typeof DEVICE_TYPES} DeviceType 21 | */ 22 | -------------------------------------------------------------------------------- /src/libs/transformers/utils/generic.ts: -------------------------------------------------------------------------------- 1 | export const Callable = /** @type {any} */ class { 2 | constructor() { 3 | let closure = function (this: any, ...args: any[]): any { 4 | return (closure as any)._call(...args); 5 | }; 6 | return Object.setPrototypeOf(closure, new.target.prototype); 7 | } 8 | 9 | _call(...args: any[]) { 10 | throw Error('Must implement _call method in subclass'); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /src/libs/transformers/utils/pipelines.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravpanda/BrowserAI/65eefbef53b3335b94631135272d04628dfbee7b/src/libs/transformers/utils/pipelines.ts -------------------------------------------------------------------------------- /src/types/backends.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'backends'; 2 | -------------------------------------------------------------------------------- /src/types/base.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'base'; 2 | -------------------------------------------------------------------------------- /src/types/generation.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'generation'; 2 | -------------------------------------------------------------------------------- /src/types/models.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'models'; 2 | -------------------------------------------------------------------------------- /src/types/ops.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'ops'; -------------------------------------------------------------------------------- /src/types/utils.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'utils'; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "resolveJsonModule": true, 9 | "isolatedModules": true, 10 | "esModuleInterop": true, 11 | "noEmit": false, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "noImplicitReturns": true, 15 | "skipLibCheck": true, 16 | "declaration": true, 17 | "outDir": "./dist", 18 | "baseUrl": ".", 19 | "paths": { 20 | "@/*": ["src/*"] 21 | }, 22 | "declarationDir": "./dist", 23 | "typeRoots": ["./src/libs/transformers", "node_modules/@types", "./src/types"] 24 | }, 25 | "include": ["src/**/*"], 26 | "exclude": ["node_modules", "dist", "examples"], 27 | "allowJs": true 28 | } 29 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.ts'], 5 | format: ['esm', 'cjs'], 6 | dts: true, 7 | clean: true, 8 | sourcemap: true, 9 | treeshake: false, 10 | splitting: false, 11 | outDir: 'dist', 12 | outExtension({ format }) { 13 | return { 14 | js: format === 'esm' ? '.mjs' : '.js' 15 | }; 16 | }, 17 | target: 'es2020', 18 | platform: 'browser', 19 | minify: false, 20 | shims: false, 21 | noExternal: [], 22 | esbuildOptions(options) { 23 | options.platform = 'neutral'; 24 | }, 25 | bundle: true, 26 | skipNodeModulesBundle: true, 27 | }); 28 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | export default defineConfig({ 5 | plugins: [react()], 6 | build: { 7 | commonjsOptions: { 8 | include: [/@browserai\/browserai/, /node_modules/] 9 | } 10 | }, 11 | optimizeDeps: { 12 | include: ['@browserai/browserai'] 13 | } 14 | }); --------------------------------------------------------------------------------
Use this panel to interact with your AI assistant.
Paragraph 1
Paragraph 2