@zerogpu/expo-android-sdk 0.1.1 → 0.2.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
@@ -68,9 +68,30 @@ await start('zgpu-sdk-…', {
68
68
  baseUrl: 'https://devices.zerogpu.ai', // default
69
69
  env: 'production', // default
70
70
  enableTelemetry: true, // default
71
+ customParams: { cust_param1: 'placement_home' }, // operator macros, see below
71
72
  });
72
73
  ```
73
74
 
75
+ ### Custom params (operator macros)
76
+
77
+ Three opaque slots — `cust_param1`, `cust_param2`, `cust_param3` — attached to every task the
78
+ device serves, so you can segment your ZeroGPU earnings by your own dimensions (placement, cohort,
79
+ campaign). ZeroGPU stores and counts them and never interprets them.
80
+
81
+ ```ts
82
+ import { setCustomParams } from '@zerogpu/expo-android-sdk';
83
+
84
+ // Replaces the whole set (a slot you leave out is cleared); `{}` clears all.
85
+ // Applies from the next task — no restart. Safe to call before start().
86
+ await setCustomParams({ cust_param1: 'placement_settings', cust_param2: 'cohort_b' });
87
+ ```
88
+
89
+ A slot takes **just a value** — the slot name is the key — so send `{ cust_param1: '1231231313' }`,
90
+ never `{ cust_param1: 'user-id=1231231313' }`. Letters, digits, `.`, `_` and `-` only; anything else
91
+ is dropped with a logcat warning. Values are truncated to 128 characters and unknown keys are
92
+ dropped. **Never put PII** (emails, phone numbers, names) in a slot — email-shaped values are
93
+ dropped with a logcat warning.
94
+
74
95
  ## Verifying it works
75
96
 
76
97
  Run the app on an `arm64-v8a` phone or an `x86_64` emulator (Android 8.0+), then
@@ -4,7 +4,7 @@ apply plugin: 'com.android.library'
4
4
  apply plugin: 'kotlin-android'
5
5
 
6
6
  group = 'ai.zerogpu.expo'
7
- version = '0.1.0'
7
+ version = '0.2.0'
8
8
 
9
9
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
10
10
  apply from: expoModulesCorePlugin
@@ -17,6 +17,10 @@ class ZeroGpuAndroidSdkModule : Module() {
17
17
  // null == not started.
18
18
  private var sdk: ZeroGpuSdk? = null
19
19
 
20
+ // Outlives stop()/start() so macros set before start (or between runs) apply
21
+ // to the next instance.
22
+ private var customParams: Map<String, String> = emptyMap()
23
+
20
24
  override fun definition() = ModuleDefinition {
21
25
  // Must match requireNativeModule('ZeroGpuAndroidSdk') on the JS side.
22
26
  Name("ZeroGpuAndroidSdk")
@@ -27,15 +31,23 @@ class ZeroGpuAndroidSdkModule : Module() {
27
31
  val appCtx = appContext.reactContext?.applicationContext
28
32
  ?: throw Exceptions.ReactContextLost()
29
33
 
34
+ (options?.get("customParams") as? Map<*, *>)?.let { customParams = toStringMap(it) }
35
+
30
36
  sdk = ZeroGpuSdk(
31
37
  context = appCtx,
32
38
  operatorKey = operatorKey,
33
39
  baseUrl = (options?.get("baseUrl") as? String) ?: DEFAULT_BASE_URL,
34
40
  env = (options?.get("env") as? String) ?: DEFAULT_ENV,
35
41
  enableTelemetry = (options?.get("enableTelemetry") as? Boolean) ?: true,
42
+ customParams = customParams,
36
43
  ).also { it.start() }
37
44
  }
38
45
 
46
+ AsyncFunction("setCustomParams") { params: Map<String, Any?> ->
47
+ customParams = toStringMap(params)
48
+ sdk?.setCustomParams(customParams)
49
+ }
50
+
39
51
  AsyncFunction("stop") {
40
52
  sdk?.stop()
41
53
  sdk = null // drop the dead instance; a later start() builds a fresh one
@@ -48,6 +60,20 @@ class ZeroGpuAndroidSdkModule : Module() {
48
60
  }
49
61
  }
50
62
 
63
+ // JS numbers/booleans are coerced like the server does; nested values are
64
+ // dropped here rather than stringified into a slot.
65
+ private fun toStringMap(raw: Map<*, *>): Map<String, String> =
66
+ raw.entries.mapNotNull { (k, v) ->
67
+ val key = k as? String ?: return@mapNotNull null
68
+ val value = when (v) {
69
+ is String -> v
70
+ is Boolean -> v.toString()
71
+ is Number -> if (v.toDouble() % 1.0 == 0.0) v.toLong().toString() else v.toString()
72
+ else -> return@mapNotNull null
73
+ }
74
+ key to value
75
+ }.toMap()
76
+
51
77
  private companion object {
52
78
  const val DEFAULT_BASE_URL = "https://devices.zerogpu.ai"
53
79
  const val DEFAULT_ENV = "production"
@@ -1,4 +1,4 @@
1
- import type { ZeroGpuOptions } from './types';
1
+ import type { CustomParams, ZeroGpuOptions } from './types';
2
2
  /**
3
3
  * Native-module contract. Backed by the Android implementation
4
4
  * (`ai.zerogpu.expo.ZeroGpuAndroidSdkModule`) and a no-op iOS stub, so both
@@ -7,6 +7,7 @@ import type { ZeroGpuOptions } from './types';
7
7
  export interface ZeroGpuAndroidSdkNativeModule {
8
8
  start(operatorKey: string, options?: ZeroGpuOptions): Promise<void>;
9
9
  stop(): Promise<void>;
10
+ setCustomParams(customParams: CustomParams): Promise<void>;
10
11
  }
11
12
  declare const _default: ZeroGpuAndroidSdkNativeModule;
12
13
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"ZeroGpuAndroidSdkModule.d.ts","sourceRoot":"","sources":["../src/ZeroGpuAndroidSdkModule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;;AAGD,wBAAuF"}
1
+ {"version":3,"file":"ZeroGpuAndroidSdkModule.d.ts","sourceRoot":"","sources":["../src/ZeroGpuAndroidSdkModule.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;;AAGD,wBAAuF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ZeroGpuAndroidSdkModule.js","sourceRoot":"","sources":["../src/ZeroGpuAndroidSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAcxD,oEAAoE;AACpE,eAAe,mBAAmB,CAAgC,mBAAmB,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\nimport type { ZeroGpuOptions } from './types';\n\n/**\n * Native-module contract. Backed by the Android implementation\n * (`ai.zerogpu.expo.ZeroGpuAndroidSdkModule`) and a no-op iOS stub, so both\n * methods resolve on every platform.\n */\nexport interface ZeroGpuAndroidSdkNativeModule {\n start(operatorKey: string, options?: ZeroGpuOptions): Promise<void>;\n stop(): Promise<void>;\n}\n\n// The name must match `Name(...)` in the native module definitions.\nexport default requireNativeModule<ZeroGpuAndroidSdkNativeModule>('ZeroGpuAndroidSdk');\n"]}
1
+ {"version":3,"file":"ZeroGpuAndroidSdkModule.js","sourceRoot":"","sources":["../src/ZeroGpuAndroidSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAexD,oEAAoE;AACpE,eAAe,mBAAmB,CAAgC,mBAAmB,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\nimport type { CustomParams, ZeroGpuOptions } from './types';\n\n/**\n * Native-module contract. Backed by the Android implementation\n * (`ai.zerogpu.expo.ZeroGpuAndroidSdkModule`) and a no-op iOS stub, so both\n * methods resolve on every platform.\n */\nexport interface ZeroGpuAndroidSdkNativeModule {\n start(operatorKey: string, options?: ZeroGpuOptions): Promise<void>;\n stop(): Promise<void>;\n setCustomParams(customParams: CustomParams): Promise<void>;\n}\n\n// The name must match `Name(...)` in the native module definitions.\nexport default requireNativeModule<ZeroGpuAndroidSdkNativeModule>('ZeroGpuAndroidSdk');\n"]}
package/build/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { ZeroGpuOptions } from './types';
2
- export type { ZeroGpuOptions } from './types';
1
+ import type { CustomParams, ZeroGpuOptions } from './types';
2
+ export type { CustomParams, ZeroGpuOptions } from './types';
3
3
  /**
4
4
  * Start the ZeroGPU node. The device registers with the ZeroGPU backend using the
5
5
  * operator key, downloads its assigned model(s), and serves on-device inference
@@ -9,7 +9,8 @@ export type { ZeroGpuOptions } from './types';
9
9
  * resolves without doing anything — the SDK is Android-only.
10
10
  *
11
11
  * @param operatorKey Your operator key from the ZeroGPU dashboard (`zgpu-sdk-…`).
12
- * @param options Optional base URL / environment / telemetry overrides.
12
+ * @param options Optional base URL / environment / telemetry overrides and
13
+ * initial `customParams`.
13
14
  */
14
15
  export declare function start(operatorKey: string, options?: ZeroGpuOptions): Promise<void>;
15
16
  /**
@@ -17,4 +18,10 @@ export declare function start(operatorKey: string, options?: ZeroGpuOptions): Pr
17
18
  * SDK down. A subsequent {@link start} spins up a fresh instance. No-op on iOS.
18
19
  */
19
20
  export declare function stop(): Promise<void>;
21
+ /**
22
+ * Replace the operator macros on the running node; `{}` clears them. Applies
23
+ * from the next task the device serves — no re-register. Values set before
24
+ * {@link start} are kept and used when it starts. No-op on iOS.
25
+ */
26
+ export declare function setCustomParams(customParams: CustomParams): Promise<void>;
20
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAED;;;GAGG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE5D,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAED;;;GAGG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE"}
package/build/index.js CHANGED
@@ -8,7 +8,8 @@ import ZeroGpuAndroidSdkModule from './ZeroGpuAndroidSdkModule';
8
8
  * resolves without doing anything — the SDK is Android-only.
9
9
  *
10
10
  * @param operatorKey Your operator key from the ZeroGPU dashboard (`zgpu-sdk-…`).
11
- * @param options Optional base URL / environment / telemetry overrides.
11
+ * @param options Optional base URL / environment / telemetry overrides and
12
+ * initial `customParams`.
12
13
  */
13
14
  export function start(operatorKey, options) {
14
15
  return ZeroGpuAndroidSdkModule.start(operatorKey, options);
@@ -20,4 +21,12 @@ export function start(operatorKey, options) {
20
21
  export function stop() {
21
22
  return ZeroGpuAndroidSdkModule.stop();
22
23
  }
24
+ /**
25
+ * Replace the operator macros on the running node; `{}` clears them. Applies
26
+ * from the next task the device serves — no re-register. Values set before
27
+ * {@link start} are kept and used when it starts. No-op on iOS.
28
+ */
29
+ export function setCustomParams(customParams) {
30
+ return ZeroGpuAndroidSdkModule.setCustomParams(customParams);
31
+ }
23
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAKhE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,KAAK,CAAC,WAAmB,EAAE,OAAwB;IACjE,OAAO,uBAAuB,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI;IAClB,OAAO,uBAAuB,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC","sourcesContent":["import ZeroGpuAndroidSdkModule from './ZeroGpuAndroidSdkModule';\nimport type { ZeroGpuOptions } from './types';\n\nexport type { ZeroGpuOptions } from './types';\n\n/**\n * Start the ZeroGPU node. The device registers with the ZeroGPU backend using the\n * operator key, downloads its assigned model(s), and serves on-device inference\n * while the app is foregrounded (the native SDK manages the socket lifecycle).\n *\n * Idempotent: calling `start` again while already running is a no-op. On iOS this\n * resolves without doing anything — the SDK is Android-only.\n *\n * @param operatorKey Your operator key from the ZeroGPU dashboard (`zgpu-sdk-…`).\n * @param options Optional base URL / environment / telemetry overrides.\n */\nexport function start(operatorKey: string, options?: ZeroGpuOptions): Promise<void> {\n return ZeroGpuAndroidSdkModule.start(operatorKey, options);\n}\n\n/**\n * Stop the ZeroGPU node: close the socket, release model adapters, and shut the\n * SDK down. A subsequent {@link start} spins up a fresh instance. No-op on iOS.\n */\nexport function stop(): Promise<void> {\n return ZeroGpuAndroidSdkModule.stop();\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAKhE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,WAAmB,EAAE,OAAwB;IACjE,OAAO,uBAAuB,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI;IAClB,OAAO,uBAAuB,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,YAA0B;IACxD,OAAO,uBAAuB,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;AAC/D,CAAC","sourcesContent":["import ZeroGpuAndroidSdkModule from './ZeroGpuAndroidSdkModule';\nimport type { CustomParams, ZeroGpuOptions } from './types';\n\nexport type { CustomParams, ZeroGpuOptions } from './types';\n\n/**\n * Start the ZeroGPU node. The device registers with the ZeroGPU backend using the\n * operator key, downloads its assigned model(s), and serves on-device inference\n * while the app is foregrounded (the native SDK manages the socket lifecycle).\n *\n * Idempotent: calling `start` again while already running is a no-op. On iOS this\n * resolves without doing anything — the SDK is Android-only.\n *\n * @param operatorKey Your operator key from the ZeroGPU dashboard (`zgpu-sdk-…`).\n * @param options Optional base URL / environment / telemetry overrides and\n * initial `customParams`.\n */\nexport function start(operatorKey: string, options?: ZeroGpuOptions): Promise<void> {\n return ZeroGpuAndroidSdkModule.start(operatorKey, options);\n}\n\n/**\n * Stop the ZeroGPU node: close the socket, release model adapters, and shut the\n * SDK down. A subsequent {@link start} spins up a fresh instance. No-op on iOS.\n */\nexport function stop(): Promise<void> {\n return ZeroGpuAndroidSdkModule.stop();\n}\n\n/**\n * Replace the operator macros on the running node; `{}` clears them. Applies\n * from the next task the device serves — no re-register. Values set before\n * {@link start} are kept and used when it starts. No-op on iOS.\n */\nexport function setCustomParams(customParams: CustomParams): Promise<void> {\n return ZeroGpuAndroidSdkModule.setCustomParams(customParams);\n}\n"]}
package/build/types.d.ts CHANGED
@@ -9,5 +9,20 @@ export type ZeroGpuOptions = {
9
9
  env?: string;
10
10
  /** Whether the SDK reports anonymous telemetry. Defaults to `true`. */
11
11
  enableTelemetry?: boolean;
12
+ /** Operator macros attached to every task this device serves. See {@link CustomParams}. */
13
+ customParams?: CustomParams;
14
+ };
15
+ /**
16
+ * Operator-defined macros: opaque values (placement, cohort, campaign…) that
17
+ * ZeroGPU stores and counts per request and never interprets, so you can
18
+ * segment your earnings by them. A slot takes just a value (letters, digits,
19
+ * `.` `_` `-`), never a nested parameter like `user-id=123`, which is dropped.
20
+ * Values are truncated to 128 characters; unset or empty slots are omitted. Never put PII (emails, phone numbers, names) in a
21
+ * slot — email-shaped values are dropped with a logcat warning.
22
+ */
23
+ export type CustomParams = {
24
+ cust_param1?: string;
25
+ cust_param2?: string;
26
+ cust_param3?: string;
12
27
  };
13
28
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,2FAA2F;IAC3F,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Optional overrides for {@link start}. All fields default to production values\n * inside the native SDK, so a typical caller only passes the operator key.\n */\nexport type ZeroGpuOptions = {\n /** Device-registration base URL. Defaults to `https://devices.zerogpu.ai`. */\n baseUrl?: string;\n /** Environment name. Defaults to `production`. */\n env?: string;\n /** Whether the SDK reports anonymous telemetry. Defaults to `true`. */\n enableTelemetry?: boolean;\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Optional overrides for {@link start}. All fields default to production values\n * inside the native SDK, so a typical caller only passes the operator key.\n */\nexport type ZeroGpuOptions = {\n /** Device-registration base URL. Defaults to `https://devices.zerogpu.ai`. */\n baseUrl?: string;\n /** Environment name. Defaults to `production`. */\n env?: string;\n /** Whether the SDK reports anonymous telemetry. Defaults to `true`. */\n enableTelemetry?: boolean;\n /** Operator macros attached to every task this device serves. See {@link CustomParams}. */\n customParams?: CustomParams;\n};\n\n/**\n * Operator-defined macros: opaque values (placement, cohort, campaign…) that\n * ZeroGPU stores and counts per request and never interprets, so you can\n * segment your earnings by them. A slot takes just a value (letters, digits,\n * `.` `_` `-`), never a nested parameter like `user-id=123`, which is dropped.\n * Values are truncated to 128 characters; unset or empty slots are omitted. Never put PII (emails, phone numbers, names) in a\n * slot — email-shaped values are dropped with a logcat warning.\n */\nexport type CustomParams = {\n cust_param1?: string;\n cust_param2?: string;\n cust_param3?: string;\n};\n"]}
@@ -13,5 +13,9 @@ public class ZeroGpuAndroidSdkModule: Module {
13
13
  AsyncFunction("stop") {
14
14
  // No-op on iOS.
15
15
  }
16
+
17
+ AsyncFunction("setCustomParams") { (_ customParams: [String: Any]) in
18
+ // No-op on iOS.
19
+ }
16
20
  }
17
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerogpu/expo-android-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Expo/React Native module that runs a ZeroGPU on-device inference node on Android by wrapping the native ai.zerogpu:android-sdk AAR.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",