cui-llama.rn 1.5.0 → 1.6.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.
Files changed (309) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +317 -319
  3. package/android/build.gradle +116 -116
  4. package/android/gradle.properties +5 -5
  5. package/android/src/main/AndroidManifest.xml +4 -4
  6. package/android/src/main/CMakeLists.txt +124 -124
  7. package/android/src/main/java/com/rnllama/LlamaContext.java +645 -645
  8. package/android/src/main/java/com/rnllama/RNLlama.java +695 -695
  9. package/android/src/main/java/com/rnllama/RNLlamaPackage.java +48 -48
  10. package/android/src/main/jni-utils.h +100 -100
  11. package/android/src/main/jni.cpp +1263 -1263
  12. package/android/src/main/jniLibs/arm64-v8a/librnllama.so +0 -0
  13. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8.so +0 -0
  14. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2.so +0 -0
  15. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_dotprod.so +0 -0
  16. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_dotprod_i8mm.so +0 -0
  17. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_i8mm.so +0 -0
  18. package/android/src/main/jniLibs/x86_64/librnllama.so +0 -0
  19. package/android/src/main/jniLibs/x86_64/librnllama_x86_64.so +0 -0
  20. package/android/src/newarch/java/com/rnllama/RNLlamaModule.java +135 -135
  21. package/android/src/oldarch/java/com/rnllama/RNLlamaModule.java +136 -136
  22. package/cpp/README.md +4 -4
  23. package/cpp/ggml-llama-sim.metallib +0 -0
  24. package/cpp/ggml-llama.metallib +0 -0
  25. package/cpp/ggml-metal-impl.h +597 -597
  26. package/cpp/ggml-metal.m +4 -0
  27. package/cpp/ggml.h +1 -1
  28. package/cpp/rn-llama.cpp +873 -873
  29. package/cpp/rn-llama.h +138 -138
  30. package/cpp/sampling.h +107 -107
  31. package/cpp/unicode-data.cpp +7034 -7034
  32. package/cpp/unicode-data.h +20 -20
  33. package/cpp/unicode.cpp +849 -849
  34. package/cpp/unicode.h +66 -66
  35. package/ios/CMakeLists.txt +116 -108
  36. package/ios/RNLlama.h +7 -7
  37. package/ios/RNLlama.mm +418 -405
  38. package/ios/RNLlamaContext.h +57 -57
  39. package/ios/RNLlamaContext.mm +835 -835
  40. package/ios/rnllama.xcframework/Info.plist +74 -74
  41. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/binary-ops.h +16 -0
  42. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/chat.h +143 -0
  43. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/common.h +677 -0
  44. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/cpu-common.h +72 -0
  45. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-alloc.h +76 -0
  46. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  47. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-backend.h +354 -0
  48. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-common.h +1857 -0
  49. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpp.h +39 -0
  50. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  51. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  52. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  53. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  54. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu.h +138 -0
  55. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-impl.h +594 -0
  56. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  57. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-metal.h +66 -0
  58. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-opt.h +216 -0
  59. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-quants.h +100 -0
  60. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-threading.h +14 -0
  61. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml.h +2222 -0
  62. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/gguf.h +202 -0
  63. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  64. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/json.hpp +24766 -0
  65. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-adapter.h +76 -0
  66. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-arch.h +428 -0
  67. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-batch.h +88 -0
  68. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-chat.h +56 -0
  69. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-context.h +265 -0
  70. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-cparams.h +38 -0
  71. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-cpp.h +30 -0
  72. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-grammar.h +173 -0
  73. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-graph.h +592 -0
  74. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-hparams.h +156 -0
  75. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-impl.h +61 -0
  76. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-io.h +35 -0
  77. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  78. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-memory.h +21 -0
  79. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-mmap.h +68 -0
  80. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-model-loader.h +169 -0
  81. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-model.h +409 -0
  82. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-sampling.h +32 -0
  83. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-vocab.h +125 -0
  84. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama.h +1434 -0
  85. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/log.h +132 -0
  86. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  87. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  88. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ops.h +128 -0
  89. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/rn-llama.h +138 -0
  90. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/sampling.h +107 -0
  91. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/sgemm.h +14 -0
  92. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/simd-mappings.h +888 -0
  93. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/speculative.h +28 -0
  94. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/unary-ops.h +28 -0
  95. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/unicode-data.h +20 -0
  96. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/unicode.h +66 -0
  97. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/vec.h +802 -0
  98. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Info.plist +0 -0
  99. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/ggml-llama.metallib +0 -0
  100. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/rnllama +0 -0
  101. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/binary-ops.h +16 -0
  102. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/chat.h +143 -0
  103. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/common.h +677 -0
  104. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/cpu-common.h +72 -0
  105. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-alloc.h +76 -0
  106. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  107. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend.h +354 -0
  108. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-common.h +1857 -0
  109. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpp.h +39 -0
  110. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  111. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  112. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  113. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  114. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu.h +138 -0
  115. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-impl.h +594 -0
  116. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  117. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal.h +66 -0
  118. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-opt.h +216 -0
  119. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-quants.h +100 -0
  120. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-threading.h +14 -0
  121. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml.h +2222 -0
  122. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/gguf.h +202 -0
  123. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  124. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/json.hpp +24766 -0
  125. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-adapter.h +76 -0
  126. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-arch.h +428 -0
  127. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-batch.h +88 -0
  128. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-chat.h +56 -0
  129. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-context.h +265 -0
  130. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cparams.h +38 -0
  131. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cpp.h +30 -0
  132. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-grammar.h +173 -0
  133. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-graph.h +592 -0
  134. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-hparams.h +156 -0
  135. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-impl.h +61 -0
  136. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-io.h +35 -0
  137. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  138. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-memory.h +21 -0
  139. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-mmap.h +68 -0
  140. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model-loader.h +169 -0
  141. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model.h +409 -0
  142. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-sampling.h +32 -0
  143. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-vocab.h +125 -0
  144. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama.h +1434 -0
  145. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/log.h +132 -0
  146. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  147. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  148. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ops.h +128 -0
  149. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/rn-llama.h +138 -0
  150. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/sampling.h +107 -0
  151. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/sgemm.h +14 -0
  152. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/simd-mappings.h +888 -0
  153. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/speculative.h +28 -0
  154. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/unary-ops.h +28 -0
  155. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/unicode-data.h +20 -0
  156. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/unicode.h +66 -0
  157. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/vec.h +802 -0
  158. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Info.plist +0 -0
  159. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/_CodeSignature/CodeResources +101 -0
  160. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/ggml-llama-sim.metallib +0 -0
  161. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/rnllama +0 -0
  162. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/binary-ops.h +16 -0
  163. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/chat.h +143 -0
  164. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/common.h +677 -0
  165. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/cpu-common.h +72 -0
  166. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-alloc.h +76 -0
  167. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  168. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-backend.h +354 -0
  169. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-common.h +1857 -0
  170. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpp.h +39 -0
  171. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  172. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  173. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  174. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  175. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu.h +138 -0
  176. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-impl.h +594 -0
  177. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  178. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-metal.h +66 -0
  179. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-opt.h +216 -0
  180. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-quants.h +100 -0
  181. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-threading.h +14 -0
  182. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml.h +2222 -0
  183. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/gguf.h +202 -0
  184. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  185. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/json.hpp +24766 -0
  186. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-adapter.h +76 -0
  187. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-arch.h +428 -0
  188. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-batch.h +88 -0
  189. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-chat.h +56 -0
  190. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-context.h +265 -0
  191. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-cparams.h +38 -0
  192. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-cpp.h +30 -0
  193. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-grammar.h +173 -0
  194. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-graph.h +592 -0
  195. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-hparams.h +156 -0
  196. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-impl.h +61 -0
  197. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-io.h +35 -0
  198. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  199. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-memory.h +21 -0
  200. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-mmap.h +68 -0
  201. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-model-loader.h +169 -0
  202. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-model.h +409 -0
  203. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-sampling.h +32 -0
  204. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-vocab.h +125 -0
  205. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama.h +1434 -0
  206. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/log.h +132 -0
  207. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  208. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  209. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ops.h +128 -0
  210. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/rn-llama.h +138 -0
  211. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/sampling.h +107 -0
  212. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/sgemm.h +14 -0
  213. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/simd-mappings.h +888 -0
  214. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/speculative.h +28 -0
  215. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/unary-ops.h +28 -0
  216. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/unicode-data.h +20 -0
  217. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/unicode.h +66 -0
  218. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/vec.h +802 -0
  219. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Info.plist +0 -0
  220. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/ggml-llama.metallib +0 -0
  221. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/rnllama +0 -0
  222. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/binary-ops.h +16 -0
  223. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/chat.h +143 -0
  224. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/common.h +677 -0
  225. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/cpu-common.h +72 -0
  226. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-alloc.h +76 -0
  227. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  228. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend.h +354 -0
  229. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-common.h +1857 -0
  230. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpp.h +39 -0
  231. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  232. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  233. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  234. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  235. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu.h +138 -0
  236. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-impl.h +594 -0
  237. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  238. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal.h +66 -0
  239. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-opt.h +216 -0
  240. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-quants.h +100 -0
  241. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-threading.h +14 -0
  242. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml.h +2222 -0
  243. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/gguf.h +202 -0
  244. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  245. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/json.hpp +24766 -0
  246. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-adapter.h +76 -0
  247. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-arch.h +428 -0
  248. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-batch.h +88 -0
  249. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-chat.h +56 -0
  250. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-context.h +265 -0
  251. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cparams.h +38 -0
  252. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cpp.h +30 -0
  253. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-grammar.h +173 -0
  254. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-graph.h +592 -0
  255. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-hparams.h +156 -0
  256. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-impl.h +61 -0
  257. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-io.h +35 -0
  258. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  259. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-memory.h +21 -0
  260. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-mmap.h +68 -0
  261. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model-loader.h +169 -0
  262. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model.h +409 -0
  263. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-sampling.h +32 -0
  264. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-vocab.h +125 -0
  265. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama.h +1434 -0
  266. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/log.h +132 -0
  267. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  268. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  269. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ops.h +128 -0
  270. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/rn-llama.h +138 -0
  271. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/sampling.h +107 -0
  272. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/sgemm.h +14 -0
  273. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/simd-mappings.h +888 -0
  274. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/speculative.h +28 -0
  275. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/unary-ops.h +28 -0
  276. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/unicode-data.h +20 -0
  277. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/unicode.h +66 -0
  278. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/vec.h +802 -0
  279. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Info.plist +0 -0
  280. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/_CodeSignature/CodeResources +101 -0
  281. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/ggml-llama-sim.metallib +0 -0
  282. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/rnllama +0 -0
  283. package/jest/mock.js +203 -203
  284. package/lib/commonjs/NativeRNLlama.js +1 -2
  285. package/lib/commonjs/NativeRNLlama.js.map +1 -1
  286. package/lib/commonjs/chat.js.map +1 -1
  287. package/lib/commonjs/grammar.js +12 -31
  288. package/lib/commonjs/grammar.js.map +1 -1
  289. package/lib/commonjs/index.js +47 -47
  290. package/lib/commonjs/index.js.map +1 -1
  291. package/lib/commonjs/package.json +1 -0
  292. package/lib/module/NativeRNLlama.js +2 -0
  293. package/lib/module/NativeRNLlama.js.map +1 -1
  294. package/lib/module/chat.js +2 -0
  295. package/lib/module/chat.js.map +1 -1
  296. package/lib/module/grammar.js +14 -31
  297. package/lib/module/grammar.js.map +1 -1
  298. package/lib/module/index.js +47 -45
  299. package/lib/module/index.js.map +1 -1
  300. package/lib/module/package.json +1 -0
  301. package/lib/typescript/NativeRNLlama.d.ts +6 -4
  302. package/lib/typescript/NativeRNLlama.d.ts.map +1 -1
  303. package/lib/typescript/index.d.ts.map +1 -1
  304. package/llama-rn.podspec +48 -48
  305. package/package.json +233 -233
  306. package/src/NativeRNLlama.ts +426 -426
  307. package/src/chat.ts +44 -44
  308. package/src/grammar.ts +854 -854
  309. package/src/index.ts +495 -487
