expo-ai-kit 0.1.20 → 0.1.22

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.
Files changed (224) hide show
  1. package/README.md +207 -2
  2. package/build/hooks.d.ts +88 -0
  3. package/build/hooks.d.ts.map +1 -0
  4. package/build/hooks.js +293 -0
  5. package/build/hooks.js.map +1 -0
  6. package/build/index.d.ts +1 -0
  7. package/build/index.d.ts.map +1 -1
  8. package/build/index.js +1 -0
  9. package/build/index.js.map +1 -1
  10. package/build/types.d.ts +71 -0
  11. package/build/types.d.ts.map +1 -1
  12. package/build/types.js.map +1 -1
  13. package/ios/ExpoAiKit.podspec +1 -1
  14. package/package.json +5 -9
  15. package/src/hooks.ts +331 -0
  16. package/src/index.ts +1 -0
  17. package/src/types.ts +80 -0
  18. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  19. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  20. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  21. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  22. package/android/.gradle/8.9/gc.properties +0 -0
  23. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  24. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  25. package/android/.gradle/vcs-1/gc.properties +0 -0
  26. package/android/build/.transforms/550f2d3d50c89e495845cc30f2214044/results.bin +0 -1
  27. package/android/build/.transforms/550f2d3d50c89e495845cc30f2214044/transformed/classes/classes_dex/classes.dex +0 -0
  28. package/android/build/.transforms/a588f18db136c18b668ecd9727a7dc6b/results.bin +0 -1
  29. package/android/build/.transforms/a588f18db136c18b668ecd9727a7dc6b/transformed/classes/classes_dex/classes.dex +0 -0
  30. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/results.bin +0 -1
  31. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/BuildConfig.dex +0 -0
  32. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$1$5$1.dex +0 -0
  33. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$AsyncFunction$1.dex +0 -0
  34. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$AsyncFunction$2.dex +0 -0
  35. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$AsyncFunction$3.dex +0 -0
  36. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$AsyncFunctionWithoutArgs$1.dex +0 -0
  37. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$Constant$1.dex +0 -0
  38. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$FunctionWithoutArgs$1.dex +0 -0
  39. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$$inlined$View$1.dex +0 -0
  40. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$6$lambda$5$$inlined$Prop$1.dex +0 -0
  41. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule.dex +0 -0
  42. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitView$webView$1$1.dex +0 -0
  43. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitView.dex +0 -0
  44. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$isAvailable$1.dex +0 -0
  45. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$isAvailableBlocking$1.dex +0 -0
  46. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient.dex +0 -0
  47. package/android/build/.transforms/c485bab123d2a96b9ef2e8051e8dcd8c/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  48. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/results.bin +0 -1
  49. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/BuildConfig.dex +0 -0
  50. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$1$2$conversationPrompt$2.dex +0 -0
  51. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$1$3$conversationPrompt$2.dex +0 -0
  52. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1$1.dex +0 -0
  53. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1.dex +0 -0
  54. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$1.dex +0 -0
  55. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$2.dex +0 -0
  56. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$3.dex +0 -0
  57. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$4.dex +0 -0
  58. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$5.dex +0 -0
  59. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$6.dex +0 -0
  60. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$7.dex +0 -0
  61. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$1.dex +0 -0
  62. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$2.dex +0 -0
  63. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$3.dex +0 -0
  64. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$FunctionWithoutArgs$1.dex +0 -0
  65. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/ExpoAiKitModule.dex +0 -0
  66. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$generateText$2.dex +0 -0
  67. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$generateTextStream$2$1.dex +0 -0
  68. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$generateTextStream$2.dex +0 -0
  69. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$isAvailable$1.dex +0 -0
  70. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient$isAvailableBlocking$1.dex +0 -0
  71. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/aikit/PromptApiClient.dex +0 -0
  72. package/android/build/.transforms/e7552020676c2f8a620fec964bf11729/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  73. package/android/build/generated/source/buildConfig/debug/expo/modules/aikit/BuildConfig.java +0 -10
  74. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -7
  75. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  76. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  77. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  78. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  79. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  80. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  81. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
  82. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  83. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  84. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  85. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  86. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/expo-ai-kit_debug.kotlin_module +0 -0
  87. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/expo/modules/aikit/BuildConfig.class +0 -0
  88. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
  89. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -7
  90. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -7
  91. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  92. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  93. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/expo-ai-kit_debug.kotlin_module +0 -0
  94. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/BuildConfig.class +0 -0
  95. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$1$2$conversationPrompt$2.class +0 -0
  96. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$conversationPrompt$2.class +0 -0
  97. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1$1.class +0 -0
  98. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1.class +0 -0
  99. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$1.class +0 -0
  100. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$2.class +0 -0
  101. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$3.class +0 -0
  102. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$4.class +0 -0
  103. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$5.class +0 -0
  104. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$6.class +0 -0
  105. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$7.class +0 -0
  106. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$1.class +0 -0
  107. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$2.class +0 -0
  108. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$3.class +0 -0
  109. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$FunctionWithoutArgs$1.class +0 -0
  110. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/ExpoAiKitModule.class +0 -0
  111. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/PromptApiClient$generateText$2.class +0 -0
  112. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/PromptApiClient$generateTextStream$2$1.class +0 -0
  113. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/PromptApiClient$generateTextStream$2.class +0 -0
  114. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/PromptApiClient$isAvailable$1.class +0 -0
  115. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/PromptApiClient$isAvailableBlocking$1.class +0 -0
  116. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/aikit/PromptApiClient.class +0 -0
  117. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  118. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
  119. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  120. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  121. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  122. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  123. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  124. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  125. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  126. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  127. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  128. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  129. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  130. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  131. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  132. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  133. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  134. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  135. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  136. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  137. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  138. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  139. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  140. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  141. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  142. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  143. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  144. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  145. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  146. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  147. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  148. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  149. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  150. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  151. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  152. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  153. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  154. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  155. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  156. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  157. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  158. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  159. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  160. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  161. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  162. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  163. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  164. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  165. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  166. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  167. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  168. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  169. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  170. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  171. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  172. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  173. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  174. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  175. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +0 -2
  176. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  177. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  178. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  179. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  180. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  181. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  182. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  183. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  184. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  185. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  186. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  187. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  188. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  189. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  190. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  191. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  192. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  193. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  194. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  195. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  196. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  197. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  198. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  199. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  200. package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -14
  201. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  202. package/android/build/tmp/kotlin-classes/debug/META-INF/expo-ai-kit_debug.kotlin_module +0 -0
  203. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$2$conversationPrompt$2.class +0 -0
  204. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$conversationPrompt$2.class +0 -0
  205. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1$1.class +0 -0
  206. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$1$3$job$1.class +0 -0
  207. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$1.class +0 -0
  208. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$2.class +0 -0
  209. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$3.class +0 -0
  210. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$4.class +0 -0
  211. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$5.class +0 -0
  212. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$6.class +0 -0
  213. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$AsyncFunction$7.class +0 -0
  214. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$1.class +0 -0
  215. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$2.class +0 -0
  216. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$Coroutine$3.class +0 -0
  217. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule$definition$lambda$11$$inlined$FunctionWithoutArgs$1.class +0 -0
  218. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/ExpoAiKitModule.class +0 -0
  219. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$generateText$2.class +0 -0
  220. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$generateTextStream$2$1.class +0 -0
  221. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$generateTextStream$2.class +0 -0
  222. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$isAvailable$1.class +0 -0
  223. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient$isAvailableBlocking$1.class +0 -0
  224. package/android/build/tmp/kotlin-classes/debug/expo/modules/aikit/PromptApiClient.class +0 -0
