Release 1.2.3
github-actions[bot] committed
Aug 19, 2026 at 09:26 UTC
b08a412e8f89c20743551d423cb6c0308f900be1
2 files changed
+188
-2
Package.swift
+2
-2
@@ -24,9 +24,9 @@ let packageRoot = URL(fileURLWithPath: #filePath).deletingLastPathComponent()
24
let localFrameworkPath = "OndeFramework.xcframework"
25
let localFrameworkAbsolutePath = packageRoot.appendingPathComponent(localFrameworkPath).path
26
let releaseFrameworkURL =
27
- "https://github.com/ondeinference/onde/releases/download/1.2.2/OndeFramework.xcframework.zip"
27
+ "https://github.com/ondeinference/onde/releases/download/1.2.3/OndeFramework.xcframework.zip"
28
let releaseFrameworkChecksum =
29
- "3e930144fd078d1bed78ebafa22edf9763a3bc6588b0a4667fb37096ba78220b"
29
+ "256ff064dbb77b7d433fe768db3dae5b63ded2768d47ed913815cc1c876cbaf3"
30
31
let ondeFrameworkTarget: Target
32
if FileManager.default.fileExists(atPath: localFrameworkAbsolutePath) {
Sources/Onde/onde.swift
+186
@@ -632,6 +632,18 @@ public protocol OndeChatEngineProtocol: AnyObject, Sendable {
632
*/
633
func loadGgufModel(config: GgufModelConfig, systemPrompt: String?, sampling: SamplingConfig?) async throws -> Double
634
635
+ /**
636
+ * Load a UQFF model into the engine.
637
+ *
638
+ * UQFF files are pre-quantised and load directly without runtime
639
+ * conversion. `config.model_id` names the UQFF export (not the original
640
+ * unquantised repo), and `config.files` should contain the first UQFF
641
+ * shard or explicit shard filenames.
642
+ *
643
+ * Returns the wall-clock loading time in seconds.
644
+ */
645
+ func loadUqffModel(config: UqffModelConfig, systemPrompt: String?, sampling: SamplingConfig?) async throws -> Double
646
+
647
/**
648
* Append a message to history without running inference.
649
*/
@@ -943,6 +955,33 @@ open func loadGgufModel(config: GgufModelConfig, systemPrompt: String?, sampling
955
)
956
}
957
958
+ /**
959
+ * Load a UQFF model into the engine.
960
+ *
961
+ * UQFF files are pre-quantised and load directly without runtime
962
+ * conversion. `config.model_id` names the UQFF export (not the original
963
+ * unquantised repo), and `config.files` should contain the first UQFF
964
+ * shard or explicit shard filenames.
965
+ *
966
+ * Returns the wall-clock loading time in seconds.
967
+ */
968
+open func loadUqffModel(config: UqffModelConfig, systemPrompt: String?, sampling: SamplingConfig?)async throws -> Double {
969
+ return
970
+ try await uniffiRustCallAsync(
971
+ rustFutureFunc: {
972
+ uniffi_onde_fn_method_ondechatengine_load_uqff_model(
973
+ self.uniffiCloneHandle(),
974
+ FfiConverterTypeUqffModelConfig_lower(config),FfiConverterOptionString.lower(systemPrompt),FfiConverterOptionTypeSamplingConfig.lower(sampling)
975
+ )
976
+ },
977
+ pollFunc: ffi_onde_rust_future_poll_f64,
978
+ completeFunc: ffi_onde_rust_future_complete_f64,
979
+ freeFunc: ffi_onde_rust_future_free_f64,
980
+ liftFunc: FfiConverterDouble.lift,
981
+ errorHandler: FfiConverterTypeInferenceError_lift
982
+ )
983
+}
984
+
985
/**
986
* Append a message to history without running inference.
987
*/
@@ -1991,6 +2030,127 @@ public func FfiConverterTypeToolResult_lower(_ value: ToolResult) -> RustBuffer
2030
return FfiConverterTypeToolResult.lower(value)
2031
}
2032
2033
+
2034
+/**
2035
+ * Configuration for loading a UQFF model via mistral.rs
2036
+ * `UqffTextModelBuilder`.
2037
+ *
2038
+ * UQFF files store pre-quantised weights and load directly
2039
+ * without the runtime memory spike of in-situ quantisation. `model_id` points
2040
+ * at the UQFF *export* — the directory or repository holding the shards
2041
+ * alongside `residual.safetensors`, `config.json`, and the tokenizer — and
2042
+ * `files` identifies the first UQFF shard or explicit UQFF shard files.
2043
+ *
2044
+ * Note that `model_id` is **not** the original unquantised model repository:
2045
+ * mistral.rs resolves the shards, the residual weights, and the JSON assets by
2046
+ * sibling lookup next to `model_id`, so pointing it at the source repo fails
2047
+ * with a missing-file error. A UQFF export is self-contained by design.
2048
+ */
2049
+public struct UqffModelConfig: Equatable, Hashable {
2050
+ /**
2051
+ * HuggingFace repository ID or local directory of the UQFF export, e.g.
2052
+ * `"mistralrs-community/gemma-4-E4B-it-UQFF"`.
2053
+ */
2054
+ public var modelId: String
2055
+ /**
2056
+ * UQFF filename(s) within the repository. For sharded UQFFs, passing the
2057
+ * first shard, e.g. `["q4k-0.uqff"]`, is enough for mistral.rs to discover
2058
+ * siblings. Numeric and ISQ-name shorthands such as `"4"` and `"q4k"` are
2059
+ * also accepted by the underlying loader.
2060
+ */
2061
+ public var files: [String]
2062
+ /**
2063
+ * Human-friendly display name, e.g. `"Gemma 4 E4B (UQFF Q4K)"`.
2064
+ */
2065
+ public var displayName: String
2066
+ /**
2067
+ * Approximate memory footprint description, e.g. `"~2.5 GB (UQFF Q4K)"`.
2068
+ */
2069
+ public var approxMemory: String
2070
+ /**
2071
+ * Optional Jinja chat template string. When set, this overrides the
2072
+ * template resolved from the base model.
2073
+ */
2074
+ public var chatTemplate: String?
2075
+
2076
+ // Default memberwise initializers are never public by default, so we
2077
+ // declare one manually.
2078
+ public init(
2079
+ /**
2080
+ * HuggingFace repository ID or local directory of the UQFF export, e.g.
2081
+ * `"mistralrs-community/gemma-4-E4B-it-UQFF"`.
2082
+ */modelId: String,
2083
+ /**
2084
+ * UQFF filename(s) within the repository. For sharded UQFFs, passing the
2085
+ * first shard, e.g. `["q4k-0.uqff"]`, is enough for mistral.rs to discover
2086
+ * siblings. Numeric and ISQ-name shorthands such as `"4"` and `"q4k"` are
2087
+ * also accepted by the underlying loader.
2088
+ */files: [String],
2089
+ /**
2090
+ * Human-friendly display name, e.g. `"Gemma 4 E4B (UQFF Q4K)"`.
2091
+ */displayName: String,
2092
+ /**
2093
+ * Approximate memory footprint description, e.g. `"~2.5 GB (UQFF Q4K)"`.
2094
+ */approxMemory: String,
2095
+ /**
2096
+ * Optional Jinja chat template string. When set, this overrides the
2097
+ * template resolved from the base model.
2098
+ */chatTemplate: String?) {
2099
+ self.modelId = modelId
2100
+ self.files = files
2101
+ self.displayName = displayName
2102
+ self.approxMemory = approxMemory
2103
+ self.chatTemplate = chatTemplate
2104
+ }
2105
+
2106
+
2107
+
2108
+
2109
+}
2110
+
2111
+#if compiler(>=6)
2112
+extension UqffModelConfig: Sendable {}
2113
+#endif
2114
+
2115
+#if swift(>=5.8)
2116
+@_documentation(visibility: private)
2117
+#endif
2118
+public struct FfiConverterTypeUqffModelConfig: FfiConverterRustBuffer {
2119
+ public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UqffModelConfig {
2120
+ return
2121
+ try UqffModelConfig(
2122
+ modelId: FfiConverterString.read(from: &buf),
2123
+ files: FfiConverterSequenceString.read(from: &buf),
2124
+ displayName: FfiConverterString.read(from: &buf),
2125
+ approxMemory: FfiConverterString.read(from: &buf),
2126
+ chatTemplate: FfiConverterOptionString.read(from: &buf)
2127
+ )
2128
+ }
2129
+
2130
+ public static func write(_ value: UqffModelConfig, into buf: inout [UInt8]) {
2131
+ FfiConverterString.write(value.modelId, into: &buf)
2132
+ FfiConverterSequenceString.write(value.files, into: &buf)
2133
+ FfiConverterString.write(value.displayName, into: &buf)
2134
+ FfiConverterString.write(value.approxMemory, into: &buf)
2135
+ FfiConverterOptionString.write(value.chatTemplate, into: &buf)
2136
+ }
2137
+}
2138
+
2139
+
2140
+#if swift(>=5.8)
2141
+@_documentation(visibility: private)
2142
+#endif
2143
+public func FfiConverterTypeUqffModelConfig_lift(_ buf: RustBuffer) throws -> UqffModelConfig {
2144
+ return try FfiConverterTypeUqffModelConfig.lift(buf)
2145
+}
2146
+
2147
+#if swift(>=5.8)
2148
+@_documentation(visibility: private)
2149
+#endif
2150
+public func FfiConverterTypeUqffModelConfig_lower(_ value: UqffModelConfig) -> RustBuffer {
2151
+ return FfiConverterTypeUqffModelConfig.lower(value)
2152
+}
2153
+
2154
// Note that we don't yet support `indirect` for enums.
2155
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
2156
/**
@@ -2919,6 +3079,26 @@ public func systemMessage(content: String) -> ChatMessage {
3079
)
3080
})
3081
}
3082
+/**
3083
+ * Create a generic UQFF model configuration.
3084
+ *
3085
+ * `model_id` is the HuggingFace repo or local directory of the UQFF export
3086
+ * (the shards plus `residual.safetensors`, `config.json`, and the tokenizer),
3087
+ * not the original unquantised repo. `files` accepts a first shard
3088
+ * (`q4k-0.uqff`), explicit shards, or mistral.rs shorthands such as `q4k`
3089
+ * and `4`.
3090
+ */
3091
+public func uqffModelConfig(modelId: String, files: [String], displayName: String, approxMemory: String, chatTemplate: String?) -> UqffModelConfig {
3092
+ return try! FfiConverterTypeUqffModelConfig_lift(try! rustCall() {
3093
+ uniffi_onde_fn_func_uqff_model_config(
3094
+ FfiConverterString.lower(modelId),
3095
+ FfiConverterSequenceString.lower(files),
3096
+ FfiConverterString.lower(displayName),
3097
+ FfiConverterString.lower(approxMemory),
3098
+ FfiConverterOptionString.lower(chatTemplate),$0
3099
+ )
3100
+})
3101
+}
3102
/**
3103
* Create a user message.
3104
*/
@@ -3005,6 +3185,9 @@ private let initializationResult: InitializationResult = {
3185
if (uniffi_onde_checksum_func_system_message() != 55655) {
3186
return InitializationResult.apiChecksumMismatch
3187
}
3188
+ if (uniffi_onde_checksum_func_uqff_model_config() != 61694) {
3189
+ return InitializationResult.apiChecksumMismatch
3190
+ }
3191
if (uniffi_onde_checksum_func_user_message() != 23108) {
3192
return InitializationResult.apiChecksumMismatch
3193
}
@@ -3035,6 +3218,9 @@ private let initializationResult: InitializationResult = {
3218
if (uniffi_onde_checksum_method_ondechatengine_load_gguf_model() != 6873) {
3219
return InitializationResult.apiChecksumMismatch
3220
}
3221
+ if (uniffi_onde_checksum_method_ondechatengine_load_uqff_model() != 18211) {
3222
+ return InitializationResult.apiChecksumMismatch
3223
+ }
3224
if (uniffi_onde_checksum_method_ondechatengine_push_history() != 61696) {
3225
return InitializationResult.apiChecksumMismatch
3226
}