expo-ai-kit 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -96
- package/android/src/main/java/expo/modules/aikit/ExpoAiKitModule.kt +26 -13
- package/android/src/main/java/expo/modules/aikit/GemmaInferenceClient.kt +47 -2
- package/build/ExpoAiKitModule.d.ts +12 -3
- package/build/ExpoAiKitModule.d.ts.map +1 -1
- package/build/ExpoAiKitModule.js.map +1 -1
- package/build/index.d.ts +31 -5
- package/build/index.d.ts.map +1 -1
- package/build/index.js +239 -34
- package/build/index.js.map +1 -1
- package/build/models.js +6 -6
- package/build/models.js.map +1 -1
- package/build/types.d.ts +66 -2
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/ios/ExpoAiKit.podspec +11 -5
- package/ios/ExpoAiKitModule.swift +255 -95
- package/ios/GemmaInferenceClient.swift +408 -0
- package/ios/Vendor/LiteRTLM/Benchmark.swift +83 -0
- package/ios/Vendor/LiteRTLM/Capabilities.swift +41 -0
- package/ios/Vendor/LiteRTLM/Config.swift +172 -0
- package/ios/Vendor/LiteRTLM/Conversation.swift +450 -0
- package/ios/Vendor/LiteRTLM/Engine.swift +208 -0
- package/ios/Vendor/LiteRTLM/ExperimentalFlags.swift +142 -0
- package/ios/Vendor/LiteRTLM/LICENSE +201 -0
- package/ios/Vendor/LiteRTLM/LiteRTLMError.swift +156 -0
- package/ios/Vendor/LiteRTLM/Message.swift +225 -0
- package/ios/Vendor/LiteRTLM/Tool.swift +291 -0
- package/ios/Vendor/LiteRTLM/ToolManager.swift +152 -0
- package/package.json +7 -3
- package/scripts/install-litertlm.sh +63 -0
- package/src/ExpoAiKitModule.ts +25 -3
- package/src/index.ts +287 -58
- package/src/models.ts +6 -6
- package/src/types.ts +72 -1
- package/android/build/.transforms/05637efea134638df3d3fc7b19d5dfdb/results.bin +0 -1
- package/android/build/.transforms/05637efea134638df3d3fc7b19d5dfdb/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/cd4ecc077e8795b855097bce5bf059b1/results.bin +0 -1
- package/android/build/.transforms/cd4ecc077e8795b855097bce5bf059b1/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/expo/modules/aikit/BuildConfig.java +0 -10
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -7
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
- package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/expo-ai-kit_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/expo/modules/aikit/BuildConfig.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -7
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -7
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +0 -2
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -14
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/expo-ai-kit_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$11$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$2$conversationPrompt$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$conversationPrompt$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1$streamCallback$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$3.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$4.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$5.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$6.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$AsyncFunction$7.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$10.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$11.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$12.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$3.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$4.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$5.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$6.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$7.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$8.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Coroutine$9.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Function$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$Function$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$FunctionWithoutArgs$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$FunctionWithoutArgs$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$FunctionWithoutArgs$3.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$20$$inlined$FunctionWithoutArgs$4.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$deleteModelFile$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$downloadModelFile$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$downloadModelFile$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$generateText$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$generateText$2$1$1$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$generateText$2$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$generateTextStream$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$generateTextStream$2$1$1$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$generateTextStream$2$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$loadModel$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$loadModel$2$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient$unloadModel$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/GemmaInferenceClient.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$generateText$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$generateTextStream$2$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$generateTextStream$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$isAvailable$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$isAvailableBlocking$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient.class +0 -0
- package/ios/.xcode.env +0 -11
package/README.md
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
# expo-ai-kit
|
|
2
2
|
|
|
3
|
-
On-device AI for Expo & React Native
|
|
3
|
+
On-device AI for Expo & React Native — run LLMs locally, no API keys, no cloud, no cost.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/expo-ai-kit)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- **Private** — inference never leaves the device
|
|
12
|
-
- **Free** — no API costs, rate limits, or subscriptions
|
|
13
|
-
- **Native** — Apple Foundation Models (iOS 26+), ML Kit (Android), Gemma 4 via [LiteRT-LM](https://ai.google.dev/edge/litert-lm)
|
|
14
|
-
- **Streaming** — progressive token output with cancellation
|
|
15
|
-
- **Model management** — download, load, and switch Gemma 4 models at runtime
|
|
8
|
+
Runs **Apple Foundation Models** (iOS 26+), **ML Kit** (Android), and downloadable
|
|
9
|
+
**Gemma 4** (E2B / E4B, iOS + Android via [LiteRT-LM](https://ai.google.dev/edge/litert-lm))
|
|
10
|
+
— with streaming, cancellation, and runtime model switching, all on-device.
|
|
16
11
|
|
|
17
12
|
## Install
|
|
18
13
|
|
|
@@ -20,111 +15,48 @@ entirely on-device — chat, streaming, and downloadable models, all local.
|
|
|
20
15
|
npx expo install expo-ai-kit
|
|
21
16
|
```
|
|
22
17
|
|
|
23
|
-
Bare
|
|
24
|
-
`minSdkVersion 26` — set it via `expo-build-properties` in `app.json`.
|
|
18
|
+
Bare RN: run `npx pod-install`. Android needs `minSdkVersion 26`. Requires Expo SDK 54+.
|
|
25
19
|
|
|
26
20
|
## Quick start
|
|
27
21
|
|
|
28
22
|
```tsx
|
|
29
|
-
import { isAvailable, sendMessage } from 'expo-ai-kit';
|
|
23
|
+
import { isAvailable, sendMessage, streamMessage } from 'expo-ai-kit';
|
|
30
24
|
|
|
31
25
|
if (await isAvailable()) {
|
|
32
|
-
const { text } = await sendMessage([
|
|
33
|
-
{ role: 'user', content: 'What is the capital of France?' },
|
|
34
|
-
]);
|
|
35
|
-
console.log(text); // "Paris"
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Add a system prompt, or include `system`/`assistant` messages for multi-turn context.
|
|
40
|
-
On-device models are stateless — pass the full message history on every call.
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
const { text } = await sendMessage(
|
|
44
|
-
[{ role: 'user', content: 'Tell me a joke' }],
|
|
45
|
-
{ systemPrompt: 'You are a stand-up comedian.' }
|
|
46
|
-
);
|
|
47
|
-
```
|
|
26
|
+
const { text } = await sendMessage([{ role: 'user', content: 'Capital of France?' }]);
|
|
48
27
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
[{ role: 'user', content: 'Write a short story' }],
|
|
56
|
-
(event) => setText(event.accumulatedText), // fired per token
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
await promise; // resolves with the final { text }
|
|
60
|
-
// stop(); // cancel at any point
|
|
28
|
+
const { promise, stop } = streamMessage(
|
|
29
|
+
[{ role: 'user', content: 'Write a short story' }],
|
|
30
|
+
(e) => setText(e.accumulatedText),
|
|
31
|
+
);
|
|
32
|
+
await promise; // stop() to cancel
|
|
33
|
+
}
|
|
61
34
|
```
|
|
62
35
|
|
|
63
|
-
|
|
36
|
+
`messages` is `{ role: 'system' | 'user' | 'assistant'; content: string }[]`. On-device
|
|
37
|
+
models are stateless — pass the full history each call.
|
|
64
38
|
|
|
65
|
-
|
|
39
|
+
## Downloadable Gemma 4
|
|
66
40
|
|
|
67
41
|
```tsx
|
|
68
|
-
import {
|
|
69
|
-
getDownloadableModels, downloadModel, setModel, sendMessage,
|
|
70
|
-
} from 'expo-ai-kit';
|
|
71
|
-
|
|
72
|
-
// List models with their on-device status
|
|
73
|
-
const models = await getDownloadableModels();
|
|
42
|
+
import { getRecommendedModel, downloadModel, setModel } from 'expo-ai-kit';
|
|
74
43
|
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
onProgress: (p) => console.log(
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// sendMessage / streamMessage now use the active model
|
|
82
|
-
const { text } = await sendMessage([{ role: 'user', content: 'Hi!' }]);
|
|
44
|
+
const best = await getRecommendedModel(); // E4B on high-RAM phones, else E2B
|
|
45
|
+
if (best) {
|
|
46
|
+
await downloadModel(best.id, { onProgress: (p) => console.log(p) });
|
|
47
|
+
await setModel(best.id, { generation: { temperature: 0.7 } });
|
|
48
|
+
// sendMessage / streamMessage now use it; unloadModel() reverts to the OS model
|
|
49
|
+
}
|
|
83
50
|
```
|
|
84
51
|
|
|
85
|
-
`unloadModel()` frees memory and reverts to the OS model; `deleteModel(id)` removes the file.
|
|
86
|
-
|
|
87
|
-
| Model | Params | Size | Platforms |
|
|
88
|
-
|-------|--------|------|-----------|
|
|
89
|
-
| `gemma-e2b` | 2.3B | ~2.6 GB | Android |
|
|
90
|
-
| `gemma-e4b` | 4.5B | ~3.7 GB | Android |
|
|
91
|
-
|
|
92
|
-
> iOS downloadable models are planned, pending LiteRT-LM Swift APIs from Google.
|
|
93
|
-
|
|
94
|
-
## Platform support
|
|
95
|
-
|
|
96
|
-
| Platform | Engine | Models |
|
|
97
|
-
|----------|--------|--------|
|
|
98
|
-
| iOS 26+ | [Apple Foundation Models](https://developer.apple.com/documentation/FoundationModels) | Built-in |
|
|
99
|
-
| Android ([supported devices](https://developers.google.com/ml-kit/genai#prompt-device)) | [ML Kit Prompt API](https://developers.google.com/ml-kit/genai#prompt-device) | Built-in + downloadable Gemma 4 |
|
|
100
|
-
| iOS < 26 / unsupported Android | — | `isAvailable()` returns `false` |
|
|
101
|
-
|
|
102
|
-
Requires Expo SDK 54+.
|
|
103
|
-
|
|
104
52
|
## API
|
|
105
53
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- `sendMessage(messages, options?)` → `Promise<{ text }>`
|
|
110
|
-
- `streamMessage(messages, onToken, options?)` → `{ promise, stop }`
|
|
111
|
-
|
|
112
|
-
**Models**
|
|
113
|
-
|
|
114
|
-
- `getBuiltInModels()` → `Promise<BuiltInModel[]>`
|
|
115
|
-
- `getDownloadableModels()` → `Promise<DownloadableModel[]>`
|
|
116
|
-
- `downloadModel(id, { onProgress? })` / `deleteModel(id)`
|
|
117
|
-
- `setModel(id, { backend? })` / `unloadModel()` / `getActiveModel()`
|
|
118
|
-
|
|
119
|
-
`messages` is `{ role: 'system' | 'user' | 'assistant'; content: string }[]` and
|
|
120
|
-
`options` accepts `{ systemPrompt?: string }`. Model operations throw `ModelError`
|
|
121
|
-
with a `.code` (e.g. `MODEL_NOT_FOUND`, `DOWNLOAD_CORRUPT`, `INFERENCE_OOM`).
|
|
122
|
-
Full TypeScript definitions ship with the package.
|
|
123
|
-
|
|
124
|
-
## Links
|
|
54
|
+
Inference: `isAvailable`, `sendMessage`, `streamMessage`.
|
|
55
|
+
Models: `getBuiltInModels`, `getDownloadableModels`, `getRecommendedModel`,
|
|
56
|
+
`downloadModel`, `cancelDownload`, `deleteModel`, `setModel`, `unloadModel`, `getActiveModel`.
|
|
125
57
|
|
|
126
|
-
|
|
127
|
-
|
|
58
|
+
Failures throw `ModelError` with a typed `.code`. Full TypeScript definitions ship with
|
|
59
|
+
the package — see [the docs](https://expo-ai-kit.dev) for the complete reference.
|
|
128
60
|
|
|
129
61
|
## License
|
|
130
62
|
|
|
@@ -40,7 +40,9 @@ class ExpoAiKitModule : Module() {
|
|
|
40
40
|
promptClient.isAvailableBlocking()
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
// sessionId is accepted for API parity with iOS. Non-streaming generation on
|
|
44
|
+
// Android isn't separately cancellable (best-effort), so the id is unused here.
|
|
45
|
+
AsyncFunction("sendMessage") Coroutine { messages: List<Map<String, Any>>, fallbackSystemPrompt: String, sessionId: String ->
|
|
44
46
|
// Extract system prompt from messages, or use fallback
|
|
45
47
|
val systemPrompt = messages
|
|
46
48
|
.firstOrNull { it["role"] == "system" }
|
|
@@ -144,11 +146,12 @@ class ExpoAiKitModule : Module() {
|
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
Function("getDownloadableModelStatus") { modelId: String ->
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
149
|
+
// "ready" if loaded in memory; "downloaded" if the file is on disk but not
|
|
150
|
+
// loaded (survives restarts -- use it to skip a redundant re-download);
|
|
151
|
+
// "not-downloaded" if no file is present.
|
|
150
152
|
when {
|
|
151
153
|
gemmaClient.getLoadedModelId() == modelId && gemmaClient.isModelLoaded() -> "ready"
|
|
154
|
+
gemmaClient.isModelFileDownloaded(modelId) -> "downloaded"
|
|
152
155
|
else -> "not-downloaded"
|
|
153
156
|
}
|
|
154
157
|
}
|
|
@@ -168,7 +171,7 @@ class ExpoAiKitModule : Module() {
|
|
|
168
171
|
// Model selection & memory management
|
|
169
172
|
// ==================================================================
|
|
170
173
|
|
|
171
|
-
AsyncFunction("setModel") Coroutine { modelId: String, minRamBytes: Long, backend: String ->
|
|
174
|
+
AsyncFunction("setModel") Coroutine { modelId: String, minRamBytes: Long, backend: String, generation: Map<String, Double> ->
|
|
172
175
|
if (modelId == "mlkit") {
|
|
173
176
|
// Switch to built-in: unload any Gemma model
|
|
174
177
|
if (gemmaClient.isModelLoaded()) {
|
|
@@ -177,7 +180,7 @@ class ExpoAiKitModule : Module() {
|
|
|
177
180
|
if (previousId != "mlkit") {
|
|
178
181
|
sendEvent("onModelStateChange", mapOf(
|
|
179
182
|
"modelId" to previousId,
|
|
180
|
-
"status" to "not-downloaded"
|
|
183
|
+
"status" to if (gemmaClient.isModelFileDownloaded(previousId)) "downloaded" else "not-downloaded"
|
|
181
184
|
))
|
|
182
185
|
}
|
|
183
186
|
}
|
|
@@ -198,7 +201,12 @@ class ExpoAiKitModule : Module() {
|
|
|
198
201
|
|
|
199
202
|
try {
|
|
200
203
|
val modelPath = gemmaClient.getModelFilePath(modelId)
|
|
201
|
-
gemmaClient.loadModel(
|
|
204
|
+
gemmaClient.loadModel(
|
|
205
|
+
modelId, modelPath, minRamBytes, backend,
|
|
206
|
+
temperature = generation["temperature"],
|
|
207
|
+
topK = generation["topK"]?.toInt(),
|
|
208
|
+
topP = generation["topP"]
|
|
209
|
+
)
|
|
202
210
|
activeModelId = modelId
|
|
203
211
|
|
|
204
212
|
// Emit ready state
|
|
@@ -207,10 +215,10 @@ class ExpoAiKitModule : Module() {
|
|
|
207
215
|
"status" to "ready"
|
|
208
216
|
))
|
|
209
217
|
} catch (e: Exception) {
|
|
210
|
-
//
|
|
218
|
+
// Load failed, but the file is still on disk -> "downloaded", not "not-downloaded".
|
|
211
219
|
sendEvent("onModelStateChange", mapOf(
|
|
212
220
|
"modelId" to modelId,
|
|
213
|
-
"status" to "not-downloaded"
|
|
221
|
+
"status" to if (gemmaClient.isModelFileDownloaded(modelId)) "downloaded" else "not-downloaded"
|
|
214
222
|
))
|
|
215
223
|
throw e
|
|
216
224
|
}
|
|
@@ -227,7 +235,7 @@ class ExpoAiKitModule : Module() {
|
|
|
227
235
|
activeModelId = "mlkit"
|
|
228
236
|
sendEvent("onModelStateChange", mapOf(
|
|
229
237
|
"modelId" to previousId,
|
|
230
|
-
"status" to "not-downloaded"
|
|
238
|
+
"status" to if (gemmaClient.isModelFileDownloaded(previousId)) "downloaded" else "not-downloaded"
|
|
231
239
|
))
|
|
232
240
|
}
|
|
233
241
|
}
|
|
@@ -250,20 +258,25 @@ class ExpoAiKitModule : Module() {
|
|
|
250
258
|
))
|
|
251
259
|
}
|
|
252
260
|
|
|
253
|
-
// Download
|
|
261
|
+
// Download succeeded: file is on disk, awaiting setModel() to load it.
|
|
254
262
|
sendEvent("onModelStateChange", mapOf(
|
|
255
263
|
"modelId" to modelId,
|
|
256
|
-
"status" to "
|
|
264
|
+
"status" to "downloaded"
|
|
257
265
|
))
|
|
258
266
|
} catch (e: Exception) {
|
|
267
|
+
// On failure, report whatever is actually on disk (a prior good copy may remain).
|
|
259
268
|
sendEvent("onModelStateChange", mapOf(
|
|
260
269
|
"modelId" to modelId,
|
|
261
|
-
"status" to "not-downloaded"
|
|
270
|
+
"status" to if (gemmaClient.isModelFileDownloaded(modelId)) "downloaded" else "not-downloaded"
|
|
262
271
|
))
|
|
263
272
|
throw e
|
|
264
273
|
}
|
|
265
274
|
}
|
|
266
275
|
|
|
276
|
+
AsyncFunction("cancelDownload") Coroutine { modelId: String ->
|
|
277
|
+
gemmaClient.cancelDownload(modelId)
|
|
278
|
+
}
|
|
279
|
+
|
|
267
280
|
AsyncFunction("deleteModel") Coroutine { modelId: String ->
|
|
268
281
|
// If this model is active, switch back to mlkit first
|
|
269
282
|
if (activeModelId == modelId) {
|
|
@@ -10,6 +10,7 @@ import com.google.ai.edge.litertlm.Backend
|
|
|
10
10
|
import com.google.ai.edge.litertlm.Message
|
|
11
11
|
import com.google.ai.edge.litertlm.MessageCallback
|
|
12
12
|
import com.google.ai.edge.litertlm.Contents
|
|
13
|
+
import com.google.ai.edge.litertlm.SamplerConfig
|
|
13
14
|
import kotlinx.coroutines.Dispatchers
|
|
14
15
|
import kotlinx.coroutines.sync.Mutex
|
|
15
16
|
import kotlinx.coroutines.sync.withLock
|
|
@@ -45,6 +46,9 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
45
46
|
@Volatile
|
|
46
47
|
private var isDownloading = false
|
|
47
48
|
|
|
49
|
+
@Volatile
|
|
50
|
+
private var cancelDownloadRequested = false
|
|
51
|
+
|
|
48
52
|
// -------------------------------------------------------------------------
|
|
49
53
|
// Model lifecycle
|
|
50
54
|
// -------------------------------------------------------------------------
|
|
@@ -54,7 +58,15 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
54
58
|
* Unloads any previously loaded model first.
|
|
55
59
|
* Caller is responsible for emitting onModelStateChange events.
|
|
56
60
|
*/
|
|
57
|
-
suspend fun loadModel(
|
|
61
|
+
suspend fun loadModel(
|
|
62
|
+
modelId: String,
|
|
63
|
+
modelPath: String,
|
|
64
|
+
minRamBytes: Long = 0,
|
|
65
|
+
backend: String = "auto",
|
|
66
|
+
temperature: Double? = null,
|
|
67
|
+
topK: Int? = null,
|
|
68
|
+
topP: Double? = null
|
|
69
|
+
) = mutex.withLock {
|
|
58
70
|
// Unload previous model if different
|
|
59
71
|
if (loadedModelId != null && loadedModelId != modelId) {
|
|
60
72
|
conversation?.close()
|
|
@@ -117,7 +129,21 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
117
129
|
}
|
|
118
130
|
}
|
|
119
131
|
|
|
120
|
-
|
|
132
|
+
// Sampling knobs are fixed at conversation creation by LiteRT-LM. If any
|
|
133
|
+
// is provided, build a SamplerConfig (filling unspecified values with
|
|
134
|
+
// Gemma-typical defaults); otherwise use the engine/model defaults.
|
|
135
|
+
val convConfig = if (temperature != null || topK != null || topP != null) {
|
|
136
|
+
ConversationConfig(
|
|
137
|
+
samplerConfig = SamplerConfig(
|
|
138
|
+
topK = topK ?: 64,
|
|
139
|
+
topP = topP ?: 0.95,
|
|
140
|
+
temperature = temperature ?: 1.0
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
} else {
|
|
144
|
+
ConversationConfig()
|
|
145
|
+
}
|
|
146
|
+
val newConversation = newEngine.createConversation(convConfig)
|
|
121
147
|
|
|
122
148
|
engine = newEngine
|
|
123
149
|
conversation = newConversation
|
|
@@ -191,6 +217,9 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
191
217
|
)
|
|
192
218
|
}
|
|
193
219
|
}
|
|
220
|
+
} catch (e: kotlinx.coroutines.CancellationException) {
|
|
221
|
+
// Cooperative cancellation — propagate, don't mask as an inference failure.
|
|
222
|
+
throw e
|
|
194
223
|
} catch (e: OutOfMemoryError) {
|
|
195
224
|
throw RuntimeException("INFERENCE_OOM:${loadedModelId ?: "unknown"}:Out of memory during inference")
|
|
196
225
|
} catch (e: Exception) {
|
|
@@ -260,6 +289,9 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
260
289
|
)
|
|
261
290
|
}
|
|
262
291
|
}
|
|
292
|
+
} catch (e: kotlinx.coroutines.CancellationException) {
|
|
293
|
+
// Cooperative cancellation — propagate, don't mask as an inference failure.
|
|
294
|
+
throw e
|
|
263
295
|
} catch (e: OutOfMemoryError) {
|
|
264
296
|
throw RuntimeException("INFERENCE_OOM:${loadedModelId ?: "unknown"}:Out of memory during inference")
|
|
265
297
|
} catch (e: Exception) {
|
|
@@ -288,6 +320,7 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
288
320
|
throw RuntimeException("DOWNLOAD_FAILED:$modelId:Download already in progress")
|
|
289
321
|
}
|
|
290
322
|
isDownloading = true
|
|
323
|
+
cancelDownloadRequested = false
|
|
291
324
|
|
|
292
325
|
try {
|
|
293
326
|
withContext(Dispatchers.IO) {
|
|
@@ -308,6 +341,9 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
308
341
|
val buffer = ByteArray(8192)
|
|
309
342
|
var read: Int
|
|
310
343
|
while (input.read(buffer).also { read = it } != -1) {
|
|
344
|
+
if (cancelDownloadRequested) {
|
|
345
|
+
throw RuntimeException("DOWNLOAD_CANCELLED:$modelId:Download cancelled")
|
|
346
|
+
}
|
|
311
347
|
output.write(buffer, 0, read)
|
|
312
348
|
bytesRead += read
|
|
313
349
|
if (totalBytes > 0) {
|
|
@@ -336,6 +372,7 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
336
372
|
tempFile.delete()
|
|
337
373
|
when {
|
|
338
374
|
e is RuntimeException && e.message?.startsWith("DOWNLOAD_CORRUPT") == true -> throw e
|
|
375
|
+
e is RuntimeException && e.message?.startsWith("DOWNLOAD_CANCELLED") == true -> throw e
|
|
339
376
|
context.filesDir.freeSpace < 100_000_000 ->
|
|
340
377
|
throw RuntimeException("DOWNLOAD_STORAGE_FULL:$modelId:Insufficient disk space")
|
|
341
378
|
else ->
|
|
@@ -372,6 +409,14 @@ class GemmaInferenceClient(private val context: Context) {
|
|
|
372
409
|
}
|
|
373
410
|
}
|
|
374
411
|
|
|
412
|
+
/**
|
|
413
|
+
* Request cancellation of the in-flight download, if any. The download loop
|
|
414
|
+
* checks this flag and throws DOWNLOAD_CANCELLED. No-op if nothing is downloading.
|
|
415
|
+
*/
|
|
416
|
+
fun cancelDownload(modelId: String) {
|
|
417
|
+
cancelDownloadRequested = true
|
|
418
|
+
}
|
|
419
|
+
|
|
375
420
|
/**
|
|
376
421
|
* Check if a model file exists on disk.
|
|
377
422
|
*/
|
|
@@ -5,18 +5,27 @@ export type ExpoAiKitModuleEvents = {
|
|
|
5
5
|
onDownloadProgress: (event: ModelDownloadProgressEvent) => void;
|
|
6
6
|
onModelStateChange: (event: ModelStateChangeEvent) => void;
|
|
7
7
|
};
|
|
8
|
+
/** Generation parameters passed to native. All fields optional; -1 / absent means "unset". */
|
|
9
|
+
export type NativeGenerationConfig = {
|
|
10
|
+
temperature?: number;
|
|
11
|
+
topK?: number;
|
|
12
|
+
topP?: number;
|
|
13
|
+
seed?: number;
|
|
14
|
+
maxTokens?: number;
|
|
15
|
+
};
|
|
8
16
|
export interface ExpoAiKitNativeModule {
|
|
9
17
|
isAvailable(): boolean;
|
|
10
|
-
sendMessage(messages: LLMMessage[], systemPrompt: string): Promise<LLMResponse>;
|
|
18
|
+
sendMessage(messages: LLMMessage[], systemPrompt: string, sessionId: string): Promise<LLMResponse>;
|
|
11
19
|
startStreaming(messages: LLMMessage[], systemPrompt: string, sessionId: string): Promise<void>;
|
|
12
20
|
stopStreaming(sessionId: string): Promise<void>;
|
|
13
21
|
getBuiltInModels(): BuiltInModel[];
|
|
14
|
-
getDownloadableModelStatus(modelId: string): DownloadableModelStatus
|
|
22
|
+
getDownloadableModelStatus(modelId: string): Promise<DownloadableModelStatus>;
|
|
15
23
|
getDeviceRamBytes(): number;
|
|
16
|
-
setModel(modelId: string, minRamBytes: number, backend: string): Promise<void>;
|
|
24
|
+
setModel(modelId: string, minRamBytes: number, backend: string, generation: NativeGenerationConfig): Promise<void>;
|
|
17
25
|
getActiveModel(): string;
|
|
18
26
|
unloadModel(): Promise<void>;
|
|
19
27
|
downloadModel(modelId: string, url: string, sha256: string): Promise<void>;
|
|
28
|
+
cancelDownload(modelId: string): Promise<void>;
|
|
20
29
|
deleteModel(modelId: string): Promise<void>;
|
|
21
30
|
addListener<K extends keyof ExpoAiKitModuleEvents>(eventName: K, listener: ExpoAiKitModuleEvents[K]): EventSubscription;
|
|
22
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAiKitModule.d.ts","sourceRoot":"","sources":["../src/ExpoAiKitModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,kBAAkB,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAChE,kBAAkB,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,CAAC;AAEF,MAAM,WAAW,qBAAqB;IAEpC,WAAW,IAAI,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoAiKitModule.d.ts","sourceRoot":"","sources":["../src/ExpoAiKitModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,kBAAkB,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAChE,kBAAkB,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,CAAC;AAEF,8FAA8F;AAC9F,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,qBAAqB;IAEpC,WAAW,IAAI,OAAO,CAAC;IAEvB,WAAW,CACT,QAAQ,EAAE,UAAU,EAAE,EACtB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,CAAC;IACxB,cAAc,CACZ,QAAQ,EAAE,UAAU,EAAE,EACtB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGhD,gBAAgB,IAAI,YAAY,EAAE,CAAC;IAGnC,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC9E,iBAAiB,IAAI,MAAM,CAAC;IAM5B,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,IAAI,MAAM,CAAC;IAGzB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAG7B,aAAa,CACX,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG5C,WAAW,CAAC,CAAC,SAAS,MAAM,qBAAqB,EAC/C,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACjC,iBAAiB,CAAC;CACtB;AAED,QAAA,MAAM,eAAe,uBACoC,CAAC;AAE1D,eAAe,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoAiKitModule.js","sourceRoot":"","sources":["../src/ExpoAiKitModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoAiKitModule.js","sourceRoot":"","sources":["../src/ExpoAiKitModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAmFxD,MAAM,eAAe,GACnB,mBAAmB,CAAwB,WAAW,CAAC,CAAC;AAE1D,eAAe,eAAe,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\nimport type { EventSubscription } from 'expo-modules-core';\nimport {\n BuiltInModel,\n DownloadableModelStatus,\n LLMMessage,\n LLMResponse,\n LLMStreamEvent,\n ModelDownloadProgressEvent,\n ModelStateChangeEvent,\n} from './types';\n\nexport type ExpoAiKitModuleEvents = {\n onStreamToken: (event: LLMStreamEvent) => void;\n onDownloadProgress: (event: ModelDownloadProgressEvent) => void;\n onModelStateChange: (event: ModelStateChangeEvent) => void;\n};\n\n/** Generation parameters passed to native. All fields optional; -1 / absent means \"unset\". */\nexport type NativeGenerationConfig = {\n temperature?: number;\n topK?: number;\n topP?: number;\n seed?: number;\n maxTokens?: number;\n};\n\nexport interface ExpoAiKitNativeModule {\n // Existing inference API\n isAvailable(): boolean;\n // sessionId lets stopStreaming() cancel an in-flight (non-streaming) generation too.\n sendMessage(\n messages: LLMMessage[],\n systemPrompt: string,\n sessionId: string\n ): Promise<LLMResponse>;\n startStreaming(\n messages: LLMMessage[],\n systemPrompt: string,\n sessionId: string\n ): Promise<void>;\n // Cancels either a streaming session or a sendMessage session by id.\n stopStreaming(sessionId: string): Promise<void>;\n\n // Model discovery\n getBuiltInModels(): BuiltInModel[];\n // Async: iOS reads actor-isolated state (so it bridges as a Promise); Android\n // returns synchronously. Callers must await — see getDownloadableModels.\n getDownloadableModelStatus(modelId: string): Promise<DownloadableModelStatus>;\n getDeviceRamBytes(): number;\n\n // Model selection & memory management\n // setModel is async: switching to a downloadable model loads it into memory.\n // Auto-unloads the previous downloadable model (only one loaded at a time).\n // `generation` carries best-effort sampling defaults for the session.\n setModel(\n modelId: string,\n minRamBytes: number,\n backend: string,\n generation: NativeGenerationConfig\n ): Promise<void>;\n getActiveModel(): string;\n // Explicitly free memory from the loaded downloadable model.\n // Reverts to the platform built-in model.\n unloadModel(): Promise<void>;\n\n // Model lifecycle (downloadable models only)\n downloadModel(\n modelId: string,\n url: string,\n sha256: string\n ): Promise<void>;\n // Cancels an in-flight download for the given model (no-op if none).\n cancelDownload(modelId: string): Promise<void>;\n deleteModel(modelId: string): Promise<void>;\n\n // Event subscription\n addListener<K extends keyof ExpoAiKitModuleEvents>(\n eventName: K,\n listener: ExpoAiKitModuleEvents[K]\n ): EventSubscription;\n}\n\nconst ExpoAiKitModule =\n requireNativeModule<ExpoAiKitNativeModule>('ExpoAiKit');\n\nexport default ExpoAiKitModule;\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LLMMessage, LLMSendOptions, LLMResponse, LLMStreamOptions, LLMStreamCallback, BuiltInModel, DownloadableModel, SetModelOptions } from './types';
|
|
1
|
+
import { LLMMessage, LLMSendOptions, LLMResponse, LLMStreamOptions, LLMStreamCallback, LLMStreamHandle, BuiltInModel, DownloadableModel, SetModelOptions } from './types';
|
|
2
2
|
export * from './types';
|
|
3
3
|
export * from './models';
|
|
4
4
|
/**
|
|
@@ -75,10 +75,7 @@ export declare function sendMessage(messages: LLMMessage[], options?: LLMSendOpt
|
|
|
75
75
|
* setTimeout(() => stop(), 5000);
|
|
76
76
|
* ```
|
|
77
77
|
*/
|
|
78
|
-
export declare function streamMessage(messages: LLMMessage[], onToken: LLMStreamCallback, options?: LLMStreamOptions):
|
|
79
|
-
promise: Promise<LLMResponse>;
|
|
80
|
-
stop: () => void;
|
|
81
|
-
};
|
|
78
|
+
export declare function streamMessage(messages: LLMMessage[], onToken: LLMStreamCallback, options?: LLMStreamOptions): LLMStreamHandle;
|
|
82
79
|
/**
|
|
83
80
|
* Get all built-in models available on the current platform.
|
|
84
81
|
*
|
|
@@ -97,6 +94,26 @@ export declare function getBuiltInModels(): Promise<BuiltInModel[]>;
|
|
|
97
94
|
* @returns Array of downloadable models with their current status
|
|
98
95
|
*/
|
|
99
96
|
export declare function getDownloadableModels(): Promise<DownloadableModel[]>;
|
|
97
|
+
/**
|
|
98
|
+
* Pick the best downloadable model the current device can run.
|
|
99
|
+
*
|
|
100
|
+
* Returns the most capable model (largest, by RAM requirement) whose
|
|
101
|
+
* `meetsRequirements` is true — e.g. Gemma 4 E4B on high-spec phones, falling
|
|
102
|
+
* back to E2B on more constrained ones — or `null` if the device can't run any.
|
|
103
|
+
*
|
|
104
|
+
* This is a convenience over {@link getDownloadableModels}; the caller still
|
|
105
|
+
* downloads + activates explicitly. Pass `platform` is implicit (current OS).
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const best = await getRecommendedModel();
|
|
110
|
+
* if (best) {
|
|
111
|
+
* await downloadModel(best.id, { onProgress });
|
|
112
|
+
* await setModel(best.id);
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function getRecommendedModel(): Promise<DownloadableModel | null>;
|
|
100
117
|
/**
|
|
101
118
|
* Download a model to the device.
|
|
102
119
|
*
|
|
@@ -115,6 +132,15 @@ export declare function getDownloadableModels(): Promise<DownloadableModel[]>;
|
|
|
115
132
|
export declare function downloadModel(modelId: string, options?: {
|
|
116
133
|
onProgress?: (progress: number) => void;
|
|
117
134
|
}): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Cancel an in-flight download for a model.
|
|
137
|
+
*
|
|
138
|
+
* The in-progress {@link downloadModel} promise rejects with a
|
|
139
|
+
* DOWNLOAD_CANCELLED {@link ModelError}. No-op if the model isn't downloading.
|
|
140
|
+
*
|
|
141
|
+
* @param modelId - ID of the model whose download should be cancelled
|
|
142
|
+
*/
|
|
143
|
+
export declare function cancelDownload(modelId: string): Promise<void>;
|
|
118
144
|
/**
|
|
119
145
|
* Delete a downloaded model from the device.
|
|
120
146
|
*
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAEhB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAEhB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,iBAAiB,EAIjB,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AAuHzB;;;GAGG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAKpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,WAAW,CAAC,CAmEtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,gBAAgB,GACzB,eAAe,CAwFjB;AAMD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAKhE;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiC1E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAM7E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GACpD,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnE;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjD"}
|