package/README.md CHANGED
@@ -32,6 +32,7 @@ On-device AI for Expo apps. Run language models locally—no API keys, no cloud,
32
32
  - **Simple API** — Core functions plus prompt helpers for common tasks
33
33
  - **Prompt helpers** — Built-in `summarize()`, `translate()`, `rewrite()`, and more
34
34
  - **Smart suggestions** — `suggest()`, `smartReply()`, and `autocomplete()` for predictive text
35
+ - **React Hooks** — `useChat`, `useCompletion`, and `useOnDeviceAI` for plug-and-play integration
35
36
  - **Chat memory** — Built-in `ChatMemoryManager` for managing conversation history
36
37
 
37
38
  ## Requirements
@@ -290,6 +291,95 @@ const { promise, stop } = streamSummarize(
290
291
  );
291
292
  ```
292
293
 
294
+ ### React Hooks
295
+
296
+ expo-ai-kit provides React hooks that handle state management, streaming, and conversation memory automatically.
297
+
298
+ #### `useChat` — Full Chat Interface
299
+
300
+ The easiest way to build a chat UI. Manages messages, input, streaming, and memory for you:
301
+
302
+ ```tsx
303
+ import { useChat } from 'expo-ai-kit';
304
+
305
+ function ChatScreen() {
306
+ const { messages, input, setInput, sendMessage, isStreaming, stop, clear, error } = useChat({
307
+ systemPrompt: 'You are a helpful assistant.',
308
+ maxTurns: 10,
309
+ });
310
+
311
+ return (
312
+ <View style={{ flex: 1 }}>
313
+ <FlatList
314
+ data={messages}
315
+ keyExtractor={(_, i) => i.toString()}
316
+ renderItem={({ item }) => (
317
+ <Text>{item.role}: {item.content}</Text>
318
+ )}
319
+ />
320
+ <TextInput value={input} onChangeText={setInput} />
321
+ {isStreaming ? (
322
+ <Button title="Stop" onPress={stop} />
323
+ ) : (
324
+ <Button title="Send" onPress={() => sendMessage()} />
325
+ )}
326
+ <Button title="Clear" onPress={clear} />
327
+ </View>
328
+ );
329
+ }
330
+ ```
331
+
332
+ You can also send a message programmatically:
333
+
334
+ ```tsx
335
+ // Send custom text instead of current input
336
+ sendMessage('What is the weather today?');
337
+ ```
338
+
339
+ #### `useCompletion` — Single-shot Completions
340
+
341
+ For one-off tasks like summarization, translation, or content generation (no conversation history):
342
+
343
+ ```tsx
344
+ import { useCompletion } from 'expo-ai-kit';
345
+
346
+ function Summarizer() {
347
+ const { completion, isLoading, complete, stop, error } = useCompletion({
348
+ systemPrompt: 'Summarize the given text concisely.',
349
+ });
350
+
351
+ return (
352
+ <View>
353
+ <Button
354
+ title="Summarize"
355
+ onPress={() => complete('Long article text here...')}
356
+ />
357
+ {isLoading && <Button title="Stop" onPress={stop} />}
358
+ <Text>{completion}</Text>
359
+ </View>
360
+ );
361
+ }
362
+ ```
363
+
364
+ #### `useOnDeviceAI` — Availability Check
365
+
366
+ A simple hook to check if on-device AI is available, with caching across components:
367
+
368
+ ```tsx
369
+ import { useOnDeviceAI } from 'expo-ai-kit';
370
+
371
+ function App() {
372
+ const { isAvailable, isChecking } = useOnDeviceAI();
373
+
374
+ if (isChecking) return <Text>Checking AI availability...</Text>;
375
+ if (!isAvailable) return <Text>On-device AI not available</Text>;
376
+
377
+ return <ChatScreen />;
378
+ }
379
+ ```
380
+
381
+ ---
382
+
293
383
  ### Streaming with Cancel Button
294
384
 
295
385
  ```tsx
