react-native-nobodywho 0.3.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,7 @@ NobodyWho is a React Native library for running large language models locally an
5
5
  Free to use in commercial projects under the EUPL-1.2 license — no API key required. Supports text, vision, embeddings, RAG & function calling.
6
6
 
7
7
  - [Documentation](https://docs.nobodywho.ooo) — React Native & other frameworks documentation
8
+ - [Starter example app](https://github.com/nobodywho-ooo/react-native-starter-example) — Test this library in 5 minutes
8
9
  - [Discord](https://discord.gg/qhaMc2qCYB) — Get help, share ideas, and connect with other developers
9
10
  - [GitHub Issues](https://github.com/nobodywho-ooo/nobodywho/issues) — Report bugs
10
11
  - [GitHub Discussions](https://github.com/nobodywho-ooo/nobodywho/discussions) — Ask questions and request features
@@ -60,7 +61,7 @@ const chat = await Chat.fromPath({
60
61
 
61
62
  // Stream tokens
62
63
  for await (const token of chat.ask("Is water wet?")) {
63
- process.stdout.write(token);
64
+ console.log(token);
64
65
  }
65
66
 
66
67
  // Or get the full response
@@ -76,13 +77,17 @@ Give your LLM the ability to interact with the outside world by defining tools:
76
77
  ```typescript
77
78
  import { Chat, Tool } from "react-native-nobodywho";
78
79
 
80
+ function getWeatherForCity(city: string): string {
81
+ return JSON.stringify({ temp: 22, condition: "sunny" });
82
+ }
83
+
79
84
  const getWeather = new Tool({
80
85
  name: "get_weather",
81
86
  description: "Get the current weather for a city",
82
- parameters: {
83
- city: { type: "string", description: "The city name" },
84
- },
85
- call: ({ city }) => JSON.stringify({ temp: 22, condition: "sunny" }),
87
+ parameters: [
88
+ { name: "city", type: "string", description: "The city name" },
89
+ ],
90
+ call: getWeatherForCity,
86
91
  });
87
92
 
88
93
  const chat = await Chat.fromPath({
@@ -130,7 +130,7 @@ task resolveNativeLibraries {
130
130
 
131
131
  android {
132
132
  if (supportsNamespace()) {
133
- namespace "com.nobodywho"
133
+ namespace "ooo.nobodywho"
134
134
 
135
135
  sourceSets {
136
136
  main {
@@ -234,6 +234,6 @@ if (isNewArchitectureEnabled()) {
234
234
  react {
235
235
  jsRootDir = file("../src/")
236
236
  libraryName = "Nobodywho"
237
- codegenJavaPackageName = "com.nobodywho"
237
+ codegenJavaPackageName = "ooo.nobodywho"
238
238
  }
239
239
  }
@@ -1,5 +1,5 @@
1
1
 
2
2
  <!-- Generated by uniffi-bindgen-react-native -->
3
3
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
4
- package="com.nobodywho">
4
+ package="ooo.nobodywho">
5
5
  </manifest>
@@ -1,5 +1,5 @@
1
1
  // Generated by uniffi-bindgen-react-native
2
- package com.nobodywho
2
+ package ooo.nobodywho
3
3
 
4
4
  import com.facebook.react.bridge.ReactApplicationContext
5
5
  import com.facebook.react.module.annotations.ReactModule
@@ -1,14 +1,14 @@
1
1
  // Generated by uniffi-bindgen-react-native
2
- package com.nobodywho
2
+ package ooo.nobodywho
3
3
 
4
- import com.facebook.react.TurboReactPackage
4
+ import com.facebook.react.BaseReactPackage
5
5
  import com.facebook.react.bridge.NativeModule
6
6
  import com.facebook.react.bridge.ReactApplicationContext
7
7
  import com.facebook.react.module.model.ReactModuleInfo
8
8
  import com.facebook.react.module.model.ReactModuleInfoProvider
9
9
  import java.util.HashMap
10
10
 
11
- class NobodywhoPackage : TurboReactPackage() {
11
+ class NobodywhoPackage : BaseReactPackage() {
12
12
  override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
13
13
  return if (name == NobodywhoModule.NAME) {
14
14
  NobodywhoModule(reactContext)
@@ -188,8 +188,17 @@ void uniffi_nobodywho_uniffi_fn_free_rusttool(
188
188
  /*handle*/ uint64_t uniffi_nobodywho_uniffi_fn_constructor_rusttool_new(
189
189
  RustBuffer name, RustBuffer description, RustBuffer parameters,
190
190
  uint64_t callback, RustCallStatus *uniffi_out_err);
191
+ /*handle*/ uint64_t uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(
192
+ RustBuffer name, RustBuffer description, RustBuffer parameters,
193
+ RustCallStatus *uniffi_out_err);
191
194
  RustBuffer uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json(
192
195
  /*handle*/ uint64_t ptr, RustCallStatus *uniffi_out_err);
196
+ /*handle*/ uint64_t
197
+ uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(
198
+ /*handle*/ uint64_t ptr);
199
+ void uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(
200
+ /*handle*/ uint64_t ptr, RustBuffer call_id, RustBuffer result,
201
+ RustCallStatus *uniffi_out_err);
193
202
  /*handle*/ uint64_t uniffi_nobodywho_uniffi_fn_clone_samplerbuilder(
194
203
  /*handle*/ uint64_t handle, RustCallStatus *uniffi_out_err);
195
204
  void uniffi_nobodywho_uniffi_fn_free_samplerbuilder(
@@ -419,6 +428,9 @@ uint16_t uniffi_nobodywho_uniffi_checksum_method_rustencoder_encode();
419
428
  uint16_t uniffi_nobodywho_uniffi_checksum_method_rusttokenstream_completed();
420
429
  uint16_t uniffi_nobodywho_uniffi_checksum_method_rusttokenstream_next_token();
421
430
  uint16_t uniffi_nobodywho_uniffi_checksum_method_rusttool_get_schema_json();
431
+ uint16_t uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call();
432
+ uint16_t
433
+ uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call();
422
434
  uint16_t uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist();
423
435
  uint16_t uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dry();
424
436
  uint16_t uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_grammar();
@@ -437,6 +449,7 @@ uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rustchat_new();
437
449
  uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rustcrossencoder_new();
438
450
  uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rustencoder_new();
439
451
  uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new();
452
+ uint16_t uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async();
440
453
  uint16_t uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new();
441
454
  uint16_t uniffi_nobodywho_uniffi_checksum_constructor_samplerconfig_from_json();
442
455
  uint16_t uniffi_nobodywho_uniffi_checksum_method_rusttoolcallback_call();
@@ -2581,6 +2594,19 @@ NativeNobodywho::NativeNobodywho(
2581
2594
  ->cpp_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new(
2582
2595
  rt, thisVal, args, count);
2583
2596
  });
2597
+ props["ubrn_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async"] =
2598
+ jsi::Function::createFromHostFunction(
2599
+ rt,
2600
+ jsi::PropNameID::forAscii(
2601
+ rt,
2602
+ "ubrn_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async"),
2603
+ 3,
2604
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal,
2605
+ const jsi::Value *args, size_t count) -> jsi::Value {
2606
+ return this
2607
+ ->cpp_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(
2608
+ rt, thisVal, args, count);
2609
+ });
2584
2610
  props["ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json"] =
2585
2611
  jsi::Function::createFromHostFunction(
2586
2612
  rt,
@@ -2593,6 +2619,30 @@ NativeNobodywho::NativeNobodywho(
2593
2619
  ->cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json(
2594
2620
  rt, thisVal, args, count);
2595
2621
  });
2622
+ props["ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call"] =
2623
+ jsi::Function::createFromHostFunction(
2624
+ rt,
2625
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_nobodywho_uniffi_fn_"
2626
+ "method_rusttool_next_pending_call"),
2627
+ 1,
2628
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal,
2629
+ const jsi::Value *args, size_t count) -> jsi::Value {
2630
+ return this
2631
+ ->cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(
2632
+ rt, thisVal, args, count);
2633
+ });
2634
+ props["ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_"
2635
+ "call"] = jsi::Function::createFromHostFunction(
2636
+ rt,
2637
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_nobodywho_uniffi_fn_method_"
2638
+ "rusttool_resolve_pending_call"),
2639
+ 3,
2640
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal,
2641
+ const jsi::Value *args, size_t count) -> jsi::Value {
2642
+ return this
2643
+ ->cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(
2644
+ rt, thisVal, args, count);
2645
+ });
2596
2646
  props["ubrn_uniffi_nobodywho_uniffi_fn_clone_samplerbuilder"] =
2597
2647
  jsi::Function::createFromHostFunction(
2598
2648
  rt,
@@ -3860,6 +3910,30 @@ NativeNobodywho::NativeNobodywho(
3860
3910
  ->cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_get_schema_json(
3861
3911
  rt, thisVal, args, count);
3862
3912
  });
3913
+ props["ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_"
3914
+ "call"] = jsi::Function::createFromHostFunction(
3915
+ rt,
3916
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_nobodywho_uniffi_checksum_"
3917
+ "method_rusttool_next_pending_call"),
3918
+ 0,
3919
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal,
3920
+ const jsi::Value *args, size_t count) -> jsi::Value {
3921
+ return this
3922
+ ->cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call(
3923
+ rt, thisVal, args, count);
3924
+ });
3925
+ props["ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_"
3926
+ "call"] = jsi::Function::createFromHostFunction(
3927
+ rt,
3928
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_nobodywho_uniffi_checksum_"
3929
+ "method_rusttool_resolve_pending_call"),
3930
+ 0,
3931
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal,
3932
+ const jsi::Value *args, size_t count) -> jsi::Value {
3933
+ return this
3934
+ ->cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call(
3935
+ rt, thisVal, args, count);
3936
+ });
3863
3937
  props["ubrn_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist"] =
3864
3938
  jsi::Function::createFromHostFunction(
3865
3939
  rt,
@@ -4078,6 +4152,18 @@ NativeNobodywho::NativeNobodywho(
4078
4152
  ->cpp_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new(
4079
4153
  rt, thisVal, args, count);
4080
4154
  });
4155
+ props["ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_"
4156
+ "async"] = jsi::Function::createFromHostFunction(
4157
+ rt,
4158
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_nobodywho_uniffi_checksum_"
4159
+ "constructor_rusttool_new_async"),
4160
+ 0,
4161
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal,
4162
+ const jsi::Value *args, size_t count) -> jsi::Value {
4163
+ return this
4164
+ ->cpp_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async(
4165
+ rt, thisVal, args, count);
4166
+ });
4081
4167
  props["ubrn_uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_"
4082
4168
  "new"] = jsi::Function::createFromHostFunction(
4083
4169
  rt,
@@ -4917,6 +5003,23 @@ NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new(
4917
5003
  value);
4918
5004
  }
4919
5005
  jsi::Value
5006
+ NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(
5007
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
5008
+ size_t count) {
5009
+ RustCallStatus status =
5010
+ uniffi::nobodywho::Bridging<RustCallStatus>::rustSuccess(rt);
5011
+ auto value = uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(
5012
+ uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[0]),
5013
+ uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[1]),
5014
+ uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[2]),
5015
+ &status);
5016
+ uniffi::nobodywho::Bridging<RustCallStatus>::copyIntoJs(
5017
+ rt, callInvoker, status, args[count - 1]);
5018
+
5019
+ return uniffi_jsi::Bridging</*handle*/ uint64_t>::toJs(rt, callInvoker,
5020
+ value);
5021
+ }
5022
+ jsi::Value
4920
5023
  NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json(
4921
5024
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
4922
5025
  size_t count) {
@@ -4931,6 +5034,34 @@ NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json(
4931
5034
 
4932
5035
  return uniffi::nobodywho::Bridging<RustBuffer>::toJs(rt, callInvoker, value);
4933
5036
  }
5037
+ jsi::Value NativeNobodywho::
5038
+ cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(
5039
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
5040
+ size_t count) {
5041
+ auto value = uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(
5042
+ uniffi_jsi::Bridging</*handle*/ uint64_t>::fromJs(rt, callInvoker,
5043
+ args[0]));
5044
+
5045
+ return uniffi_jsi::Bridging</*handle*/ uint64_t>::toJs(rt, callInvoker,
5046
+ value);
5047
+ }
5048
+ jsi::Value NativeNobodywho::
5049
+ cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(
5050
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
5051
+ size_t count) {
5052
+ RustCallStatus status =
5053
+ uniffi::nobodywho::Bridging<RustCallStatus>::rustSuccess(rt);
5054
+ uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(
5055
+ uniffi_jsi::Bridging</*handle*/ uint64_t>::fromJs(rt, callInvoker,
5056
+ args[0]),
5057
+ uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[1]),
5058
+ uniffi::nobodywho::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[2]),
5059
+ &status);
5060
+ uniffi::nobodywho::Bridging<RustCallStatus>::copyIntoJs(
5061
+ rt, callInvoker, status, args[count - 1]);
5062
+
5063
+ return jsi::Value::undefined();
5064
+ }
4934
5065
  jsi::Value NativeNobodywho::cpp_uniffi_nobodywho_uniffi_fn_clone_samplerbuilder(
4935
5066
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
4936
5067
  size_t count) {
@@ -6213,6 +6344,24 @@ jsi::Value NativeNobodywho::
6213
6344
 
6214
6345
  return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
6215
6346
  }
6347
+ jsi::Value NativeNobodywho::
6348
+ cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call(
6349
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
6350
+ size_t count) {
6351
+ auto value =
6352
+ uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call();
6353
+
6354
+ return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
6355
+ }
6356
+ jsi::Value NativeNobodywho::
6357
+ cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call(
6358
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
6359
+ size_t count) {
6360
+ auto value =
6361
+ uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call();
6362
+
6363
+ return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
6364
+ }
6216
6365
  jsi::Value NativeNobodywho::
6217
6366
  cpp_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist(
6218
6367
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
@@ -6363,6 +6512,15 @@ NativeNobodywho::cpp_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new(
6363
6512
 
6364
6513
  return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
6365
6514
  }
6515
+ jsi::Value NativeNobodywho::
6516
+ cpp_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async(
6517
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
6518
+ size_t count) {
6519
+ auto value =
6520
+ uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async();
6521
+
6522
+ return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
6523
+ }
6366
6524
  jsi::Value NativeNobodywho::
6367
6525
  cpp_uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new(
6368
6526
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
@@ -137,9 +137,19 @@ protected:
137
137
  jsi::Value cpp_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new(
138
138
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
139
139
  size_t count);
140
+ jsi::Value cpp_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(
141
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
142
+ size_t count);
140
143
  jsi::Value cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json(
141
144
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
142
145
  size_t count);
146
+ jsi::Value cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(
147
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
148
+ size_t count);
149
+ jsi::Value
150
+ cpp_uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(
151
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
152
+ size_t count);
143
153
  jsi::Value cpp_uniffi_nobodywho_uniffi_fn_clone_samplerbuilder(
144
154
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
145
155
  size_t count);
@@ -483,6 +493,14 @@ protected:
483
493
  cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_get_schema_json(
484
494
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
485
495
  size_t count);
496
+ jsi::Value
497
+ cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call(
498
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
499
+ size_t count);
500
+ jsi::Value
501
+ cpp_uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call(
502
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
503
+ size_t count);
486
504
  jsi::Value cpp_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist(
487
505
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
488
506
  size_t count);
@@ -544,6 +562,10 @@ protected:
544
562
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
545
563
  size_t count);
546
564
  jsi::Value
565
+ cpp_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async(
566
+ jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
567
+ size_t count);
568
+ jsi::Value
547
569
  cpp_uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new(
548
570
  jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args,
549
571
  size_t count);
@@ -53,7 +53,10 @@ interface NativeModuleInterface {
53
53
  ubrn_uniffi_nobodywho_uniffi_fn_clone_rusttool(handle: bigint, uniffi_out_err: UniffiRustCallStatus): bigint;
54
54
  ubrn_uniffi_nobodywho_uniffi_fn_free_rusttool(handle: bigint, uniffi_out_err: UniffiRustCallStatus): void;
55
55
  ubrn_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new(name: Uint8Array, description: Uint8Array, parameters: Uint8Array, callback: bigint, uniffi_out_err: UniffiRustCallStatus): bigint;
56
+ ubrn_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(name: Uint8Array, description: Uint8Array, parameters: Uint8Array, uniffi_out_err: UniffiRustCallStatus): bigint;
56
57
  ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_get_schema_json(ptr: bigint, uniffi_out_err: UniffiRustCallStatus): Uint8Array;
58
+ ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(ptr: bigint): bigint;
59
+ ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(ptr: bigint, callId: Uint8Array, result: Uint8Array, uniffi_out_err: UniffiRustCallStatus): void;
57
60
  ubrn_uniffi_nobodywho_uniffi_fn_clone_samplerbuilder(handle: bigint, uniffi_out_err: UniffiRustCallStatus): bigint;
58
61
  ubrn_uniffi_nobodywho_uniffi_fn_free_samplerbuilder(handle: bigint, uniffi_out_err: UniffiRustCallStatus): void;
59
62
  ubrn_uniffi_nobodywho_uniffi_fn_constructor_samplerbuilder_new(uniffi_out_err: UniffiRustCallStatus): bigint;
@@ -163,6 +166,8 @@ interface NativeModuleInterface {
163
166
  ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttokenstream_completed(): number;
164
167
  ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttokenstream_next_token(): number;
165
168
  ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_get_schema_json(): number;
169
+ ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call(): number;
170
+ ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call(): number;
166
171
  ubrn_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist(): number;
167
172
  ubrn_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dry(): number;
168
173
  ubrn_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_grammar(): number;
@@ -181,6 +186,7 @@ interface NativeModuleInterface {
181
186
  ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rustcrossencoder_new(): number;
182
187
  ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rustencoder_new(): number;
183
188
  ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new(): number;
189
+ ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async(): number;
184
190
  ubrn_uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new(): number;
185
191
  ubrn_uniffi_nobodywho_uniffi_checksum_constructor_samplerconfig_from_json(): number;
186
192
  ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttoolcallback_call(): number;
@@ -358,6 +358,67 @@ const FfiConverterTypeAsset = (() => {
358
358
  })();
359
359
 
360
360
 
361
+ /**
362
+ * A pending tool call waiting for resolution from the language binding.
363
+ */
364
+ export type PendingToolCall = {
365
+ callId: string,
366
+ argumentsJson: string
367
+ }
368
+
369
+ /**
370
+ * Generated factory for {@link PendingToolCall} record objects.
371
+ */
372
+ export const PendingToolCall = (() => {
373
+ const defaults = () => ({
374
+ });
375
+ const create = (() => {
376
+ return uniffiCreateRecord<PendingToolCall, ReturnType<typeof defaults>>(defaults);
377
+ })();
378
+ return Object.freeze({
379
+ /**
380
+ * Create a frozen instance of {@link PendingToolCall}, with defaults specified
381
+ * in Rust, in the {@link nobodywho} crate.
382
+ */
383
+ create,
384
+
385
+ /**
386
+ * Create a frozen instance of {@link PendingToolCall}, with defaults specified
387
+ * in Rust, in the {@link nobodywho} crate.
388
+ */
389
+ new: create,
390
+
391
+ /**
392
+ * Defaults specified in the {@link nobodywho} crate.
393
+ */
394
+ defaults: () => Object.freeze(defaults()) as Partial<PendingToolCall>,
395
+
396
+ });
397
+ })();
398
+
399
+ const FfiConverterTypePendingToolCall = (() => {
400
+ type TypeName = PendingToolCall;
401
+ class FFIConverter extends AbstractFfiConverterByteArray<TypeName> {
402
+ read(from: RustBuffer): TypeName {
403
+ return {
404
+ callId: FfiConverterString.read(from),
405
+ argumentsJson: FfiConverterString.read(from)
406
+ };
407
+ }
408
+ write(value: TypeName, into: RustBuffer): void {
409
+ FfiConverterString.write(value.callId, into);
410
+ FfiConverterString.write(value.argumentsJson, into);
411
+ }
412
+ allocationSize(value: TypeName): number {
413
+ return FfiConverterString.allocationSize(value.callId) +
414
+ FfiConverterString.allocationSize(value.argumentsJson);
415
+
416
+ }
417
+ };
418
+ return new FFIConverter();
419
+ })();
420
+
421
+
361
422
  export type ToolCall = {
362
423
  name: string,
363
424
  argumentsJson: string
@@ -2154,6 +2215,14 @@ export interface RustToolInterface {
2154
2215
  * Get the JSON schema for this tool's parameters as a string.
2155
2216
  */
2156
2217
  getSchemaJson() : string;
2218
+ /**
2219
+ * Await the next tool call from inference. Returns `None` when the tool is dropped.
2220
+ */
2221
+ nextPendingCall(asyncOpts_?: { signal: AbortSignal }) : Promise<PendingToolCall | undefined>;
2222
+ /**
2223
+ * Resolve a pending tool call with the result string.
2224
+ */
2225
+ resolvePendingCall(callId: string, result: string) : void;
2157
2226
  }
2158
2227
 
2159
2228
 
@@ -2163,21 +2232,7 @@ export class RustTool extends UniffiAbstractObject implements RustToolInterface
2163
2232
  readonly [destructorGuardSymbol]: UniffiGcObject;
2164
2233
  readonly [pointerLiteralSymbol]: UniffiHandle;
2165
2234
  /**
2166
- * Create a tool that the model can call during inference.
2167
- *
2168
- * `parameters` is an ordered list of parameter definitions.
2169
- * Each entry has a `name` and a `type` (e.g. `"string"`, `"integer"`, `"number"`, `"boolean"`).
2170
- * The order matters — binding layers use it to map positional arguments
2171
- * in the user's callback function to named JSON parameters.
2172
- *
2173
- * Supported types: `"string"`, `"integer"` / `"int"`, `"number"` / `"float"` / `"double"`,
2174
- * `"boolean"` / `"bool"`.
2175
- * A JSON schema is generated automatically from this list.
2176
- *
2177
- * The callback receives the model's arguments as a JSON string
2178
- * (e.g. `{"city": "London", "degrees": 22}`).
2179
- * Each binding layer wraps the user's function to parse this JSON and
2180
- * pass individual typed arguments to the original function.
2235
+ * Create a tool with a synchronous callback (for Swift, Kotlin).
2181
2236
  */
2182
2237
  constructor(name: string, description: string, parameters: Array<ToolParameter>, callback: RustToolCallback) {
2183
2238
  super();
@@ -2198,6 +2253,26 @@ export class RustTool extends UniffiAbstractObject implements RustToolInterface
2198
2253
  }
2199
2254
 
2200
2255
 
2256
+ /**
2257
+ * Create a tool with async callback support (for React Native).
2258
+ *
2259
+ * Use `next_pending_call` to await tool invocations and
2260
+ * `resolve_pending_call` to return results. The inference thread
2261
+ * blocks until resolved.
2262
+ */
2263
+ static newAsync(name: string, description: string, parameters: Array<ToolParameter>): RustToolInterface {
2264
+ return FfiConverterTypeRustTool.lift(uniffiCaller.rustCall(
2265
+ /*caller:*/ (callStatus) => {
2266
+ return nativeModule().ubrn_uniffi_nobodywho_uniffi_fn_constructor_rusttool_new_async(
2267
+ FfiConverterString.lower(name),
2268
+ FfiConverterString.lower(description),
2269
+ FfiConverterArrayTypeToolParameter.lower(parameters),
2270
+ callStatus);
2271
+ },
2272
+ /*liftString:*/ FfiConverterString.lift,
2273
+ ));
2274
+ }
2275
+
2201
2276
 
2202
2277
 
2203
2278
  /**
@@ -2213,6 +2288,50 @@ export class RustTool extends UniffiAbstractObject implements RustToolInterface
2213
2288
  ));
2214
2289
  }
2215
2290
 
2291
+ /**
2292
+ * Await the next tool call from inference. Returns `None` when the tool is dropped.
2293
+ */
2294
+ async nextPendingCall(asyncOpts_?: { signal: AbortSignal }): Promise<PendingToolCall | undefined> {
2295
+ const __stack = uniffiIsDebug ? new Error().stack : undefined;
2296
+ try {
2297
+ return await uniffiRustCallAsync(
2298
+ /*rustCaller:*/ uniffiCaller,
2299
+ /*rustFutureFunc:*/ () => {
2300
+ return nativeModule().ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_next_pending_call(
2301
+ uniffiTypeRustToolObjectFactory.clonePointer(this)
2302
+
2303
+ );
2304
+ },
2305
+ /*pollFunc:*/ nativeModule().ubrn_ffi_nobodywho_uniffi_rust_future_poll_rust_buffer,
2306
+ /*cancelFunc:*/ nativeModule().ubrn_ffi_nobodywho_uniffi_rust_future_cancel_rust_buffer,
2307
+ /*completeFunc:*/ nativeModule().ubrn_ffi_nobodywho_uniffi_rust_future_complete_rust_buffer,
2308
+ /*freeFunc:*/ nativeModule().ubrn_ffi_nobodywho_uniffi_rust_future_free_rust_buffer,
2309
+ /*liftFunc:*/ FfiConverterOptionalTypePendingToolCall.lift.bind(FfiConverterOptionalTypePendingToolCall),
2310
+ /*liftString:*/ FfiConverterString.lift,
2311
+ /*asyncOpts:*/ asyncOpts_,
2312
+
2313
+ );
2314
+ } catch (__error: any) {
2315
+ if (uniffiIsDebug && __error instanceof Error) {
2316
+ __error.stack = __stack;
2317
+ }
2318
+ throw __error;
2319
+ }
2320
+ }
2321
+
2322
+ /**
2323
+ * Resolve a pending tool call with the result string.
2324
+ */
2325
+ resolvePendingCall(callId: string, result: string): void {uniffiCaller.rustCall(
2326
+ /*caller:*/ (callStatus) => { nativeModule().ubrn_uniffi_nobodywho_uniffi_fn_method_rusttool_resolve_pending_call(uniffiTypeRustToolObjectFactory.clonePointer(this),
2327
+ FfiConverterString.lower(callId),
2328
+ FfiConverterString.lower(result),
2329
+ callStatus);
2330
+ },
2331
+ /*liftString:*/ FfiConverterString.lift,
2332
+ );
2333
+ }
2334
+
2216
2335
 
2217
2336
  /**
2218
2337
  * {@inheritDoc uniffi-bindgen-react-native#UniffiAbstractObject.uniffiDestroy}
@@ -2772,6 +2891,10 @@ const uniffiTypeSamplerConfigObjectFactory: UniffiObjectFactory<SamplerConfigInt
2772
2891
  const FfiConverterTypeSamplerConfig = new FfiConverterObject(uniffiTypeSamplerConfigObjectFactory);
2773
2892
 
2774
2893
 
2894
+ // FfiConverter for PendingToolCall | undefined
2895
+ const FfiConverterOptionalTypePendingToolCall = new FfiConverterOptional(FfiConverterTypePendingToolCall);
2896
+
2897
+
2775
2898
  // FfiConverter for string | undefined
2776
2899
  const FfiConverterOptionalString = new FfiConverterOptional(FfiConverterString);
2777
2900
 
@@ -2931,6 +3054,12 @@ function uniffiEnsureInitialized() {
2931
3054
  if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_get_schema_json() !== 4679) {
2932
3055
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_method_rusttool_get_schema_json");
2933
3056
  }
3057
+ if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call() !== 52020) {
3058
+ throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_method_rusttool_next_pending_call");
3059
+ }
3060
+ if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call() !== 10096) {
3061
+ throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_method_rusttool_resolve_pending_call");
3062
+ }
2934
3063
  if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist() !== 23376) {
2935
3064
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_method_samplerbuilder_dist");
2936
3065
  }
@@ -2982,9 +3111,12 @@ function uniffiEnsureInitialized() {
2982
3111
  if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rustencoder_new() !== 27902) {
2983
3112
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_constructor_rustencoder_new");
2984
3113
  }
2985
- if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new() !== 54104) {
3114
+ if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new() !== 9431) {
2986
3115
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new");
2987
3116
  }
3117
+ if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async() !== 54521) {
3118
+ throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_constructor_rusttool_new_async");
3119
+ }
2988
3120
  if (nativeModule().ubrn_uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new() !== 50214) {
2989
3121
  throw new UniffiInternalError.ApiChecksumMismatch("uniffi_nobodywho_uniffi_checksum_constructor_samplerbuilder_new");
2990
3122
  }
@@ -3004,6 +3136,7 @@ export default Object.freeze({
3004
3136
  FfiConverterTypeAsset,
3005
3137
  FfiConverterTypeMessage,
3006
3138
  FfiConverterTypeNobodyWhoError,
3139
+ FfiConverterTypePendingToolCall,
3007
3140
  FfiConverterTypePromptPart,
3008
3141
  FfiConverterTypeRole,
3009
3142
  FfiConverterTypeRustChat,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nobodywho",
3
- "version": "0.3.2",
3
+ "version": "1.0.0",
4
4
  "description": "Run LLMs locally with offline inference — React Native bindings",
5
5
  "main": "src/wrapper.ts",
6
6
  "types": "src/wrapper.ts",
package/src/chat.ts CHANGED
@@ -34,7 +34,7 @@ export class Chat {
34
34
  model: Model;
35
35
  systemPrompt?: string;
36
36
  contextSize?: number;
37
- templateVariables?: Map<string, boolean>;
37
+ templateVariables?: Record<string, boolean>;
38
38
  tools?: Tool[];
39
39
  sampler?: SamplerConfig;
40
40
  }) {
@@ -42,7 +42,7 @@ export class Chat {
42
42
  opts.model._inner,
43
43
  opts.systemPrompt ?? undefined,
44
44
  opts.contextSize ?? 4096,
45
- opts.templateVariables ?? undefined,
45
+ opts.templateVariables ? new Map(Object.entries(opts.templateVariables)) : undefined,
46
46
  opts.tools?.map((t) => t._inner) ?? undefined,
47
47
  opts.sampler ?? undefined,
48
48
  );
@@ -66,7 +66,7 @@ export class Chat {
66
66
  projectionModelPath?: string;
67
67
  systemPrompt?: string;
68
68
  contextSize?: number;
69
- templateVariables?: Map<string, boolean>;
69
+ templateVariables?: Record<string, boolean>;
70
70
  tools?: Tool[];
71
71
  sampler?: SamplerConfig;
72
72
  }): Promise<Chat> {
@@ -139,8 +139,8 @@ export class Chat {
139
139
  }
140
140
 
141
141
  /** Get all template variables. */
142
- async getTemplateVariables(): Promise<Map<string, boolean>> {
143
- return this._inner.getTemplateVariables();
142
+ async getTemplateVariables(): Promise<Record<string, boolean>> {
143
+ return Object.fromEntries(await this._inner.getTemplateVariables());
144
144
  }
145
145
 
146
146
  /** Set the sampler configuration. */
@@ -24,41 +24,41 @@ export class SamplerPresets {
24
24
 
25
25
  /** Get the default sampler configuration. */
26
26
  static default(): SamplerConfig {
27
- return samplerPresetDefault();
27
+ return samplerPresetDefault() as SamplerConfig;
28
28
  }
29
29
 
30
30
  /** Create a sampler with top-k filtering only. */
31
31
  static topK(topK: number): SamplerConfig {
32
- return samplerPresetTopK(topK);
32
+ return samplerPresetTopK(topK) as SamplerConfig;
33
33
  }
34
34
 
35
35
  /** Create a sampler with nucleus (top-p) sampling. */
36
36
  static topP(topP: number): SamplerConfig {
37
- return samplerPresetTopP(topP);
37
+ return samplerPresetTopP(topP) as SamplerConfig;
38
38
  }
39
39
 
40
40
  /** Create a greedy sampler (always picks most probable token). */
41
41
  static greedy(): SamplerConfig {
42
- return samplerPresetGreedy();
42
+ return samplerPresetGreedy() as SamplerConfig;
43
43
  }
44
44
 
45
45
  /** Create a sampler with temperature scaling. */
46
46
  static temperature(temperature: number): SamplerConfig {
47
- return samplerPresetTemperature(temperature);
47
+ return samplerPresetTemperature(temperature) as SamplerConfig;
48
48
  }
49
49
 
50
50
  /** Create a DRY sampler preset to reduce repetition. */
51
51
  static dry(): SamplerConfig {
52
- return samplerPresetDry();
52
+ return samplerPresetDry() as SamplerConfig;
53
53
  }
54
54
 
55
55
  /** Create a sampler configured for JSON output generation. */
56
56
  static json(): SamplerConfig {
57
- return samplerPresetJson();
57
+ return samplerPresetJson() as SamplerConfig;
58
58
  }
59
59
 
60
60
  /** Create a sampler with a custom grammar constraint. */
61
61
  static grammar(grammar: string): SamplerConfig {
62
- return samplerPresetGrammar(grammar);
62
+ return samplerPresetGrammar(grammar) as SamplerConfig;
63
63
  }
64
64
  }
package/src/tool.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  RustTool,
3
- type RustToolCallback,
4
3
  type ToolParameter,
5
4
  } from "../generated/ts/nobodywho";
6
5
 
@@ -55,18 +54,33 @@ function convertValue(
55
54
  * A tool that the model can call during inference.
56
55
  *
57
56
  * Wraps the internal RustTool with an ergonomic API that handles
58
- * JSON parsing and typed argument dispatch.
57
+ * JSON parsing and typed argument dispatch. Both sync and async
58
+ * callbacks are supported.
59
59
  *
60
60
  * @example
61
61
  * ```typescript
62
- * const weatherTool = new Tool({
62
+ * // Any function can be used as a tool — arguments are passed positionally
63
+ * // in the same order as the parameters object.
64
+ * function getWeather(city: string, unit: string): string {
65
+ * return JSON.stringify({ temp: 22, unit });
66
+ * }
67
+ *
68
+ * const tool = new Tool({
63
69
  * name: "get_weather",
64
70
  * description: "Get the current weather for a city",
65
- * parameters: {
66
- * city: { type: "string" },
67
- * unit: { type: "string", enum: ["celsius", "fahrenheit"] },
68
- * },
69
- * call: ({ city, unit }) => JSON.stringify({ temp: 22, unit }),
71
+ * parameters: [
72
+ * { name: "city", type: "string" },
73
+ * { name: "unit", type: "string", enum: ["celsius", "fahrenheit"] },
74
+ * ],
75
+ * call: getWeather,
76
+ * });
77
+ *
78
+ * // Async functions work too
79
+ * const tool = new Tool({
80
+ * name: "search",
81
+ * description: "Search the knowledge base",
82
+ * parameters: [{ name: "query", type: "string" }],
83
+ * call: async (query) => await searchDatabase(query as string),
70
84
  * });
71
85
  * ```
72
86
  */
@@ -77,27 +91,45 @@ export class Tool {
77
91
  constructor(opts: {
78
92
  name: string;
79
93
  description: string;
80
- parameters: Record<string, Record<string, unknown>>;
81
- call: (args: Record<string, unknown>) => string;
94
+ parameters: { name: string; [schemaKey: string]: unknown }[];
95
+ call: (...args: any[]) => string | Promise<string>;
82
96
  }) {
83
- const paramEntries = Object.entries(opts.parameters);
97
+ const params = opts.parameters;
98
+ const toolParams: ToolParameter[] = params.map(({ name, ...schema }) => ({
99
+ name,
100
+ schema: JSON.stringify(schema),
101
+ }));
84
102
 
85
- const callback: RustToolCallback = {
86
- call(argumentsJson: string): string {
87
- const parsed = JSON.parse(argumentsJson);
88
- const args: Record<string, unknown> = {};
89
- for (const [paramName, schema] of paramEntries) {
90
- args[paramName] = convertValue(parsed[paramName], schema);
91
- }
92
- return opts.call(args);
93
- },
94
- };
103
+ function parseArgs(argumentsJson: string): unknown[] {
104
+ const parsed = JSON.parse(argumentsJson);
105
+ return params.map(({ name, ...schema }) =>
106
+ convertValue(parsed[name], schema),
107
+ );
108
+ }
95
109
 
96
- const toolParams: ToolParameter[] = paramEntries.map(
97
- ([name, schema]) => ({ name, schema: JSON.stringify(schema) }),
98
- );
110
+ // Use the async constructor — the polling loop handles both sync
111
+ // and async callbacks uniformly via await.
112
+ this._inner = RustTool.newAsync(opts.name, opts.description, toolParams) as RustTool;
99
113
 
100
- this._inner = new RustTool(opts.name, opts.description, toolParams, callback);
114
+ // Start the polling loop. It exits when the RustTool is dropped
115
+ // (nextPendingCall returns null).
116
+ const poll = async () => {
117
+ for (;;) {
118
+ const call = await this._inner.nextPendingCall();
119
+ if (call == null) break;
120
+ try {
121
+ const args = parseArgs(call.argumentsJson);
122
+ const result = await opts.call(...args);
123
+ this._inner.resolvePendingCall(call.callId, result);
124
+ } catch (e) {
125
+ this._inner.resolvePendingCall(
126
+ call.callId,
127
+ `Error: ${e instanceof Error ? e.message : String(e)}`,
128
+ );
129
+ }
130
+ }
131
+ };
132
+ poll();
101
133
  }
102
134
 
103
135
  /** Get the JSON schema for this tool's parameters. */