feat: add bare React Native LLM chat example app#2
Open
rizalibnu wants to merge 66 commits into
Open
Conversation
c27a355 to
bb65951
Compare
6a63f5a to
246348c
Compare
…oftware-mansion#811) ## Description A base64 data URI (e.g. data:image/png;base64,iVBOR...) splits text into 2 segments, but the check was comparing against 1, causing all valid base64 image inputs to be rejected. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [x] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [x] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [ ] Android ### Testing instructions Run tests and check if they work. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues software-mansion#809 ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. --> --------- Co-authored-by: ionkorol <ion@korol.dev>
…Native (software-mansion#759) ## Description This PR introduces modular resource fetcher adapters to support both Expo and bare React Native environments, replacing the previous monolithic approach with a flexible, platform-specific architecture. **Key Changes** New Adapter Packages: - @rn-executorch/expo-adapter: Resource fetcher for Expo projects using expo-file-system and expo-asset - @rn-executorch/bare-adapter: Resource fetcher for bare React Native projects using @dr.pogodin/react-native-fs and @kesha-antonov/react-native-background-downloader **Initialization Changes:** - Added initExecutorch() function that requires explicit adapter selection - Users must now choose and configure the appropriate adapter for their project type - Provides better separation of concerns and platform-specific optimizations **Documentation Updates:** - Created individual README.md files for each adapter package ### Introduces a breaking change? - [x] Yes - [ ] No **Migration Required:** Users must now explicitly initialize the library with a resource fetcher adapter: ```typescript // Before (no initialization needed) import { useLLM } from 'react-native-executorch'; // After (required initialization) import { initExecutorch, useLLM } from 'react-native-executorch'; import { ExpoResourceFetcher } from '@rn-executorch/expo-adapter'; // or BareResourceFetcher initExecutorch({ resourceFetcher: ExpoResourceFetcher, }); ``` ### Type of change - [ ] Bug fix (change which fixes an issue) - [x] New feature (change which adds functionality) - [x] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions **For Expo projects:** - Install dependencies: `yarn add @rn-executorch/expo-adapter expo-file-system expo-asset` - Initialize: `initExecutorch({ resourceFetcher: ExpoResourceFetcher })` - Run existing LLM example app to verify model downloads work correctly **For bare React Native projects:** - Install dependencies: `yarn add @rn-executorch/bare-adapter @dr.pogodin/react-native-fs @kesha-antonov/react-native-background-downloader` - Initialize: `initExecutorch({ resourceFetcher: BareResourceFetcher })` - Run the bare React Native example app in PR software-mansion#763 > Note: A separate PR will add a dedicated bare React Native example app to make this PR easier to review. The Expo example apps can be used to verify the Expo adapter functionality. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues Closes software-mansion#549 ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes **Why This Change:** - Different React Native environments have different filesystem APIs and c - apabilities - Expo projects benefit from using Expo's managed filesystem APIs - Bare React Native projects can leverage native libraries with background download support - Modular architecture allows for better platform-specific optimizations - Enables future extensibility for other environments (e.g., React Native Windows, macOS) **Split Into Multiple PRs:** To make review easier, this work has been split: - This PR: Core adapter infrastructure and Expo adapter implementation - Follow-up PR: Bare React Native example app demonstrating the bare adapter usage BREAKING CHANGE: `initExecutorch()` with explicit adapter selection is now required before using any react-native-executorch hooks. Users must install and configure either `@rn-executorch/expo-adapter` or `@rn-executorch/bare-adapter` depending on their project type. --------- Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com> Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com> Co-authored-by: Jakub Chmura <92989966+chmjkb@users.noreply.github.com>
## Description Adds GTM integration. Tag G-TJND8QJM9P is now embedded inside GTM-WNBF6SVN container.
…nsion#814) ## Description Refactors image segmentation into a generic, multi-model architecture. Previously the module was hardcoded to DeepLab V3 — now it supports multiple built-in models (DeepLab V3, selfie segmentation, RF-DETR) and custom user-provided models with type-safe label maps. **Key changes:** - **C++ base class**: Extracted `BaseImageSegmentation` with virtual `preprocess()`/`postprocess()` methods. `ImageSegmentation` is now a thin subclass. This allows future models to override preprocessing (e.g. different normalization) or postprocessing without duplicating the pipeline. - **Optional normalization in C++**: `readImageToTensor` now accepts optional `normMean`/`normStd` params, eliminating duplicated normalization logic. **also, imo it would be a good idea to do such factories for the entire API** - **Generic TypeScript module**: `ImageSegmentationModule<T>` is generic over model name or custom `LabelEnum`. Two static factories: `fromModelName()` (built-in models with auto label resolution) and `fromCustomConfig()` (custom models with user-provided labels). - **Generic hook**: `useImageSegmentation` infers the model's label types from the config — no explicit generic parameter needed. `forward()` return type narrows based on `classesOfInterest` passed in. - **Correct return types**: `forward()` now returns `Record<'ARGMAX', Int32Array> & Record<K, Float32Array>` matching what the native side actually produces (was incorrectly typed as `number[]`). - **ARGMAX always returned**: Removed `'ARGMAX'` from `classesOfInterest` — it's always in the output regardless, and the return type reflects this. ### Introduces a breaking change? - [x] Yes - [ ] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [x] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [x] Android ### Testing instructions 1. Build and run the `computer-vision` demo app 2. Navigate to Image Segmentation screen 3. Pick an image and run segmentation — verify the ARGMAX overlay renders correctly 4. Verify the hook API works as expected: ```ts const { isReady, forward } = useImageSegmentation({ model: { modelName: 'deeplab-v3', modelSource: DEEPLAB_V3_RESNET50 }, }); // Returns Record<'ARGMAX', Int32Array> — no generic needed const result = await forward(imageUri); // Narrows return type to include 'PERSON' key as Float32Array const result2 = await forward(imageUri, ['PERSON']); ``` 5. Verify TypeScript autocompletion: `classesOfInterest` should only suggest valid label keys for the chosen model (e.g. `'PERSON'`, `'CAR'` for DeepLab, `'SELFIE'`/`'BACKGROUND'` for selfie segmentation) 6. You can also try changing the parameters, to say selfie segmentation and see how the return types react. Please contact me for weights for selfie segmentation as I'm not pushing them to HF yet ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes The `ImageSegmentationModule.fromCustomConfig()` API allows users to bring their own segmentation model with a custom label map: ```ts const MyLabels = { BACKGROUND: 0, FOREGROUND: 1 } as const; const seg = await ImageSegmentationModule.fromCustomConfig( 'https://example.com/model.pte', { labelMap: MyLabels }, ); ``` --------- Co-authored-by: Mateusz Kopcinski <120639731+mkopcins@users.noreply.github.com>
## Description This PR adds new tokenizer headers and bumps executorch binaries to reflect the changes. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions Run apps for LLM, T2I, S2T, Embedding
## Description This PR fixes few bugs related to the LLMs, caused by mixing two approaches - functional (as we pass whole messages history each time) and stateful (as we keep `pos_` in the runner, representing at which position the KV cache is), which resulted in 3 bugs: - broken KV cache for reasoning models - in the runner, we counted tokens generated for the reasoning and included these in KV cache (`pos_ += num_generated_tokens`), but in next turns, `jinja template` removed these reasoning tokens from the messages history - as a result, KV-cache was incoherent - duplicated tokens in KV cache - we were passing whole messages history to the runner (functional approach), but we were also appending all tokens (prompt and generated) to the KV cache (which position is represented by `pos_`) - as a result tokens were "duplicated" in the KV cache and we were running out of available tokens very fast (exceeding `context_window_length`) - stateful TS functional API - even though our `generate()` method is called functional, it kept internal state in the runner (e. g. `pos_`) These bugs were fixed by resetting the runner before each generation, which makes it truly functional - old messages are prefilled and the KV cache can be still used during generation phase. Additionally, this PR adds `ContextStrategy` to `ChatConfig` interface, so now it's possible to define (or use one of already implemented) strategy for managing context (e. g. naive, message count based, sliding window) - it gives us more flexibility and user can decide what's best for their use case. From now on, `SlidingWindowContextStrategy` is also configured as the default one. ### Introduces a breaking change? - [x] Yes - [ ] No These changes will not break anything until max number of messages is not modified (I removed `contextWindowLength` from `ChatConfig` and replaced it with `contextStrategy`) ### Type of change - [x] Bug fix (change which fixes an issue) - [x] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions Run example llm app, open executorch logs (`adb logcat | grep -i "executorch"` for example) and see if numbers of tokens are properly aligned and if `pos_` is correct. To test different context management strategies, change `contextStrategy` in llm app and modify model configuration. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues software-mansion#776 ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes Position in KV cache, number of prompt tokens and number of generated tokens for both non-reasoning and reasoning models BEFORE changes. LLAMA 3.2 1B SPINQUANT (without reasoning) | pos_ | Prompt tokens | Generated tokens | |------------------|---------------|------------------| | 0 | 335 | 269 | | 604=269+335 | 872 | 372 | | 1848=604+872+372 | 1513 | CRASH | QWEN 3.0 0.6B QUANTIZED (with reasoning) | pos_ | Prompt tokens | Generated tokens | |------------------|---------------|------------------| | 0 | 309 | 457 | | 766=309+457 | 617 (<766!) | 192 | | 1575=766+617+192 | 925 (<1575!) | CRASH |
## Description This PR necessary scripts and CI workflows to handle autogenerated API-reference docs. Currently, any change to the Typescript API changes all references files because SHA in urls changes - as a result PRs are hard to review and some bugs/discrepancies in docs can be merged more easily. This PR: - adds CI workflow that checks if TS API-reference is up-to-date with TypeDocs from code - configures TypeDoc so urls point to `main` branch instead of specific SHAs and so external references are excluded - adds script for building versioned docs that build specific version of docs and replaces all `main` occurences in reference URLs to appropriate SHAs (we want to truncate the history there and point to specific point in history instead of `main` branch) - rebuilds docs with new configuration ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [x] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on N/A ### Testing instructions **1. Script for building specific version of docs** Run: ```bash cd docs yarn docs:version 0.8.x ``` and verify if `main` was changed to valid SHA in all reference urls (so urls for specific version are truncated to some point in history instead of latest main) **2. Github Action for detecting outdated api reference** Check results of actions for commits [7133ca4](software-mansion@7133ca4) and [2a4247c](software-mansion@2a4247c): - the first commit introduces some changes to typescript api, but docs were not built on purpose - as a result `Check if API reference is up-to-date` workflow failed - the first commit reverts this change, so generated api reference is up-to-date with typedocs - as a result `Check if API reference is up-to-date` workflow succeeded **3. Start docs locally and check if everything (exceptionally API-reference) works** ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues software-mansion#790 ### Checklist - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
## Description This PR fixes paths on which `api-reference-up-to-date-check.yml` workflow is triggered, so now any change to TS api triggers workflow that checks if TS api reference is up-to-date ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions <!-- Provide step-by-step instructions on how to test your changes. Include setup details if necessary. --> ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
…on#836) ## Description <!-- Provide a concise and descriptive summary of the changes implemented in this PR. --> ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions After merge it should trigger aggregated PR with all packages updated to fixed versions. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
…xample app) (software-mansion#834) ## Description This PR fixes permissions management for tool calling example app, so user will be always prompted for missing permissions even if denied them at some point. This PR: - adds `Alert` that asks for permissions again - adds banners (with links) that show missing permissions ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [x] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions Run LLM Tool Calling example app ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues software-mansion#774 ### Checklist - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
## Description Adds support for fm-2.5 instruct model. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions Run llm example app with model changed from `LLAMA3_2_1B_SPINQUANT` to both `LFM2_5_1_2B_INSTRUCT` and `LFM2_5_1_2B_INSTRUCT_QUANTIZED`. Also check that Hugging Face page for the model is correct and contains every needed information: https://huggingface.co/software-mansion/react-native-executorch-lfm2.5-1.2B-instruct. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues Closes software-mansion#812 ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
…ansion#838-software-mansion#877) (software-mansion#878) Aggregates 40 Dependabot PRs into a single update: - @evilmartians/lefthook: 1.13.6 -> 2.1.1 - @babel/core: 7.28.5 -> 7.29.0 (all apps) - react: 19.1.0 -> 19.2.4 (packages + apps) - react-native: 0.81.5 -> 0.84.0 (packages + apps/llm) - react-native-svg: 15.12.1 -> 15.15.3 (all apps) - react-native-svg-transformer: 1.5.2 -> 1.5.3 (all apps) - react-native-screens: 4.16.0 -> 4.24.0 (llm, text-embeddings) - react-native-safe-area-context: 5.6.2 -> 5.7.0 (speech, text-embeddings) - react-native-device-info: 14.1.1 -> 15.0.2 (all apps) - react-native-reanimated: 4.1.6 -> 4.2.2 (computer-vision) - react-native-worklets: 0.5.1 -> 0.7.4 (llm) - react-native-audio-api: 0.11.3 -> 0.11.5 (speech) - react-native-gesture-handler: 2.28.0 -> 2.30.0 (text-embeddings) - @react-native/metro-config: 0.81.6 -> 0.84.0 (llm, speech) - @react-navigation/drawer: 7.7.8 -> 7.8.1 (computer-vision, llm, text-embeddings) - @shopify/react-native-skia: 2.2.12 -> 2.4.21 (computer-vision) - jest: 29.7.0 -> 30.2.0 (react-native-executorch) - @types/jest: 29.5.14 -> 30.0.0 (react-native-executorch) - zod: 3.25.76 -> 4.3.6 (react-native-executorch) - expo-asset: 12.0.11 -> 12.0.12 (expo-resource-fetcher) - @docsearch/css + sidepanel: 4.5.3 -> 4.6.0 (docs) - typedoc: 0.28.16 -> 0.28.17 (docs) - typedoc-plugin-markdown: 4.9.0 -> 4.10.0 (docs) - swiper: 11.2.10 -> 12.1.2 (docs) ## Description <!-- Provide a concise and descriptive summary of the changes implemented in this PR. --> ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions * Run in `docs` directory `yarn build && yarn serve` and check that documentation builds correctly * Run all demo apps on iOS and Android and check that they are still running correctly. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. --> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…-mansion#837) ## Description This PR renames image segmentation, to more relevant and precise - semantic segmentation ### Introduces a breaking change? - [x] Yes - [ ] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions Run tests, check Semantic Segmentation app in computer-vision/ Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com>
…, FCN (software-mansion#881) ## Description Adds support for semantic segmentation models DeeplabV3, LRASPP, FCN, both in quantized and FP32 versions. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions 1. Run the computer vision semantic segmentation example app with all added models. 2. Check HF pages for added models in the semantic segmentation collection: - https://huggingface.co/software-mansion/react-native-executorch-deeplab-v3 - https://huggingface.co/software-mansion/react-native-executorch-lraspp - https://huggingface.co/software-mansion/react-native-executorch-fcn ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> Closes software-mansion#799 software-mansion#830 ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. --> --------- Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com>
## Description This PR updates docs with full LLM configuration example. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [x] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions Check out docs and check out `useLLM` section (there are no examples for `LLMModule` at all, so I did not add this there) ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [ ] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
…ware-mansion#886) ## Description This PR fixes package.json in both expo and bare resource fetchers. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [x] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [ ] Android ### Testing instructions * Run minimal app that utilizes this version of our library with expo 55 (pack react native executorch and expo resource fetchers into tgz and install in template app) and check if everything works correctly. * Run text to image example as this PR introduces changes in this package and check if everything works ok. ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues Closes software-mansion#882 ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [ ] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
## Description This PR adds real-time camera frame processing capabilities to React Native ExecuTorch by integrating with VisionCamera v5. It introduces a new VisionModule base class and extends ObjectDetectionModule to support three input methods: image URLs/paths, raw pixel data (PixelData), and live camera frames. This PR includes: - a dedicated screen for testing object detection + vision camera - new tests for added methods ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [x] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [x] Android ### Testing instructions Run the computer vision example app and test object detection and object detection (live) ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [x] I have performed a self-review of my code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes --------- Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com> Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com>
…re-mansion#896) ## Description Fix documentation about resource fetchers. ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [x] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions <!-- Provide step-by-step instructions on how to test your changes. Include setup details if necessary. --> ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [ ] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
bb65951 to
8816fbc
Compare
…tware-mansion#826) ## Description <!-- Provide a concise and descriptive summary of the changes implemented in this PR. --> ### Introduces a breaking change? - [x] Yes - [ ] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [x] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [x] iOS - [ ] Android ### Testing instructions Run demo app with RF-DETR model ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation accordingly - [x] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. --> --------- Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com> Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com> Co-authored-by: Norbert Klockiewicz <Nklockiewicz12@gmail.com>
…sion#933) Consolidate npm update configurations and change schedule to monthly. Currently, every week there will be ~35 PR triggered by dependabot. This change change frequency to only one per month, refactor config, do not apply changes if there is only patch change. ## Description <!-- Provide a concise and descriptive summary of the changes implemented in this PR. --> ### Introduces a breaking change? - [ ] Yes - [x] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [x] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions <!-- Provide step-by-step instructions on how to test your changes. Include setup details if necessary. --> ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [ ] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
## Description <!-- Provide a concise and descriptive summary of the changes implemented in this PR. --> ### Introduces a breaking change? - [ ] Yes - [ ] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions <!-- Provide step-by-step instructions on how to test your changes. Include setup details if necessary. --> ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [ ] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
…ion#947) ## Summary `TextToImage::unload()` is implemented in C++ and correctly delegates to its sub-components (encoder, unet, decoder), but the JSI binding was never registered in `ModelHostObject`. This causes a `TypeError: this.nativeModule.unload is not a function` when calling `BaseModule.delete()` from JavaScript. Every other composite model (OCR, VerticalOCR, Kokoro, LLM) already registers `unload` in its `if constexpr` block — this adds the same one-liner for TextToImage. ## Changes - Added `unload` JSI export to the `TextToImage` block in `ModelHostObject.h`, matching the existing pattern used by other models ## Test plan - [x] Call `module.delete()` on a loaded `TextToImageModule` — should no longer throw - [x] Verify model memory is released after `delete()` (encoder, unet, decoder sub-models are unloaded)
Right now if you want to use Kokoro TTS, you have to go through the built-in phonemis G2P pipeline. There's no way around it. This PR adds `generateFromPhonemes` / `streamFromPhonemes` methods that let you skip phonemis and pass your own IPA phoneme strings directly to the synthesis engine. Why would you want this? A few reasons we've run into: - phonemis doesn't handle every word well. Libraries like [phonemizer](https://github.com/bootphon/phonemizer) (espeak-ng backend) do better on edge cases, foreign words, etc. - Custom lexicons. If you have domain-specific pronunciation (game character names, medical terms), you probably want control over the G2P step. - Server-side G2P. Pre-compute phonemes on a server with a proper NLP pipeline, send them to the device. - Languages phonemis doesn't cover yet. ## What changed The existing `generate()` / `stream()` methods now delegate to shared internal helpers (`generateFromPhonemesImpl` / `streamFromPhonemesImpl`). The new public methods call the same helpers but skip the `phonemizer_.process()` step. No behavior change for existing callers. Changes across layers: - C++ `Kokoro`: `generateFromPhonemes`, `streamFromPhonemes` + input validation (empty string, invalid UTF-8) - JSI `ModelHostObject`: exposes new methods - `TextToSpeechModule`: `forwardFromPhonemes()`, `streamFromPhonemes()` (shared `streamImpl` helper, no copy-paste) - `useTextToSpeech` hook: same, with shared guard + streaming orchestration - Types: `TextToSpeechPhonemeInput`, `TextToSpeechStreamingPhonemeInput`, `TextToSpeechStreamingCallbacks` ## Usage ```typescript const tts = new TextToSpeechModule(); await tts.load(config); // text path (unchanged -- goes through phonemis) const audio = await tts.forward("Hello world"); // phoneme path (bypasses phonemis) const audio = await tts.forwardFromPhonemes("həloʊ wɝːld"); // streaming for await (const chunk of tts.streamFromPhonemes({ phonemes: "həloʊ wɝːld", speed: 1.0 })) { playAudio(chunk); } ``` ## Test plan - [ ] Existing `generate()` and `stream()` still work (refactor is internal) - [ ] `generateFromPhonemes()` with known Kokoro IPA strings - [ ] `streamFromPhonemes()` produces same audio as `stream()` for identical phonemes - [ ] Multi-byte UTF-8 phoneme characters (ʊ, ɪ, ŋ, etc.) - [ ] Empty string and invalid UTF-8 rejected with proper error --------- Co-authored-by: IgorSwat <igorswat2002@o2.pl>
b4e11d3 to
295701d
Compare
## Problem The `loadModel` template in `RnExecutorchInstaller.h` constructs model objects **synchronously on the JS thread**. For models like Kokoro TTS, the constructor loads `.pte` files, initializes the phonemizer, and reads voice data — blocking the JS thread for several seconds. This prevents React from rendering any pending state updates (loading spinners, progress indicators, etc.) until construction completes. For example, calling `setIsSynthesizing(true)` followed by `tts.load()` will not show the loading UI for 3-4 seconds because the JS thread is blocked by the synchronous native constructor. ## Solution Make `loadModel` return a **Promise** and dispatch the heavy model construction to `GlobalThreadPool::detach` — matching the pattern already used by `promiseHostFunction` for inference calls like `generate()`. ### C++ (`RnExecutorchInstaller.h`) - JSI arguments are still parsed on the JS thread (required for `jsi::Value` access) - Model construction is dispatched to `GlobalThreadPool::detach` - The Promise resolves on the JS thread via `callInvoker->invokeAsync` with the host object - Error handling follows the same pattern as `promiseHostFunction` in `ModelHostObject.h` ### TypeScript - All `global.load*()` call sites updated to `await` the now-async result - Global type declarations updated to return `Promise<any>` - `SpeechToText` already used `await`, so no change needed there ## Breaking Change This is a breaking change for any consumers calling `global.load*()` directly and expecting a synchronous return value. However: - The public module APIs (`load()` methods) are already `async` — no user-facing API changes needed - The `global.load*()` functions are internal/undocumented ## Test Plan - Verify model loading still works for all model types (TTS, LLM, OCR, etc.) - Verify that React state updates (loading spinners) render immediately when `load()` is called, rather than being delayed until construction completes - Verify error handling still propagates correctly from native construction failures --------- Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ty fixes (software-mansion#943) Fixes for Kokoro TTS native code. Addresses voice data truncation, missing Synthesizer method selection, progressive speed-up on longer inputs, phoneme token reordering, and several additional safety fixes. ### Voice loading reads only 128 of 510 rows `voice_` was a fixed `std::array<..., kMaxInputTokens>` (128 elements), but `hexgrad/Kokoro-82M` voice files contain 510 rows. The remaining 382 rows were silently dropped. Changed `voice_` to `std::vector`, sized dynamically from the file. Also fixed an OOB in `voiceID` — upstream used `std::min(phonemes.size() - 1, noTokens)` where `noTokens` could equal 128, indexing past the end of a 128-element array. Now uses a three-way `std::min({phonemes.size() - 1, noTokens - 1, voice_.size() - 1})`. ### Synthesizer doesn't do method selection `DurationPredictor` discovers and selects from `forward_8`/`forward_32`/`forward_64`/`forward_128` based on input size, but `Synthesizer` only knew about `forward`. Added the same discovery and selection logic. Falls back to `"forward"` if no `forward_N` methods exist, so older models still work. ### Audio progressively speeds up on longer inputs The Synthesizer's attention mechanism drifts on longer input sequences (60+ tokens), causing later phonemes to be spoken progressively faster than the Duration Predictor intended. The DP's timing predictions are correct, but the Synthesizer compresses later phonemes into fewer samples. Fixed by capping `inputTokensLimit` to 60, which forces the Partitioner to split text into shorter chunks that the Synthesizer can render faithfully. Each chunk is roughly one sentence (~15-20 words). ### `tokenize()` scrambles phoneme order on invalid tokens `std::partition` was used to filter out invalid (unrecognized) phoneme tokens, but `partition` does not preserve relative order. When any phonemes fall outside the vocabulary, the remaining valid tokens could be reordered, producing garbled audio. Changed to `std::stable_partition` which preserves relative order. ### `stripAudio` unsigned integer underflow `lbound - margin` wraps `size_t` to ~2^64 when the audio's first non-silent sample is near the start of the buffer (i.e., `lbound < margin`). `std::max(huge_value, 0)` returns the huge value, and `audio.subspan()` reads out-of-bounds. This is especially triggered in streaming mode where `paddingMs=15` (margin = 360 samples) on short chunks. Fixed by guarding the subtraction: `lbound > margin ? lbound - margin : 0`. Also guarded `audio.size() - 1` against empty spans. ### `isStreaming_` data race `isStreaming_` is a plain `bool` read by `stream()` on a background thread and written by `streamStop()` from the JS thread. Non-atomic access is undefined behavior — the compiler may optimize away the read, making `streamStop()` ineffective. Changed to `std::atomic<bool>`. ### `scaleDurations` drops phonemes When aggressively shrinking durations (many tokens, few total ticks), individual token durations can be driven to 0 by the correction loop. A zero-duration token is skipped by `repeatInterleave`, effectively deleting that phoneme from the output. Fixed by clamping each scaled duration to a minimum of 1, and guarding the correction loop so it never drives a duration below 1. Without the correction loop guard, the clamp is immediately undone — the priority queue picks clamped entries (they have high remainders) and subtracts 1, defeating the purpose. ### Misc perf - Replace temporary pause zero-vectors with `resize()` directly on the output - Move-capture audio in the streaming callback instead of copying ## Changes - `Kokoro.h` — `voice_` from fixed array to vector, `isStreaming_` to `std::atomic<bool>` - `Kokoro.cpp` — `loadVoice()`, `synthesize()`, `generate()`, `stream()`, constructor token limit cap - `DurationPredictor.cpp` — `scaleDurations()` min-1 clamp with correction loop guard - `Synthesizer.h` — `forwardMethods_` member - `Synthesizer.cpp` — method discovery and selection - `Utils.cpp` — `stable_partition` in `tokenize()`, `stripAudio` underflow guard
## Description The generated API reference under docs/docs/06-api-reference/ is regenerated at build time by docusaurus-plugin-typedoc (runs as part of yarn build), so there's no reason to track it in git. This removes the files, gitignores the directory, and deletes the now-redundant api-reference-up-to-date-check CI workflow. ### Introduces a breaking change? - [ ] Yes - [ ] No ### Type of change - [ ] Bug fix (change which fixes an issue) - [ ] New feature (change which adds functionality) - [ ] Documentation update (improves or adds clarity to existing documentation) - [ ] Other (chores, tests, code style improvements etc.) ### Tested on - [ ] iOS - [ ] Android ### Testing instructions <!-- Provide step-by-step instructions on how to test your changes. Include setup details if necessary. --> ### Screenshots <!-- Add screenshots here, if applicable --> ### Related issues <!-- Link related issues here using #issue-number --> ### Checklist - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [ ] My changes generate no new warnings ### Additional notes <!-- Include any additional information, assumptions, or context that reviewers might need to understand this PR. -->
…r for better error handling
…nerated files - Resolve merge conflict in .github/workflows/ci.yml (keep topological prepare) - Resolve merge conflict in yarn.lock and fix stale checksums - Resolve merge conflict in ResourceFetcher.ts - Update bare_rn: rename @rn-executorch/bare-adapter to @react-native-executorch/bare-resource-fetcher - Switch bare_rn dependencies from file: to workspace: protocol - Remove apps/bare_rn/android, ios, and yarn.lock from git index (covered by .gitignore) - Remove integration test model assets from git index; add .gitignore to prevent re-tracking Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cies The jest@npm:^29.6.3 lockfile entry was corrupted during merge conflict resolution, pointing to @jest/core@30.2.0 instead of @jest/core@29.7.0. This caused Yarn hardened mode in CI to detect a resolution mismatch and fail with YN0028. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Another corrupted lockfile entry from the merge conflict: metro-config@0.81.5 was referencing @react-native/babel-preset@0.84.0 instead of 0.81.5 deps, causing the missing @react-native/metro-babel-transformer@0.81.5 in hardened mode CI resolution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pace The lockfile had numerous corrupted entries from the merge conflict resolution (wrong dep version ranges, mismatched babel/jest versions). Reset to origin/main and ran yarn install to produce a clean lockfile that passes hardened mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ondition The typecheck script was changed to run `react-native-executorch prepare` before typechecking, but this causes a race condition in CI: the parallel `yarn typecheck` step triggers bob build (which cleans lib/typescript) while expo-resource-fetcher is concurrently typechecking against it, resulting in TS2307 "Cannot find module 'react-native-executorch'" errors. Revert to simple `tsc --noEmit` matching the main branch; CI already runs `--topological-dev run prepare` before typecheck. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unlike Expo apps, bare React Native requires native project directories to build. Re-add ios/ and android/ for apps/bare_rn and update .gitignore negation rules to allow them. Rename Android package from com.bare_rn to com.barern to comply with Kotlin package naming conventions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ruby 3.4 removed kconv from its standard library. CocoaPods 1.15.x uses it via CFPropertyList, causing pod install to fail. Adding the kconv gem alongside the other Ruby 3.4 compat gems already in the Gemfile. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CFPropertyList < 3.0.9 requires kconv which was removed from Ruby 3.4 standard library (there is no kconv gem). Pinning to 3.0.9+ uses a version that no longer depends on kconv. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CocoaPods 1.16.0+ dropped the kconv dependency (removed from Ruby 3.4 stdlib). Remove the xcodeproj < 1.26.0 upper bound since CocoaPods 1.16.x requires xcodeproj >= 1.26.0. Also drop the now-unnecessary CFPropertyList pin. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
node_modules are hoisted to the repo root, so update settings.gradle and app/build.gradle to point to ../../../node_modules/ instead of ../node_modules/. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tasksMap bug The @kesha-antonov/react-native-background-downloader library on Android loses the task reference in its JS-side tasksMap, causing the done callback to never fire even after a successful download. Fall back to RNFS.downloadFile on Android which reliably resolves the promise on completion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9f75c02 to
fe18a04
Compare
…egration/assets/models/.gitignore
Keep rocket emoji in the description and 1️⃣/2️⃣/3️⃣ in the quickstart section. Also remove bold from quickstart headings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Align ES, FR, CN, IN, PT readmes with the English README layout: remove emoji prefixes from headings and table of contents, keep :one:/:two:/:three: in quickstart steps, remove bold from step titles. Also add --no-must-find-files to cspell hook so it doesn't fail when all staged .md files are excluded by ignorePaths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a new bare React Native example application demonstrating LLM chat functionality using Executorch. This example provides a complete reference implementation for running local LLM inference on mobile devices through a simple chat interface.
Key features:
Introduces a breaking change?
Type of change
Tested on
Testing instructions
cd examples/bare-react-nativeyarn installyarn iosOr run on Android:
yarn androidVerify the app launches and displays the chat interface
Test message sending and model inference (requires model file setup)
Screenshots
Related issues
Checklist
Additional notes
This example app was generated using
npx @react-native-community/cli@latest init bare_rn --version 0.81.5 --pm yarnand follows bare React Native project structure (not Expo). It serves as a foundational example for developers to understand how to integrate Executorch for on-device LLM inference in their React Native applications.Why this example is not included in the yarn workspace:
The bare React Native example is maintained outside the yarn workspace structure due to fundamental architectural differences and specific technical issues:
Native Module Resolution Issues with Background Downloader:
Using the workspace monorepo breaks the Android app's integration with
@kesha-antonov/react-native-background-downloader. The monorepo's package hoisting and workspace resolution interferes with the native module's ability to properly register and resolve its native components. This causes runtime failures when attempting to download AI models in the background, which is a critical feature for this LLM chat example.Dependency Isolation: Bare React Native projects have distinct native dependency chains (iOS Pods, Android Gradle) that conflict with the monorepo's package management. The monorepo uses workspaces and hoisting strategies optimized for JavaScript/TypeScript packages, which can interfere with native module resolution.