@@ -668,6 +758,80 @@ function parseSuggestResponse(raw: string): LLMSuggestResponse
668
758
 
669
759
  ---
670
760
 
761
+ ### `useChat(options?)`
762
+
763
+ React hook for building chat interfaces. Manages messages, input, streaming, and conversation memory automatically.
764
+
765
+ ```typescript
766
+ function useChat(options?: UseChatOptions): UseChatReturn
767
+ ```
768
+
769
+ | Option | Type | Description |
770
+ |--------|------|-------------|
771
+ | `systemPrompt` | `string` | System prompt for the AI assistant |
772
+ | `maxTurns` | `number` | Maximum conversation turns to keep in memory (default: `10`) |
773
+ | `initialMessages` | `LLMMessage[]` | Initial messages to populate the chat |
774
+ | `onFinish` | `(response: LLMResponse) => void` | Callback when a response is complete |
775
+ | `onError` | `(error: Error) => void` | Callback when an error occurs |
776
+
777
+ **Returns:**
778
+
779
+ | Property | Type | Description |
780
+ |----------|------|-------------|
781
+ | `messages` | `LLMMessage[]` | All messages in the conversation |
782
+ | `input` | `string` | Current input text value |
783
+ | `setInput` | `(input: string) => void` | Set the input text value |
784
+ | `sendMessage` | `(text?: string) => Promise<void>` | Send the current input (or provided text) |
785
+ | `isStreaming` | `boolean` | Whether the AI is currently streaming |
786
+ | `stop` | `() => void` | Stop the current streaming response |
787
+ | `clear` | `() => void` | Clear all messages and reset |
788
+ | `error` | `Error \| null` | The most recent error, if any |
789
+
790
+ ---
791
+
792
+ ### `useCompletion(options?)`
793
+
794
+ React hook for single-shot AI completions (summarization, translation, etc.).
795
+
796
+ ```typescript
797
+ function useCompletion(options?: UseCompletionOptions): UseCompletionReturn
798
+ ```
799
+
800
+ | Option | Type | Description |
801
+ |--------|------|-------------|
802
+ | `systemPrompt` | `string` | System prompt for the AI |
803
+ | `onFinish` | `(response: LLMResponse) => void` | Callback when completion is done |
804
+ | `onError` | `(error: Error) => void` | Callback when an error occurs |
805
+
806
+ **Returns:**
807
+
808
+ | Property | Type | Description |
809
+ |----------|------|-------------|
810
+ | `completion` | `string` | The current completion text |
811
+ | `isLoading` | `boolean` | Whether a completion is in progress |
812
+ | `complete` | `(prompt: string) => Promise<string>` | Request a completion |
813
+ | `stop` | `() => void` | Stop the current completion |
814
+ | `error` | `Error \| null` | The most recent error, if any |
815
+
816
+ ---
817
+
818
+ ### `useOnDeviceAI()`
819
+
820
+ React hook to check if on-device AI is available. Caches the result across components.
821
+
822
+ ```typescript
823
+ function useOnDeviceAI(): UseOnDeviceAIReturn
824
+ ```
825
+
826
+ **Returns:**
827
+
828
+ | Property | Type | Description |
829
+ |----------|------|-------------|
830
+ | `isAvailable` | `boolean` | Whether on-device AI is available |
831
+ | `isChecking` | `boolean` | Whether the check is still in progress |
832
+
833
+ ---
834
+
671
835
  ### `ChatMemoryManager`
672
836
 
673
837
  Manages conversation history for stateless on-device AI models. Automatically handles turn limits and provides the full message array for each request.
@@ -851,6 +1015,45 @@ type LLMSuggestResponse = {
851
1015
  raw: string;
852
1016
  };
853
1017
 
