feature/example
swift 2,931 lines 91 KB
Raw
1 // This file was autogenerated by some hot garbage in the `uniffi` crate.
2 // Trust me, you don't want to mess with it!
3
4 // swiftlint:disable all
5 import Foundation
6
7 // Depending on the consumer's build setup, the low-level FFI code
8 // might be in a separate module, or it might be compiled inline into
9 // this module. This is a bit of light hackery to work with both.
10 #if canImport(ondeFFI)
11 import ondeFFI
12 #endif
13
14 fileprivate extension RustBuffer {
15 // Allocate a new buffer, copying the contents of a `UInt8` array.
16 init(bytes: [UInt8]) {
17 let rbuf = bytes.withUnsafeBufferPointer { ptr in
18 RustBuffer.from(ptr)
19 }
20 self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
21 }
22
23 static func empty() -> RustBuffer {
24 RustBuffer(capacity: 0, len:0, data: nil)
25 }
26
27 static func from(_ ptr: UnsafeBufferPointer<UInt8>) -> RustBuffer {
28 try! rustCall { ffi_onde_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
29 }
30
31 // Frees the buffer in place.
32 // The buffer must not be used after this is called.
33 func deallocate() {
34 try! rustCall { ffi_onde_rustbuffer_free(self, $0) }
35 }
36 }
37
38 fileprivate extension ForeignBytes {
39 init(bufferPointer: UnsafeBufferPointer<UInt8>) {
40 self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress)
41 }
42 }
43
44 // For every type used in the interface, we provide helper methods for conveniently
45 // lifting and lowering that type from C-compatible data, and for reading and writing
46 // values of that type in a buffer.
47
48 // Helper classes/extensions that don't change.
49 // Someday, this will be in a library of its own.
50
51 fileprivate extension Data {
52 init(rustBuffer: RustBuffer) {
53 self.init(
54 bytesNoCopy: rustBuffer.data!,
55 count: Int(rustBuffer.len),
56 deallocator: .none
57 )
58 }
59 }
60
61 // Define reader functionality. Normally this would be defined in a class or
62 // struct, but we use standalone functions instead in order to make external
63 // types work.
64 //
65 // With external types, one swift source file needs to be able to call the read
66 // method on another source file's FfiConverter, but then what visibility
67 // should Reader have?
68 // - If Reader is fileprivate, then this means the read() must also
69 // be fileprivate, which doesn't work with external types.
70 // - If Reader is internal/public, we'll get compile errors since both source
71 // files will try define the same type.
72 //
73 // Instead, the read() method and these helper functions input a tuple of data
74
75 fileprivate func createReader(data: Data) -> (data: Data, offset: Data.Index) {
76 (data: data, offset: 0)
77 }
78
79 // Reads an integer at the current offset, in big-endian order, and advances
80 // the offset on success. Throws if reading the integer would move the
81 // offset past the end of the buffer.
82 fileprivate func readInt<T: FixedWidthInteger>(_ reader: inout (data: Data, offset: Data.Index)) throws -> T {
83 let range = reader.offset..<reader.offset + MemoryLayout<T>.size
84 guard reader.data.count >= range.upperBound else {
85 throw UniffiInternalError.bufferOverflow
86 }
87 if T.self == UInt8.self {
88 let value = reader.data[reader.offset]
89 reader.offset += 1
90 return value as! T
91 }
92 var value: T = 0
93 let _ = withUnsafeMutableBytes(of: &value, { reader.data.copyBytes(to: $0, from: range)})
94 reader.offset = range.upperBound
95 return value.bigEndian
96 }
97
98 // Reads an arbitrary number of bytes, to be used to read
99 // raw bytes, this is useful when lifting strings
100 fileprivate func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> Array<UInt8> {
101 let range = reader.offset..<(reader.offset+count)
102 guard reader.data.count >= range.upperBound else {
103 throw UniffiInternalError.bufferOverflow
104 }
105 var value = [UInt8](repeating: 0, count: count)
106 value.withUnsafeMutableBufferPointer({ buffer in
107 reader.data.copyBytes(to: buffer, from: range)
108 })
109 reader.offset = range.upperBound
110 return value
111 }
112
113 // Reads a float at the current offset.
114 fileprivate func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float {
115 return Float(bitPattern: try readInt(&reader))
116 }
117
118 // Reads a float at the current offset.
119 fileprivate func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double {
120 return Double(bitPattern: try readInt(&reader))
121 }
122
123 // Indicates if the offset has reached the end of the buffer.
124 fileprivate func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool {
125 return reader.offset < reader.data.count
126 }
127
128 // Define writer functionality. Normally this would be defined in a class or
129 // struct, but we use standalone functions instead in order to make external
130 // types work. See the above discussion on Readers for details.
131
132 fileprivate func createWriter() -> [UInt8] {
133 return []
134 }
135
136 fileprivate func writeBytes<S>(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 {
137 writer.append(contentsOf: byteArr)
138 }
139
140 // Writes an integer in big-endian order.
141 //
142 // Warning: make sure what you are trying to write
143 // is in the correct type!
144 fileprivate func writeInt<T: FixedWidthInteger>(_ writer: inout [UInt8], _ value: T) {
145 var value = value.bigEndian
146 withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) }
147 }
148
149 fileprivate func writeFloat(_ writer: inout [UInt8], _ value: Float) {
150 writeInt(&writer, value.bitPattern)
151 }
152
153 fileprivate func writeDouble(_ writer: inout [UInt8], _ value: Double) {
154 writeInt(&writer, value.bitPattern)
155 }
156
157 // Protocol for types that transfer other types across the FFI. This is
158 // analogous to the Rust trait of the same name.
159 fileprivate protocol FfiConverter {
160 associatedtype FfiType
161 associatedtype SwiftType
162
163 static func lift(_ value: FfiType) throws -> SwiftType
164 static func lower(_ value: SwiftType) -> FfiType
165 static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType
166 static func write(_ value: SwiftType, into buf: inout [UInt8])
167 }
168
169 // Types conforming to `Primitive` pass themselves directly over the FFI.
170 fileprivate protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType { }
171
172 extension FfiConverterPrimitive {
173 #if swift(>=5.8)
174 @_documentation(visibility: private)
175 #endif
176 public static func lift(_ value: FfiType) throws -> SwiftType {
177 return value
178 }
179
180 #if swift(>=5.8)
181 @_documentation(visibility: private)
182 #endif
183 public static func lower(_ value: SwiftType) -> FfiType {
184 return value
185 }
186 }
187
188 // Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`.
189 // Used for complex types where it's hard to write a custom lift/lower.
190 fileprivate protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {}
191
192 extension FfiConverterRustBuffer {
193 #if swift(>=5.8)
194 @_documentation(visibility: private)
195 #endif
196 public static func lift(_ buf: RustBuffer) throws -> SwiftType {
197 var reader = createReader(data: Data(rustBuffer: buf))
198 let value = try read(from: &reader)
199 if hasRemaining(reader) {
200 throw UniffiInternalError.incompleteData
201 }
202 buf.deallocate()
203 return value
204 }
205
206 #if swift(>=5.8)
207 @_documentation(visibility: private)
208 #endif
209 public static func lower(_ value: SwiftType) -> RustBuffer {
210 var writer = createWriter()
211 write(value, into: &writer)
212 return RustBuffer(bytes: writer)
213 }
214 }
215 // An error type for FFI errors. These errors occur at the UniFFI level, not
216 // the library level.
217 fileprivate enum UniffiInternalError: LocalizedError {
218 case bufferOverflow
219 case incompleteData
220 case unexpectedOptionalTag
221 case unexpectedEnumCase
222 case unexpectedNullPointer
223 case unexpectedRustCallStatusCode
224 case unexpectedRustCallError
225 case unexpectedStaleHandle
226 case rustPanic(_ message: String)
227
228 public var errorDescription: String? {
229 switch self {
230 case .bufferOverflow: return "Reading the requested value would read past the end of the buffer"
231 case .incompleteData: return "The buffer still has data after lifting its containing value"
232 case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1"
233 case .unexpectedEnumCase: return "Raw enum value doesn't match any cases"
234 case .unexpectedNullPointer: return "Raw pointer value was null"
235 case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code"
236 case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified"
237 case .unexpectedStaleHandle: return "The object in the handle map has been dropped already"
238 case let .rustPanic(message): return message
239 }
240 }
241 }
242
243 fileprivate extension NSLock {
244 func withLock<T>(f: () throws -> T) rethrows -> T {
245 self.lock()
246 defer { self.unlock() }
247 return try f()
248 }
249 }
250
251 fileprivate let CALL_SUCCESS: Int8 = 0
252 fileprivate let CALL_ERROR: Int8 = 1
253 fileprivate let CALL_UNEXPECTED_ERROR: Int8 = 2
254 fileprivate let CALL_CANCELLED: Int8 = 3
255
256 fileprivate extension RustCallStatus {
257 init() {
258 self.init(
259 code: CALL_SUCCESS,
260 errorBuf: RustBuffer.init(
261 capacity: 0,
262 len: 0,
263 data: nil
264 )
265 )
266 }
267 }
268
269 private func rustCall<T>(_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
270 let neverThrow: ((RustBuffer) throws -> Never)? = nil
271 return try makeRustCall(callback, errorHandler: neverThrow)
272 }
273
274 private func rustCallWithError<T, E: Swift.Error>(
275 _ errorHandler: @escaping (RustBuffer) throws -> E,
276 _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
277 try makeRustCall(callback, errorHandler: errorHandler)
278 }
279
280 private func makeRustCall<T, E: Swift.Error>(
281 _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T,
282 errorHandler: ((RustBuffer) throws -> E)?
283 ) throws -> T {
284 uniffiEnsureOndeInitialized()
285 var callStatus = RustCallStatus.init()
286 let returnedVal = callback(&callStatus)
287 try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler)
288 return returnedVal
289 }
290
291 private func uniffiCheckCallStatus<E: Swift.Error>(
292 callStatus: RustCallStatus,
293 errorHandler: ((RustBuffer) throws -> E)?
294 ) throws {
295 switch callStatus.code {
296 case CALL_SUCCESS:
297 return
298
299 case CALL_ERROR:
300 if let errorHandler = errorHandler {
301 throw try errorHandler(callStatus.errorBuf)
302 } else {
303 callStatus.errorBuf.deallocate()
304 throw UniffiInternalError.unexpectedRustCallError
305 }
306
307 case CALL_UNEXPECTED_ERROR:
308 // When the rust code sees a panic, it tries to construct a RustBuffer
309 // with the message. But if that code panics, then it just sends back
310 // an empty buffer.
311 if callStatus.errorBuf.len > 0 {
312 throw UniffiInternalError.rustPanic(try FfiConverterString.lift(callStatus.errorBuf))
313 } else {
314 callStatus.errorBuf.deallocate()
315 throw UniffiInternalError.rustPanic("Rust panic")
316 }
317
318 case CALL_CANCELLED:
319 fatalError("Cancellation not supported yet")
320
321 default:
322 throw UniffiInternalError.unexpectedRustCallStatusCode
323 }
324 }
325
326 private func uniffiTraitInterfaceCall<T>(
327 callStatus: UnsafeMutablePointer<RustCallStatus>,
328 makeCall: () throws -> T,
329 writeReturn: (T) -> ()
330 ) {
331 do {
332 try writeReturn(makeCall())
333 } catch let error {
334 callStatus.pointee.code = CALL_UNEXPECTED_ERROR
335 callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
336 }
337 }
338
339 private func uniffiTraitInterfaceCallWithError<T, E>(
340 callStatus: UnsafeMutablePointer<RustCallStatus>,
341 makeCall: () throws -> T,
342 writeReturn: (T) -> (),
343 lowerError: (E) -> RustBuffer
344 ) {
345 do {
346 try writeReturn(makeCall())
347 } catch let error as E {
348 callStatus.pointee.code = CALL_ERROR
349 callStatus.pointee.errorBuf = lowerError(error)
350 } catch {
351 callStatus.pointee.code = CALL_UNEXPECTED_ERROR
352 callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
353 }
354 }
355 // Initial value and increment amount for handles.
356 // These ensure that SWIFT handles always have the lowest bit set
357 fileprivate let UNIFFI_HANDLEMAP_INITIAL: UInt64 = 1
358 fileprivate let UNIFFI_HANDLEMAP_DELTA: UInt64 = 2
359
360 fileprivate final class UniffiHandleMap<T>: @unchecked Sendable {
361 // All mutation happens with this lock held, which is why we implement @unchecked Sendable.
362 private let lock = NSLock()
363 private var map: [UInt64: T] = [:]
364 private var currentHandle: UInt64 = UNIFFI_HANDLEMAP_INITIAL
365
366 func insert(obj: T) -> UInt64 {
367 lock.withLock {
368 return doInsert(obj)
369 }
370 }
371
372 // Low-level insert function, this assumes `lock` is held.
373 private func doInsert(_ obj: T) -> UInt64 {
374 let handle = currentHandle
375 currentHandle += UNIFFI_HANDLEMAP_DELTA
376 map[handle] = obj
377 return handle
378 }
379
380 func get(handle: UInt64) throws -> T {
381 try lock.withLock {
382 guard let obj = map[handle] else {
383 throw UniffiInternalError.unexpectedStaleHandle
384 }
385 return obj
386 }
387 }
388
389 func clone(handle: UInt64) throws -> UInt64 {
390 try lock.withLock {
391 guard let obj = map[handle] else {
392 throw UniffiInternalError.unexpectedStaleHandle
393 }
394 return doInsert(obj)
395 }
396 }
397
398 @discardableResult
399 func remove(handle: UInt64) throws -> T {
400 try lock.withLock {
401 guard let obj = map.removeValue(forKey: handle) else {
402 throw UniffiInternalError.unexpectedStaleHandle
403 }
404 return obj
405 }
406 }
407
408 var count: Int {
409 get {
410 map.count
411 }
412 }
413 }
414
415
416 // Public interface members begin here.
417 // Magic number for the Rust proxy to call using the same mechanism as every other method,
418 // to free the callback once it's dropped by Rust.
419 private let IDX_CALLBACK_FREE: Int32 = 0
420 // Callback return codes
421 private let UNIFFI_CALLBACK_SUCCESS: Int32 = 0
422 private let UNIFFI_CALLBACK_ERROR: Int32 = 1
423 private let UNIFFI_CALLBACK_UNEXPECTED_ERROR: Int32 = 2
424
425 #if swift(>=5.8)
426 @_documentation(visibility: private)
427 #endif
428 fileprivate struct FfiConverterUInt8: FfiConverterPrimitive {
429 typealias FfiType = UInt8
430 typealias SwiftType = UInt8
431
432 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt8 {
433 return try lift(readInt(&buf))
434 }
435
436 public static func write(_ value: UInt8, into buf: inout [UInt8]) {
437 writeInt(&buf, lower(value))
438 }
439 }
440
441 #if swift(>=5.8)
442 @_documentation(visibility: private)
443 #endif
444 fileprivate struct FfiConverterUInt64: FfiConverterPrimitive {
445 typealias FfiType = UInt64
446 typealias SwiftType = UInt64
447
448 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt64 {
449 return try lift(readInt(&buf))
450 }
451
452 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
453 writeInt(&buf, lower(value))
454 }
455 }
456
457 #if swift(>=5.8)
458 @_documentation(visibility: private)
459 #endif
460 fileprivate struct FfiConverterFloat: FfiConverterPrimitive {
461 typealias FfiType = Float
462 typealias SwiftType = Float
463
464 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Float {
465 return try lift(readFloat(&buf))
466 }
467
468 public static func write(_ value: Float, into buf: inout [UInt8]) {
469 writeFloat(&buf, lower(value))
470 }
471 }
472
473 #if swift(>=5.8)
474 @_documentation(visibility: private)
475 #endif
476 fileprivate struct FfiConverterDouble: FfiConverterPrimitive {
477 typealias FfiType = Double
478 typealias SwiftType = Double
479
480 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Double {
481 return try lift(readDouble(&buf))
482 }
483
484 public static func write(_ value: Double, into buf: inout [UInt8]) {
485 writeDouble(&buf, lower(value))
486 }
487 }
488
489 #if swift(>=5.8)
490 @_documentation(visibility: private)
491 #endif
492 fileprivate struct FfiConverterBool : FfiConverter {
493 typealias FfiType = Int8
494 typealias SwiftType = Bool
495
496 public static func lift(_ value: Int8) throws -> Bool {
497 return value != 0
498 }
499
500 public static func lower(_ value: Bool) -> Int8 {
501 return value ? 1 : 0
502 }
503
504 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Bool {
505 return try lift(readInt(&buf))
506 }
507
508 public static func write(_ value: Bool, into buf: inout [UInt8]) {
509 writeInt(&buf, lower(value))
510 }
511 }
512
513 #if swift(>=5.8)
514 @_documentation(visibility: private)
515 #endif
516 fileprivate struct FfiConverterString: FfiConverter {
517 typealias SwiftType = String
518 typealias FfiType = RustBuffer
519
520 public static func lift(_ value: RustBuffer) throws -> String {
521 defer {
522 value.deallocate()
523 }
524 if value.data == nil {
525 return String()
526 }
527 let bytes = UnsafeBufferPointer<UInt8>(start: value.data!, count: Int(value.len))
528 return String(bytes: bytes, encoding: String.Encoding.utf8)!
529 }
530
531 public static func lower(_ value: String) -> RustBuffer {
532 return value.utf8CString.withUnsafeBufferPointer { ptr in
533 // The swift string gives us int8_t, we want uint8_t.
534 ptr.withMemoryRebound(to: UInt8.self) { ptr in
535 // The swift string gives us a trailing null byte, we don't want it.
536 let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1))
537 return RustBuffer.from(buf)
538 }
539 }
540 }
541
542 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String {
543 let len: Int32 = try readInt(&buf)
544 return String(bytes: try readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)!
545 }
546
547 public static func write(_ value: String, into buf: inout [UInt8]) {
548 let len = Int32(value.utf8.count)
549 writeInt(&buf, len)
550 writeBytes(&buf, value.utf8)
551 }
552 }
553
554
555
556
557 /**
558 * On-device LLM chat inference engine — UniFFI-exported wrapper.
559 *
560 * This is the primary entry point for Swift / Kotlin consumers. It wraps
561 * [`ChatEngine`] with FFI-safe method signatures (no generics, no Rust
562 * channels, concrete `String` parameters).
563 *
564 * Construct with [`OndeChatEngine::new()`]. The engine starts with no
565 * model loaded — call [`load_gguf_model`] or [`load_default_model`] first.
566 */
567 public protocol OndeChatEngineProtocol: AnyObject, Sendable {
568
569 /**
570 * Clear the conversation history but keep the model loaded.
571 *
572 * Returns the number of turns that were removed.
573 */
574 func clearHistory() async -> UInt64
575
576 /**
577 * Clear the system prompt.
578 */
579 func clearSystemPrompt() async
580
581 /**
582 * Run inference on an explicit list of messages WITHOUT modifying the
583 * engine's internal history.
584 *
585 * Useful for one-shot prompts (e.g. prompt enhancement).
586 */
587 func generate(messages: [ChatMessage], sampling: SamplingConfig?) async throws -> InferenceResult
588
589 /**
590 * Get a copy of the full conversation history.
591 */
592 func history() async -> [ChatMessage]
593
594 /**
595 * Get a snapshot of the engine's current state.
596 */
597 func info() async -> EngineInfo
598
599 /**
600 * Check whether a model is currently loaded.
601 */
602 func isLoaded() async -> Bool
603
604 /**
605 * Load the model assigned to this app via the Onde dashboard.
606 *
607 * The `app_id` and `app_secret` identify your app on
608 * [ondeinference.com](https://ondeinference.com). The backend returns
609 * the GGUF model configuration assigned to your app; if no model is
610 * assigned (HTTP 404) the platform default is loaded instead.
611 *
612 * Returns the wall-clock loading time in seconds.
613 */
614 func loadAssignedModel(appId: String, appSecret: String, systemPrompt: String?, sampling: SamplingConfig?) async throws -> Double
615
616 /**
617 * Load the platform-appropriate default model.
618 *
619 * - tvOS / iOS / Android → Qwen 2.5 1.5B (~941 MB)
620 * - macOS / Windows / Linux → Qwen 2.5 3B (~1.93 GB)
621 *
622 * Returns the wall-clock loading time in seconds.
623 */
624 func loadDefaultModel(systemPrompt: String?, sampling: SamplingConfig?) async throws -> Double
625
626 /**
627 * Load a GGUF model into the engine.
628 *
629 * If a model is already loaded it will be unloaded first.
630 *
631 * Returns the wall-clock loading time in seconds.
632 */
633 func loadGgufModel(config: GgufModelConfig, systemPrompt: String?, sampling: SamplingConfig?) async throws -> Double
634
635 /**
636 * Append a message to history without running inference.
637 */
638 func pushHistory(message: ChatMessage) async
639
640 /**
641 * Send a user message and receive a complete assistant reply.
642 *
643 * The user message and assistant reply are automatically appended to
644 * the conversation history on success.
645 */
646 func sendMessage(message: String) async throws -> InferenceResult
647
648 /**
649 * Replace the sampling configuration.
650 */
651 func setSampling(sampling: SamplingConfig) async
652
653 /**
654 * Set or replace the system prompt.
655 */
656 func setSystemPrompt(prompt: String) async
657
658 /**
659 * Unload the current model, freeing all memory.
660 *
661 * Returns the display name of the model that was unloaded, or `nil`
662 * if no model was loaded.
663 */
664 func unloadModel() async -> String?
665
666 }
667 /**
668 * On-device LLM chat inference engine — UniFFI-exported wrapper.
669 *
670 * This is the primary entry point for Swift / Kotlin consumers. It wraps
671 * [`ChatEngine`] with FFI-safe method signatures (no generics, no Rust
672 * channels, concrete `String` parameters).
673 *
674 * Construct with [`OndeChatEngine::new()`]. The engine starts with no
675 * model loaded — call [`load_gguf_model`] or [`load_default_model`] first.
676 */
677 open class OndeChatEngine: OndeChatEngineProtocol, @unchecked Sendable {
678 fileprivate let handle: UInt64
679
680 /// Used to instantiate a [FFIObject] without an actual handle, for fakes in tests, mostly.
681 #if swift(>=5.8)
682 @_documentation(visibility: private)
683 #endif
684 public struct NoHandle {
685 public init() {}
686 }
687
688 // TODO: We'd like this to be `private` but for Swifty reasons,
689 // we can't implement `FfiConverter` without making this `required` and we can't
690 // make it `required` without making it `public`.
691 #if swift(>=5.8)
692 @_documentation(visibility: private)
693 #endif
694 required public init(unsafeFromHandle handle: UInt64) {
695 self.handle = handle
696 }
697
698 // This constructor can be used to instantiate a fake object.
699 // - Parameter noHandle: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject].
700 //
701 // - Warning:
702 // Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing handle the FFI lower functions will crash.
703 #if swift(>=5.8)
704 @_documentation(visibility: private)
705 #endif
706 public init(noHandle: NoHandle) {
707 self.handle = 0
708 }
709
710 #if swift(>=5.8)
711 @_documentation(visibility: private)
712 #endif
713 public func uniffiCloneHandle() -> UInt64 {
714 return try! rustCall { uniffi_onde_fn_clone_ondechatengine(self.handle, $0) }
715 }
716 /**
717 * Create a new engine with no model loaded.
718 */
719 public convenience init() {
720 let handle =
721 try! rustCall() {
722 uniffi_onde_fn_constructor_ondechatengine_new($0
723 )
724 }
725 self.init(unsafeFromHandle: handle)
726 }
727
728 deinit {
729 if handle == 0 {
730 // Mock objects have handle=0 don't try to free them
731 return
732 }
733
734 try! rustCall { uniffi_onde_fn_free_ondechatengine(handle, $0) }
735 }
736
737
738
739
740 /**
741 * Clear the conversation history but keep the model loaded.
742 *
743 * Returns the number of turns that were removed.
744 */
745 open func clearHistory()async -> UInt64 {
746 return
747 try! await uniffiRustCallAsync(
748 rustFutureFunc: {
749 uniffi_onde_fn_method_ondechatengine_clear_history(
750 self.uniffiCloneHandle()
751
752 )
753 },
754 pollFunc: ffi_onde_rust_future_poll_u64,
755 completeFunc: ffi_onde_rust_future_complete_u64,
756 freeFunc: ffi_onde_rust_future_free_u64,
757 liftFunc: FfiConverterUInt64.lift,
758 errorHandler: nil
759
760 )
761 }
762
763 /**
764 * Clear the system prompt.
765 */
766 open func clearSystemPrompt()async {
767 return
768 try! await uniffiRustCallAsync(
769 rustFutureFunc: {
770 uniffi_onde_fn_method_ondechatengine_clear_system_prompt(
771 self.uniffiCloneHandle()
772
773 )
774 },
775 pollFunc: ffi_onde_rust_future_poll_void,
776 completeFunc: ffi_onde_rust_future_complete_void,
777 freeFunc: ffi_onde_rust_future_free_void,
778 liftFunc: { $0 },
779 errorHandler: nil
780
781 )
782 }
783
784 /**
785 * Run inference on an explicit list of messages WITHOUT modifying the
786 * engine's internal history.
787 *
788 * Useful for one-shot prompts (e.g. prompt enhancement).
789 */
790 open func generate(messages: [ChatMessage], sampling: SamplingConfig?)async throws -> InferenceResult {
791 return
792 try await uniffiRustCallAsync(
793 rustFutureFunc: {
794 uniffi_onde_fn_method_ondechatengine_generate(
795 self.uniffiCloneHandle(),
796 FfiConverterSequenceTypeChatMessage.lower(messages),FfiConverterOptionTypeSamplingConfig.lower(sampling)
797 )
798 },
799 pollFunc: ffi_onde_rust_future_poll_rust_buffer,
800 completeFunc: ffi_onde_rust_future_complete_rust_buffer,
801 freeFunc: ffi_onde_rust_future_free_rust_buffer,
802 liftFunc: FfiConverterTypeInferenceResult_lift,
803 errorHandler: FfiConverterTypeInferenceError_lift
804 )
805 }
806
807 /**
808 * Get a copy of the full conversation history.
809 */
810 open func history()async -> [ChatMessage] {
811 return
812 try! await uniffiRustCallAsync(
813 rustFutureFunc: {
814 uniffi_onde_fn_method_ondechatengine_history(
815 self.uniffiCloneHandle()
816
817 )
818 },
819 pollFunc: ffi_onde_rust_future_poll_rust_buffer,
820 completeFunc: ffi_onde_rust_future_complete_rust_buffer,
821 freeFunc: ffi_onde_rust_future_free_rust_buffer,
822 liftFunc: FfiConverterSequenceTypeChatMessage.lift,
823 errorHandler: nil
824
825 )
826 }
827
828 /**
829 * Get a snapshot of the engine's current state.
830 */
831 open func info()async -> EngineInfo {
832 return
833 try! await uniffiRustCallAsync(
834 rustFutureFunc: {
835 uniffi_onde_fn_method_ondechatengine_info(
836 self.uniffiCloneHandle()
837
838 )
839 },
840 pollFunc: ffi_onde_rust_future_poll_rust_buffer,
841 completeFunc: ffi_onde_rust_future_complete_rust_buffer,
842 freeFunc: ffi_onde_rust_future_free_rust_buffer,
843 liftFunc: FfiConverterTypeEngineInfo_lift,
844 errorHandler: nil
845
846 )
847 }
848
849 /**
850 * Check whether a model is currently loaded.
851 */
852 open func isLoaded()async -> Bool {
853 return
854 try! await uniffiRustCallAsync(
855 rustFutureFunc: {
856 uniffi_onde_fn_method_ondechatengine_is_loaded(
857 self.uniffiCloneHandle()
858
859 )
860 },
861 pollFunc: ffi_onde_rust_future_poll_i8,
862 completeFunc: ffi_onde_rust_future_complete_i8,
863 freeFunc: ffi_onde_rust_future_free_i8,
864 liftFunc: FfiConverterBool.lift,
865 errorHandler: nil
866
867 )
868 }
869
870 /**
871 * Load the model assigned to this app via the Onde dashboard.
872 *
873 * The `app_id` and `app_secret` identify your app on
874 * [ondeinference.com](https://ondeinference.com). The backend returns
875 * the GGUF model configuration assigned to your app; if no model is
876 * assigned (HTTP 404) the platform default is loaded instead.
877 *
878 * Returns the wall-clock loading time in seconds.
879 */
880 open func loadAssignedModel(appId: String, appSecret: String, systemPrompt: String?, sampling: SamplingConfig?)async throws -> Double {
881 return
882 try await uniffiRustCallAsync(
883 rustFutureFunc: {
884 uniffi_onde_fn_method_ondechatengine_load_assigned_model(
885 self.uniffiCloneHandle(),
886 FfiConverterString.lower(appId),FfiConverterString.lower(appSecret),FfiConverterOptionString.lower(systemPrompt),FfiConverterOptionTypeSamplingConfig.lower(sampling)
887 )
888 },
889 pollFunc: ffi_onde_rust_future_poll_f64,
890 completeFunc: ffi_onde_rust_future_complete_f64,
891 freeFunc: ffi_onde_rust_future_free_f64,
892 liftFunc: FfiConverterDouble.lift,
893 errorHandler: FfiConverterTypeInferenceError_lift
894 )
895 }
896
897 /**
898 * Load the platform-appropriate default model.
899 *
900 * - tvOS / iOS / Android → Qwen 2.5 1.5B (~941 MB)
901 * - macOS / Windows / Linux → Qwen 2.5 3B (~1.93 GB)
902 *
903 * Returns the wall-clock loading time in seconds.
904 */
905 open func loadDefaultModel(systemPrompt: String?, sampling: SamplingConfig?)async throws -> Double {
906 return
907 try await uniffiRustCallAsync(
908 rustFutureFunc: {
909 uniffi_onde_fn_method_ondechatengine_load_default_model(
910 self.uniffiCloneHandle(),
911 FfiConverterOptionString.lower(systemPrompt),FfiConverterOptionTypeSamplingConfig.lower(sampling)
912 )
913 },
914 pollFunc: ffi_onde_rust_future_poll_f64,
915 completeFunc: ffi_onde_rust_future_complete_f64,
916 freeFunc: ffi_onde_rust_future_free_f64,
917 liftFunc: FfiConverterDouble.lift,
918 errorHandler: FfiConverterTypeInferenceError_lift
919 )
920 }
921
922 /**
923 * Load a GGUF model into the engine.
924 *
925 * If a model is already loaded it will be unloaded first.
926 *
927 * Returns the wall-clock loading time in seconds.
928 */
929 open func loadGgufModel(config: GgufModelConfig, systemPrompt: String?, sampling: SamplingConfig?)async throws -> Double {
930 return
931 try await uniffiRustCallAsync(
932 rustFutureFunc: {
933 uniffi_onde_fn_method_ondechatengine_load_gguf_model(
934 self.uniffiCloneHandle(),
935 FfiConverterTypeGgufModelConfig_lower(config),FfiConverterOptionString.lower(systemPrompt),FfiConverterOptionTypeSamplingConfig.lower(sampling)
936 )
937 },
938 pollFunc: ffi_onde_rust_future_poll_f64,
939 completeFunc: ffi_onde_rust_future_complete_f64,
940 freeFunc: ffi_onde_rust_future_free_f64,
941 liftFunc: FfiConverterDouble.lift,
942 errorHandler: FfiConverterTypeInferenceError_lift
943 )
944 }
945
946 /**
947 * Append a message to history without running inference.
948 */
949 open func pushHistory(message: ChatMessage)async {
950 return
951 try! await uniffiRustCallAsync(
952 rustFutureFunc: {
953 uniffi_onde_fn_method_ondechatengine_push_history(
954 self.uniffiCloneHandle(),
955 FfiConverterTypeChatMessage_lower(message)
956 )
957 },
958 pollFunc: ffi_onde_rust_future_poll_void,
959 completeFunc: ffi_onde_rust_future_complete_void,
960 freeFunc: ffi_onde_rust_future_free_void,
961 liftFunc: { $0 },
962 errorHandler: nil
963
964 )
965 }
966
967 /**
968 * Send a user message and receive a complete assistant reply.
969 *
970 * The user message and assistant reply are automatically appended to
971 * the conversation history on success.
972 */
973 open func sendMessage(message: String)async throws -> InferenceResult {
974 return
975 try await uniffiRustCallAsync(
976 rustFutureFunc: {
977 uniffi_onde_fn_method_ondechatengine_send_message(
978 self.uniffiCloneHandle(),
979 FfiConverterString.lower(message)
980 )
981 },
982 pollFunc: ffi_onde_rust_future_poll_rust_buffer,
983 completeFunc: ffi_onde_rust_future_complete_rust_buffer,
984 freeFunc: ffi_onde_rust_future_free_rust_buffer,
985 liftFunc: FfiConverterTypeInferenceResult_lift,
986 errorHandler: FfiConverterTypeInferenceError_lift
987 )
988 }
989
990 /**
991 * Replace the sampling configuration.
992 */
993 open func setSampling(sampling: SamplingConfig)async {
994 return
995 try! await uniffiRustCallAsync(
996 rustFutureFunc: {
997 uniffi_onde_fn_method_ondechatengine_set_sampling(
998 self.uniffiCloneHandle(),
999 FfiConverterTypeSamplingConfig_lower(sampling)
1000 )
1001 },
1002 pollFunc: ffi_onde_rust_future_poll_void,
1003 completeFunc: ffi_onde_rust_future_complete_void,
1004 freeFunc: ffi_onde_rust_future_free_void,
1005 liftFunc: { $0 },
1006 errorHandler: nil
1007
1008 )
1009 }
1010
1011 /**
1012 * Set or replace the system prompt.
1013 */
1014 open func setSystemPrompt(prompt: String)async {
1015 return
1016 try! await uniffiRustCallAsync(
1017 rustFutureFunc: {
1018 uniffi_onde_fn_method_ondechatengine_set_system_prompt(
1019 self.uniffiCloneHandle(),
1020 FfiConverterString.lower(prompt)
1021 )
1022 },
1023 pollFunc: ffi_onde_rust_future_poll_void,
1024 completeFunc: ffi_onde_rust_future_complete_void,
1025 freeFunc: ffi_onde_rust_future_free_void,
1026 liftFunc: { $0 },
1027 errorHandler: nil
1028
1029 )
1030 }
1031
1032 /**
1033 * Unload the current model, freeing all memory.
1034 *
1035 * Returns the display name of the model that was unloaded, or `nil`
1036 * if no model was loaded.
1037 */
1038 open func unloadModel()async -> String? {
1039 return
1040 try! await uniffiRustCallAsync(
1041 rustFutureFunc: {
1042 uniffi_onde_fn_method_ondechatengine_unload_model(
1043 self.uniffiCloneHandle()
1044
1045 )
1046 },
1047 pollFunc: ffi_onde_rust_future_poll_rust_buffer,
1048 completeFunc: ffi_onde_rust_future_complete_rust_buffer,
1049 freeFunc: ffi_onde_rust_future_free_rust_buffer,
1050 liftFunc: FfiConverterOptionString.lift,
1051 errorHandler: nil
1052
1053 )
1054 }
1055
1056
1057
1058 }
1059
1060
1061 #if swift(>=5.8)
1062 @_documentation(visibility: private)
1063 #endif
1064 public struct FfiConverterTypeOndeChatEngine: FfiConverter {
1065 typealias FfiType = UInt64
1066 typealias SwiftType = OndeChatEngine
1067
1068 public static func lift(_ handle: UInt64) throws -> OndeChatEngine {
1069 return OndeChatEngine(unsafeFromHandle: handle)
1070 }
1071
1072 public static func lower(_ value: OndeChatEngine) -> UInt64 {
1073 return value.uniffiCloneHandle()
1074 }
1075
1076 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OndeChatEngine {
1077 let handle: UInt64 = try readInt(&buf)
1078 return try lift(handle)
1079 }
1080
1081 public static func write(_ value: OndeChatEngine, into buf: inout [UInt8]) {
1082 writeInt(&buf, lower(value))
1083 }
1084 }
1085
1086
1087 #if swift(>=5.8)
1088 @_documentation(visibility: private)
1089 #endif
1090 public func FfiConverterTypeOndeChatEngine_lift(_ handle: UInt64) throws -> OndeChatEngine {
1091 return try FfiConverterTypeOndeChatEngine.lift(handle)
1092 }
1093
1094 #if swift(>=5.8)
1095 @_documentation(visibility: private)
1096 #endif
1097 public func FfiConverterTypeOndeChatEngine_lower(_ value: OndeChatEngine) -> UInt64 {
1098 return FfiConverterTypeOndeChatEngine.lower(value)
1099 }
1100
1101
1102
1103
1104 /**
1105 * A single message in a conversation.
1106 */
1107 public struct ChatMessage: Equatable, Hashable {
1108 public var role: ChatRole
1109 public var content: String
1110
1111 // Default memberwise initializers are never public by default, so we
1112 // declare one manually.
1113 public init(role: ChatRole, content: String) {
1114 self.role = role
1115 self.content = content
1116 }
1117
1118
1119
1120
1121 }
1122
1123 #if compiler(>=6)
1124 extension ChatMessage: Sendable {}
1125 #endif
1126
1127 #if swift(>=5.8)
1128 @_documentation(visibility: private)
1129 #endif
1130 public struct FfiConverterTypeChatMessage: FfiConverterRustBuffer {
1131 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ChatMessage {
1132 return
1133 try ChatMessage(
1134 role: FfiConverterTypeChatRole.read(from: &buf),
1135 content: FfiConverterString.read(from: &buf)
1136 )
1137 }
1138
1139 public static func write(_ value: ChatMessage, into buf: inout [UInt8]) {
1140 FfiConverterTypeChatRole.write(value.role, into: &buf)
1141 FfiConverterString.write(value.content, into: &buf)
1142 }
1143 }
1144
1145
1146 #if swift(>=5.8)
1147 @_documentation(visibility: private)
1148 #endif
1149 public func FfiConverterTypeChatMessage_lift(_ buf: RustBuffer) throws -> ChatMessage {
1150 return try FfiConverterTypeChatMessage.lift(buf)
1151 }
1152
1153 #if swift(>=5.8)
1154 @_documentation(visibility: private)
1155 #endif
1156 public func FfiConverterTypeChatMessage_lower(_ value: ChatMessage) -> RustBuffer {
1157 return FfiConverterTypeChatMessage.lower(value)
1158 }
1159
1160
1161 /**
1162 * A point-in-time snapshot of the engine's state, suitable for status UIs.
1163 *
1164 * Note: `history_length` is `u64` (not `usize`) for UniFFI compatibility.
1165 */
1166 public struct EngineInfo: Equatable, Hashable {
1167 public var status: EngineStatus
1168 /**
1169 * Display name of the currently loaded model, if any.
1170 */
1171 public var modelName: String?
1172 /**
1173 * Approximate memory footprint description, if a model is loaded.
1174 */
1175 public var approxMemory: String?
1176 /**
1177 * Number of conversation turns in the current history.
1178 */
1179 public var historyLength: UInt64
1180
1181 // Default memberwise initializers are never public by default, so we
1182 // declare one manually.
1183 public init(status: EngineStatus,
1184 /**
1185 * Display name of the currently loaded model, if any.
1186 */modelName: String?,
1187 /**
1188 * Approximate memory footprint description, if a model is loaded.
1189 */approxMemory: String?,
1190 /**
1191 * Number of conversation turns in the current history.
1192 */historyLength: UInt64) {
1193 self.status = status
1194 self.modelName = modelName
1195 self.approxMemory = approxMemory
1196 self.historyLength = historyLength
1197 }
1198
1199
1200
1201
1202 }
1203
1204 #if compiler(>=6)
1205 extension EngineInfo: Sendable {}
1206 #endif
1207
1208 #if swift(>=5.8)
1209 @_documentation(visibility: private)
1210 #endif
1211 public struct FfiConverterTypeEngineInfo: FfiConverterRustBuffer {
1212 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EngineInfo {
1213 return
1214 try EngineInfo(
1215 status: FfiConverterTypeEngineStatus.read(from: &buf),
1216 modelName: FfiConverterOptionString.read(from: &buf),
1217 approxMemory: FfiConverterOptionString.read(from: &buf),
1218 historyLength: FfiConverterUInt64.read(from: &buf)
1219 )
1220 }
1221
1222 public static func write(_ value: EngineInfo, into buf: inout [UInt8]) {
1223 FfiConverterTypeEngineStatus.write(value.status, into: &buf)
1224 FfiConverterOptionString.write(value.modelName, into: &buf)
1225 FfiConverterOptionString.write(value.approxMemory, into: &buf)
1226 FfiConverterUInt64.write(value.historyLength, into: &buf)
1227 }
1228 }
1229
1230
1231 #if swift(>=5.8)
1232 @_documentation(visibility: private)
1233 #endif
1234 public func FfiConverterTypeEngineInfo_lift(_ buf: RustBuffer) throws -> EngineInfo {
1235 return try FfiConverterTypeEngineInfo.lift(buf)
1236 }
1237
1238 #if swift(>=5.8)
1239 @_documentation(visibility: private)
1240 #endif
1241 public func FfiConverterTypeEngineInfo_lower(_ value: EngineInfo) -> RustBuffer {
1242 return FfiConverterTypeEngineInfo.lower(value)
1243 }
1244
1245
1246 /**
1247 * Configuration for loading a GGUF model via mistral.rs.
1248 *
1249 * This is the primary model format for on-device mobile/desktop inference
1250 * because GGUF files are pre-quantized and load at their compressed size,
1251 * avoiding the large memory spike of in-situ quantization.
1252 */
1253 public struct GgufModelConfig: Equatable, Hashable {
1254 /**
1255 * HuggingFace model repository ID, e.g. `"bartowski/Qwen2.5-1.5B-Instruct-GGUF"`.
1256 */
1257 public var modelId: String
1258 /**
1259 * GGUF filename(s) within the repository, e.g. `["Qwen2.5-1.5B-Instruct-Q4_K_M.gguf"]`.
1260 */
1261 public var files: [String]
1262 /**
1263 * Optional: explicit tokenizer model ID (required on Android where GGUF
1264 * embedded tokenizers are not supported by the candle backend).
1265 */
1266 public var tokModelId: String?
1267 /**
1268 * Human-friendly display name, e.g. `"Qwen 2.5 1.5B"`.
1269 */
1270 public var displayName: String
1271 /**
1272 * Approximate memory footprint description, e.g. `"~941 MB (GGUF Q4_K_M)"`.
1273 */
1274 public var approxMemory: String
1275 /**
1276 * Optional Jinja chat template string. When set, this overrides the
1277 * template embedded in the GGUF file (if any). Required for older GGUF
1278 * files that don't embed a chat template (e.g. TheBloke models).
1279 */
1280 public var chatTemplate: String?
1281
1282 // Default memberwise initializers are never public by default, so we
1283 // declare one manually.
1284 public init(
1285 /**
1286 * HuggingFace model repository ID, e.g. `"bartowski/Qwen2.5-1.5B-Instruct-GGUF"`.
1287 */modelId: String,
1288 /**
1289 * GGUF filename(s) within the repository, e.g. `["Qwen2.5-1.5B-Instruct-Q4_K_M.gguf"]`.
1290 */files: [String],
1291 /**
1292 * Optional: explicit tokenizer model ID (required on Android where GGUF
1293 * embedded tokenizers are not supported by the candle backend).
1294 */tokModelId: String?,
1295 /**
1296 * Human-friendly display name, e.g. `"Qwen 2.5 1.5B"`.
1297 */displayName: String,
1298 /**
1299 * Approximate memory footprint description, e.g. `"~941 MB (GGUF Q4_K_M)"`.
1300 */approxMemory: String,
1301 /**
1302 * Optional Jinja chat template string. When set, this overrides the
1303 * template embedded in the GGUF file (if any). Required for older GGUF
1304 * files that don't embed a chat template (e.g. TheBloke models).
1305 */chatTemplate: String?) {
1306 self.modelId = modelId
1307 self.files = files
1308 self.tokModelId = tokModelId
1309 self.displayName = displayName
1310 self.approxMemory = approxMemory
1311 self.chatTemplate = chatTemplate
1312 }
1313
1314
1315
1316
1317 }
1318
1319 #if compiler(>=6)
1320 extension GgufModelConfig: Sendable {}
1321 #endif
1322
1323 #if swift(>=5.8)
1324 @_documentation(visibility: private)
1325 #endif
1326 public struct FfiConverterTypeGgufModelConfig: FfiConverterRustBuffer {
1327 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> GgufModelConfig {
1328 return
1329 try GgufModelConfig(
1330 modelId: FfiConverterString.read(from: &buf),
1331 files: FfiConverterSequenceString.read(from: &buf),
1332 tokModelId: FfiConverterOptionString.read(from: &buf),
1333 displayName: FfiConverterString.read(from: &buf),
1334 approxMemory: FfiConverterString.read(from: &buf),
1335 chatTemplate: FfiConverterOptionString.read(from: &buf)
1336 )
1337 }
1338
1339 public static func write(_ value: GgufModelConfig, into buf: inout [UInt8]) {
1340 FfiConverterString.write(value.modelId, into: &buf)
1341 FfiConverterSequenceString.write(value.files, into: &buf)
1342 FfiConverterOptionString.write(value.tokModelId, into: &buf)
1343 FfiConverterString.write(value.displayName, into: &buf)
1344 FfiConverterString.write(value.approxMemory, into: &buf)
1345 FfiConverterOptionString.write(value.chatTemplate, into: &buf)
1346 }
1347 }
1348
1349
1350 #if swift(>=5.8)
1351 @_documentation(visibility: private)
1352 #endif
1353 public func FfiConverterTypeGgufModelConfig_lift(_ buf: RustBuffer) throws -> GgufModelConfig {
1354 return try FfiConverterTypeGgufModelConfig.lift(buf)
1355 }
1356
1357 #if swift(>=5.8)
1358 @_documentation(visibility: private)
1359 #endif
1360 public func FfiConverterTypeGgufModelConfig_lower(_ value: GgufModelConfig) -> RustBuffer {
1361 return FfiConverterTypeGgufModelConfig.lower(value)
1362 }
1363
1364
1365 /**
1366 * The result of a chat inference request.
1367 */
1368 public struct InferenceResult: Equatable, Hashable {
1369 /**
1370 * The generated assistant reply text.
1371 */
1372 public var text: String
1373 /**
1374 * Wall-clock duration of the inference in seconds.
1375 */
1376 public var durationSecs: Double
1377 /**
1378 * Human-readable duration string (e.g. `"2m 3.1s"` or `"4.5s"`).
1379 */
1380 public var durationDisplay: String
1381 /**
1382 * Finish reason reported by the model (e.g. `"stop"`, `"length"`).
1383 */
1384 public var finishReason: String
1385 /**
1386 * Tool calls requested by the model (empty when no tools were invoked).
1387 */
1388 public var toolCalls: [ToolCallInfo]
1389
1390 // Default memberwise initializers are never public by default, so we
1391 // declare one manually.
1392 public init(
1393 /**
1394 * The generated assistant reply text.
1395 */text: String,
1396 /**
1397 * Wall-clock duration of the inference in seconds.
1398 */durationSecs: Double,
1399 /**
1400 * Human-readable duration string (e.g. `"2m 3.1s"` or `"4.5s"`).
1401 */durationDisplay: String,
1402 /**
1403 * Finish reason reported by the model (e.g. `"stop"`, `"length"`).
1404 */finishReason: String,
1405 /**
1406 * Tool calls requested by the model (empty when no tools were invoked).
1407 */toolCalls: [ToolCallInfo]) {
1408 self.text = text
1409 self.durationSecs = durationSecs
1410 self.durationDisplay = durationDisplay
1411 self.finishReason = finishReason
1412 self.toolCalls = toolCalls
1413 }
1414
1415
1416
1417
1418 }
1419
1420 #if compiler(>=6)
1421 extension InferenceResult: Sendable {}
1422 #endif
1423
1424 #if swift(>=5.8)
1425 @_documentation(visibility: private)
1426 #endif
1427 public struct FfiConverterTypeInferenceResult: FfiConverterRustBuffer {
1428 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> InferenceResult {
1429 return
1430 try InferenceResult(
1431 text: FfiConverterString.read(from: &buf),
1432 durationSecs: FfiConverterDouble.read(from: &buf),
1433 durationDisplay: FfiConverterString.read(from: &buf),
1434 finishReason: FfiConverterString.read(from: &buf),
1435 toolCalls: FfiConverterSequenceTypeToolCallInfo.read(from: &buf)
1436 )
1437 }
1438
1439 public static func write(_ value: InferenceResult, into buf: inout [UInt8]) {
1440 FfiConverterString.write(value.text, into: &buf)
1441 FfiConverterDouble.write(value.durationSecs, into: &buf)
1442 FfiConverterString.write(value.durationDisplay, into: &buf)
1443 FfiConverterString.write(value.finishReason, into: &buf)
1444 FfiConverterSequenceTypeToolCallInfo.write(value.toolCalls, into: &buf)
1445 }
1446 }
1447
1448
1449 #if swift(>=5.8)
1450 @_documentation(visibility: private)
1451 #endif
1452 public func FfiConverterTypeInferenceResult_lift(_ buf: RustBuffer) throws -> InferenceResult {
1453 return try FfiConverterTypeInferenceResult.lift(buf)
1454 }
1455
1456 #if swift(>=5.8)
1457 @_documentation(visibility: private)
1458 #endif
1459 public func FfiConverterTypeInferenceResult_lower(_ value: InferenceResult) -> RustBuffer {
1460 return FfiConverterTypeInferenceResult.lower(value)
1461 }
1462
1463
1464 /**
1465 * Configuration for loading an ISQ (in-situ quantised) model via mistral.rs
1466 * `TextModelBuilder`.
1467 *
1468 * Unlike GGUF models, ISQ models are loaded directly from a HuggingFace
1469 * safetensors repo and quantised in-situ on the device. They require more
1470 * RAM during the load phase but support a wider range of architectures
1471 * (e.g. DeepSeek-Coder-V2-Lite, Qwen2.5-Coder-7B).
1472 *
1473 * **macOS-only for now** — ISQ with Metal acceleration requires the `metal`
1474 * feature on mistral.rs. The struct is still defined on all platforms so
1475 * that types.rs compiles everywhere without `cfg` gates on the record
1476 * (UniFFI requires all record types to be reachable without feature flags).
1477 */
1478 public struct IsqModelConfig: Equatable, Hashable {
1479 /**
1480 * HuggingFace model repository ID, e.g. `"Qwen/Qwen2.5-Coder-7B-Instruct"`.
1481 */
1482 public var modelId: String
1483 /**
1484 * Number of quantisation bits. `4` → Q4K (AFQ4 on Metal), `8` → Q8_0 (AFQ8 on Metal).
1485 * Any value outside `{4, 8}` defaults to 4-bit.
1486 */
1487 public var isqBits: UInt8
1488 /**
1489 * Human-friendly display name, e.g. `"Qwen 2.5 Coder 7B"`.
1490 */
1491 public var displayName: String
1492 /**
1493 * Approximate memory footprint description, e.g. `"~4.5 GB (Q4K, Metal)"`.
1494 */
1495 public var approxMemory: String
1496
1497 // Default memberwise initializers are never public by default, so we
1498 // declare one manually.
1499 public init(
1500 /**
1501 * HuggingFace model repository ID, e.g. `"Qwen/Qwen2.5-Coder-7B-Instruct"`.
1502 */modelId: String,
1503 /**
1504 * Number of quantisation bits. `4` → Q4K (AFQ4 on Metal), `8` → Q8_0 (AFQ8 on Metal).
1505 * Any value outside `{4, 8}` defaults to 4-bit.
1506 */isqBits: UInt8,
1507 /**
1508 * Human-friendly display name, e.g. `"Qwen 2.5 Coder 7B"`.
1509 */displayName: String,
1510 /**
1511 * Approximate memory footprint description, e.g. `"~4.5 GB (Q4K, Metal)"`.
1512 */approxMemory: String) {
1513 self.modelId = modelId
1514 self.isqBits = isqBits
1515 self.displayName = displayName
1516 self.approxMemory = approxMemory
1517 }
1518
1519
1520
1521
1522 }
1523
1524 #if compiler(>=6)
1525 extension IsqModelConfig: Sendable {}
1526 #endif
1527
1528 #if swift(>=5.8)
1529 @_documentation(visibility: private)
1530 #endif
1531 public struct FfiConverterTypeIsqModelConfig: FfiConverterRustBuffer {
1532 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> IsqModelConfig {
1533 return
1534 try IsqModelConfig(
1535 modelId: FfiConverterString.read(from: &buf),
1536 isqBits: FfiConverterUInt8.read(from: &buf),
1537 displayName: FfiConverterString.read(from: &buf),
1538 approxMemory: FfiConverterString.read(from: &buf)
1539 )
1540 }
1541
1542 public static func write(_ value: IsqModelConfig, into buf: inout [UInt8]) {
1543 FfiConverterString.write(value.modelId, into: &buf)
1544 FfiConverterUInt8.write(value.isqBits, into: &buf)
1545 FfiConverterString.write(value.displayName, into: &buf)
1546 FfiConverterString.write(value.approxMemory, into: &buf)
1547 }
1548 }
1549
1550
1551 #if swift(>=5.8)
1552 @_documentation(visibility: private)
1553 #endif
1554 public func FfiConverterTypeIsqModelConfig_lift(_ buf: RustBuffer) throws -> IsqModelConfig {
1555 return try FfiConverterTypeIsqModelConfig.lift(buf)
1556 }
1557
1558 #if swift(>=5.8)
1559 @_documentation(visibility: private)
1560 #endif
1561 public func FfiConverterTypeIsqModelConfig_lower(_ value: IsqModelConfig) -> RustBuffer {
1562 return FfiConverterTypeIsqModelConfig.lower(value)
1563 }
1564
1565
1566 /**
1567 * Sampling parameters for text generation.
1568 *
1569 * All fields are optional — `None` means "use the engine default".
1570 *
1571 * Note: `usize` is replaced with `u64` for UniFFI compatibility.
1572 */
1573 public struct SamplingConfig: Equatable, Hashable {
1574 /**
1575 * Sampling temperature (higher = more random). Typical range: 0.0–2.0.
1576 */
1577 public var temperature: Double?
1578 /**
1579 * Nucleus (top-p) sampling threshold. Typical value: 0.9–0.95.
1580 */
1581 public var topP: Double?
1582 /**
1583 * Top-k sampling limit.
1584 */
1585 public var topK: UInt64?
1586 /**
1587 * Min-p sampling threshold.
1588 */
1589 public var minP: Double?
1590 /**
1591 * Maximum number of tokens to generate.
1592 */
1593 public var maxTokens: UInt64?
1594 /**
1595 * Frequency penalty (penalise tokens proportional to occurrence count).
1596 */
1597 public var frequencyPenalty: Float?
1598 /**
1599 * Presence penalty (penalise tokens that appeared at all).
1600 */
1601 public var presencePenalty: Float?
1602
1603 // Default memberwise initializers are never public by default, so we
1604 // declare one manually.
1605 public init(
1606 /**
1607 * Sampling temperature (higher = more random). Typical range: 0.0–2.0.
1608 */temperature: Double?,
1609 /**
1610 * Nucleus (top-p) sampling threshold. Typical value: 0.9–0.95.
1611 */topP: Double?,
1612 /**
1613 * Top-k sampling limit.
1614 */topK: UInt64?,
1615 /**
1616 * Min-p sampling threshold.
1617 */minP: Double?,
1618 /**
1619 * Maximum number of tokens to generate.
1620 */maxTokens: UInt64?,
1621 /**
1622 * Frequency penalty (penalise tokens proportional to occurrence count).
1623 */frequencyPenalty: Float?,
1624 /**
1625 * Presence penalty (penalise tokens that appeared at all).
1626 */presencePenalty: Float?) {
1627 self.temperature = temperature
1628 self.topP = topP
1629 self.topK = topK
1630 self.minP = minP
1631 self.maxTokens = maxTokens
1632 self.frequencyPenalty = frequencyPenalty
1633 self.presencePenalty = presencePenalty
1634 }
1635
1636
1637
1638
1639 }
1640
1641 #if compiler(>=6)
1642 extension SamplingConfig: Sendable {}
1643 #endif
1644
1645 #if swift(>=5.8)
1646 @_documentation(visibility: private)
1647 #endif
1648 public struct FfiConverterTypeSamplingConfig: FfiConverterRustBuffer {
1649 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SamplingConfig {
1650 return
1651 try SamplingConfig(
1652 temperature: FfiConverterOptionDouble.read(from: &buf),
1653 topP: FfiConverterOptionDouble.read(from: &buf),
1654 topK: FfiConverterOptionUInt64.read(from: &buf),
1655 minP: FfiConverterOptionDouble.read(from: &buf),
1656 maxTokens: FfiConverterOptionUInt64.read(from: &buf),
1657 frequencyPenalty: FfiConverterOptionFloat.read(from: &buf),
1658 presencePenalty: FfiConverterOptionFloat.read(from: &buf)
1659 )
1660 }
1661
1662 public static func write(_ value: SamplingConfig, into buf: inout [UInt8]) {
1663 FfiConverterOptionDouble.write(value.temperature, into: &buf)
1664 FfiConverterOptionDouble.write(value.topP, into: &buf)
1665 FfiConverterOptionUInt64.write(value.topK, into: &buf)
1666 FfiConverterOptionDouble.write(value.minP, into: &buf)
1667 FfiConverterOptionUInt64.write(value.maxTokens, into: &buf)
1668 FfiConverterOptionFloat.write(value.frequencyPenalty, into: &buf)
1669 FfiConverterOptionFloat.write(value.presencePenalty, into: &buf)
1670 }
1671 }
1672
1673
1674 #if swift(>=5.8)
1675 @_documentation(visibility: private)
1676 #endif
1677 public func FfiConverterTypeSamplingConfig_lift(_ buf: RustBuffer) throws -> SamplingConfig {
1678 return try FfiConverterTypeSamplingConfig.lift(buf)
1679 }
1680
1681 #if swift(>=5.8)
1682 @_documentation(visibility: private)
1683 #endif
1684 public func FfiConverterTypeSamplingConfig_lower(_ value: SamplingConfig) -> RustBuffer {
1685 return FfiConverterTypeSamplingConfig.lower(value)
1686 }
1687
1688
1689 /**
1690 * A single streaming token chunk from the inference engine.
1691 */
1692 public struct StreamChunk: Equatable, Hashable {
1693 /**
1694 * The token text delta (may be empty for the final chunk).
1695 */
1696 public var delta: String
1697 /**
1698 * Whether this is the final chunk in the stream.
1699 */
1700 public var done: Bool
1701 /**
1702 * Finish reason (only set on the final chunk).
1703 */
1704 public var finishReason: String?
1705
1706 // Default memberwise initializers are never public by default, so we
1707 // declare one manually.
1708 public init(
1709 /**
1710 * The token text delta (may be empty for the final chunk).
1711 */delta: String,
1712 /**
1713 * Whether this is the final chunk in the stream.
1714 */done: Bool,
1715 /**
1716 * Finish reason (only set on the final chunk).
1717 */finishReason: String?) {
1718 self.delta = delta
1719 self.done = done
1720 self.finishReason = finishReason
1721 }
1722
1723
1724
1725
1726 }
1727
1728 #if compiler(>=6)
1729 extension StreamChunk: Sendable {}
1730 #endif
1731
1732 #if swift(>=5.8)
1733 @_documentation(visibility: private)
1734 #endif
1735 public struct FfiConverterTypeStreamChunk: FfiConverterRustBuffer {
1736 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> StreamChunk {
1737 return
1738 try StreamChunk(
1739 delta: FfiConverterString.read(from: &buf),
1740 done: FfiConverterBool.read(from: &buf),
1741 finishReason: FfiConverterOptionString.read(from: &buf)
1742 )
1743 }
1744
1745 public static func write(_ value: StreamChunk, into buf: inout [UInt8]) {
1746 FfiConverterString.write(value.delta, into: &buf)
1747 FfiConverterBool.write(value.done, into: &buf)
1748 FfiConverterOptionString.write(value.finishReason, into: &buf)
1749 }
1750 }
1751
1752
1753 #if swift(>=5.8)
1754 @_documentation(visibility: private)
1755 #endif
1756 public func FfiConverterTypeStreamChunk_lift(_ buf: RustBuffer) throws -> StreamChunk {
1757 return try FfiConverterTypeStreamChunk.lift(buf)
1758 }
1759
1760 #if swift(>=5.8)
1761 @_documentation(visibility: private)
1762 #endif
1763 public func FfiConverterTypeStreamChunk_lower(_ value: StreamChunk) -> RustBuffer {
1764 return FfiConverterTypeStreamChunk.lower(value)
1765 }
1766
1767
1768 /**
1769 * Information about a single tool call requested by the model.
1770 */
1771 public struct ToolCallInfo: Equatable, Hashable {
1772 /**
1773 * Unique identifier for this tool call (used to correlate results).
1774 */
1775 public var id: String
1776 /**
1777 * The name of the function the model wants to invoke.
1778 */
1779 public var functionName: String
1780 /**
1781 * JSON-encoded arguments for the function.
1782 */
1783 public var arguments: String
1784
1785 // Default memberwise initializers are never public by default, so we
1786 // declare one manually.
1787 public init(
1788 /**
1789 * Unique identifier for this tool call (used to correlate results).
1790 */id: String,
1791 /**
1792 * The name of the function the model wants to invoke.
1793 */functionName: String,
1794 /**
1795 * JSON-encoded arguments for the function.
1796 */arguments: String) {
1797 self.id = id
1798 self.functionName = functionName
1799 self.arguments = arguments
1800 }
1801
1802
1803
1804
1805 }
1806
1807 #if compiler(>=6)
1808 extension ToolCallInfo: Sendable {}
1809 #endif
1810
1811 #if swift(>=5.8)
1812 @_documentation(visibility: private)
1813 #endif
1814 public struct FfiConverterTypeToolCallInfo: FfiConverterRustBuffer {
1815 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ToolCallInfo {
1816 return
1817 try ToolCallInfo(
1818 id: FfiConverterString.read(from: &buf),
1819 functionName: FfiConverterString.read(from: &buf),
1820 arguments: FfiConverterString.read(from: &buf)
1821 )
1822 }
1823
1824 public static func write(_ value: ToolCallInfo, into buf: inout [UInt8]) {
1825 FfiConverterString.write(value.id, into: &buf)
1826 FfiConverterString.write(value.functionName, into: &buf)
1827 FfiConverterString.write(value.arguments, into: &buf)
1828 }
1829 }
1830
1831
1832 #if swift(>=5.8)
1833 @_documentation(visibility: private)
1834 #endif
1835 public func FfiConverterTypeToolCallInfo_lift(_ buf: RustBuffer) throws -> ToolCallInfo {
1836 return try FfiConverterTypeToolCallInfo.lift(buf)
1837 }
1838
1839 #if swift(>=5.8)
1840 @_documentation(visibility: private)
1841 #endif
1842 public func FfiConverterTypeToolCallInfo_lower(_ value: ToolCallInfo) -> RustBuffer {
1843 return FfiConverterTypeToolCallInfo.lower(value)
1844 }
1845
1846
1847 /**
1848 * A tool definition passed to the model so it knows which tools are available.
1849 */
1850 public struct ToolDefinition: Equatable, Hashable {
1851 /**
1852 * Tool name (e.g. `"read_file"`).
1853 */
1854 public var name: String
1855 /**
1856 * Human-readable description of what the tool does.
1857 */
1858 public var description: String
1859 /**
1860 * JSON Schema string describing the tool's parameters.
1861 */
1862 public var parametersSchema: String
1863
1864 // Default memberwise initializers are never public by default, so we
1865 // declare one manually.
1866 public init(
1867 /**
1868 * Tool name (e.g. `"read_file"`).
1869 */name: String,
1870 /**
1871 * Human-readable description of what the tool does.
1872 */description: String,
1873 /**
1874 * JSON Schema string describing the tool's parameters.
1875 */parametersSchema: String) {
1876 self.name = name
1877 self.description = description
1878 self.parametersSchema = parametersSchema
1879 }
1880
1881
1882
1883
1884 }
1885
1886 #if compiler(>=6)
1887 extension ToolDefinition: Sendable {}
1888 #endif
1889
1890 #if swift(>=5.8)
1891 @_documentation(visibility: private)
1892 #endif
1893 public struct FfiConverterTypeToolDefinition: FfiConverterRustBuffer {
1894 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ToolDefinition {
1895 return
1896 try ToolDefinition(
1897 name: FfiConverterString.read(from: &buf),
1898 description: FfiConverterString.read(from: &buf),
1899 parametersSchema: FfiConverterString.read(from: &buf)
1900 )
1901 }
1902
1903 public static func write(_ value: ToolDefinition, into buf: inout [UInt8]) {
1904 FfiConverterString.write(value.name, into: &buf)
1905 FfiConverterString.write(value.description, into: &buf)
1906 FfiConverterString.write(value.parametersSchema, into: &buf)
1907 }
1908 }
1909
1910
1911 #if swift(>=5.8)
1912 @_documentation(visibility: private)
1913 #endif
1914 public func FfiConverterTypeToolDefinition_lift(_ buf: RustBuffer) throws -> ToolDefinition {
1915 return try FfiConverterTypeToolDefinition.lift(buf)
1916 }
1917
1918 #if swift(>=5.8)
1919 @_documentation(visibility: private)
1920 #endif
1921 public func FfiConverterTypeToolDefinition_lower(_ value: ToolDefinition) -> RustBuffer {
1922 return FfiConverterTypeToolDefinition.lower(value)
1923 }
1924
1925
1926 /**
1927 * The result of executing a tool, sent back to the model.
1928 */
1929 public struct ToolResult: Equatable, Hashable {
1930 /**
1931 * The tool call ID this result corresponds to.
1932 */
1933 public var toolCallId: String
1934 /**
1935 * The output produced by executing the tool.
1936 */
1937 public var content: String
1938
1939 // Default memberwise initializers are never public by default, so we
1940 // declare one manually.
1941 public init(
1942 /**
1943 * The tool call ID this result corresponds to.
1944 */toolCallId: String,
1945 /**
1946 * The output produced by executing the tool.
1947 */content: String) {
1948 self.toolCallId = toolCallId
1949 self.content = content
1950 }
1951
1952
1953
1954
1955 }
1956
1957 #if compiler(>=6)
1958 extension ToolResult: Sendable {}
1959 #endif
1960
1961 #if swift(>=5.8)
1962 @_documentation(visibility: private)
1963 #endif
1964 public struct FfiConverterTypeToolResult: FfiConverterRustBuffer {
1965 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ToolResult {
1966 return
1967 try ToolResult(
1968 toolCallId: FfiConverterString.read(from: &buf),
1969 content: FfiConverterString.read(from: &buf)
1970 )
1971 }
1972
1973 public static func write(_ value: ToolResult, into buf: inout [UInt8]) {
1974 FfiConverterString.write(value.toolCallId, into: &buf)
1975 FfiConverterString.write(value.content, into: &buf)
1976 }
1977 }
1978
1979
1980 #if swift(>=5.8)
1981 @_documentation(visibility: private)
1982 #endif
1983 public func FfiConverterTypeToolResult_lift(_ buf: RustBuffer) throws -> ToolResult {
1984 return try FfiConverterTypeToolResult.lift(buf)
1985 }
1986
1987 #if swift(>=5.8)
1988 @_documentation(visibility: private)
1989 #endif
1990 public func FfiConverterTypeToolResult_lower(_ value: ToolResult) -> RustBuffer {
1991 return FfiConverterTypeToolResult.lower(value)
1992 }
1993
1994 // Note that we don't yet support `indirect` for enums.
1995 // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
1996 /**
1997 * Role of a message in a chat conversation.
1998 *
1999 * Mirrors the standard OpenAI / mistral.rs role taxonomy but is decoupled
2000 * from `mistralrs::TextMessageRole` so that callers don't need a direct
2001 * dependency on mistral.rs.
2002 */
2003
2004 public enum ChatRole: Equatable, Hashable {
2005
2006 case system
2007 case user
2008 case assistant
2009
2010
2011
2012
2013
2014 }
2015
2016 #if compiler(>=6)
2017 extension ChatRole: Sendable {}
2018 #endif
2019
2020 #if swift(>=5.8)
2021 @_documentation(visibility: private)
2022 #endif
2023 public struct FfiConverterTypeChatRole: FfiConverterRustBuffer {
2024 typealias SwiftType = ChatRole
2025
2026 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ChatRole {
2027 let variant: Int32 = try readInt(&buf)
2028 switch variant {
2029
2030 case 1: return .system
2031
2032 case 2: return .user
2033
2034 case 3: return .assistant
2035
2036 default: throw UniffiInternalError.unexpectedEnumCase
2037 }
2038 }
2039
2040 public static func write(_ value: ChatRole, into buf: inout [UInt8]) {
2041 switch value {
2042
2043
2044 case .system:
2045 writeInt(&buf, Int32(1))
2046
2047
2048 case .user:
2049 writeInt(&buf, Int32(2))
2050
2051
2052 case .assistant:
2053 writeInt(&buf, Int32(3))
2054
2055 }
2056 }
2057 }
2058
2059
2060 #if swift(>=5.8)
2061 @_documentation(visibility: private)
2062 #endif
2063 public func FfiConverterTypeChatRole_lift(_ buf: RustBuffer) throws -> ChatRole {
2064 return try FfiConverterTypeChatRole.lift(buf)
2065 }
2066
2067 #if swift(>=5.8)
2068 @_documentation(visibility: private)
2069 #endif
2070 public func FfiConverterTypeChatRole_lower(_ value: ChatRole) -> RustBuffer {
2071 return FfiConverterTypeChatRole.lower(value)
2072 }
2073
2074
2075 // Note that we don't yet support `indirect` for enums.
2076 // See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
2077 /**
2078 * Lifecycle status of the inference engine.
2079 */
2080
2081 public enum EngineStatus: Equatable, Hashable {
2082
2083 /**
2084 * No model loaded.
2085 */
2086 case unloaded
2087 /**
2088 * Model is being downloaded / loaded into memory.
2089 */
2090 case loading
2091 /**
2092 * Model is loaded and ready to accept requests.
2093 */
2094 case ready
2095 /**
2096 * Model is currently running inference.
2097 */
2098 case generating
2099 /**
2100 * An error occurred (model may or may not still be loaded).
2101 */
2102 case error
2103
2104
2105
2106
2107
2108 }
2109
2110 #if compiler(>=6)
2111 extension EngineStatus: Sendable {}
2112 #endif
2113
2114 #if swift(>=5.8)
2115 @_documentation(visibility: private)
2116 #endif
2117 public struct FfiConverterTypeEngineStatus: FfiConverterRustBuffer {
2118 typealias SwiftType = EngineStatus
2119
2120 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EngineStatus {
2121 let variant: Int32 = try readInt(&buf)
2122 switch variant {
2123
2124 case 1: return .unloaded
2125
2126 case 2: return .loading
2127
2128 case 3: return .ready
2129
2130 case 4: return .generating
2131
2132 case 5: return .error
2133
2134 default: throw UniffiInternalError.unexpectedEnumCase
2135 }
2136 }
2137
2138 public static func write(_ value: EngineStatus, into buf: inout [UInt8]) {
2139 switch value {
2140
2141
2142 case .unloaded:
2143 writeInt(&buf, Int32(1))
2144
2145
2146 case .loading:
2147 writeInt(&buf, Int32(2))
2148
2149
2150 case .ready:
2151 writeInt(&buf, Int32(3))
2152
2153
2154 case .generating:
2155 writeInt(&buf, Int32(4))
2156
2157
2158 case .error:
2159 writeInt(&buf, Int32(5))
2160
2161 }
2162 }
2163 }
2164
2165
2166 #if swift(>=5.8)
2167 @_documentation(visibility: private)
2168 #endif
2169 public func FfiConverterTypeEngineStatus_lift(_ buf: RustBuffer) throws -> EngineStatus {
2170 return try FfiConverterTypeEngineStatus.lift(buf)
2171 }
2172
2173 #if swift(>=5.8)
2174 @_documentation(visibility: private)
2175 #endif
2176 public func FfiConverterTypeEngineStatus_lower(_ value: EngineStatus) -> RustBuffer {
2177 return FfiConverterTypeEngineStatus.lower(value)
2178 }
2179
2180
2181
2182 /**
2183 * Errors that can occur during inference engine operations.
2184 *
2185 * Exposed to Swift / Kotlin as a sealed class / enum via `uniffi::Error`.
2186 */
2187 public enum InferenceError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError {
2188
2189
2190
2191 case NoModelLoaded
2192 case AlreadyLoaded(modelName: String
2193 )
2194 case ModelBuild(reason: String
2195 )
2196 case Inference(reason: String
2197 )
2198 case Cancelled
2199 case Other(reason: String
2200 )
2201
2202
2203
2204
2205
2206
2207 public var errorDescription: String? {
2208 String(reflecting: self)
2209 }
2210
2211 }
2212
2213 #if compiler(>=6)
2214 extension InferenceError: Sendable {}
2215 #endif
2216
2217 #if swift(>=5.8)
2218 @_documentation(visibility: private)
2219 #endif
2220 public struct FfiConverterTypeInferenceError: FfiConverterRustBuffer {
2221 typealias SwiftType = InferenceError
2222
2223 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> InferenceError {
2224 let variant: Int32 = try readInt(&buf)
2225 switch variant {
2226
2227
2228
2229
2230 case 1: return .NoModelLoaded
2231 case 2: return .AlreadyLoaded(
2232 modelName: try FfiConverterString.read(from: &buf)
2233 )
2234 case 3: return .ModelBuild(
2235 reason: try FfiConverterString.read(from: &buf)
2236 )
2237 case 4: return .Inference(
2238 reason: try FfiConverterString.read(from: &buf)
2239 )
2240 case 5: return .Cancelled
2241 case 6: return .Other(
2242 reason: try FfiConverterString.read(from: &buf)
2243 )
2244
2245 default: throw UniffiInternalError.unexpectedEnumCase
2246 }
2247 }
2248
2249 public static func write(_ value: InferenceError, into buf: inout [UInt8]) {
2250 switch value {
2251
2252
2253
2254
2255
2256 case .NoModelLoaded:
2257 writeInt(&buf, Int32(1))
2258
2259
2260 case let .AlreadyLoaded(modelName):
2261 writeInt(&buf, Int32(2))
2262 FfiConverterString.write(modelName, into: &buf)
2263
2264
2265 case let .ModelBuild(reason):
2266 writeInt(&buf, Int32(3))
2267 FfiConverterString.write(reason, into: &buf)
2268
2269
2270 case let .Inference(reason):
2271 writeInt(&buf, Int32(4))
2272 FfiConverterString.write(reason, into: &buf)
2273
2274
2275 case .Cancelled:
2276 writeInt(&buf, Int32(5))
2277
2278
2279 case let .Other(reason):
2280 writeInt(&buf, Int32(6))
2281 FfiConverterString.write(reason, into: &buf)
2282
2283 }
2284 }
2285 }
2286
2287
2288 #if swift(>=5.8)
2289 @_documentation(visibility: private)
2290 #endif
2291 public func FfiConverterTypeInferenceError_lift(_ buf: RustBuffer) throws -> InferenceError {
2292 return try FfiConverterTypeInferenceError.lift(buf)
2293 }
2294
2295 #if swift(>=5.8)
2296 @_documentation(visibility: private)
2297 #endif
2298 public func FfiConverterTypeInferenceError_lower(_ value: InferenceError) -> RustBuffer {
2299 return FfiConverterTypeInferenceError.lower(value)
2300 }
2301
2302
2303
2304
2305 /**
2306 * Callback interface for receiving streaming token chunks.
2307 *
2308 * Implement this in Swift / Kotlin and pass it to the free function
2309 * [`stream_chat_message`].
2310 *
2311 * ```swift
2312 * class MyStreamHandler: StreamChunkListener {
2313 * func onChunk(chunk: StreamChunk) -> Bool {
2314 * print(chunk.delta, terminator: "")
2315 * return !chunk.done // return false to stop early
2316 * }
2317 * }
2318 * ```
2319 */
2320 public protocol StreamChunkListener: AnyObject, Sendable {
2321
2322 /**
2323 * Called for each token chunk during streaming inference.
2324 *
2325 * Return `true` to continue receiving chunks, or `false` to cancel
2326 * the stream early (the engine will still persist partial history).
2327 */
2328 func onChunk(chunk: StreamChunk) -> Bool
2329
2330 }
2331
2332
2333 // Put the implementation in a struct so we don't pollute the top-level namespace
2334 fileprivate struct UniffiCallbackInterfaceStreamChunkListener {
2335
2336 // Create the VTable using a series of closures.
2337 // Swift automatically converts these into C callback functions.
2338 //
2339 // This creates 1-element array, since this seems to be the only way to construct a const
2340 // pointer that we can pass to the Rust code.
2341 static let vtable: [UniffiVTableCallbackInterfaceStreamChunkListener] = [UniffiVTableCallbackInterfaceStreamChunkListener(
2342 uniffiFree: { (uniffiHandle: UInt64) -> () in
2343 do {
2344 try FfiConverterCallbackInterfaceStreamChunkListener.handleMap.remove(handle: uniffiHandle)
2345 } catch {
2346 print("Uniffi callback interface StreamChunkListener: handle missing in uniffiFree")
2347 }
2348 },
2349 uniffiClone: { (uniffiHandle: UInt64) -> UInt64 in
2350 do {
2351 return try FfiConverterCallbackInterfaceStreamChunkListener.handleMap.clone(handle: uniffiHandle)
2352 } catch {
2353 fatalError("Uniffi callback interface StreamChunkListener: handle missing in uniffiClone")
2354 }
2355 },
2356 onChunk: { (
2357 uniffiHandle: UInt64,
2358 chunk: RustBuffer,
2359 uniffiOutReturn: UnsafeMutablePointer<Int8>,
2360 uniffiCallStatus: UnsafeMutablePointer<RustCallStatus>
2361 ) in
2362 let makeCall = {
2363 () throws -> Bool in
2364 guard let uniffiObj = try? FfiConverterCallbackInterfaceStreamChunkListener.handleMap.get(handle: uniffiHandle) else {
2365 throw UniffiInternalError.unexpectedStaleHandle
2366 }
2367 return uniffiObj.onChunk(
2368 chunk: try FfiConverterTypeStreamChunk_lift(chunk)
2369 )
2370 }
2371
2372
2373 let writeReturn = { uniffiOutReturn.pointee = FfiConverterBool.lower($0) }
2374 uniffiTraitInterfaceCall(
2375 callStatus: uniffiCallStatus,
2376 makeCall: makeCall,
2377 writeReturn: writeReturn
2378 )
2379 }
2380 )]
2381 }
2382
2383 private func uniffiCallbackInitStreamChunkListener() {
2384 uniffi_onde_fn_init_callback_vtable_streamchunklistener(UniffiCallbackInterfaceStreamChunkListener.vtable)
2385 }
2386
2387 // FfiConverter protocol for callback interfaces
2388 #if swift(>=5.8)
2389 @_documentation(visibility: private)
2390 #endif
2391 fileprivate struct FfiConverterCallbackInterfaceStreamChunkListener {
2392 fileprivate static let handleMap = UniffiHandleMap<StreamChunkListener>()
2393 }
2394
2395 #if swift(>=5.8)
2396 @_documentation(visibility: private)
2397 #endif
2398 extension FfiConverterCallbackInterfaceStreamChunkListener : FfiConverter {
2399 typealias SwiftType = StreamChunkListener
2400 typealias FfiType = UInt64
2401
2402 #if swift(>=5.8)
2403 @_documentation(visibility: private)
2404 #endif
2405 public static func lift(_ handle: UInt64) throws -> SwiftType {
2406 try handleMap.get(handle: handle)
2407 }
2408
2409 #if swift(>=5.8)
2410 @_documentation(visibility: private)
2411 #endif
2412 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
2413 let handle: UInt64 = try readInt(&buf)
2414 return try lift(handle)
2415 }
2416
2417 #if swift(>=5.8)
2418 @_documentation(visibility: private)
2419 #endif
2420 public static func lower(_ v: SwiftType) -> UInt64 {
2421 return handleMap.insert(obj: v)
2422 }
2423
2424 #if swift(>=5.8)
2425 @_documentation(visibility: private)
2426 #endif
2427 public static func write(_ v: SwiftType, into buf: inout [UInt8]) {
2428 writeInt(&buf, lower(v))
2429 }
2430 }
2431
2432
2433 #if swift(>=5.8)
2434 @_documentation(visibility: private)
2435 #endif
2436 public func FfiConverterCallbackInterfaceStreamChunkListener_lift(_ handle: UInt64) throws -> StreamChunkListener {
2437 return try FfiConverterCallbackInterfaceStreamChunkListener.lift(handle)
2438 }
2439
2440 #if swift(>=5.8)
2441 @_documentation(visibility: private)
2442 #endif
2443 public func FfiConverterCallbackInterfaceStreamChunkListener_lower(_ v: StreamChunkListener) -> UInt64 {
2444 return FfiConverterCallbackInterfaceStreamChunkListener.lower(v)
2445 }
2446
2447 #if swift(>=5.8)
2448 @_documentation(visibility: private)
2449 #endif
2450 fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer {
2451 typealias SwiftType = UInt64?
2452
2453 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
2454 guard let value = value else {
2455 writeInt(&buf, Int8(0))
2456 return
2457 }
2458 writeInt(&buf, Int8(1))
2459 FfiConverterUInt64.write(value, into: &buf)
2460 }
2461
2462 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
2463 switch try readInt(&buf) as Int8 {
2464 case 0: return nil
2465 case 1: return try FfiConverterUInt64.read(from: &buf)
2466 default: throw UniffiInternalError.unexpectedOptionalTag
2467 }
2468 }
2469 }
2470
2471 #if swift(>=5.8)
2472 @_documentation(visibility: private)
2473 #endif
2474 fileprivate struct FfiConverterOptionFloat: FfiConverterRustBuffer {
2475 typealias SwiftType = Float?
2476
2477 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
2478 guard let value = value else {
2479 writeInt(&buf, Int8(0))
2480 return
2481 }
2482 writeInt(&buf, Int8(1))
2483 FfiConverterFloat.write(value, into: &buf)
2484 }
2485
2486 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
2487 switch try readInt(&buf) as Int8 {
2488 case 0: return nil
2489 case 1: return try FfiConverterFloat.read(from: &buf)
2490 default: throw UniffiInternalError.unexpectedOptionalTag
2491 }
2492 }
2493 }
2494
2495 #if swift(>=5.8)
2496 @_documentation(visibility: private)
2497 #endif
2498 fileprivate struct FfiConverterOptionDouble: FfiConverterRustBuffer {
2499 typealias SwiftType = Double?
2500
2501 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
2502 guard let value = value else {
2503 writeInt(&buf, Int8(0))
2504 return
2505 }
2506 writeInt(&buf, Int8(1))
2507 FfiConverterDouble.write(value, into: &buf)
2508 }
2509
2510 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
2511 switch try readInt(&buf) as Int8 {
2512 case 0: return nil
2513 case 1: return try FfiConverterDouble.read(from: &buf)
2514 default: throw UniffiInternalError.unexpectedOptionalTag
2515 }
2516 }
2517 }
2518
2519 #if swift(>=5.8)
2520 @_documentation(visibility: private)
2521 #endif
2522 fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer {
2523 typealias SwiftType = String?
2524
2525 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
2526 guard let value = value else {
2527 writeInt(&buf, Int8(0))
2528 return
2529 }
2530 writeInt(&buf, Int8(1))
2531 FfiConverterString.write(value, into: &buf)
2532 }
2533
2534 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
2535 switch try readInt(&buf) as Int8 {
2536 case 0: return nil
2537 case 1: return try FfiConverterString.read(from: &buf)
2538 default: throw UniffiInternalError.unexpectedOptionalTag
2539 }
2540 }
2541 }
2542
2543 #if swift(>=5.8)
2544 @_documentation(visibility: private)
2545 #endif
2546 fileprivate struct FfiConverterOptionTypeSamplingConfig: FfiConverterRustBuffer {
2547 typealias SwiftType = SamplingConfig?
2548
2549 public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
2550 guard let value = value else {
2551 writeInt(&buf, Int8(0))
2552 return
2553 }
2554 writeInt(&buf, Int8(1))
2555 FfiConverterTypeSamplingConfig.write(value, into: &buf)
2556 }
2557
2558 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
2559 switch try readInt(&buf) as Int8 {
2560 case 0: return nil
2561 case 1: return try FfiConverterTypeSamplingConfig.read(from: &buf)
2562 default: throw UniffiInternalError.unexpectedOptionalTag
2563 }
2564 }
2565 }
2566
2567 #if swift(>=5.8)
2568 @_documentation(visibility: private)
2569 #endif
2570 fileprivate struct FfiConverterSequenceString: FfiConverterRustBuffer {
2571 typealias SwiftType = [String]
2572
2573 public static func write(_ value: [String], into buf: inout [UInt8]) {
2574 let len = Int32(value.count)
2575 writeInt(&buf, len)
2576 for item in value {
2577 FfiConverterString.write(item, into: &buf)
2578 }
2579 }
2580
2581 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String] {
2582 let len: Int32 = try readInt(&buf)
2583 var seq = [String]()
2584 seq.reserveCapacity(Int(len))
2585 for _ in 0 ..< len {
2586 seq.append(try FfiConverterString.read(from: &buf))
2587 }
2588 return seq
2589 }
2590 }
2591
2592 #if swift(>=5.8)
2593 @_documentation(visibility: private)
2594 #endif
2595 fileprivate struct FfiConverterSequenceTypeChatMessage: FfiConverterRustBuffer {
2596 typealias SwiftType = [ChatMessage]
2597
2598 public static func write(_ value: [ChatMessage], into buf: inout [UInt8]) {
2599 let len = Int32(value.count)
2600 writeInt(&buf, len)
2601 for item in value {
2602 FfiConverterTypeChatMessage.write(item, into: &buf)
2603 }
2604 }
2605
2606 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ChatMessage] {
2607 let len: Int32 = try readInt(&buf)
2608 var seq = [ChatMessage]()
2609 seq.reserveCapacity(Int(len))
2610 for _ in 0 ..< len {
2611 seq.append(try FfiConverterTypeChatMessage.read(from: &buf))
2612 }
2613 return seq
2614 }
2615 }
2616
2617 #if swift(>=5.8)
2618 @_documentation(visibility: private)
2619 #endif
2620 fileprivate struct FfiConverterSequenceTypeToolCallInfo: FfiConverterRustBuffer {
2621 typealias SwiftType = [ToolCallInfo]
2622
2623 public static func write(_ value: [ToolCallInfo], into buf: inout [UInt8]) {
2624 let len = Int32(value.count)
2625 writeInt(&buf, len)
2626 for item in value {
2627 FfiConverterTypeToolCallInfo.write(item, into: &buf)
2628 }
2629 }
2630
2631 public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ToolCallInfo] {
2632 let len: Int32 = try readInt(&buf)
2633 var seq = [ToolCallInfo]()
2634 seq.reserveCapacity(Int(len))
2635 for _ in 0 ..< len {
2636 seq.append(try FfiConverterTypeToolCallInfo.read(from: &buf))
2637 }
2638 return seq
2639 }
2640 }
2641 private let UNIFFI_RUST_FUTURE_POLL_READY: Int8 = 0
2642 private let UNIFFI_RUST_FUTURE_POLL_WAKE: Int8 = 1
2643
2644 fileprivate let uniffiContinuationHandleMap = UniffiHandleMap<UnsafeContinuation<Int8, Never>>()
2645
2646 fileprivate func uniffiRustCallAsync<F, T>(
2647 rustFutureFunc: () -> UInt64,
2648 pollFunc: (UInt64, @escaping UniffiRustFutureContinuationCallback, UInt64) -> (),
2649 completeFunc: (UInt64, UnsafeMutablePointer<RustCallStatus>) -> F,
2650 freeFunc: (UInt64) -> (),
2651 liftFunc: (F) throws -> T,
2652 errorHandler: ((RustBuffer) throws -> Swift.Error)?
2653 ) async throws -> T {
2654 // Make sure to call the ensure init function since future creation doesn't have a
2655 // RustCallStatus param, so doesn't use makeRustCall()
2656 uniffiEnsureOndeInitialized()
2657 let rustFuture = rustFutureFunc()
2658 defer {
2659 freeFunc(rustFuture)
2660 }
2661 var pollResult: Int8;
2662 repeat {
2663 pollResult = await withUnsafeContinuation {
2664 pollFunc(
2665 rustFuture,
2666 { handle, pollResult in
2667 uniffiFutureContinuationCallback(handle: handle, pollResult: pollResult)
2668 },
2669 uniffiContinuationHandleMap.insert(obj: $0)
2670 )
2671 }
2672 } while pollResult != UNIFFI_RUST_FUTURE_POLL_READY
2673
2674 return try liftFunc(makeRustCall(
2675 { completeFunc(rustFuture, $0) },
2676 errorHandler: errorHandler
2677 ))
2678 }
2679
2680 // Callback handlers for an async calls. These are invoked by Rust when the future is ready. They
2681 // lift the return value or error and resume the suspended function.
2682 fileprivate func uniffiFutureContinuationCallback(handle: UInt64, pollResult: Int8) {
2683 if let continuation = try? uniffiContinuationHandleMap.remove(handle: handle) {
2684 continuation.resume(returning: pollResult)
2685 } else {
2686 print("uniffiFutureContinuationCallback invalid handle")
2687 }
2688 }
2689 /**
2690 * Create an assistant message.
2691 */
2692 public func assistantMessage(content: String) -> ChatMessage {
2693 return try! FfiConverterTypeChatMessage_lift(try! rustCall() {
2694 uniffi_onde_fn_func_assistant_message(
2695 FfiConverterString.lower(content),$0
2696 )
2697 })
2698 }
2699 /**
2700 * Return the platform-appropriate default GGUF model configuration.
2701 *
2702 * - tvOS / iOS / Android → Qwen 2.5 1.5B (~941 MB)
2703 * - macOS / Windows / Linux → Qwen 2.5 3B (~1.93 GB)
2704 */
2705 public func defaultModelConfig() -> GgufModelConfig {
2706 return try! FfiConverterTypeGgufModelConfig_lift(try! rustCall() {
2707 uniffi_onde_fn_func_default_model_config($0
2708 )
2709 })
2710 }
2711 /**
2712 * Return default sampling parameters for creative chat.
2713 */
2714 public func defaultSamplingConfig() -> SamplingConfig {
2715 return try! FfiConverterTypeSamplingConfig_lift(try! rustCall() {
2716 uniffi_onde_fn_func_default_sampling_config($0
2717 )
2718 })
2719 }
2720 /**
2721 * Return deterministic (greedy) sampling parameters.
2722 */
2723 public func deterministicSamplingConfig() -> SamplingConfig {
2724 return try! FfiConverterTypeSamplingConfig_lift(try! rustCall() {
2725 uniffi_onde_fn_func_deterministic_sampling_config($0
2726 )
2727 })
2728 }
2729 /**
2730 * Return conservative sampling parameters for mobile devices.
2731 */
2732 public func mobileSamplingConfig() -> SamplingConfig {
2733 return try! FfiConverterTypeSamplingConfig_lift(try! rustCall() {
2734 uniffi_onde_fn_func_mobile_sampling_config($0
2735 )
2736 })
2737 }
2738 /**
2739 * Return the Qwen 2.5 1.5B GGUF model configuration (~941 MB).
2740 */
2741 public func qwen2515bConfig() -> GgufModelConfig {
2742 return try! FfiConverterTypeGgufModelConfig_lift(try! rustCall() {
2743 uniffi_onde_fn_func_qwen25_1_5b_config($0
2744 )
2745 })
2746 }
2747 /**
2748 * Return the Qwen 2.5 3B GGUF model configuration (~1.93 GB).
2749 */
2750 public func qwen253bConfig() -> GgufModelConfig {
2751 return try! FfiConverterTypeGgufModelConfig_lift(try! rustCall() {
2752 uniffi_onde_fn_func_qwen25_3b_config($0
2753 )
2754 })
2755 }
2756 /**
2757 * Stream a chat message through the engine, delivering token chunks to
2758 * the `listener` callback.
2759 *
2760 * This is a **free function** (not an Object method) because UniFFI 0.31
2761 * requires `callback_interface` parameters to be passed to free functions
2762 * rather than Object methods.
2763 *
2764 * The `listener.on_chunk()` callback is called for each token delta.
2765 * Return `true` to continue, or `false` to cancel early.
2766 *
2767 * The user message and assembled reply are automatically appended to the
2768 * engine's conversation history when streaming completes.
2769 *
2770 * ```swift
2771 * class MyHandler: StreamChunkListener {
2772 * func onChunk(chunk: StreamChunk) -> Bool {
2773 * print(chunk.delta, terminator: "")
2774 * return !chunk.done
2775 * }
2776 * }
2777 *
2778 * try await streamChatMessage(
2779 * engine: engine,
2780 * message: "Tell me a story.",
2781 * listener: MyHandler()
2782 * )
2783 * ```
2784 */
2785 public func streamChatMessage(engine: OndeChatEngine, message: String, listener: StreamChunkListener)async throws {
2786 return
2787 try await uniffiRustCallAsync(
2788 rustFutureFunc: {
2789 uniffi_onde_fn_func_stream_chat_message(FfiConverterTypeOndeChatEngine_lower(engine),FfiConverterString.lower(message),FfiConverterCallbackInterfaceStreamChunkListener_lower(listener)
2790 )
2791 },
2792 pollFunc: ffi_onde_rust_future_poll_void,
2793 completeFunc: ffi_onde_rust_future_complete_void,
2794 freeFunc: ffi_onde_rust_future_free_void,
2795 liftFunc: { $0 },
2796 errorHandler: FfiConverterTypeInferenceError_lift
2797 )
2798 }
2799 /**
2800 * Create a system message.
2801 */
2802 public func systemMessage(content: String) -> ChatMessage {
2803 return try! FfiConverterTypeChatMessage_lift(try! rustCall() {
2804 uniffi_onde_fn_func_system_message(
2805 FfiConverterString.lower(content),$0
2806 )
2807 })
2808 }
2809 /**
2810 * Create a user message.
2811 */
2812 public func userMessage(content: String) -> ChatMessage {
2813 return try! FfiConverterTypeChatMessage_lift(try! rustCall() {
2814 uniffi_onde_fn_func_user_message(
2815 FfiConverterString.lower(content),$0
2816 )
2817 })
2818 }
2819
2820 private enum InitializationResult {
2821 case ok
2822 case contractVersionMismatch
2823 case apiChecksumMismatch
2824 }
2825 // Use a global variable to perform the versioning checks. Swift ensures that
2826 // the code inside is only computed once.
2827 private let initializationResult: InitializationResult = {
2828 // Get the bindings contract version from our ComponentInterface
2829 let bindings_contract_version = 30
2830 // Get the scaffolding contract version by calling the into the dylib
2831 let scaffolding_contract_version = ffi_onde_uniffi_contract_version()
2832 if bindings_contract_version != scaffolding_contract_version {
2833 return InitializationResult.contractVersionMismatch
2834 }
2835 if (uniffi_onde_checksum_func_assistant_message() != 47135) {
2836 return InitializationResult.apiChecksumMismatch
2837 }
2838 if (uniffi_onde_checksum_func_default_model_config() != 34766) {
2839 return InitializationResult.apiChecksumMismatch
2840 }
2841 if (uniffi_onde_checksum_func_default_sampling_config() != 57358) {
2842 return InitializationResult.apiChecksumMismatch
2843 }
2844 if (uniffi_onde_checksum_func_deterministic_sampling_config() != 3003) {
2845 return InitializationResult.apiChecksumMismatch
2846 }
2847 if (uniffi_onde_checksum_func_mobile_sampling_config() != 46137) {
2848 return InitializationResult.apiChecksumMismatch
2849 }
2850 if (uniffi_onde_checksum_func_qwen25_1_5b_config() != 41668) {
2851 return InitializationResult.apiChecksumMismatch
2852 }
2853 if (uniffi_onde_checksum_func_qwen25_3b_config() != 36458) {
2854 return InitializationResult.apiChecksumMismatch
2855 }
2856 if (uniffi_onde_checksum_func_stream_chat_message() != 5168) {
2857 return InitializationResult.apiChecksumMismatch
2858 }
2859 if (uniffi_onde_checksum_func_system_message() != 55655) {
2860 return InitializationResult.apiChecksumMismatch
2861 }
2862 if (uniffi_onde_checksum_func_user_message() != 23108) {
2863 return InitializationResult.apiChecksumMismatch
2864 }
2865 if (uniffi_onde_checksum_method_ondechatengine_clear_history() != 5662) {
2866 return InitializationResult.apiChecksumMismatch
2867 }
2868 if (uniffi_onde_checksum_method_ondechatengine_clear_system_prompt() != 46275) {
2869 return InitializationResult.apiChecksumMismatch
2870 }
2871 if (uniffi_onde_checksum_method_ondechatengine_generate() != 63069) {
2872 return InitializationResult.apiChecksumMismatch
2873 }
2874 if (uniffi_onde_checksum_method_ondechatengine_history() != 45301) {
2875 return InitializationResult.apiChecksumMismatch
2876 }
2877 if (uniffi_onde_checksum_method_ondechatengine_info() != 42415) {
2878 return InitializationResult.apiChecksumMismatch
2879 }
2880 if (uniffi_onde_checksum_method_ondechatengine_is_loaded() != 59838) {
2881 return InitializationResult.apiChecksumMismatch
2882 }
2883 if (uniffi_onde_checksum_method_ondechatengine_load_assigned_model() != 25824) {
2884 return InitializationResult.apiChecksumMismatch
2885 }
2886 if (uniffi_onde_checksum_method_ondechatengine_load_default_model() != 32187) {
2887 return InitializationResult.apiChecksumMismatch
2888 }
2889 if (uniffi_onde_checksum_method_ondechatengine_load_gguf_model() != 6873) {
2890 return InitializationResult.apiChecksumMismatch
2891 }
2892 if (uniffi_onde_checksum_method_ondechatengine_push_history() != 61696) {
2893 return InitializationResult.apiChecksumMismatch
2894 }
2895 if (uniffi_onde_checksum_method_ondechatengine_send_message() != 23695) {
2896 return InitializationResult.apiChecksumMismatch
2897 }
2898 if (uniffi_onde_checksum_method_ondechatengine_set_sampling() != 10759) {
2899 return InitializationResult.apiChecksumMismatch
2900 }
2901 if (uniffi_onde_checksum_method_ondechatengine_set_system_prompt() != 63168) {
2902 return InitializationResult.apiChecksumMismatch
2903 }
2904 if (uniffi_onde_checksum_method_ondechatengine_unload_model() != 33799) {
2905 return InitializationResult.apiChecksumMismatch
2906 }
2907 if (uniffi_onde_checksum_constructor_ondechatengine_new() != 39683) {
2908 return InitializationResult.apiChecksumMismatch
2909 }
2910 if (uniffi_onde_checksum_method_streamchunklistener_on_chunk() != 33920) {
2911 return InitializationResult.apiChecksumMismatch
2912 }
2913
2914 uniffiCallbackInitStreamChunkListener()
2915 return InitializationResult.ok
2916 }()
2917
2918 // Make the ensure init function public so that other modules which have external type references to
2919 // our types can call it.
2920 public func uniffiEnsureOndeInitialized() {
2921 switch initializationResult {
2922 case .ok:
2923 break
2924 case .contractVersionMismatch:
2925 fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project")
2926 case .apiChecksumMismatch:
2927 fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
2928 }
2929 }
2930
2931 // swiftlint:enable all