@xybrid/react-native 0.10.1 → 0.13.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 +3 -2
- package/android/build.gradle +1 -1
- package/android/src/main/java/ai/xybrid/reactnative/XybridModule.kt +4 -1
- package/ios/XybridModuleImpl.swift +3 -1
- package/ios/XybridSwift/Xybrid.swift +18 -8
- package/ios/XybridSwift/xybrid_bolt.swift +58 -13
- package/lib/commonjs/model.js +8 -4
- package/lib/commonjs/xybrid.js +3 -3
- package/lib/module/model.js +8 -4
- package/lib/module/xybrid.js +3 -3
- package/lib/typescript/model.d.ts +8 -4
- package/lib/typescript/model.d.ts.map +1 -1
- package/lib/typescript/xybrid.d.ts +3 -3
- package/package.json +2 -2
- package/src/model.ts +8 -4
- package/src/xybrid.ts +3 -3
package/README.md
CHANGED
|
@@ -215,8 +215,9 @@ const download = await loader.download();
|
|
|
215
215
|
for await (const status of download!.progress()) setProgress(status.progress);
|
|
216
216
|
const model = await loader.load();
|
|
217
217
|
|
|
218
|
-
// Answer from the cloud while the weights download (needs an API key
|
|
219
|
-
|
|
218
|
+
// Answer from the cloud while the weights download (needs an API key and a
|
|
219
|
+
// chat model the registry serves as a direct GGUF download).
|
|
220
|
+
const fast = await ModelLoader.fromRegistrySpeculative('lfm2.5-350m').load();
|
|
220
221
|
await fast.isCloudServing(); // true until the local weights land
|
|
221
222
|
|
|
222
223
|
await Xybrid.modelCacheStatus(); // bytes and models on disk
|
package/android/build.gradle
CHANGED
|
@@ -429,9 +429,12 @@ class XybridModule(reactContext: ReactApplicationContext) : NativeXybridSpec(rea
|
|
|
429
429
|
handles.dispose(stream)
|
|
430
430
|
mapOf("kind" to "complete", "result" to XybridCodec.encodeResult(result))
|
|
431
431
|
}
|
|
432
|
+
XybridStreamEventKind.AUDIO -> throw BridgeException.InvalidArgument(
|
|
433
|
+
"Token streams cannot deliver audio; use run for batch speech"
|
|
434
|
+
)
|
|
432
435
|
}
|
|
433
436
|
} catch (t: Throwable) {
|
|
434
|
-
//
|
|
437
|
+
// Dispose also aborts a stream rejected for an unsupported event.
|
|
435
438
|
handles.dispose(stream)
|
|
436
439
|
throw cancellationAware(t, s.cancel)
|
|
437
440
|
}
|
|
@@ -616,9 +616,11 @@ public final class XybridModuleImpl: NSObject {
|
|
|
616
616
|
let result = try entry.model.streamResult(streamId: entry.streamId)
|
|
617
617
|
handles.dispose(stream)
|
|
618
618
|
return ["kind": "complete", "result": XybridCodec.encodeResult(result)] as JSObject
|
|
619
|
+
case .audio:
|
|
620
|
+
throw BridgeError.invalidArgument("Token streams cannot deliver audio; use run for batch speech")
|
|
619
621
|
}
|
|
620
622
|
} catch {
|
|
621
|
-
//
|
|
623
|
+
// Dispose also aborts a stream rejected for an unsupported event.
|
|
622
624
|
handles.dispose(stream)
|
|
623
625
|
throw Self.cancellationAware(error, entry.cancel)
|
|
624
626
|
}
|
|
@@ -162,8 +162,9 @@ public enum Xybrid {
|
|
|
162
162
|
/// ``ModelLoader/fromRegistrySpeculative(_:)`` opts in explicitly and is
|
|
163
163
|
/// unaffected by this toggle. Off by default. Either way, speculation also
|
|
164
164
|
/// needs a resolvable API key and a model that is not already cached —
|
|
165
|
-
/// ``ModelLoader/willSpeculate``
|
|
166
|
-
///
|
|
165
|
+
/// ``ModelLoader/willSpeculate`` checks both for a specific loader — and
|
|
166
|
+
/// the load asks the registry first, so only chat models are served this
|
|
167
|
+
/// way.
|
|
167
168
|
public static func setSpeculativeCloud(_ enabled: Bool) {
|
|
168
169
|
boltSetSpeculativeCloud(enabled)
|
|
169
170
|
}
|
|
@@ -366,9 +367,10 @@ public struct ModelLoader: Sendable {
|
|
|
366
367
|
///
|
|
367
368
|
/// ``load()`` returns almost immediately with a cloud-backed model that
|
|
368
369
|
/// switches to on-device by itself once the download lands. Requires an API
|
|
369
|
-
/// key
|
|
370
|
-
///
|
|
371
|
-
///
|
|
370
|
+
/// key, an uncached model, and a chat model the registry serves as a direct
|
|
371
|
+
/// download (GGUF or vision-language, not a `.xyb` bundle) — otherwise it
|
|
372
|
+
/// behaves exactly like ``fromRegistry(_:)``. ``willSpeculate`` checks the
|
|
373
|
+
/// first two up front.
|
|
372
374
|
///
|
|
373
375
|
/// Track the handover with ``XybridModel/isCloudServing()``,
|
|
374
376
|
/// ``XybridModel/downloadStatus()`` and ``XybridModel/awaitDownload(timeoutMs:)``.
|
|
@@ -376,10 +378,13 @@ public struct ModelLoader: Sendable {
|
|
|
376
378
|
Self(source: .registrySpeculative(id))
|
|
377
379
|
}
|
|
378
380
|
|
|
379
|
-
/// Whether ``load()``
|
|
380
|
-
///
|
|
381
|
+
/// Whether ``load()`` may speculate: speculation is possible for this
|
|
382
|
+
/// source, an API key resolves, and the model is not already cached.
|
|
381
383
|
///
|
|
382
|
-
/// Always `false` for non-speculative sources. Never touches the network
|
|
384
|
+
/// Always `false` for non-speculative sources. Never touches the network,
|
|
385
|
+
/// so it cannot know the model type: ``load()`` asks the registry and
|
|
386
|
+
/// speculates only for a chat model. ``XybridModel/isCloudServing()``
|
|
387
|
+
/// reports the outcome.
|
|
383
388
|
public var willSpeculate: Bool {
|
|
384
389
|
guard case .registrySpeculative(let id) = source else { return false }
|
|
385
390
|
return willSpeculateForModel(modelId: id)
|
|
@@ -643,6 +648,11 @@ private final class XybridTokenStreamState: @unchecked Sendable {
|
|
|
643
648
|
case .complete:
|
|
644
649
|
close()
|
|
645
650
|
return nil
|
|
651
|
+
case .audio:
|
|
652
|
+
close()
|
|
653
|
+
throw XybridError.inferenceError(
|
|
654
|
+
message: "Token streams cannot deliver audio; use run for batch speech"
|
|
655
|
+
)
|
|
646
656
|
}
|
|
647
657
|
}
|
|
648
658
|
|
|
@@ -592,6 +592,42 @@ public struct XybridStreamToken: Hashable, Equatable, Sendable {
|
|
|
592
592
|
}
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
+
/// Owned PCM16 LE packet. Offsets count samples per channel.
|
|
596
|
+
public struct XybridTtsAudioChunk: Hashable, Equatable, Sendable {
|
|
597
|
+
public var pcm: Data
|
|
598
|
+
public var sampleRate: UInt32
|
|
599
|
+
public var channels: UInt32
|
|
600
|
+
public var firstSample: UInt64
|
|
601
|
+
|
|
602
|
+
public init(
|
|
603
|
+
pcm: Data,
|
|
604
|
+
sampleRate: UInt32,
|
|
605
|
+
channels: UInt32,
|
|
606
|
+
firstSample: UInt64
|
|
607
|
+
) {
|
|
608
|
+
self.pcm = pcm
|
|
609
|
+
self.sampleRate = sampleRate
|
|
610
|
+
self.channels = channels
|
|
611
|
+
self.firstSample = firstSample
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
@inlinable static func decode(from reader: inout WireReader) -> XybridTtsAudioChunk {
|
|
615
|
+
XybridTtsAudioChunk(
|
|
616
|
+
pcm: reader.readBytes(),
|
|
617
|
+
sampleRate: reader.readU32(),
|
|
618
|
+
channels: reader.readU32(),
|
|
619
|
+
firstSample: reader.readU64()
|
|
620
|
+
)
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
@inlinable func encode(to writer: inout WireWriter) {
|
|
624
|
+
writer.writeBytes(self.pcm)
|
|
625
|
+
writer.writeU32(self.sampleRate)
|
|
626
|
+
writer.writeU32(self.channels)
|
|
627
|
+
writer.writeU64(self.firstSample)
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
595
631
|
/// One pull from a streaming inference session.
|
|
596
632
|
///
|
|
597
633
|
/// This is a flat record instead of a data-carrying enum because the pinned
|
|
@@ -603,19 +639,22 @@ public struct XybridStreamToken: Hashable, Equatable, Sendable {
|
|
|
603
639
|
public struct XybridStreamEvent: Hashable, Equatable, Sendable {
|
|
604
640
|
public var kind: XybridStreamEventKind
|
|
605
641
|
public var token: XybridStreamToken?
|
|
642
|
+
public var audio: XybridTtsAudioChunk?
|
|
606
643
|
|
|
607
|
-
public init(kind: XybridStreamEventKind, token: XybridStreamToken?) {
|
|
644
|
+
public init(kind: XybridStreamEventKind, token: XybridStreamToken?, audio: XybridTtsAudioChunk?) {
|
|
608
645
|
self.kind = kind
|
|
609
646
|
self.token = token
|
|
647
|
+
self.audio = audio
|
|
610
648
|
}
|
|
611
649
|
|
|
612
650
|
@inlinable static func decode(from reader: inout WireReader) -> XybridStreamEvent {
|
|
613
|
-
XybridStreamEvent(kind: XybridStreamEventKind(rawValue: reader.readI32())!, token: reader.readOptional { reader in XybridStreamToken.decode(from: &reader) })
|
|
651
|
+
XybridStreamEvent(kind: XybridStreamEventKind(rawValue: reader.readI32())!, token: reader.readOptional { reader in XybridStreamToken.decode(from: &reader) }, audio: reader.readOptional { reader in XybridTtsAudioChunk.decode(from: &reader) })
|
|
614
652
|
}
|
|
615
653
|
|
|
616
654
|
@inlinable func encode(to writer: inout WireWriter) {
|
|
617
655
|
writer.writeI32(self.kind.rawValue)
|
|
618
656
|
writer.writeOptional(self.token) { writer, boltffiValue0 in boltffiValue0.encode(to: &writer) }
|
|
657
|
+
writer.writeOptional(self.audio) { writer, boltffiValue0 in boltffiValue0.encode(to: &writer) }
|
|
619
658
|
}
|
|
620
659
|
}
|
|
621
660
|
|
|
@@ -1122,6 +1161,7 @@ public enum XybridDownloadState: Int32, Hashable, Sendable, CaseIterable {
|
|
|
1122
1161
|
public enum XybridStreamEventKind: Int32, Hashable, Sendable, CaseIterable {
|
|
1123
1162
|
case token = 0
|
|
1124
1163
|
case complete = 1
|
|
1164
|
+
case audio = 2
|
|
1125
1165
|
|
|
1126
1166
|
@usableFromInline init(fromC c: Int32) {
|
|
1127
1167
|
self = XybridStreamEventKind(rawValue: c)!
|
|
@@ -1414,9 +1454,11 @@ public final class XybridModel {
|
|
|
1414
1454
|
/// download in the background.
|
|
1415
1455
|
///
|
|
1416
1456
|
/// Returns almost immediately instead of blocking on the download. Requires
|
|
1417
|
-
/// a resolvable API key
|
|
1418
|
-
///
|
|
1419
|
-
///
|
|
1457
|
+
/// a resolvable API key, an uncached model, and a chat model the registry
|
|
1458
|
+
/// serves as a direct download (GGUF or vision-language, not a `.xyb`
|
|
1459
|
+
/// bundle); otherwise it behaves exactly like `from_registry`. Poll
|
|
1460
|
+
/// `download_status` for progress and `is_cloud_serving` to know which leg
|
|
1461
|
+
/// is answering.
|
|
1420
1462
|
public init(fromRegistrySpeculative id: String) throws {
|
|
1421
1463
|
let boltffiIdBytes = boltffiEncode { boltffiIdWriter in boltffiIdWriter.writeString(id) }
|
|
1422
1464
|
let boltffiHandle = try boltffiIdBytes.withUnsafeBufferPointer { boltffiIdBuffer in
|
|
@@ -2428,11 +2470,12 @@ public func setPlatformUrl(url: String) {
|
|
|
2428
2470
|
}
|
|
2429
2471
|
}
|
|
2430
2472
|
|
|
2431
|
-
/// Enable speculative cloud fallback globally: a registry model that
|
|
2432
|
-
/// downloaded yet is served from the gateway while the weights download.
|
|
2473
|
+
/// Enable speculative cloud fallback globally: a registry chat model that
|
|
2474
|
+
/// isn't downloaded yet is served from the gateway while the weights download.
|
|
2433
2475
|
///
|
|
2434
|
-
///
|
|
2435
|
-
///
|
|
2476
|
+
/// An uncached load asks the registry first, so other models (ASR, TTS,
|
|
2477
|
+
/// `.xyb` bundles) download and load as usual.
|
|
2478
|
+
/// `XybridModel.fromRegistrySpeculative` opts a single load in instead.
|
|
2436
2479
|
public func setSpeculativeCloud(enabled: Bool) {
|
|
2437
2480
|
boltffi_function_xybrid_bolt_set_speculative_cloud(enabled)
|
|
2438
2481
|
}
|
|
@@ -2447,11 +2490,13 @@ public func isSpeculativeCloudEnabled() -> Bool {
|
|
|
2447
2490
|
return boltffi_function_xybrid_bolt_is_speculative_cloud_enabled()
|
|
2448
2491
|
}
|
|
2449
2492
|
|
|
2450
|
-
/// Whether `XybridModel::from_registry_speculative(model_id)`
|
|
2451
|
-
///
|
|
2493
|
+
/// Whether `XybridModel::from_registry_speculative(model_id)` may speculate:
|
|
2494
|
+
/// an API key resolves and the model is not already cached.
|
|
2452
2495
|
///
|
|
2453
|
-
/// Lets the hand-written Swift/Kotlin loader facades answer "
|
|
2454
|
-
/// speculate?" before loading. Never touches the network
|
|
2496
|
+
/// Lets the hand-written Swift/Kotlin loader facades answer "can this
|
|
2497
|
+
/// speculate?" before loading. Never touches the network, so it cannot know
|
|
2498
|
+
/// the model type: the load asks the registry and speculates only for a chat
|
|
2499
|
+
/// model.
|
|
2455
2500
|
public func willSpeculateForModel(modelId: String) -> Bool {
|
|
2456
2501
|
let boltffiModelIdBytes = boltffiEncode { boltffiModelIdWriter in boltffiModelIdWriter.writeString(modelId) }
|
|
2457
2502
|
return boltffiModelIdBytes.withUnsafeBufferPointer { boltffiModelIdBuffer in
|
package/lib/commonjs/model.js
CHANGED
|
@@ -45,8 +45,10 @@ class ModelLoader {
|
|
|
45
45
|
* Serve from the cloud gateway while the registry weights download in the
|
|
46
46
|
* background, instead of blocking on the download. `load()` then resolves
|
|
47
47
|
* almost immediately with a model that switches to on-device by itself.
|
|
48
|
-
* Needs an API key
|
|
49
|
-
*
|
|
48
|
+
* Needs an API key, an uncached model ({@link willSpeculate} checks both up
|
|
49
|
+
* front) and a chat model the registry serves as a direct download (GGUF or
|
|
50
|
+
* vision-language, not a `.xyb` bundle) — otherwise it behaves like
|
|
51
|
+
* {@link fromRegistry}.
|
|
50
52
|
*/
|
|
51
53
|
static fromRegistrySpeculative(id) {
|
|
52
54
|
return new ModelLoader({ kind: 'registrySpeculative', id });
|
|
@@ -72,8 +74,10 @@ class ModelLoader {
|
|
|
72
74
|
return new Model(await NativeXybrid_1.default.loadModel(toWireSource(this.source)));
|
|
73
75
|
}
|
|
74
76
|
/**
|
|
75
|
-
* Whether {@link load}
|
|
76
|
-
*
|
|
77
|
+
* Whether {@link load} may speculate: a speculative source, an API key, and
|
|
78
|
+
* a model not yet cached. Never touches the network, so it cannot know the
|
|
79
|
+
* model type: `load()` asks the registry and speculates only for a chat
|
|
80
|
+
* model. `isCloudServing()` on the loaded model reports the outcome.
|
|
77
81
|
*/
|
|
78
82
|
async willSpeculate() {
|
|
79
83
|
if (this.source.kind !== 'registrySpeculative')
|
package/lib/commonjs/xybrid.js
CHANGED
|
@@ -50,9 +50,9 @@ exports.Xybrid = {
|
|
|
50
50
|
},
|
|
51
51
|
/**
|
|
52
52
|
* Default speculative cloud serving on or off for loads that don't opt in
|
|
53
|
-
* per load (`ModelLoader.fromRegistrySpeculative`
|
|
54
|
-
*
|
|
55
|
-
*
|
|
53
|
+
* per load (`ModelLoader.fromRegistrySpeculative` opts in itself). Needs an
|
|
54
|
+
* API key. An uncached load asks the registry first, so only chat models
|
|
55
|
+
* are served this way; ASR, TTS and `.xyb` bundles load as usual.
|
|
56
56
|
*/
|
|
57
57
|
setSpeculativeCloud(enabled) {
|
|
58
58
|
return NativeXybrid_1.default.setSpeculativeCloud(enabled);
|
package/lib/module/model.js
CHANGED
|
@@ -39,8 +39,10 @@ export class ModelLoader {
|
|
|
39
39
|
* Serve from the cloud gateway while the registry weights download in the
|
|
40
40
|
* background, instead of blocking on the download. `load()` then resolves
|
|
41
41
|
* almost immediately with a model that switches to on-device by itself.
|
|
42
|
-
* Needs an API key
|
|
43
|
-
*
|
|
42
|
+
* Needs an API key, an uncached model ({@link willSpeculate} checks both up
|
|
43
|
+
* front) and a chat model the registry serves as a direct download (GGUF or
|
|
44
|
+
* vision-language, not a `.xyb` bundle) — otherwise it behaves like
|
|
45
|
+
* {@link fromRegistry}.
|
|
44
46
|
*/
|
|
45
47
|
static fromRegistrySpeculative(id) {
|
|
46
48
|
return new ModelLoader({ kind: 'registrySpeculative', id });
|
|
@@ -66,8 +68,10 @@ export class ModelLoader {
|
|
|
66
68
|
return new Model(await NativeXybrid.loadModel(toWireSource(this.source)));
|
|
67
69
|
}
|
|
68
70
|
/**
|
|
69
|
-
* Whether {@link load}
|
|
70
|
-
*
|
|
71
|
+
* Whether {@link load} may speculate: a speculative source, an API key, and
|
|
72
|
+
* a model not yet cached. Never touches the network, so it cannot know the
|
|
73
|
+
* model type: `load()` asks the registry and speculates only for a chat
|
|
74
|
+
* model. `isCloudServing()` on the loaded model reports the outcome.
|
|
71
75
|
*/
|
|
72
76
|
async willSpeculate() {
|
|
73
77
|
if (this.source.kind !== 'registrySpeculative')
|
package/lib/module/xybrid.js
CHANGED
|
@@ -44,9 +44,9 @@ export const Xybrid = {
|
|
|
44
44
|
},
|
|
45
45
|
/**
|
|
46
46
|
* Default speculative cloud serving on or off for loads that don't opt in
|
|
47
|
-
* per load (`ModelLoader.fromRegistrySpeculative`
|
|
48
|
-
*
|
|
49
|
-
*
|
|
47
|
+
* per load (`ModelLoader.fromRegistrySpeculative` opts in itself). Needs an
|
|
48
|
+
* API key. An uncached load asks the registry first, so only chat models
|
|
49
|
+
* are served this way; ASR, TTS and `.xyb` bundles load as usual.
|
|
50
50
|
*/
|
|
51
51
|
setSpeculativeCloud(enabled) {
|
|
52
52
|
return NativeXybrid.setSpeculativeCloud(enabled);
|
|
@@ -66,8 +66,10 @@ export declare class ModelLoader {
|
|
|
66
66
|
* Serve from the cloud gateway while the registry weights download in the
|
|
67
67
|
* background, instead of blocking on the download. `load()` then resolves
|
|
68
68
|
* almost immediately with a model that switches to on-device by itself.
|
|
69
|
-
* Needs an API key
|
|
70
|
-
*
|
|
69
|
+
* Needs an API key, an uncached model ({@link willSpeculate} checks both up
|
|
70
|
+
* front) and a chat model the registry serves as a direct download (GGUF or
|
|
71
|
+
* vision-language, not a `.xyb` bundle) — otherwise it behaves like
|
|
72
|
+
* {@link fromRegistry}.
|
|
71
73
|
*/
|
|
72
74
|
static fromRegistrySpeculative(id: string): ModelLoader;
|
|
73
75
|
/** A local `.xyb` bundle. */
|
|
@@ -83,8 +85,10 @@ export declare class ModelLoader {
|
|
|
83
85
|
/** Resolve, download if needed, and load. Rejects with a typed `xybrid_*` code. */
|
|
84
86
|
load(): Promise<Model>;
|
|
85
87
|
/**
|
|
86
|
-
* Whether {@link load}
|
|
87
|
-
*
|
|
88
|
+
* Whether {@link load} may speculate: a speculative source, an API key, and
|
|
89
|
+
* a model not yet cached. Never touches the network, so it cannot know the
|
|
90
|
+
* model type: `load()` asks the registry and speculates only for a chat
|
|
91
|
+
* model. `isCloudServing()` on the loaded model reports the outcome.
|
|
88
92
|
*/
|
|
89
93
|
willSpeculate(): Promise<boolean>;
|
|
90
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACV,MAAM,SAAS,CAAC;AAYjB;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,sDAAsD;IACtD,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,kFAAkF;AAClF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBxC;;;GAGG;AACH,qBAAa,WAAW;IACF,QAAQ,CAAC,MAAM,EAAE,WAAW;IAAhD,OAAO;IAEP,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;IAI7C,8DAA8D;IAC9D,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW;IAI5C
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,9 +46,9 @@ export declare const Xybrid: {
|
|
|
46
46
|
setPlatformUrl(url: string): Promise<void>;
|
|
47
47
|
/**
|
|
48
48
|
* Default speculative cloud serving on or off for loads that don't opt in
|
|
49
|
-
* per load (`ModelLoader.fromRegistrySpeculative`
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
* per load (`ModelLoader.fromRegistrySpeculative` opts in itself). Needs an
|
|
50
|
+
* API key. An uncached load asks the registry first, so only chat models
|
|
51
|
+
* are served this way; ASR, TTS and `.xyb` bundles load as usual.
|
|
52
52
|
*/
|
|
53
53
|
setSpeculativeCloud(enabled: boolean): Promise<void>;
|
|
54
54
|
isSpeculativeCloudEnabled(): Promise<boolean>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xybrid/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "On-device (and optionally cloud) ML inference for React Native: LLM, ASR, TTS, embeddings and vision, backed by the Xybrid Rust SDK",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"typescript": "^5.9.3"
|
|
71
71
|
},
|
|
72
72
|
"xybrid": {
|
|
73
|
-
"iosXcframeworkSha256": "
|
|
73
|
+
"iosXcframeworkSha256": "a3a6abdadeea791a4fcc3fc005746b9115fced514725a0faf657774a22652ad9"
|
|
74
74
|
},
|
|
75
75
|
"codegenConfig": {
|
|
76
76
|
"name": "RNXybridSpec",
|
package/src/model.ts
CHANGED
|
@@ -101,8 +101,10 @@ export class ModelLoader {
|
|
|
101
101
|
* Serve from the cloud gateway while the registry weights download in the
|
|
102
102
|
* background, instead of blocking on the download. `load()` then resolves
|
|
103
103
|
* almost immediately with a model that switches to on-device by itself.
|
|
104
|
-
* Needs an API key
|
|
105
|
-
*
|
|
104
|
+
* Needs an API key, an uncached model ({@link willSpeculate} checks both up
|
|
105
|
+
* front) and a chat model the registry serves as a direct download (GGUF or
|
|
106
|
+
* vision-language, not a `.xyb` bundle) — otherwise it behaves like
|
|
107
|
+
* {@link fromRegistry}.
|
|
106
108
|
*/
|
|
107
109
|
static fromRegistrySpeculative(id: string): ModelLoader {
|
|
108
110
|
return new ModelLoader({ kind: 'registrySpeculative', id });
|
|
@@ -134,8 +136,10 @@ export class ModelLoader {
|
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
/**
|
|
137
|
-
* Whether {@link load}
|
|
138
|
-
*
|
|
139
|
+
* Whether {@link load} may speculate: a speculative source, an API key, and
|
|
140
|
+
* a model not yet cached. Never touches the network, so it cannot know the
|
|
141
|
+
* model type: `load()` asks the registry and speculates only for a chat
|
|
142
|
+
* model. `isCloudServing()` on the loaded model reports the outcome.
|
|
139
143
|
*/
|
|
140
144
|
async willSpeculate(): Promise<boolean> {
|
|
141
145
|
if (this.source.kind !== 'registrySpeculative') return false;
|
package/src/xybrid.ts
CHANGED
|
@@ -75,9 +75,9 @@ export const Xybrid = {
|
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Default speculative cloud serving on or off for loads that don't opt in
|
|
78
|
-
* per load (`ModelLoader.fromRegistrySpeculative`
|
|
79
|
-
*
|
|
80
|
-
*
|
|
78
|
+
* per load (`ModelLoader.fromRegistrySpeculative` opts in itself). Needs an
|
|
79
|
+
* API key. An uncached load asks the registry first, so only chat models
|
|
80
|
+
* are served this way; ASR, TTS and `.xyb` bundles load as usual.
|
|
81
81
|
*/
|
|
82
82
|
setSpeculativeCloud(enabled: boolean): Promise<void> {
|
|
83
83
|
return NativeXybrid.setSpeculativeCloud(enabled);
|