1018
+ // Hook Types
1019
+ type UseChatOptions = {
1020
+ systemPrompt?: string;
1021
+ maxTurns?: number;
1022
+ initialMessages?: LLMMessage[];
1023
+ onFinish?: (response: LLMResponse) => void;
1024
+ onError?: (error: Error) => void;
1025
+ };
1026
+
1027
+ type UseChatReturn = {
1028
+ messages: LLMMessage[];
1029
+ input: string;
1030
+ setInput: (input: string) => void;
1031
+ sendMessage: (text?: string) => Promise<void>;
1032
+ isStreaming: boolean;
1033
+ stop: () => void;
1034
+ clear: () => void;
1035
+ error: Error | null;
1036
+ };
1037
+
1038
+ type UseCompletionOptions = {
1039
+ systemPrompt?: string;
1040
+ onFinish?: (response: LLMResponse) => void;
1041
+ onError?: (error: Error) => void;
1042
+ };
1043
+
1044
+ type UseCompletionReturn = {
1045
+ completion: string;
1046
+ isLoading: boolean;
1047
+ complete: (prompt: string) => Promise<string>;
1048
+ stop: () => void;
1049
+ error: Error | null;
1050
+ };
1051
+
1052
+ type UseOnDeviceAIReturn = {
1053
+ isAvailable: boolean;
1054
+ isChecking: boolean;
1055
+ };
1056
+
854
1057
  // Chat Memory Types