package/src/grammar.ts CHANGED
@@ -1,854 +1,854 @@
1
- /* eslint-disable no-restricted-syntax */
2
- /* eslint-disable no-underscore-dangle */
3
-
4
- // NOTE: Deprecated, please use tools or response_format with json_schema instead
5
-
6
- const SPACE_RULE = '" "?'
7
-
8
- function buildRepetition(
9
- itemRule: string,
10
- minItems: number,
11
- maxItems: number | undefined,
12
- opts: {
13
- separatorRule?: string
14
- itemRuleIsLiteral?: boolean
15
- } = {},
16
- ) {
17
- const separatorRule = opts.separatorRule ?? ''
18
- const itemRuleIsLiteral = opts.itemRuleIsLiteral ?? false
19
-
20
- if (separatorRule === '') {
21
- if (minItems === 0 && maxItems === 1) {
22
- return `${itemRule}?`
23
- } else if (minItems === 1 && maxItems === undefined) {
24
- return `${itemRule}+`
25
- }
26
- }
27
-
28
- let result = ''
29
- if (minItems > 0) {
30
- if (itemRuleIsLiteral && separatorRule === '') {
31
- result = `"${itemRule.slice(1, -1).repeat(minItems)}"`
32
- } else {
33
- result = Array.from({ length: minItems }, () => itemRule).join(
34
- separatorRule !== '' ? ` ${separatorRule} ` : ' ',
35
- )
36
- }
37
- }
38
-
39
- const optRepetitions = (upToN: number, prefixWithSep = false): string => {
40
- const content =
41
- separatorRule !== '' && prefixWithSep
42
- ? `${separatorRule} ${itemRule}`
43
- : itemRule
44
- if (upToN === 0) {
45
- return ''
46
- } else if (upToN === 1) {
47
- return `(${content})?`
48
- } else if (separatorRule !== '' && !prefixWithSep) {
49
- return `(${content} ${optRepetitions(upToN - 1, true)})?`
50
- } else {
51
- return (
52
- Array.from({ length: upToN }, () => `(${content}`)
53
- .join(' ')
54
- .trim() + Array.from({ length: upToN }, () => ')?').join('')
55
- )
56
- }
57
- }
58
-
59
- if (minItems > 0 && maxItems !== minItems) {
60
- result += ' '
61
- }
62
-
63
- if (maxItems !== undefined) {
64
- result += optRepetitions(maxItems - minItems, minItems > 0)
65
- } else {
66
- const itemOperator = `(${
67
- separatorRule !== '' ? `${separatorRule} ` : ''
68
- }${itemRule})`
69
-
70
- if (minItems === 0 && separatorRule !== '') {
71
- result = `(${itemRule} ${itemOperator}*)?`
72
- } else {
73
- result += `${itemOperator}*`
74
- }
75
- }
76
-
77
- return result
78
- }
79
-
80
- export class SchemaGrammarConverterBuiltinRule {
81
- content: string
82
-
83
- deps: string[]
84
-
85
- constructor(content: string, deps: string[]) {
86
- this.content = content
87
- this.deps = deps || []
88
- }
89
- }
90
-
91
- const BuiltinRule = SchemaGrammarConverterBuiltinRule
92
-
93
- const UP_TO_15_DIGITS = buildRepetition('[0-9]', 0, 15)
94
-
95
- const PRIMITIVE_RULES: { [key: string]: SchemaGrammarConverterBuiltinRule } = {
96
- boolean: new BuiltinRule('("true" | "false") space', []),
97
- 'decimal-part': new BuiltinRule(`[0-9] ${UP_TO_15_DIGITS}`, []),
98
- 'integral-part': new BuiltinRule(`[0-9] | [1-9] ${UP_TO_15_DIGITS}`, []),
99
- number: new BuiltinRule(
100
- '("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space',
101
- ['integral-part', 'decimal-part'],
102
- ),
103
- integer: new BuiltinRule('("-"? integral-part) space', ['integral-part']),
104
- value: new BuiltinRule('object | array | string | number | boolean | null', [
105
- 'object',
106
- 'array',
107
- 'string',
108
- 'number',
109
- 'boolean',
110
- 'null',
111
- ]),
112
- object: new BuiltinRule(
113
- '"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space',
114
- ['string', 'value'],
115
- ),
116
- array: new BuiltinRule('"[" space ( value ("," space value)* )? "]" space', [
117
- 'value',
118
- ]),
119
- uuid: new BuiltinRule(
120
- `"\\"" ${[8, 4, 4, 4, 12]
121
- .map((n) => [...new Array(n)].map((_) => '[0-9a-fA-F]').join(''))
122
- .join(' "-" ')} "\\"" space`,
123
- [],
124
- ),
125
- char: new BuiltinRule(
126
- `[^"\\\\] | "\\\\" (["\\\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])`,
127
- [],
128
- ),
129
- string: new BuiltinRule(`"\\"" char* "\\"" space`, ['char']),
130
- null: new BuiltinRule('"null" space', []),
131
- }
132
-
133
- // TODO: support "uri", "email" string formats
134
- const STRING_FORMAT_RULES: { [key: string]: SchemaGrammarConverterBuiltinRule } = {
135
- date: new BuiltinRule(
136
- '[0-9] [0-9] [0-9] [0-9] "-" ( "0" [1-9] | "1" [0-2] ) "-" ( "0" [1-9] | [1-2] [0-9] | "3" [0-1] )',
137
- [],
138
- ),
139
- time: new BuiltinRule(
140
- '([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9] [0-9] [0-9] )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )',
141
- [],
142
- ),
143
- 'date-time': new BuiltinRule('date "T" time', ['date', 'time']),
144
- 'date-string': new BuiltinRule('"\\"" date "\\"" space', ['date']),
145
- 'time-string': new BuiltinRule('"\\"" time "\\"" space', ['time']),
146
- 'date-time-string': new BuiltinRule('"\\"" date-time "\\"" space', [
147
- 'date-time',
148
- ]),
149
- }
150
-
151
- const RESERVED_NAMES = {
152
- root: true,
153
- ...PRIMITIVE_RULES,
154
- ...STRING_FORMAT_RULES,
155
- }
156
-
157
- const INVALID_RULE_CHARS_RE = /[^\dA-Za-z-]+/g
158
- const GRAMMAR_LITERAL_ESCAPE_RE = /[\n\r"]/g
159
- const GRAMMAR_LITERAL_ESCAPES: any = {
160
- '\r': '\\r',
161
- '\n': '\\n',
162
- '"': '\\"',
163
- '-': '\\-',
164
- ']': '\\]',
165
- }
166
-
167
- const NON_LITERAL_SET = new Set('|.()[]{}*+?')
168
- const ESCAPED_IN_REGEXPS_BUT_NOT_IN_LITERALS = new Set('[]()|{}*+?')
169
-
170
- const formatLiteral = (literal: string): string => {
171
- const escaped = literal.replace(
172
- GRAMMAR_LITERAL_ESCAPE_RE,
173
- (m) => GRAMMAR_LITERAL_ESCAPES[m] || '',
174
- )
175
- return `"${escaped}"`
176
- }
177
-
178
- const generateConstantRule = (value: any): string =>
179
- formatLiteral(JSON.stringify(value))
180
-
181
- export interface SchemaGrammarConverterPropOrder {
182
- [key: string]: number
183
- }
184
-
185
- // Helper function to group elements by a key function
186
- function* groupBy(iterable: Iterable<any>, keyFn: (x: any) => any) {
187
- let lastKey = null
188
- let group = []
189
- for (const element of iterable) {
190
- const key = keyFn(element)
191
- if (lastKey !== null && key !== lastKey) {
192
- yield [lastKey, group]
193
- group = []
194
- }
195
- group.push(element)
196
- lastKey = key
197
- }
198
- if (group.length > 0) {
199
- yield [lastKey, group]
200
- }
201
- }
202
-
203
- export class SchemaGrammarConverter {
204
- private _propOrder: SchemaGrammarConverterPropOrder
205
-
206
- private _allowFetch: boolean
207
-
208
- private _dotall: boolean
209
-
210
- private _rules: { [key: string]: string }
211
-
212
- private _refs: { [key: string]: any }
213
-
214
- private _refsBeingResolved: Set<string>
215
-
216
- constructor(options: {
217
- prop_order?: SchemaGrammarConverterPropOrder
218
- allow_fetch?: boolean
219
- dotall?: boolean
220
- }) {
221
- this._propOrder = options.prop_order || {}
222
- this._allowFetch = options.allow_fetch || false
223
- this._dotall = options.dotall || false
224
- this._rules = { space: SPACE_RULE }
225
- this._refs = {}
226
- this._refsBeingResolved = new Set()
227
- }
228
-
229
- _addRule(name: string, rule: string): string {
230
- const escName = name.replace(INVALID_RULE_CHARS_RE, '-')
231
- let key = escName
232
-
233
- if (escName in this._rules) {
234
- if (this._rules[escName] === rule) {
235
- return key
236
- }
237
-
238
- let i = 0
239
- while (
240
- `${escName}${i}` in this._rules &&
241
- this._rules[`${escName}${i}`] !== rule
242
- ) {
243
- i += 1
244
- }
245
- key = `${escName}${i}`
246
- }
247
-
248
- this._rules[key] = rule
249
- return key
250
- }
251
-
252
- async resolveRefs(schema: any, url: string): Promise<any> {
253
- const visit: any = async (n: any) => {
254
- if (Array.isArray(n)) {
255
- return Promise.all(n.map(visit))
256
- } else if (typeof n === 'object' && n !== null) {
257
- let ref = n.$ref
258
- let target
259
- if (ref !== undefined && !this._refs[ref]) {
260
- if (ref.startsWith('https://')) {
261
- if (!this._allowFetch) {
262
- throw new Error(
263
- 'Fetching remote schemas is not allowed (use --allow-fetch for force)',
264
- )
265
- }
266
-
267
- const fragSplit = ref.split('#')
268
- const baseUrl = fragSplit[0]
269
-
270
- target = this._refs[baseUrl]
271
- if (!target) {
272
- target = await this.resolveRefs(
273
- await fetch(ref).then((res) => res.json()),
274
- baseUrl,
275
- )
276
- this._refs[baseUrl] = target
277
- }
278
-
279
- if (
280
- fragSplit.length === 1 ||
281
- fragSplit[fragSplit.length - 1] === ''
282
- ) {
283
- return target
284
- }
285
- } else if (ref.startsWith('#/')) {
286
- target = schema
287
- ref = `${url}${ref}`
288
- n.$ref = ref
289
- } else {
290
- throw new Error(`Unsupported ref ${ref}`)
291
- }
292
-
293
- const selectors = ref.split('#')[1].split('/').slice(1)
294
- for (const sel of selectors) {
295
- if (!target || !(sel in target)) {
296
- throw new Error(
297
- `Error resolving ref ${ref}: ${sel} not in ${JSON.stringify(
298
- target,
299
- )}`,
300
- )
301
- }
302
- target = target[sel]
303
- }
304
-
305
- this._refs[ref] = target
306
- } else {
307
- await Promise.all(Object.values(n).map(visit))
308
- }
309
- }
310
-
311
- return n
312
- }
313
-
314
- return visit(schema)
315
- }
316
-
317
- _generateUnionRule(name: string, altSchemas: any[]): string {
318
- return altSchemas
319
- .map((altSchema, i) =>
320
- this.visit(
321
- altSchema,
322
- `${name ?? ''}${name ? '-' : 'alternative-'}${i}`,
323
- ),
324
- )
325
- .join(' | ')
326
- }
327
-
328
- _visitPattern(pattern: string, name: string): string {
329
- if (!pattern.startsWith('^') || !pattern.endsWith('$')) {
330
- throw new Error('Pattern must start with "^" and end with "$"')
331
- }
332
- pattern = pattern.slice(1, -1)
333
- const subRuleIds: { [key: string]: string } = {}
334
-
335
- let i = 0
336
- const { length } = pattern
337
-
338
- const getDot = () => {
339
- let rule
340
- if (this._dotall) {
341
- rule = '[\\U00000000-\\U0010FFFF]'
342
- } else {
343
- // Accept any character... except \n and \r line break chars (\x0A and \xOD)
344
- rule = '[^\\x0A\\x0D]'
345
- }
346
- return this._addRule('dot', rule)
347
- }
348
-
349
- const toRule = ([s, isLiteral]: [string, boolean]) =>
350
- isLiteral ? `"${s}"` : s
351
-
352
- const transform = () => {
353
- const start = i
354
- // For each component of this sequence, store its string representation and whether it's a literal.
355
- // We only need a flat structure here to apply repetition operators to the last item, and
356
- // to merge literals at the and (we're parsing grouped ( sequences ) recursively and don't treat '|' specially
357
- // (GBNF's syntax is luckily very close to regular expressions!)
358
- const seq: Array<[string, boolean]> = []
359
-
360
- const joinSeq = () => {
361
- const ret = []
362
- for (const [isLiteral, g] of groupBy(seq, (x) => x[1])) {
363
- if (isLiteral) {
364
- ret.push([[...g].map((x) => x[0]).join(''), true])
365
- } else {
366
- ret.push(...g)
367
- }
368
- }
369
- if (ret.length === 1) {
370
- return ret[0]
371
- }
372
- return [ret.map((x) => toRule(x)).join(' '), false]
373
- }
374
-
375
- while (i < length) {
376
- const c = pattern[i]
377
- if (c === '.') {
378
- seq.push([getDot(), false])
379
- i += 1
380
- } else if (c === '(') {
381
- i += 1
382
- if (i < length) {
383
- if (pattern[i] === '?') {
384
- throw new Error(
385
- `Unsupported pattern syntax "${pattern[i]}" at index ${i} of /${pattern}/`,
386
- )
387
- }
388
- }
389
- seq.push([`(${toRule(transform())})`, false])
390
- } else if (c === ')') {
391
- i += 1
392
- if (start <= 0 || pattern[start - 1] !== '(') {
393
- throw new Error(
394
- `Unbalanced parentheses; start = ${start}, i = ${i}, pattern = ${pattern}`,
395
- )
396
- }
397
- return joinSeq()
398
- } else if (c === '[') {
399
- let squareBrackets = c
400
- i += 1
401
- while (i < length && pattern[i] !== ']') {
402
- if (pattern[i] === '\\') {
403
- squareBrackets += pattern.slice(i, i + 2)
404
- i += 2
405
- } else {
406
- squareBrackets += pattern[i]
407
- i += 1
408
- }
409
- }
410
- if (i >= length) {
411
- throw new Error(
412
- `Unbalanced square brackets; start = ${start}, i = ${i}, pattern = ${pattern}`,
413
- )
414
- }
415
- squareBrackets += ']'
416
- i += 1
417
- seq.push([squareBrackets, false])
418
- } else if (c === '|') {
419
- seq.push(['|', false])
420
- i += 1
421
- } else if (c === '*' || c === '+' || c === '?') {
422
- seq[seq.length - 1] = [
423
- toRule(seq[seq.length - 1] || ['', false]) + c,
424
- false,
425
- ]
426
- i += 1
427
- } else if (c === '{') {
428
- let curlyBrackets = c
429
- i += 1
430
- while (i < length && pattern[i] !== '}') {
431
- curlyBrackets += pattern[i]
432
- i += 1
433
- }
434
- if (i >= length) {
435
- throw new Error(
436
- `Unbalanced curly brackets; start = ${start}, i = ${i}, pattern = ${pattern}`,
437
- )
438
- }
439
- curlyBrackets += '}'
440
- i += 1
441
- const nums = curlyBrackets
442
- .slice(1, -1)
443
- .split(',')
444
- .map((s) => s.trim())
445
- let minTimes: number
446
- let maxTimes: number | undefined
447
- if (nums.length === 1) {
448
- minTimes = parseInt(nums[0] as string, 10)
449
- maxTimes = minTimes
450
- } else {
451
- if (nums.length !== 2) {
452
- throw new Error(`Invalid quantifier ${curlyBrackets}`)
453
- }
454
- minTimes = nums[0] ? parseInt(nums[0], 10) : 0
455
- maxTimes = nums[1] ? parseInt(nums[1], 10) : Infinity
456
- }
457
-
458
- let [sub] = seq[seq.length - 1] || ['', false]
459
- const [, subIsLiteral] = seq[seq.length - 1] || ['', false]
460
-
461
- if (!subIsLiteral) {
462
- let id = subRuleIds[sub]
463
- if (id === undefined) {
464
- id = this._addRule(
465
- `${name}-${Object.keys(subRuleIds).length + 1}`,
466
- sub,
467
- )
468
- subRuleIds[sub] = id
469
- }
470
- sub = id
471
- }
472
-
473
- seq[seq.length - 1] = [
474
- buildRepetition(
475
- subIsLiteral ? `"${sub}"` : sub,
476
- minTimes,
477
- maxTimes,
478
- { itemRuleIsLiteral: subIsLiteral },
479
- ),
480
- false,
481
- ]
482
- } else {
483
- let literal = ''
484
- while (i < length) {
485
- if (pattern[i] === '\\' && i < length - 1) {
486
- const next = pattern[i + 1]
487
- if (ESCAPED_IN_REGEXPS_BUT_NOT_IN_LITERALS.has(next || '')) {
488
- i += 1
489
- literal += pattern[i]
490
- i += 1
491
- } else {
492
- literal += pattern.slice(i, i + 2)
493
- i += 2
494
- }
495
- } else if (pattern[i] === '"') {
496
- literal += '\\"'
497
- i += 1
498
- } else if (
499
- !NON_LITERAL_SET.has(pattern[i] || '') &&
500
- (i === length - 1 ||
501
- literal === '' ||
502
- pattern[i + 1] === '.' ||
503
- !NON_LITERAL_SET.has(pattern[i + 1] || ''))
504
- ) {
505
- literal += pattern[i]
506
- i += 1
507
- } else {
508
- break
509
- }
510
- }
511
- if (literal !== '') {
512
- seq.push([literal, true])
513
- }
514
- }
515
- }
516
-
517
- return joinSeq()
518
- }
519
-
520
- return this._addRule(name, `"\\"" ${toRule(transform())} "\\"" space`)
521
- }
522
-
523
- _resolveRef(ref: string): string {
524
- let refName = ref.split('/').pop() || ''
525
- if (!(refName in this._rules) && !this._refsBeingResolved.has(ref)) {
526
- this._refsBeingResolved.add(ref)
527
- const resolved = this._refs[ref]
528
- refName = this.visit(resolved, refName)
529
- this._refsBeingResolved.delete(ref)
530
- }
531
- return refName
532
- }
533
-
534
- visit(schema: any, name: string): string {
535
- const schemaType = schema.type
536
- const schemaFormat = schema.format
537
- const isRoot = name in RESERVED_NAMES ? `${name}-` : name == ''
538
- const ruleName = isRoot ? 'root' : name
539
-
540
- const ref = schema.$ref
541
- if (ref !== undefined) {
542
- return this._addRule(ruleName, this._resolveRef(ref))
543
- } else if (schema.oneOf || schema.anyOf) {
544
- return this._addRule(
545
- ruleName,
546
- this._generateUnionRule(name, schema.oneOf || schema.anyOf),
547
- )
548
- } else if (Array.isArray(schemaType)) {
549
- return this._addRule(
550
- ruleName,
551
- this._generateUnionRule(
552
- name,
553
- schemaType.map((t) => ({ type: t })),
554
- ),
555
- )
556
- } else if ('const' in schema) {
557
- return this._addRule(ruleName, generateConstantRule(schema.const))
558
- } else if ('enum' in schema) {
559
- const rule = schema.enum
560
- .map((v: any) => generateConstantRule(v))
561
- .join(' | ')
562
- return this._addRule(ruleName, rule)
563
- } else if (
564
- (schemaType === undefined || schemaType === 'object') &&
565
- ('properties' in schema ||
566
- ('additionalProperties' in schema &&
567
- schema.additionalProperties !== true))
568
- ) {
569
- const required: Set<string> = new Set(schema.required || [])
570
- const properties = Object.entries(schema.properties ?? {})
571
- return this._addRule(
572
- ruleName,
573
- this._buildObjectRule(
574
- properties,
575
- required,
576
- name,
577
- schema.additionalProperties,
578
- ),
579
- )
580
- } else if (
581
- (schemaType === undefined || schemaType === 'object') &&
582
- 'allOf' in schema
583
- ) {
584
- const required: Set<string> = new Set()
585
- const properties: Array<[string, any]> = []
586
- const addComponent = (compSchema: any, isRequired: boolean) => {
587
- if (compSchema.$ref !== undefined) {
588
- compSchema = this._refs[compSchema.$ref]
589
- }
590
-
591
- if ('properties' in compSchema) {
592
- for (const [propName, propSchema] of Object.entries(
593
- compSchema.properties,
594
- )) {
595
- properties.push([propName, propSchema])
596
- if (isRequired) {
597
- required.add(propName)
598
- }
599
- }
600
- }
601
- }
602
-
603
- for (const t of schema.allOf) {
604
- if ('anyOf' in t) {
605
- for (const tt of t.anyOf) {
606
- addComponent(tt, false)
607
- }
608
- } else {
609
- addComponent(t, true)
610
- }
611
- }
612
-
613
- return this._addRule(
614
- ruleName,
615
- this._buildObjectRule(
616
- properties,
617
- required,
618
- name,
619
- /* additionalProperties= */ false,
620
- ),
621
- )
622
- } else if (
623
- (schemaType === undefined || schemaType === 'array') &&
624
- ('items' in schema || 'prefixItems' in schema)
625
- ) {
626
- const items = schema.items ?? schema.prefixItems
627
- if (Array.isArray(items)) {
628
- const rules = items
629
- .map((item, i) =>
630
- this.visit(item, `${name ?? ''}${name ? '-' : ''}tuple-${i}`),
631
- )
632
- .join(' "," space ')
633
- return this._addRule(ruleName, `"[" space ${rules} "]" space`)
634
- } else {
635
- const itemRuleName = this.visit(
636
- items,
637
- `${name ?? ''}${name ? '-' : ''}item`,
638
- )
639
- const minItems = schema.minItems || 0
640
- const { maxItems } = schema
641
- return this._addRule(
642
- ruleName,
643
- `"[" space ${buildRepetition(itemRuleName, minItems, maxItems, {
644
- separatorRule: '"," space',
645
- })} "]" space`,
646
- )
647
- }
648
- } else if (
649
- (schemaType === undefined || schemaType === 'string') &&
650
- 'pattern' in schema
651
- ) {
652
- return this._visitPattern(schema.pattern, ruleName)
653
- } else if (
654
- (schemaType === undefined || schemaType === 'string') &&
655
- /^uuid[1-5]?$/.test(schema.format || '')
656
- ) {
657
- return this._addPrimitive(
658
- ruleName === 'root' ? 'root' : schemaFormat,
659
- PRIMITIVE_RULES['uuid'],
660
- )
661
- } else if (
662
- (schemaType === undefined || schemaType === 'string') &&
663
- `${schema.format}-string` in STRING_FORMAT_RULES
664
- ) {
665
- const primName = `${schema.format}-string`
666
- return this._addRule(
667
- ruleName,
668
- this._addPrimitive(primName, STRING_FORMAT_RULES[primName]),
669
- )
670
- } else if (
671
- schemaType === 'string' &&
672
- ('minLength' in schema || 'maxLength' in schema)
673
- ) {
674
- const charRuleName = this._addPrimitive('char', PRIMITIVE_RULES['char'])
675
- const minLen = schema.minLength || 0
676
- const maxLen = schema.maxLength
677
- return this._addRule(
678
- ruleName,
679
- `"\\"" ${buildRepetition(charRuleName, minLen, maxLen)} "\\"" space`,
680
- )
681
- } else if (schemaType === 'object' || Object.keys(schema).length === 0) {
682
- return this._addRule(
683
- ruleName,
684
- this._addPrimitive('object', PRIMITIVE_RULES['object']),
685
- )
686
- } else {
687
- if (!(schemaType in PRIMITIVE_RULES)) {
688
- throw new Error(`Unrecognized schema: ${JSON.stringify(schema)}`)
689
- }
690
- // TODO: support minimum, maximum, exclusiveMinimum, exclusiveMaximum at least for zero
691
- return this._addPrimitive(
692
- ruleName === 'root' ? 'root' : schemaType,
693
- PRIMITIVE_RULES[schemaType],
694
- )
695
- }
696
- }
697
-
698
- _addPrimitive(name: string, rule: SchemaGrammarConverterBuiltinRule | undefined) {
699
- if (!rule) {
700
- throw new Error(`Rule ${name} not known`)
701
- }
702
- const n = this._addRule(name, rule.content)
703
- for (const dep of rule.deps) {
704
- const depRule = PRIMITIVE_RULES[dep] || STRING_FORMAT_RULES[dep]
705
- if (!depRule) {
706
- throw new Error(`Rule ${dep} not known`)
707
- }
708
- if (!(dep in this._rules)) {
709
- this._addPrimitive(dep, depRule)
710
- }
711
- }
712
- return n
713
- }
714
-
715
- _buildObjectRule(
716
- properties: any[],
717
- required: Set<string>,
718
- name: string,
719
- additionalProperties: any,
720
- ) {
721
- const propOrder = this._propOrder
722
- // sort by position in prop_order (if specified) then by original order
723
- const sortedProps = properties
724
- .map(([k]) => k)
725
- .sort((a, b) => {
726
- const orderA = propOrder[a] || Infinity
727
- const orderB = propOrder[b] || Infinity
728
- return (
729
- orderA - orderB ||
730
- properties.findIndex(([k]) => k === a) -
731
- properties.findIndex(([k]) => k === b)
732
- )
733
- })
734
-
735
- const propKvRuleNames: { [key: string]: string } = {}
736
- for (const [propName, propSchema] of properties) {
737
- const propRuleName = this.visit(
738
- propSchema,
739
- `${name ?? ''}${name ? '-' : ''}${propName}`,
740
- )
741
- propKvRuleNames[propName] = this._addRule(
742
- `${name ?? ''}${name ? '-' : ''}${propName}-kv`,
743
- `${formatLiteral(
744
- JSON.stringify(propName),
745
- )} space ":" space ${propRuleName}`,
746
- )
747
- }
748
- const requiredProps = sortedProps.filter((k) => required.has(k))
749
- const optionalProps = sortedProps.filter((k) => !required.has(k))
750
-
751
- if (
752
- typeof additionalProperties === 'object' ||
753
- additionalProperties === true
754
- ) {
755
- const subName = `${name ?? ''}${name ? '-' : ''}additional`
756
- const valueRule = this.visit(
757
- additionalProperties === true ? {} : additionalProperties,
758
- `${subName}-value`,
759
- )
760
- propKvRuleNames['*'] = this._addRule(
761
- `${subName}-kv`,
762
- `${this._addPrimitive(
763
- 'string',
764
- PRIMITIVE_RULES['string'],
765
- )} ":" space ${valueRule}`,
766
- )
767
- optionalProps.push('*')
768
- }
769
-
770
- let rule = '"{" space '
771
- rule += requiredProps.map((k) => propKvRuleNames[k]).join(' "," space ')
772
-
773
- if (optionalProps.length > 0) {
774
- rule += ' ('
775
- if (requiredProps.length > 0) {
776
- rule += ' "," space ( '
777
- }
778
-
779
- const getRecursiveRefs = (ks: any[], firstIsOptional: boolean) => {
780
- const [k, ...rest] = ks
781
- const kvRuleName = propKvRuleNames[k]
782
- let res
783
- if (k === '*') {
784
- res = this._addRule(
785
- `${name ?? ''}${name ? '-' : ''}additional-kvs`,
786
- `${kvRuleName} ( "," space ${kvRuleName} )*`,
787
- )
788
- } else if (firstIsOptional) {
789
- res = `( "," space ${kvRuleName} )?`
790
- } else {
791
- res = kvRuleName
792
- }
793
- if (rest.length > 0) {
794
- res += ` ${this._addRule(
795
- `${name ?? ''}${name ? '-' : ''}${k}-rest`,
796
- getRecursiveRefs(rest, true) || '',
797
- )}`
798
- }
799
- return res
800
- }
801
-
802
- rule += optionalProps
803
- .map((_: any, i: number) =>
804
- getRecursiveRefs(optionalProps.slice(i), false),
805
- )
806
- .join(' | ')
807
- if (requiredProps.length > 0) {
808
- rule += ' )'
809
- }
810
- rule += ' )?'
811
- }
812
-
813
- rule += ' "}" space'
814
-
815
- return rule
816
- }
817
-
818
- formatGrammar() {
819
- let grammar = ''
820
- for (const [name, rule] of Object.entries(this._rules).sort(([a], [b]) =>
821
- a.localeCompare(b),
822
- )) {
823
- grammar += `${name} ::= ${rule}\n`
824
- }
825
- return grammar
826
- }
827
- }
828
-
829
- export const convertJsonSchemaToGrammar = ({
830
- schema,
831
- propOrder,
832
- dotall,
833
- allowFetch,
834
- }: {
835
- schema: any
836
- propOrder?: SchemaGrammarConverterPropOrder
837
- dotall?: boolean
838
- allowFetch?: boolean
839
- }): string | Promise<string> => {
840
- const converter = new SchemaGrammarConverter({
841
- prop_order: propOrder,
842
- dotall,
843
- allow_fetch: allowFetch,
844
- })
845
-
846
- if (allowFetch) {
847
- return converter.resolveRefs(schema, '').then(() => {
848
- converter.visit(schema, '')
849
- return converter.formatGrammar()
850
- })
851
- }
852
- converter.visit(schema, '')
853
- return converter.formatGrammar()
854
- }
1
+ /* eslint-disable no-restricted-syntax */
2
+ /* eslint-disable no-underscore-dangle */
3
+
4
+ // NOTE: Deprecated, please use tools or response_format with json_schema instead
5
+
6
+ const SPACE_RULE = '" "?'
7
+
8
+ function buildRepetition(
9
+ itemRule: string,
10
+ minItems: number,
11
+ maxItems: number | undefined,
12
+ opts: {
13
+ separatorRule?: string
14
+ itemRuleIsLiteral?: boolean
15
+ } = {},
16
+ ) {
17
+ const separatorRule = opts.separatorRule ?? ''
18
+ const itemRuleIsLiteral = opts.itemRuleIsLiteral ?? false
19
+
20
+ if (separatorRule === '') {
21
+ if (minItems === 0 && maxItems === 1) {
22
+ return `${itemRule}?`
23
+ } else if (minItems === 1 && maxItems === undefined) {
24
+ return `${itemRule}+`
25
+ }
26
+ }
27
+
28
+ let result = ''
29
+ if (minItems > 0) {
30
+ if (itemRuleIsLiteral && separatorRule === '') {
31
+ result = `"${itemRule.slice(1, -1).repeat(minItems)}"`
32
+ } else {
33
+ result = Array.from({ length: minItems }, () => itemRule).join(
34
+ separatorRule !== '' ? ` ${separatorRule} ` : ' ',
35
+ )
36
+ }
37
+ }
38
+
39
+ const optRepetitions = (upToN: number, prefixWithSep = false): string => {
40
+ const content =
41
+ separatorRule !== '' && prefixWithSep
42
+ ? `${separatorRule} ${itemRule}`
43
+ : itemRule
44
+ if (upToN === 0) {
45
+ return ''
46
+ } else if (upToN === 1) {
47
+ return `(${content})?`
48
+ } else if (separatorRule !== '' && !prefixWithSep) {
49
+ return `(${content} ${optRepetitions(upToN - 1, true)})?`
50
+ } else {
51
+ return (
52
+ Array.from({ length: upToN }, () => `(${content}`)
53
+ .join(' ')
54
+ .trim() + Array.from({ length: upToN }, () => ')?').join('')
55
+ )
56
+ }
57
+ }
58
+
59
+ if (minItems > 0 && maxItems !== minItems) {
60
+ result += ' '
61
+ }
62
+
63
+ if (maxItems !== undefined) {
64
+ result += optRepetitions(maxItems - minItems, minItems > 0)
65
+ } else {
66
+ const itemOperator = `(${
67
+ separatorRule !== '' ? `${separatorRule} ` : ''
68
+ }${itemRule})`
69
+
70
+ if (minItems === 0 && separatorRule !== '') {
71
+ result = `(${itemRule} ${itemOperator}*)?`
72
+ } else {
73
+ result += `${itemOperator}*`
74
+ }
75
+ }
76
+
77
+ return result
78
+ }
79
+
80
+ export class SchemaGrammarConverterBuiltinRule {
81
+ content: string
82
+
83
+ deps: string[]
84
+
85
+ constructor(content: string, deps: string[]) {
86
+ this.content = content
87
+ this.deps = deps || []
88
+ }
89
+ }
90
+
91
+ const BuiltinRule = SchemaGrammarConverterBuiltinRule
92
+
93
+ const UP_TO_15_DIGITS = buildRepetition('[0-9]', 0, 15)
94
+
95
+ const PRIMITIVE_RULES: { [key: string]: SchemaGrammarConverterBuiltinRule } = {
96
+ boolean: new BuiltinRule('("true" | "false") space', []),
97
+ 'decimal-part': new BuiltinRule(`[0-9] ${UP_TO_15_DIGITS}`, []),
98
+ 'integral-part': new BuiltinRule(`[0-9] | [1-9] ${UP_TO_15_DIGITS}`, []),
99
+ number: new BuiltinRule(
100
+ '("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space',
101
+ ['integral-part', 'decimal-part'],
102
+ ),
103
+ integer: new BuiltinRule('("-"? integral-part) space', ['integral-part']),
104
+ value: new BuiltinRule('object | array | string | number | boolean | null', [
105
+ 'object',
106
+ 'array',
107
+ 'string',
108
+ 'number',
109
+ 'boolean',
110
+ 'null',
111
+ ]),
112
+ object: new BuiltinRule(
113
+ '"{" space ( string ":" space value ("," space string ":" space value)* )? "}" space',
114
+ ['string', 'value'],
115
+ ),
116
+ array: new BuiltinRule('"[" space ( value ("," space value)* )? "]" space', [
117
+ 'value',
118
+ ]),
119
+ uuid: new BuiltinRule(
120
+ `"\\"" ${[8, 4, 4, 4, 12]
121
+ .map((n) => [...new Array(n)].map((_) => '[0-9a-fA-F]').join(''))
122
+ .join(' "-" ')} "\\"" space`,
123
+ [],
124
+ ),
125
+ char: new BuiltinRule(
126
+ `[^"\\\\] | "\\\\" (["\\\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])`,
127
+ [],
128
+ ),
129
+ string: new BuiltinRule(`"\\"" char* "\\"" space`, ['char']),
130
+ null: new BuiltinRule('"null" space', []),
131
+ }
132
+
133
+ // TODO: support "uri", "email" string formats
134
+ const STRING_FORMAT_RULES: { [key: string]: SchemaGrammarConverterBuiltinRule } = {
135
+ date: new BuiltinRule(
136
+ '[0-9] [0-9] [0-9] [0-9] "-" ( "0" [1-9] | "1" [0-2] ) "-" ( "0" [1-9] | [1-2] [0-9] | "3" [0-1] )',
137
+ [],
138
+ ),
139
+ time: new BuiltinRule(
140
+ '([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9] [0-9] [0-9] )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )',
141
+ [],
142
+ ),
143
+ 'date-time': new BuiltinRule('date "T" time', ['date', 'time']),
144
+ 'date-string': new BuiltinRule('"\\"" date "\\"" space', ['date']),
145
+ 'time-string': new BuiltinRule('"\\"" time "\\"" space', ['time']),
146
+ 'date-time-string': new BuiltinRule('"\\"" date-time "\\"" space', [
147
+ 'date-time',
148
+ ]),
149
+ }
150
+
151
+ const RESERVED_NAMES = {
152
+ root: true,
153
+ ...PRIMITIVE_RULES,
154
+ ...STRING_FORMAT_RULES,
155
+ }
156
+
157
+ const INVALID_RULE_CHARS_RE = /[^\dA-Za-z-]+/g
158
+ const GRAMMAR_LITERAL_ESCAPE_RE = /[\n\r"]/g
159
+ const GRAMMAR_LITERAL_ESCAPES: any = {
160
+ '\r': '\\r',
161
+ '\n': '\\n',
162
+ '"': '\\"',
163
+ '-': '\\-',
164
+ ']': '\\]',
165
+ }
166
+
167
+ const NON_LITERAL_SET = new Set('|.()[]{}*+?')
168
+ const ESCAPED_IN_REGEXPS_BUT_NOT_IN_LITERALS = new Set('[]()|{}*+?')
169
+
170
+ const formatLiteral = (literal: string): string => {
171
+ const escaped = literal.replace(
172
+ GRAMMAR_LITERAL_ESCAPE_RE,
173
+ (m) => GRAMMAR_LITERAL_ESCAPES[m] || '',
174
+ )
175
+ return `"${escaped}"`
176
+ }
177
+
178
+ const generateConstantRule = (value: any): string =>
179
+ formatLiteral(JSON.stringify(value))
180
+
181
+ export interface SchemaGrammarConverterPropOrder {
182
+ [key: string]: number
183
+ }
184
+
185
+ // Helper function to group elements by a key function
186
+ function* groupBy(iterable: Iterable<any>, keyFn: (x: any) => any) {
187
+ let lastKey = null
188
+ let group = []
189
+ for (const element of iterable) {
190
+ const key = keyFn(element)
191
+ if (lastKey !== null && key !== lastKey) {
192
+ yield [lastKey, group]
193
+ group = []
194
+ }
195
+ group.push(element)
196
+ lastKey = key
197
+ }
198
+ if (group.length > 0) {
199
+ yield [lastKey, group]
200
+ }
201
+ }
202
+
203
+ export class SchemaGrammarConverter {
204
+ private _propOrder: SchemaGrammarConverterPropOrder
205
+
206
+ private _allowFetch: boolean
207
+
208
+ private _dotall: boolean
209
+
210
+ private _rules: { [key: string]: string }
211
+
212
+ private _refs: { [key: string]: any }
213
+
214
+ private _refsBeingResolved: Set<string>
215
+
216
+ constructor(options: {
217
+ prop_order?: SchemaGrammarConverterPropOrder
218
+ allow_fetch?: boolean
219
+ dotall?: boolean
220
+ }) {
221
+ this._propOrder = options.prop_order || {}
222
+ this._allowFetch = options.allow_fetch || false
223
+ this._dotall = options.dotall || false
224
+ this._rules = { space: SPACE_RULE }
225
+ this._refs = {}
226
+ this._refsBeingResolved = new Set()
227
+ }
228
+
229
+ _addRule(name: string, rule: string): string {
230
+ const escName = name.replace(INVALID_RULE_CHARS_RE, '-')
231
+ let key = escName
232
+
233
+ if (escName in this._rules) {
234
+ if (this._rules[escName] === rule) {
235
+ return key
236
+ }
237
+
238
+ let i = 0
239
+ while (
240
+ `${escName}${i}` in this._rules &&
241
+ this._rules[`${escName}${i}`] !== rule
242
+ ) {
243
+ i += 1
244
+ }
245
+ key = `${escName}${i}`
246
+ }
247
+
248
+ this._rules[key] = rule
249
+ return key
250
+ }
251
+
252
+ async resolveRefs(schema: any, url: string): Promise<any> {
253
+ const visit: any = async (n: any) => {
254
+ if (Array.isArray(n)) {
255
+ return Promise.all(n.map(visit))
256
+ } else if (typeof n === 'object' && n !== null) {
257
+ let ref = n.$ref
258
+ let target
259
+ if (ref !== undefined && !this._refs[ref]) {
260
+ if (ref.startsWith('https://')) {
261
+ if (!this._allowFetch) {
262
+ throw new Error(
263
+ 'Fetching remote schemas is not allowed (use --allow-fetch for force)',
264
+ )
265
+ }
266
+
267
+ const fragSplit = ref.split('#')
268
+ const baseUrl = fragSplit[0]
269
+
270
+ target = this._refs[baseUrl]
271
+ if (!target) {
272
+ target = await this.resolveRefs(
273
+ await fetch(ref).then((res) => res.json()),
274
+ baseUrl,
275
+ )
276
+ this._refs[baseUrl] = target
277
+ }
278
+
279
+ if (
280
+ fragSplit.length === 1 ||
281
+ fragSplit[fragSplit.length - 1] === ''
282
+ ) {
283
+ return target
284
+ }
285
+ } else if (ref.startsWith('#/')) {
286
+ target = schema
287
+ ref = `${url}${ref}`
288
+ n.$ref = ref
289
+ } else {
290
+ throw new Error(`Unsupported ref ${ref}`)
291
+ }
292
+
293
+ const selectors = ref.split('#')[1].split('/').slice(1)
294
+ for (const sel of selectors) {
295
+ if (!target || !(sel in target)) {
296
+ throw new Error(
297
+ `Error resolving ref ${ref}: ${sel} not in ${JSON.stringify(
298
+ target,
299
+ )}`,
300
+ )
301
+ }
302
+ target = target[sel]
303
+ }
304
+
305
+ this._refs[ref] = target
306
+ } else {
307
+ await Promise.all(Object.values(n).map(visit))
308
+ }
309
+ }
310
+
311
+ return n
312
+ }
313
+
314
+ return visit(schema)
315
+ }
316
+
317
+ _generateUnionRule(name: string, altSchemas: any[]): string {
318
+ return altSchemas
319
+ .map((altSchema, i) =>
320
+ this.visit(
321
+ altSchema,
322
+ `${name ?? ''}${name ? '-' : 'alternative-'}${i}`,
323
+ ),
324
+ )
325
+ .join(' | ')
326
+ }
327
+
328
+ _visitPattern(pattern: string, name: string): string {
329
+ if (!pattern.startsWith('^') || !pattern.endsWith('$')) {
330
+ throw new Error('Pattern must start with "^" and end with "$"')
331
+ }
332
+ pattern = pattern.slice(1, -1)
333
+ const subRuleIds: { [key: string]: string } = {}
334
+
335
+ let i = 0
336
+ const { length } = pattern
337
+
338
+ const getDot = () => {
339
+ let rule
340
+ if (this._dotall) {
341
+ rule = '[\\U00000000-\\U0010FFFF]'
342
+ } else {
343
+ // Accept any character... except \n and \r line break chars (\x0A and \xOD)
344
+ rule = '[^\\x0A\\x0D]'
345
+ }
346
+ return this._addRule('dot', rule)
347
+ }
348
+
349
+ const toRule = ([s, isLiteral]: [string, boolean]) =>
350
+ isLiteral ? `"${s}"` : s
351
+
352
+ const transform = () => {
353
+ const start = i
354
+ // For each component of this sequence, store its string representation and whether it's a literal.
355
+ // We only need a flat structure here to apply repetition operators to the last item, and
356
+ // to merge literals at the and (we're parsing grouped ( sequences ) recursively and don't treat '|' specially
357
+ // (GBNF's syntax is luckily very close to regular expressions!)
358
+ const seq: Array<[string, boolean]> = []
359
+
360
+ const joinSeq = () => {
361
+ const ret = []
362
+ for (const [isLiteral, g] of groupBy(seq, (x) => x[1])) {
363
+ if (isLiteral) {
364
+ ret.push([[...g].map((x) => x[0]).join(''), true])
365
+ } else {
366
+ ret.push(...g)
367
+ }
368
+ }
369
+ if (ret.length === 1) {
370
+ return ret[0]
371
+ }
372
+ return [ret.map((x) => toRule(x)).join(' '), false]
373
+ }
374
+
375
+ while (i < length) {
376
+ const c = pattern[i]
377
+ if (c === '.') {
378
+ seq.push([getDot(), false])
379
+ i += 1
380
+ } else if (c === '(') {
381
+ i += 1
382
+ if (i < length) {
383
+ if (pattern[i] === '?') {
384
+ throw new Error(
385
+ `Unsupported pattern syntax "${pattern[i]}" at index ${i} of /${pattern}/`,
386
+ )
387
+ }
388
+ }
389
+ seq.push([`(${toRule(transform())})`, false])
390
+ } else if (c === ')') {
391
+ i += 1
392
+ if (start <= 0 || pattern[start - 1] !== '(') {
393
+ throw new Error(
394
+ `Unbalanced parentheses; start = ${start}, i = ${i}, pattern = ${pattern}`,
395
+ )
396
+ }
397
+ return joinSeq()
398
+ } else if (c === '[') {
399
+ let squareBrackets = c
400
+ i += 1
401
+ while (i < length && pattern[i] !== ']') {
402
+ if (pattern[i] === '\\') {
403
+ squareBrackets += pattern.slice(i, i + 2)
404
+ i += 2
405
+ } else {
406
+ squareBrackets += pattern[i]
407
+ i += 1
408
+ }
409
+ }
410
+ if (i >= length) {
411
+ throw new Error(
412
+ `Unbalanced square brackets; start = ${start}, i = ${i}, pattern = ${pattern}`,
413
+ )
414
+ }
415
+ squareBrackets += ']'
416
+ i += 1
417
+ seq.push([squareBrackets, false])
418
+ } else if (c === '|') {
419
+ seq.push(['|', false])
420
+ i += 1
421
+ } else if (c === '*' || c === '+' || c === '?') {
422
+ seq[seq.length - 1] = [
423
+ toRule(seq[seq.length - 1] || ['', false]) + c,
424
+ false,
425
+ ]
426
+ i += 1
427
+ } else if (c === '{') {
428
+ let curlyBrackets = c
429
+ i += 1
430
+ while (i < length && pattern[i] !== '}') {
431
+ curlyBrackets += pattern[i]
432
+ i += 1
433
+ }
434
+ if (i >= length) {
435
+ throw new Error(
436
+ `Unbalanced curly brackets; start = ${start}, i = ${i}, pattern = ${pattern}`,
437
+ )
438
+ }
439
+ curlyBrackets += '}'
440
+ i += 1
441
+ const nums = curlyBrackets
442
+ .slice(1, -1)
443
+ .split(',')
444
+ .map((s) => s.trim())
445
+ let minTimes: number
446
+ let maxTimes: number | undefined
447
+ if (nums.length === 1) {
448
+ minTimes = parseInt(nums[0] as string, 10)
449
+ maxTimes = minTimes
450
+ } else {
451
+ if (nums.length !== 2) {
452
+ throw new Error(`Invalid quantifier ${curlyBrackets}`)
453
+ }
454
+ minTimes = nums[0] ? parseInt(nums[0], 10) : 0
455
+ maxTimes = nums[1] ? parseInt(nums[1], 10) : Infinity
456
+ }
457
+
458
+ let [sub] = seq[seq.length - 1] || ['', false]
459
+ const [, subIsLiteral] = seq[seq.length - 1] || ['', false]
460
+
461
+ if (!subIsLiteral) {
462
+ let id = subRuleIds[sub]
463
+ if (id === undefined) {
464
+ id = this._addRule(
465
+ `${name}-${Object.keys(subRuleIds).length + 1}`,
466
+ sub,
467
+ )
468
+ subRuleIds[sub] = id
469
+ }
470
+ sub = id
471
+ }
472
+
473
+ seq[seq.length - 1] = [
474
+ buildRepetition(
475
+ subIsLiteral ? `"${sub}"` : sub,
476
+ minTimes,
477
+ maxTimes,
478
+ { itemRuleIsLiteral: subIsLiteral },
479
+ ),
480
+ false,
481
+ ]
482
+ } else {
483
+ let literal = ''
484
+ while (i < length) {
485
+ if (pattern[i] === '\\' && i < length - 1) {
486
+ const next = pattern[i + 1]
487
+ if (ESCAPED_IN_REGEXPS_BUT_NOT_IN_LITERALS.has(next || '')) {
488
+ i += 1
489
+ literal += pattern[i]
490
+ i += 1
491
+ } else {
492
+ literal += pattern.slice(i, i + 2)
493
+ i += 2
494
+ }
495
+ } else if (pattern[i] === '"') {
496
+ literal += '\\"'
497
+ i += 1
498
+ } else if (
499
+ !NON_LITERAL_SET.has(pattern[i] || '') &&
500
+ (i === length - 1 ||
501
+ literal === '' ||
502
+ pattern[i + 1] === '.' ||
503
+ !NON_LITERAL_SET.has(pattern[i + 1] || ''))
504
+ ) {
505
+ literal += pattern[i]
506
+ i += 1
507
+ } else {
508
+ break
509
+ }
510
+ }
511
+ if (literal !== '') {
512
+ seq.push([literal, true])
513
+ }
514
+ }
515
+ }
516
+
517
+ return joinSeq()
518
+ }
519
+
520
+ return this._addRule(name, `"\\"" ${toRule(transform())} "\\"" space`)
521
+ }
522
+
523
+ _resolveRef(ref: string): string {
524
+ let refName = ref.split('/').pop() || ''
525
+ if (!(refName in this._rules) && !this._refsBeingResolved.has(ref)) {
526
+ this._refsBeingResolved.add(ref)
527
+ const resolved = this._refs[ref]
528
+ refName = this.visit(resolved, refName)
529
+ this._refsBeingResolved.delete(ref)
530
+ }
531
+ return refName
532
+ }
533
+
534
+ visit(schema: any, name: string): string {
535
+ const schemaType = schema.type
536
+ const schemaFormat = schema.format
537
+ const isRoot = name in RESERVED_NAMES ? `${name}-` : name == ''
538
+ const ruleName = isRoot ? 'root' : name
539
+
540
+ const ref = schema.$ref
541
+ if (ref !== undefined) {
542
+ return this._addRule(ruleName, this._resolveRef(ref))
543
+ } else if (schema.oneOf || schema.anyOf) {
544
+ return this._addRule(
545
+ ruleName,
546
+ this._generateUnionRule(name, schema.oneOf || schema.anyOf),
547
+ )
548
+ } else if (Array.isArray(schemaType)) {
549
+ return this._addRule(
550
+ ruleName,
551
+ this._generateUnionRule(
552
+ name,
553
+ schemaType.map((t) => ({ type: t })),
554
+ ),
555
+ )
556
+ } else if ('const' in schema) {
557
+ return this._addRule(ruleName, generateConstantRule(schema.const))
558
+ } else if ('enum' in schema) {
559
+ const rule = schema.enum
560
+ .map((v: any) => generateConstantRule(v))
561
+ .join(' | ')
562
+ return this._addRule(ruleName, rule)
563
+ } else if (
564
+ (schemaType === undefined || schemaType === 'object') &&
565
+ ('properties' in schema ||
566
+ ('additionalProperties' in schema &&
567
+ schema.additionalProperties !== true))
568
+ ) {
569
+ const required: Set<string> = new Set(schema.required || [])
570
+ const properties = Object.entries(schema.properties ?? {})
571
+ return this._addRule(
572
+ ruleName,
573
+ this._buildObjectRule(
574
+ properties,
575
+ required,
576
+ name,
577
+ schema.additionalProperties,
578
+ ),
579
+ )
580
+ } else if (
581
+ (schemaType === undefined || schemaType === 'object') &&
582
+ 'allOf' in schema
583
+ ) {
584
+ const required: Set<string> = new Set()
585
+ const properties: Array<[string, any]> = []
586
+ const addComponent = (compSchema: any, isRequired: boolean) => {
587
+ if (compSchema.$ref !== undefined) {
588
+ compSchema = this._refs[compSchema.$ref]
589
+ }
590
+
591
+ if ('properties' in compSchema) {
592
+ for (const [propName, propSchema] of Object.entries(
593
+ compSchema.properties,
594
+ )) {
595
+ properties.push([propName, propSchema])
596
+ if (isRequired) {
597
+ required.add(propName)
598
+ }
599
+ }
600
+ }
601
+ }
602
+
603
+ for (const t of schema.allOf) {
604
+ if ('anyOf' in t) {
605
+ for (const tt of t.anyOf) {
606
+ addComponent(tt, false)
607
+ }
608
+ } else {
609
+ addComponent(t, true)
610
+ }
611
+ }
612
+
613
+ return this._addRule(
614
+ ruleName,
615
+ this._buildObjectRule(
616
+ properties,
617
+ required,
618
+ name,
619
+ /* additionalProperties= */ false,
620
+ ),
621
+ )
622
+ } else if (
623
+ (schemaType === undefined || schemaType === 'array') &&
624
+ ('items' in schema || 'prefixItems' in schema)
625
+ ) {
626
+ const items = schema.items ?? schema.prefixItems
627
+ if (Array.isArray(items)) {
628
+ const rules = items
629
+ .map((item, i) =>
630
+ this.visit(item, `${name ?? ''}${name ? '-' : ''}tuple-${i}`),
631
+ )
632
+ .join(' "," space ')
633
+ return this._addRule(ruleName, `"[" space ${rules} "]" space`)
634
+ } else {
635
+ const itemRuleName = this.visit(
636
+ items,
637
+ `${name ?? ''}${name ? '-' : ''}item`,
638
+ )
639
+ const minItems = schema.minItems || 0
640
+ const { maxItems } = schema
641
+ return this._addRule(
642
+ ruleName,
643
+ `"[" space ${buildRepetition(itemRuleName, minItems, maxItems, {
644
+ separatorRule: '"," space',
645
+ })} "]" space`,
646
+ )
647
+ }
648
+ } else if (
649
+ (schemaType === undefined || schemaType === 'string') &&
650
+ 'pattern' in schema
651
+ ) {
652
+ return this._visitPattern(schema.pattern, ruleName)
653
+ } else if (
654
+ (schemaType === undefined || schemaType === 'string') &&
655
+ /^uuid[1-5]?$/.test(schema.format || '')
656
+ ) {
657
+ return this._addPrimitive(
658
+ ruleName === 'root' ? 'root' : schemaFormat,
659
+ PRIMITIVE_RULES['uuid'],
660
+ )
661
+ } else if (
662
+ (schemaType === undefined || schemaType === 'string') &&
663
+ `${schema.format}-string` in STRING_FORMAT_RULES
664
+ ) {
665
+ const primName = `${schema.format}-string`
666
+ return this._addRule(
667
+ ruleName,
668
+ this._addPrimitive(primName, STRING_FORMAT_RULES[primName]),
669
+ )
670
+ } else if (
671
+ schemaType === 'string' &&
672
+ ('minLength' in schema || 'maxLength' in schema)
673
+ ) {
674
+ const charRuleName = this._addPrimitive('char', PRIMITIVE_RULES['char'])
675
+ const minLen = schema.minLength || 0
676
+ const maxLen = schema.maxLength
677
+ return this._addRule(
678
+ ruleName,
679
+ `"\\"" ${buildRepetition(charRuleName, minLen, maxLen)} "\\"" space`,
680
+ )
681
+ } else if (schemaType === 'object' || Object.keys(schema).length === 0) {
682
+ return this._addRule(
683
+ ruleName,
684
+ this._addPrimitive('object', PRIMITIVE_RULES['object']),
685
+ )
686
+ } else {
687
+ if (!(schemaType in PRIMITIVE_RULES)) {
688
+ throw new Error(`Unrecognized schema: ${JSON.stringify(schema)}`)
689
+ }
690
+ // TODO: support minimum, maximum, exclusiveMinimum, exclusiveMaximum at least for zero
691
+ return this._addPrimitive(
692
+ ruleName === 'root' ? 'root' : schemaType,
693
+ PRIMITIVE_RULES[schemaType],
694
+ )
695
+ }
696
+ }
697
+
698
+ _addPrimitive(name: string, rule: SchemaGrammarConverterBuiltinRule | undefined) {
699
+ if (!rule) {
700
+ throw new Error(`Rule ${name} not known`)
701
+ }
702
+ const n = this._addRule(name, rule.content)
703
+ for (const dep of rule.deps) {
704
+ const depRule = PRIMITIVE_RULES[dep] || STRING_FORMAT_RULES[dep]
705
+ if (!depRule) {
706
+ throw new Error(`Rule ${dep} not known`)
707
+ }
708
+ if (!(dep in this._rules)) {
709
+ this._addPrimitive(dep, depRule)
710
+ }
711
+ }
712
+ return n
713
+ }
714
+
715
+ _buildObjectRule(
716
+ properties: any[],
717
+ required: Set<string>,
718
+ name: string,
719
+ additionalProperties: any,
720
+ ) {
721
+ const propOrder = this._propOrder
722
+ // sort by position in prop_order (if specified) then by original order
723
+ const sortedProps = properties
724
+ .map(([k]) => k)
725
+ .sort((a, b) => {
726
+ const orderA = propOrder[a] || Infinity
727
+ const orderB = propOrder[b] || Infinity
728
+ return (
729
+ orderA - orderB ||
730
+ properties.findIndex(([k]) => k === a) -
731
+ properties.findIndex(([k]) => k === b)
732
+ )
733
+ })
734
+
735
+ const propKvRuleNames: { [key: string]: string } = {}
736
+ for (const [propName, propSchema] of properties) {
737
+ const propRuleName = this.visit(
738
+ propSchema,
739
+ `${name ?? ''}${name ? '-' : ''}${propName}`,
740
+ )
741
+ propKvRuleNames[propName] = this._addRule(
742
+ `${name ?? ''}${name ? '-' : ''}${propName}-kv`,
743
+ `${formatLiteral(
744
+ JSON.stringify(propName),
745
+ )} space ":" space ${propRuleName}`,
746
+ )
747
+ }
748
+ const requiredProps = sortedProps.filter((k) => required.has(k))
749
+ const optionalProps = sortedProps.filter((k) => !required.has(k))
750
+
751
+ if (
752
+ typeof additionalProperties === 'object' ||
753
+ additionalProperties === true
754
+ ) {
755
+ const subName = `${name ?? ''}${name ? '-' : ''}additional`
756
+ const valueRule = this.visit(
757
+ additionalProperties === true ? {} : additionalProperties,
758
+ `${subName}-value`,
759
+ )
760
+ propKvRuleNames['*'] = this._addRule(
761
+ `${subName}-kv`,
762
+ `${this._addPrimitive(
763
+ 'string',
764
+ PRIMITIVE_RULES['string'],
765
+ )} ":" space ${valueRule}`,
766
+ )
767
+ optionalProps.push('*')
768
+ }
769
+
770
+ let rule = '"{" space '
771
+ rule += requiredProps.map((k) => propKvRuleNames[k]).join(' "," space ')
772
+
773
+ if (optionalProps.length > 0) {
774
+ rule += ' ('
775
+ if (requiredProps.length > 0) {
776
+ rule += ' "," space ( '
777
+ }
778
+
779
+ const getRecursiveRefs = (ks: any[], firstIsOptional: boolean) => {
780
+ const [k, ...rest] = ks
781
+ const kvRuleName = propKvRuleNames[k]
782
+ let res
783
+ if (k === '*') {
784
+ res = this._addRule(
785
+ `${name ?? ''}${name ? '-' : ''}additional-kvs`,
786
+ `${kvRuleName} ( "," space ${kvRuleName} )*`,
787
+ )
788
+ } else if (firstIsOptional) {
789
+ res = `( "," space ${kvRuleName} )?`
790
+ } else {
791
+ res = kvRuleName
792
+ }
793
+ if (rest.length > 0) {
794
+ res += ` ${this._addRule(
795
+ `${name ?? ''}${name ? '-' : ''}${k}-rest`,
796
+ getRecursiveRefs(rest, true) || '',
797
+ )}`
798
+ }
799
+ return res
800
+ }
801
+
802
+ rule += optionalProps
803
+ .map((_: any, i: number) =>
804
+ getRecursiveRefs(optionalProps.slice(i), false),
805
+ )
806
+ .join(' | ')
807
+ if (requiredProps.length > 0) {
808
+ rule += ' )'
809
+ }
810
+ rule += ' )?'
811
+ }
812
+
813
+ rule += ' "}" space'
814
+
815
+ return rule
816
+ }
817
+
818
+ formatGrammar() {
819
+ let grammar = ''
820
+ for (const [name, rule] of Object.entries(this._rules).sort(([a], [b]) =>
821
+ a.localeCompare(b),
822
+ )) {
823
+ grammar += `${name} ::= ${rule}\n`
824
+ }
825
+ return grammar
826
+ }
827
+ }
828
+
829
+ export const convertJsonSchemaToGrammar = ({
830
+ schema,
831
+ propOrder,
832
+ dotall,
833
+ allowFetch,
834
+ }: {
835
+ schema: any
836
+ propOrder?: SchemaGrammarConverterPropOrder
837
+ dotall?: boolean
838
+ allowFetch?: boolean
839
+ }): string | Promise<string> => {
840
+ const converter = new SchemaGrammarConverter({
841
+ prop_order: propOrder,
842
+ dotall,
843
+ allow_fetch: allowFetch,
844
+ })
845
+
846
+ if (allowFetch) {
847
+ return converter.resolveRefs(schema, '').then(() => {
848
+ converter.visit(schema, '')
849
+ return converter.formatGrammar()
850
+ })
851
+ }
852
+ converter.visit(schema, '')
853
+ return converter.formatGrammar()
854
+ }