855
1058
  type ChatMemoryOptions = {
856
1059
  /** Maximum conversation turns to keep (default: 10) */
@@ -877,6 +1080,7 @@ type ChatMemorySnapshot = {
877
1080
  | Prompt helpers | ✅ | ✅ |
878
1081
  | Smart suggestions | ✅ | ✅ |
879
1082
  | `ChatMemoryManager` | ✅ | ✅ |
1083
+ | React Hooks (`useChat`, etc.) | ✅ | ✅ |
880
1084
  | System prompts | ✅ Native | ✅ Prepended |
881
1085
  | Multi-turn context | ✅ | ✅ |
882
1086
  | Cancel streaming | ✅ | ✅ |
@@ -930,10 +1134,11 @@ const { text } = await sendMessage(messages, { systemPrompt: '...' });
930
1134
  | ✅ Prompt helpers (summarize, translate, etc.) | Done | - |
931
1135
  | ✅ Chat memory management | Done | - |
932
1136
  | ✅ Smart suggestions (suggest, smartReply, autocomplete) | Done | - |
1137
+ | ✅ React Hooks (useChat, useCompletion, useOnDeviceAI) | Done | - |
933
1138
  | Web/generic fallback | Idea | Medium |
934
1139
  | Configurable hyperparameters (temperature, etc.) | Idea | Low |
935
1140
 
936
- Have a feature request? [Open an issue](https://github.com/laraelmas/expo-ai-kit/issues)!
1141
+ Have a feature request? [Open an issue](https://github.com/saidkaban/expo-ai-kit/issues)!
937
1142
 
938
1143
  ## License
939
1144
 
@@ -947,6 +1152,6 @@ Contributions are welcome! Please refer to guidelines described in the [contribu
947
1152
 
948
1153
  - [Documentation](https://expo-ai-kit.com)
949
1154
  - [npm package](https://www.npmjs.com/package/expo-ai-kit)
950
- - [GitHub repository](https://github.com/laraelmas/expo-ai-kit)
1155
+ - [GitHub repository](https://github.com/saidkaban/expo-ai-kit)
951
1156
  - [Apple Foundation Models](https://developer.apple.com/documentation/foundationmodels)
952
1157
  - [Google ML Kit Prompt API](https://developers.google.com/ml-kit/genai)
@@ -0,0 +1,88 @@
1
+ import type { UseChatOptions, UseChatReturn, UseCompletionOptions, UseCompletionReturn, UseOnDeviceAIReturn } from './types';
2
+ /**
3
+ * React hook to check if on-device AI is available.
4
+ *
5
+ * Caches the result so multiple components don't re-check.
6
+ *
7
+ * @returns Object with isAvailable and isChecking states
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * function MyComponent() {
12
+ * const { isAvailable, isChecking } = useOnDeviceAI();
13
+ *
14
+ * if (isChecking) return <Text>Checking AI availability...</Text>;
15
+ * if (!isAvailable) return <Text>On-device AI not available</Text>;
16
+ *
17
+ * return <ChatComponent />;
18
+ * }
19
+ * ```
20
+ */
21
+ export declare function useOnDeviceAI(): UseOnDeviceAIReturn;
22
+ /**
23
+ * React hook for building chat interfaces with on-device AI.
24
+ *
25
+ * Manages messages, input state, streaming, and conversation memory automatically.
26
+ * Built on top of ChatMemoryManager and streamMessage.
27
+ *
28
+ * @param options - Configuration options for the chat
29
+ * @returns Chat state and control functions
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * function ChatScreen() {
34
+ * const { messages, input, setInput, sendMessage, isStreaming, stop } = useChat({
35
+ * systemPrompt: 'You are a helpful assistant.',
36
+ * });
37
+ *
38
+ * return (
39
+ * <View>
40
+ * <FlatList
41
+ * data={messages}
42
+ * renderItem={({ item }) => (
43
+ * <Text>{item.role}: {item.content}</Text>
44
+ * )}
45
+ * />
46
+ * <TextInput value={input} onChangeText={setInput} />
47
+ * {isStreaming ? (
48
+ * <Button title="Stop" onPress={stop} />
49
+ * ) : (
50
+ * <Button title="Send" onPress={() => sendMessage()} />
51
+ * )}
52
+ * </View>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export declare function useChat(options?: UseChatOptions): UseChatReturn;
58
+ /**
59
+ * React hook for single-shot AI completions.
60
+ *
61
+ * Unlike useChat (which manages a conversation), useCompletion is for
62
+ * one-off tasks like summarization, translation, or content generation.
63
+ *
64
+ * @param options - Configuration options
65
+ * @returns Completion state and control functions
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * function SummarizerScreen() {
70
+ * const { completion, isLoading, complete, stop } = useCompletion({
71
+ * systemPrompt: 'You are a summarization assistant. Summarize the given text concisely.',
72
+ * });
73
+ *
74
+ * return (
75
+ * <View>
76
+ * <Button
77
+ * title="Summarize"
78
+ * onPress={() => complete('Long article text here...')}
79
+ * />
80
+ * {isLoading && <Button title="Stop" onPress={stop} />}
81
+ * <Text>{completion}</Text>
82
+ * </View>
83
+ * );
84
+ * }
85
+ * ```
86
+ */
87
+ export declare function useCompletion(options?: UseCompletionOptions): UseCompletionReturn;
88
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAmBjB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,IAAI,mBAAmB,CAwBnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,CA8GnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAgFrF"}
package/build/hooks.js ADDED
@@ -0,0 +1,293 @@
1
+ import { useState, useEffect, useRef, useCallback } from 'react';
2
+ import { isAvailable, streamMessage } from './index';
3
+ import { ChatMemoryManager } from './memory';
4
+ // Cache availability result across all hook instances
5
+ let availabilityCache = null;
6
+ let availabilityPromise = null;
7
+ function checkAvailability() {
8
+ if (availabilityCache !== null) {
9
+ return Promise.resolve(availabilityCache);
10
+ }
11
+ if (!availabilityPromise) {
12
+ availabilityPromise = isAvailable().then((result) => {
13
+ availabilityCache = result;
14
+ return result;
15
+ });
16
+ }
17
+ return availabilityPromise;
18
+ }
19
+ /**
20
+ * React hook to check if on-device AI is available.
21
+ *
22
+ * Caches the result so multiple components don't re-check.
23
+ *
24
+ * @returns Object with isAvailable and isChecking states
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * function MyComponent() {
29
+ * const { isAvailable, isChecking } = useOnDeviceAI();
30
+ *
31
+ * if (isChecking) return <Text>Checking AI availability...</Text>;
32
+ * if (!isAvailable) return <Text>On-device AI not available</Text>;
33
+ *
34
+ * return <ChatComponent />;
35
+ * }
36
+ * ```
37
+ */
38
+ export function useOnDeviceAI() {
39
+ const [available, setAvailable] = useState(availabilityCache ?? false);
40
+ const [checking, setChecking] = useState(availabilityCache === null);
41
+ useEffect(() => {
42
+ if (availabilityCache !== null) {
43
+ setAvailable(availabilityCache);
44
+ setChecking(false);
45
+ return;
46
+ }
47
+ let mounted = true;
48
+ checkAvailability().then((result) => {
49
+ if (mounted) {
50
+ setAvailable(result);
51
+ setChecking(false);
52
+ }
53
+ });
54
+ return () => {
55
+ mounted = false;
56
+ };
57
+ }, []);
58
+ return { isAvailable: available, isChecking: checking };
59
+ }
60
+ /**
61
+ * React hook for building chat interfaces with on-device AI.
62
+ *
63
+ * Manages messages, input state, streaming, and conversation memory automatically.
64
+ * Built on top of ChatMemoryManager and streamMessage.
65
+ *
66
+ * @param options - Configuration options for the chat
67
+ * @returns Chat state and control functions
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * function ChatScreen() {
72
+ * const { messages, input, setInput, sendMessage, isStreaming, stop } = useChat({
73
+ * systemPrompt: 'You are a helpful assistant.',
74
+ * });
75
+ *
76
+ * return (
77
+ * <View>
78
+ * <FlatList
79
+ * data={messages}
80
+ * renderItem={({ item }) => (
81
+ * <Text>{item.role}: {item.content}</Text>
82
+ * )}
83
+ * />
84
+ * <TextInput value={input} onChangeText={setInput} />
85
+ * {isStreaming ? (
86
+ * <Button title="Stop" onPress={stop} />
87
+ * ) : (
88
+ * <Button title="Send" onPress={() => sendMessage()} />
89
+ * )}
90
+ * </View>
91
+ * );
92
+ * }
93
+ * ```
94
+ */
95
+ export function useChat(options = {}) {
96
+ const { systemPrompt, maxTurns, initialMessages, onFinish, onError } = options;
97
+ const memoryRef = useRef(new ChatMemoryManager({ maxTurns, systemPrompt }));
98
+ // Initialize with initial messages
99
+ const initializedRef = useRef(false);
100
+ if (!initializedRef.current && initialMessages) {
101
+ for (const msg of initialMessages) {
102
+ memoryRef.current.addMessage(msg);
103
+ }
104
+ initializedRef.current = true;
105
+ }
106
+ const [messages, setMessages] = useState(memoryRef.current.getMessages());
107
+ const [input, setInput] = useState('');
108
+ const [isStreaming, setIsStreaming] = useState(false);
109
+ const [error, setError] = useState(null);
110
+ const stopRef = useRef(null);
111
+ const mountedRef = useRef(true);
112
+ const inputRef = useRef(input);
113
+ inputRef.current = input;
114
+ const streamingRef = useRef(isStreaming);
115
+ streamingRef.current = isStreaming;
116
+ const onFinishRef = useRef(onFinish);
117
+ onFinishRef.current = onFinish;
118
+ const onErrorRef = useRef(onError);
119
+ onErrorRef.current = onError;
120
+ useEffect(() => {
121
+ return () => {
122
+ mountedRef.current = false;
123
+ stopRef.current?.();
124
+ };
125
+ }, []);
126
+ const send = useCallback(async (text) => {
127
+ const content = (text ?? inputRef.current).trim();
128
+ if (!content || streamingRef.current)
129
+ return;
130
+ setError(null);
131
+ // Add user message
132
+ memoryRef.current.addUserMessage(content);
133
+ setMessages([...memoryRef.current.getMessages()]);
134
+ if (!text)
135
+ setInput('');
136
+ setIsStreaming(true);
137
+ try {
138
+ const allMessages = memoryRef.current.getAllMessages();
139
+ // Use a temporary message for streaming display
140
+ let accumulatedText = '';
141
+ const { promise, stop } = streamMessage(allMessages, (event) => {
142
+ if (!mountedRef.current)
143
+ return;
144
+ accumulatedText = event.accumulatedText;
145
+ // Update messages with streaming assistant response
146
+ const currentMessages = memoryRef.current.getMessages();
147
+ setMessages([
148
+ ...currentMessages,
149
+ { role: 'assistant', content: accumulatedText },
150
+ ]);
151
+ });
152
+ stopRef.current = stop;
153
+ const response = await promise;
154
+ if (!mountedRef.current)
155
+ return;
156
+ // Add the final assistant message to memory
157
+ memoryRef.current.addAssistantMessage(response.text);
158
+ setMessages([...memoryRef.current.getMessages()]);
159
+ onFinishRef.current?.(response);
160
+ }
161
+ catch (err) {
162
+ if (!mountedRef.current)
163
+ return;
164
+ const e = err instanceof Error ? err : new Error(String(err));
165
+ setError(e);
166
+ onErrorRef.current?.(e);
167
+ }
168
+ finally {
169
+ stopRef.current = null;
170
+ if (mountedRef.current) {
171
+ setIsStreaming(false);
172
+ }
173
+ }
174
+ }, []);
175
+ const stop = useCallback(() => {
176
+ stopRef.current?.();
177
+ }, []);
178
+ const clear = useCallback(() => {
179
+ memoryRef.current.clear();
180
+ setMessages([]);
181
+ setError(null);
182
+ }, []);
183
+ return {
184
+ messages,
185
+ input,
186
+ setInput,
187
+ sendMessage: send,
188
+ isStreaming,
189
+ stop,
190
+ clear,
191
+ error,
192
+ };
193
+ }
194
+ /**
195
+ * React hook for single-shot AI completions.
196
+ *
197
+ * Unlike useChat (which manages a conversation), useCompletion is for
198
+ * one-off tasks like summarization, translation, or content generation.
199
+ *
200
+ * @param options - Configuration options
201
+ * @returns Completion state and control functions
202
+ *
203
+ * @example
204
+ * ```tsx
205
+ * function SummarizerScreen() {
206
+ * const { completion, isLoading, complete, stop } = useCompletion({
207
+ * systemPrompt: 'You are a summarization assistant. Summarize the given text concisely.',
208
+ * });
209
+ *
210
+ * return (
211
+ * <View>
212
+ * <Button
213
+ * title="Summarize"
214
+ * onPress={() => complete('Long article text here...')}
215
+ * />
216
+ * {isLoading && <Button title="Stop" onPress={stop} />}
217
+ * <Text>{completion}</Text>
218
+ * </View>
219
+ * );
220
+ * }
221
+ * ```
222
+ */
223
+ export function useCompletion(options = {}) {
224
+ const { systemPrompt, onFinish, onError } = options;
225
+ const [completion, setCompletion] = useState('');
226
+ const [isLoading, setIsLoading] = useState(false);
227
+ const [error, setError] = useState(null);
228
+ const stopRef = useRef(null);
229
+ const mountedRef = useRef(true);
230
+ const loadingRef = useRef(isLoading);
231
+ loadingRef.current = isLoading;
232
+ const completionRef = useRef(completion);
233
+ completionRef.current = completion;
234
+ const systemPromptRef = useRef(systemPrompt);
235
+ systemPromptRef.current = systemPrompt;
236
+ const onFinishRef = useRef(onFinish);
237
+ onFinishRef.current = onFinish;
238
+ const onErrorRef = useRef(onError);
239
+ onErrorRef.current = onError;
240
+ useEffect(() => {
241
+ return () => {
242
+ mountedRef.current = false;
243
+ stopRef.current?.();
244
+ };
245
+ }, []);
246
+ const complete = useCallback(async (prompt) => {
247
+ if (loadingRef.current)
248
+ return completionRef.current;
249
+ setError(null);
250
+ setCompletion('');
251
+ setIsLoading(true);
252
+ try {
253
+ const messages = [{ role: 'user', content: prompt }];
254
+ const { promise, stop } = streamMessage(messages, (event) => {
255
+ if (!mountedRef.current)
256
+ return;
257
+ setCompletion(event.accumulatedText);
258
+ }, systemPromptRef.current ? { systemPrompt: systemPromptRef.current } : undefined);
259
+ stopRef.current = stop;
260
+ const response = await promise;
261
+ if (!mountedRef.current)
262
+ return '';
263
+ setCompletion(response.text);
264
+ onFinishRef.current?.(response);
265
+ return response.text;
266
+ }
267
+ catch (err) {
268
+ if (!mountedRef.current)
269
+ return '';
270
+ const e = err instanceof Error ? err : new Error(String(err));
271
+ setError(e);
272
+ onErrorRef.current?.(e);
273
+ return '';
274
+ }
275
+ finally {
276
+ stopRef.current = null;
277
+ if (mountedRef.current) {
278
+ setIsLoading(false);
279
+ }
280
+ }
281
+ }, []);
282
+ const stop = useCallback(() => {
283
+ stopRef.current?.();
284
+ }, []);
285
+ return {
286
+ completion,
287
+ isLoading,
288
+ complete,
289
+ stop,
290
+ error,
291
+ };
292
+ }
293
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react';\nimport { isAvailable, streamMessage } from './index';\nimport { ChatMemoryManager } from './memory';\nimport type {\n LLMMessage,\n UseChatOptions,\n UseChatReturn,\n UseCompletionOptions,\n UseCompletionReturn,\n UseOnDeviceAIReturn,\n} from './types';\n\n// Cache availability result across all hook instances\nlet availabilityCache: boolean | null = null;\nlet availabilityPromise: Promise<boolean> | null = null;\n\nfunction checkAvailability(): Promise<boolean> {\n if (availabilityCache !== null) {\n return Promise.resolve(availabilityCache);\n }\n if (!availabilityPromise) {\n availabilityPromise = isAvailable().then((result) => {\n availabilityCache = result;\n return result;\n });\n }\n return availabilityPromise;\n}\n\n/**\n * React hook to check if on-device AI is available.\n *\n * Caches the result so multiple components don't re-check.\n *\n * @returns Object with isAvailable and isChecking states\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { isAvailable, isChecking } = useOnDeviceAI();\n *\n * if (isChecking) return <Text>Checking AI availability...</Text>;\n * if (!isAvailable) return <Text>On-device AI not available</Text>;\n *\n * return <ChatComponent />;\n * }\n * ```\n */\nexport function useOnDeviceAI(): UseOnDeviceAIReturn {\n const [available, setAvailable] = useState(availabilityCache ?? false);\n const [checking, setChecking] = useState(availabilityCache === null);\n\n useEffect(() => {\n if (availabilityCache !== null) {\n setAvailable(availabilityCache);\n setChecking(false);\n return;\n }\n\n let mounted = true;\n checkAvailability().then((result) => {\n if (mounted) {\n setAvailable(result);\n setChecking(false);\n }\n });\n return () => {\n mounted = false;\n };\n }, []);\n\n return { isAvailable: available, isChecking: checking };\n}\n\n/**\n * React hook for building chat interfaces with on-device AI.\n *\n * Manages messages, input state, streaming, and conversation memory automatically.\n * Built on top of ChatMemoryManager and streamMessage.\n *\n * @param options - Configuration options for the chat\n * @returns Chat state and control functions\n *\n * @example\n * ```tsx\n * function ChatScreen() {\n * const { messages, input, setInput, sendMessage, isStreaming, stop } = useChat({\n * systemPrompt: 'You are a helpful assistant.',\n * });\n *\n * return (\n * <View>\n * <FlatList\n * data={messages}\n * renderItem={({ item }) => (\n * <Text>{item.role}: {item.content}</Text>\n * )}\n * />\n * <TextInput value={input} onChangeText={setInput} />\n * {isStreaming ? (\n * <Button title=\"Stop\" onPress={stop} />\n * ) : (\n * <Button title=\"Send\" onPress={() => sendMessage()} />\n * )}\n * </View>\n * );\n * }\n * ```\n */\nexport function useChat(options: UseChatOptions = {}): UseChatReturn {\n const { systemPrompt, maxTurns, initialMessages, onFinish, onError } = options;\n\n const memoryRef = useRef(new ChatMemoryManager({ maxTurns, systemPrompt }));\n\n // Initialize with initial messages\n const initializedRef = useRef(false);\n if (!initializedRef.current && initialMessages) {\n for (const msg of initialMessages) {\n memoryRef.current.addMessage(msg);\n }\n initializedRef.current = true;\n }\n\n const [messages, setMessages] = useState<LLMMessage[]>(memoryRef.current.getMessages());\n const [input, setInput] = useState('');\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const stopRef = useRef<(() => void) | null>(null);\n const mountedRef = useRef(true);\n const inputRef = useRef(input);\n inputRef.current = input;\n const streamingRef = useRef(isStreaming);\n streamingRef.current = isStreaming;\n const onFinishRef = useRef(onFinish);\n onFinishRef.current = onFinish;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n return () => {\n mountedRef.current = false;\n stopRef.current?.();\n };\n }, []);\n\n const send = useCallback(\n async (text?: string) => {\n const content = (text ?? inputRef.current).trim();\n if (!content || streamingRef.current) return;\n\n setError(null);\n\n // Add user message\n memoryRef.current.addUserMessage(content);\n setMessages([...memoryRef.current.getMessages()]);\n if (!text) setInput('');\n\n setIsStreaming(true);\n\n try {\n const allMessages = memoryRef.current.getAllMessages();\n\n // Use a temporary message for streaming display\n let accumulatedText = '';\n const { promise, stop } = streamMessage(allMessages, (event) => {\n if (!mountedRef.current) return;\n accumulatedText = event.accumulatedText;\n // Update messages with streaming assistant response\n const currentMessages = memoryRef.current.getMessages();\n setMessages([\n ...currentMessages,\n { role: 'assistant' as const, content: accumulatedText },\n ]);\n });\n\n stopRef.current = stop;\n const response = await promise;\n\n if (!mountedRef.current) return;\n\n // Add the final assistant message to memory\n memoryRef.current.addAssistantMessage(response.text);\n setMessages([...memoryRef.current.getMessages()]);\n onFinishRef.current?.(response);\n } catch (err) {\n if (!mountedRef.current) return;\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n onErrorRef.current?.(e);\n } finally {\n stopRef.current = null;\n if (mountedRef.current) {\n setIsStreaming(false);\n }\n }\n },\n []\n );\n\n const stop = useCallback(() => {\n stopRef.current?.();\n }, []);\n\n const clear = useCallback(() => {\n memoryRef.current.clear();\n setMessages([]);\n setError(null);\n }, []);\n\n return {\n messages,\n input,\n setInput,\n sendMessage: send,\n isStreaming,\n stop,\n clear,\n error,\n };\n}\n\n/**\n * React hook for single-shot AI completions.\n *\n * Unlike useChat (which manages a conversation), useCompletion is for\n * one-off tasks like summarization, translation, or content generation.\n *\n * @param options - Configuration options\n * @returns Completion state and control functions\n *\n * @example\n * ```tsx\n * function SummarizerScreen() {\n * const { completion, isLoading, complete, stop } = useCompletion({\n * systemPrompt: 'You are a summarization assistant. Summarize the given text concisely.',\n * });\n *\n * return (\n * <View>\n * <Button\n * title=\"Summarize\"\n * onPress={() => complete('Long article text here...')}\n * />\n * {isLoading && <Button title=\"Stop\" onPress={stop} />}\n * <Text>{completion}</Text>\n * </View>\n * );\n * }\n * ```\n */\nexport function useCompletion(options: UseCompletionOptions = {}): UseCompletionReturn {\n const { systemPrompt, onFinish, onError } = options;\n\n const [completion, setCompletion] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const stopRef = useRef<(() => void) | null>(null);\n const mountedRef = useRef(true);\n const loadingRef = useRef(isLoading);\n loadingRef.current = isLoading;\n const completionRef = useRef(completion);\n completionRef.current = completion;\n const systemPromptRef = useRef(systemPrompt);\n systemPromptRef.current = systemPrompt;\n const onFinishRef = useRef(onFinish);\n onFinishRef.current = onFinish;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n return () => {\n mountedRef.current = false;\n stopRef.current?.();\n };\n }, []);\n\n const complete = useCallback(\n async (prompt: string) => {\n if (loadingRef.current) return completionRef.current;\n\n setError(null);\n setCompletion('');\n setIsLoading(true);\n\n try {\n const messages: LLMMessage[] = [{ role: 'user', content: prompt }];\n const { promise, stop } = streamMessage(\n messages,\n (event) => {\n if (!mountedRef.current) return;\n setCompletion(event.accumulatedText);\n },\n systemPromptRef.current ? { systemPrompt: systemPromptRef.current } : undefined\n );\n\n stopRef.current = stop;\n const response = await promise;\n\n if (!mountedRef.current) return '';\n\n setCompletion(response.text);\n onFinishRef.current?.(response);\n return response.text;\n } catch (err) {\n if (!mountedRef.current) return '';\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n onErrorRef.current?.(e);\n return '';\n } finally {\n stopRef.current = null;\n if (mountedRef.current) {\n setIsLoading(false);\n }\n }\n },\n []\n );\n\n const stop = useCallback(() => {\n stopRef.current?.();\n }, []);\n\n return {\n completion,\n isLoading,\n complete,\n stop,\n error,\n };\n}\n"]}
package/build/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { LLMMessage, LLMSendOptions, LLMResponse, LLMStreamOptions, LLMStreamCallback, LLMSummarizeOptions, LLMTranslateOptions, LLMRewriteOptions, LLMExtractKeyPointsOptions, LLMAnswerQuestionOptions, LLMSuggestOptions, LLMSuggestResponse, LLMSmartReplyOptions, LLMAutocompleteOptions } from './types';
2
2
  export * from './types';
3
3
  export * from './memory';
4
+ export * from './hooks';
4
5
  /**
5
6
  * Check if on-device AI is available on the current device.
6
7
  * Returns false on unsupported platforms (web, etc.).