|
1
|
// This file is automatically generated, so please do not edit it. |
|
2
|
// @generated by `flutter_rust_bridge`@ 2.12.0. |
|
3
|
|
|
4
|
// ignore_for_file: type=lint, unused_import, unnecessary_import |
|
5
|
|
|
6
|
// ignore_for_file: invalid_use_of_internal_member |
|
7
|
|
|
8
|
import 'frb_generated.dart'; |
|
9
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; |
|
10
|
import 'package:freezed_annotation/freezed_annotation.dart' hide protected; |
|
11
|
part 'api.freezed.dart'; |
|
12
|
|
|
13
|
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `assert_fields_are_eq`, `assert_fields_are_eq`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `clone`, `eq`, `eq`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from`, `from` |
|
14
|
|
|
15
|
/// Return the platform-appropriate default `GgufModelConfig`. |
|
16
|
/// |
|
17
|
/// Selects the 1.5B model on iOS / tvOS / Android and the 3B model on |
|
18
|
/// macOS / Windows / Linux. |
|
19
|
GgufModelConfig defaultModelConfig() => |
|
20
|
RustLib.instance.api.crateApiDefaultModelConfig(); |
|
21
|
|
|
22
|
/// Build a generic `UqffModelConfig`. |
|
23
|
UqffModelConfig uqffModelConfig({ |
|
24
|
required String modelId, |
|
25
|
required List<String> files, |
|
26
|
required String displayName, |
|
27
|
required String approxMemory, |
|
28
|
String? chatTemplate, |
|
29
|
}) => RustLib.instance.api.crateApiUqffModelConfig( |
|
30
|
modelId: modelId, |
|
31
|
files: files, |
|
32
|
displayName: displayName, |
|
33
|
approxMemory: approxMemory, |
|
34
|
chatTemplate: chatTemplate, |
|
35
|
); |
|
36
|
|
|
37
|
/// `GgufModelConfig` for Qwen 2.5 1.5B Instruct Q4_K_M (~941 MB). |
|
38
|
GgufModelConfig qwen2515BConfig() => |
|
39
|
RustLib.instance.api.crateApiQwen2515BConfig(); |
|
40
|
|
|
41
|
/// `GgufModelConfig` for Qwen 2.5 3B Instruct Q4_K_M (~1.93 GB). |
|
42
|
GgufModelConfig qwen253BConfig() => |
|
43
|
RustLib.instance.api.crateApiQwen253BConfig(); |
|
44
|
|
|
45
|
/// `GgufModelConfig` for Qwen 2.5 Coder 1.5B Instruct Q4_K_M (~941 MB). |
|
46
|
GgufModelConfig qwen25Coder15BConfig() => |
|
47
|
RustLib.instance.api.crateApiQwen25Coder15BConfig(); |
|
48
|
|
|
49
|
/// `GgufModelConfig` for Qwen 2.5 Coder 3B Instruct Q4_K_M (~1.93 GB). |
|
50
|
GgufModelConfig qwen25Coder3BConfig() => |
|
51
|
RustLib.instance.api.crateApiQwen25Coder3BConfig(); |
|
52
|
|
|
53
|
/// `GgufModelConfig` for Qwen 3 0.6B Q4_K_M (~0.5 GB). |
|
54
|
GgufModelConfig qwen306BConfig() => |
|
55
|
RustLib.instance.api.crateApiQwen306BConfig(); |
|
56
|
|
|
57
|
/// `GgufModelConfig` for Qwen 3 1.7B Q4_K_M (~1.3 GB). |
|
58
|
GgufModelConfig qwen317BConfig() => |
|
59
|
RustLib.instance.api.crateApiQwen317BConfig(); |
|
60
|
|
|
61
|
/// `GgufModelConfig` for Qwen 3 4B Q4_K_M (~2.7 GB). |
|
62
|
GgufModelConfig qwen34BConfig() => RustLib.instance.api.crateApiQwen34BConfig(); |
|
63
|
|
|
64
|
/// `GgufModelConfig` for Qwen 3 8B Q4_K_M (~5 GB). |
|
65
|
GgufModelConfig qwen38BConfig() => RustLib.instance.api.crateApiQwen38BConfig(); |
|
66
|
|
|
67
|
/// `GgufModelConfig` for Qwen 3 14B Q4_K_M (~8.4 GB). |
|
68
|
GgufModelConfig qwen314BConfig() => |
|
69
|
RustLib.instance.api.crateApiQwen314BConfig(); |
|
70
|
|
|
71
|
/// `GgufModelConfig` for Qwen 3 32B Q4_K_M (~19.8 GB). |
|
72
|
GgufModelConfig qwen332BConfig() => |
|
73
|
RustLib.instance.api.crateApiQwen332BConfig(); |
|
74
|
|
|
75
|
/// `GgufModelConfig` for Qwen 3 4B Instruct 2507 Q4_K_M (~2.5 GB). |
|
76
|
GgufModelConfig qwen34BInstruct2507Config() => |
|
77
|
RustLib.instance.api.crateApiQwen34BInstruct2507Config(); |
|
78
|
|
|
79
|
/// `GgufModelConfig` for Qwen 3 4B Thinking 2507 Q4_K_M (~2.5 GB). |
|
80
|
GgufModelConfig qwen34BThinking2507Config() => |
|
81
|
RustLib.instance.api.crateApiQwen34BThinking2507Config(); |
|
82
|
|
|
83
|
/// `GgufModelConfig` for Qwen 3 30B-A3B Instruct 2507 (MoE) Q4_K_M (~18.6 GB). |
|
84
|
GgufModelConfig qwen330BA3BInstruct2507Config() => |
|
85
|
RustLib.instance.api.crateApiQwen330BA3BInstruct2507Config(); |
|
86
|
|
|
87
|
/// Default sampling config: `temperature=0.7`, `top_p=0.95`, `max_tokens=512`. |
|
88
|
SamplingConfig defaultSamplingConfig() => |
|
89
|
RustLib.instance.api.crateApiDefaultSamplingConfig(); |
|
90
|
|
|
91
|
/// Deterministic sampling config: `temperature=0.0`, greedy, `max_tokens=512`. |
|
92
|
SamplingConfig deterministicSamplingConfig() => |
|
93
|
RustLib.instance.api.crateApiDeterministicSamplingConfig(); |
|
94
|
|
|
95
|
/// Mobile sampling config: `temperature=0.7`, `top_p=0.95`, `max_tokens=128`. |
|
96
|
SamplingConfig mobileSamplingConfig() => |
|
97
|
RustLib.instance.api.crateApiMobileSamplingConfig(); |
|
98
|
|
|
99
|
/// Seed the HuggingFace cache environment for sandboxed platforms. |
|
100
|
/// |
|
101
|
/// On iOS (and Android), the default `~/.cache/huggingface/hub` path is outside |
|
102
|
/// the app sandbox and writes fail with `Operation not permitted (os error 1)`. |
|
103
|
/// |
|
104
|
/// Call this **once** at startup — before any `load_gguf_model` or |
|
105
|
/// `download_model` — with the app's writable data directory. |
|
106
|
/// |
|
107
|
/// # Dart usage |
|
108
|
/// |
|
109
|
/// ```dart |
|
110
|
/// import 'package:path_provider/path_provider.dart'; |
|
111
|
/// |
|
112
|
/// final dir = await getApplicationSupportDirectory(); |
|
113
|
/// configureCacheDir(appDataDir: dir.path); |
|
114
|
/// ``` |
|
115
|
/// |
|
116
|
/// Internally this: |
|
117
|
/// 1. Creates `<app_data_dir>/huggingface/hub/` if it doesn't exist. |
|
118
|
/// 2. Sets the `HF_HOME` and `HF_HUB_CACHE` environment variables. |
|
119
|
/// 3. Seeds `mistralrs_core::GLOBAL_HF_CACHE` so the model loader never |
|
120
|
/// falls back to `Cache::default()`. |
|
121
|
void configureCacheDir({required String appDataDir}) => |
|
122
|
RustLib.instance.api.crateApiConfigureCacheDir(appDataDir: appDataDir); |
|
123
|
|
|
124
|
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<OndeChatEngine>> |
|
125
|
abstract class OndeChatEngine implements RustOpaqueInterface { |
|
126
|
/// Clear the conversation history while keeping the model loaded. |
|
127
|
/// |
|
128
|
/// Returns the number of turns that were removed. |
|
129
|
Future<BigInt> clearHistory(); |
|
130
|
|
|
131
|
/// Clear the current system prompt. |
|
132
|
Future<void> clearSystemPrompt(); |
|
133
|
|
|
134
|
/// One-shot generation from an explicit message list. |
|
135
|
/// |
|
136
|
/// Does **not** modify the conversation history. |
|
137
|
Future<InferenceResult> generate({ |
|
138
|
required List<ChatMessage> messages, |
|
139
|
SamplingConfig? sampling, |
|
140
|
}); |
|
141
|
|
|
142
|
/// Returns a clone of the full conversation history. |
|
143
|
Future<List<ChatMessage>> history(); |
|
144
|
|
|
145
|
/// Returns a point-in-time snapshot of the engine's state. |
|
146
|
Future<EngineInfo> info(); |
|
147
|
|
|
148
|
/// Returns `true` if a model is currently loaded and ready. |
|
149
|
Future<bool> isLoaded(); |
|
150
|
|
|
151
|
/// Load the model assigned to this Onde app from the dashboard. |
|
152
|
/// |
|
153
|
/// Returns the wall-clock seconds taken to load the model. |
|
154
|
Future<double> loadAssignedModel({ |
|
155
|
required String appId, |
|
156
|
required String appSecret, |
|
157
|
String? systemPrompt, |
|
158
|
SamplingConfig? sampling, |
|
159
|
}); |
|
160
|
|
|
161
|
/// Load a GGUF model into the engine. |
|
162
|
/// |
|
163
|
/// Returns the load duration in seconds on success. |
|
164
|
Future<double> loadGgufModel({ |
|
165
|
required GgufModelConfig config, |
|
166
|
String? systemPrompt, |
|
167
|
SamplingConfig? sampling, |
|
168
|
}); |
|
169
|
|
|
170
|
/// Load a UQFF model into the engine. |
|
171
|
/// |
|
172
|
/// Returns the load duration in seconds on success. |
|
173
|
Future<double> loadUqffModel({ |
|
174
|
required UqffModelConfig config, |
|
175
|
String? systemPrompt, |
|
176
|
SamplingConfig? sampling, |
|
177
|
}); |
|
178
|
|
|
179
|
/// Create a new engine with no model loaded. |
|
180
|
factory OndeChatEngine() => RustLib.instance.api.crateApiOndeChatEngineNew(); |
|
181
|
|
|
182
|
/// Append a message to history without running inference. |
|
183
|
/// |
|
184
|
/// Useful for restoring a saved conversation or injecting context. |
|
185
|
Future<void> pushHistory({required ChatMessage message}); |
|
186
|
|
|
187
|
/// Send a user message and receive a complete assistant reply. |
|
188
|
/// |
|
189
|
/// Both the user message and assistant reply are appended to the |
|
190
|
/// conversation history on success. |
|
191
|
Future<InferenceResult> sendMessage({required String message}); |
|
192
|
|
|
193
|
/// Replace the sampling configuration used for all subsequent inference. |
|
194
|
Future<void> setSampling({required SamplingConfig sampling}); |
|
195
|
|
|
196
|
/// Set or replace the system prompt. |
|
197
|
/// |
|
198
|
/// The prompt is prepended to every inference request and is **not** |
|
199
|
/// stored in the conversation history. |
|
200
|
Future<void> setSystemPrompt({required String prompt}); |
|
201
|
|
|
202
|
/// Stream a reply token-by-token. |
|
203
|
/// |
|
204
|
/// Each [`StreamChunk`] carries a `delta` string. The final chunk has |
|
205
|
/// `done == true`. The `sink` is closed automatically when the stream |
|
206
|
/// ends or if the receiver is dropped. |
|
207
|
Stream<StreamChunk> streamMessage({required String message}); |
|
208
|
|
|
209
|
/// Unload the current model and release its memory. |
|
210
|
/// |
|
211
|
/// Returns the display name of the model that was unloaded, or `None` |
|
212
|
/// if no model was loaded. |
|
213
|
Future<String?> unloadModel(); |
|
214
|
} |
|
215
|
|
|
216
|
/// A single message in a conversation. |
|
217
|
class ChatMessage { |
|
218
|
final ChatRole role; |
|
219
|
final String content; |
|
220
|
|
|
221
|
const ChatMessage({required this.role, required this.content}); |
|
222
|
|
|
223
|
@override |
|
224
|
int get hashCode => role.hashCode ^ content.hashCode; |
|
225
|
|
|
226
|
@override |
|
227
|
bool operator ==(Object other) => |
|
228
|
identical(this, other) || |
|
229
|
other is ChatMessage && |
|
230
|
runtimeType == other.runtimeType && |
|
231
|
role == other.role && |
|
232
|
content == other.content; |
|
233
|
} |
|
234
|
|
|
235
|
/// Role of a participant in a chat conversation. |
|
236
|
enum ChatRole { system, user, assistant } |
|
237
|
|
|
238
|
/// A point-in-time snapshot of the engine's state. |
|
239
|
class EngineInfo { |
|
240
|
final EngineStatus status; |
|
241
|
|
|
242
|
/// Display name of the currently loaded model, if any. |
|
243
|
final String? modelName; |
|
244
|
|
|
245
|
/// Approximate memory footprint of the loaded model, if any. |
|
246
|
final String? approxMemory; |
|
247
|
|
|
248
|
/// Number of conversation turns in the current history. |
|
249
|
final BigInt historyLength; |
|
250
|
|
|
251
|
const EngineInfo({ |
|
252
|
required this.status, |
|
253
|
this.modelName, |
|
254
|
this.approxMemory, |
|
255
|
required this.historyLength, |
|
256
|
}); |
|
257
|
|
|
258
|
@override |
|
259
|
int get hashCode => |
|
260
|
status.hashCode ^ |
|
261
|
modelName.hashCode ^ |
|
262
|
approxMemory.hashCode ^ |
|
263
|
historyLength.hashCode; |
|
264
|
|
|
265
|
@override |
|
266
|
bool operator ==(Object other) => |
|
267
|
identical(this, other) || |
|
268
|
other is EngineInfo && |
|
269
|
runtimeType == other.runtimeType && |
|
270
|
status == other.status && |
|
271
|
modelName == other.modelName && |
|
272
|
approxMemory == other.approxMemory && |
|
273
|
historyLength == other.historyLength; |
|
274
|
} |
|
275
|
|
|
276
|
/// Lifecycle status of the inference engine. |
|
277
|
enum EngineStatus { unloaded, loading, ready, generating, error } |
|
278
|
|
|
279
|
/// Configuration for loading a pre-quantised GGUF model. |
|
280
|
class GgufModelConfig { |
|
281
|
/// HuggingFace repository ID, e.g. `"bartowski/Qwen2.5-1.5B-Instruct-GGUF"`. |
|
282
|
final String modelId; |
|
283
|
|
|
284
|
/// GGUF filename(s) within the repository. |
|
285
|
final List<String> files; |
|
286
|
|
|
287
|
/// Optional explicit tokenizer model ID (required on Android). |
|
288
|
final String? tokModelId; |
|
289
|
|
|
290
|
/// Human-friendly display name, e.g. `"Qwen 2.5 1.5B"`. |
|
291
|
final String displayName; |
|
292
|
|
|
293
|
/// Approximate memory footprint, e.g. `"~941 MB (GGUF Q4_K_M)"`. |
|
294
|
final String approxMemory; |
|
295
|
|
|
296
|
const GgufModelConfig({ |
|
297
|
required this.modelId, |
|
298
|
required this.files, |
|
299
|
this.tokModelId, |
|
300
|
required this.displayName, |
|
301
|
required this.approxMemory, |
|
302
|
}); |
|
303
|
|
|
304
|
@override |
|
305
|
int get hashCode => |
|
306
|
modelId.hashCode ^ |
|
307
|
files.hashCode ^ |
|
308
|
tokModelId.hashCode ^ |
|
309
|
displayName.hashCode ^ |
|
310
|
approxMemory.hashCode; |
|
311
|
|
|
312
|
@override |
|
313
|
bool operator ==(Object other) => |
|
314
|
identical(this, other) || |
|
315
|
other is GgufModelConfig && |
|
316
|
runtimeType == other.runtimeType && |
|
317
|
modelId == other.modelId && |
|
318
|
files == other.files && |
|
319
|
tokModelId == other.tokModelId && |
|
320
|
displayName == other.displayName && |
|
321
|
approxMemory == other.approxMemory; |
|
322
|
} |
|
323
|
|
|
324
|
/// The result of a completed inference request. |
|
325
|
class InferenceResult { |
|
326
|
/// The generated assistant reply text. |
|
327
|
final String text; |
|
328
|
|
|
329
|
/// Wall-clock inference duration in seconds. |
|
330
|
final double durationSecs; |
|
331
|
|
|
332
|
/// Human-readable duration string, e.g. `"4.5s"` or `"2m 3.1s"`. |
|
333
|
final String durationDisplay; |
|
334
|
|
|
335
|
/// Finish reason reported by the model, e.g. `"stop"` or `"length"`. |
|
336
|
final String finishReason; |
|
337
|
|
|
338
|
/// Tool calls requested by the model (empty if none). |
|
339
|
final List<ToolCallInfo> toolCalls; |
|
340
|
|
|
341
|
const InferenceResult({ |
|
342
|
required this.text, |
|
343
|
required this.durationSecs, |
|
344
|
required this.durationDisplay, |
|
345
|
required this.finishReason, |
|
346
|
required this.toolCalls, |
|
347
|
}); |
|
348
|
|
|
349
|
@override |
|
350
|
int get hashCode => |
|
351
|
text.hashCode ^ |
|
352
|
durationSecs.hashCode ^ |
|
353
|
durationDisplay.hashCode ^ |
|
354
|
finishReason.hashCode ^ |
|
355
|
toolCalls.hashCode; |
|
356
|
|
|
357
|
@override |
|
358
|
bool operator ==(Object other) => |
|
359
|
identical(this, other) || |
|
360
|
other is InferenceResult && |
|
361
|
runtimeType == other.runtimeType && |
|
362
|
text == other.text && |
|
363
|
durationSecs == other.durationSecs && |
|
364
|
durationDisplay == other.durationDisplay && |
|
365
|
finishReason == other.finishReason && |
|
366
|
toolCalls == other.toolCalls; |
|
367
|
} |
|
368
|
|
|
369
|
@freezed |
|
370
|
sealed class OndeError with _$OndeError implements FrbException { |
|
371
|
const OndeError._(); |
|
372
|
|
|
373
|
const factory OndeError.noModelLoaded() = OndeError_NoModelLoaded; |
|
374
|
const factory OndeError.alreadyLoaded({required String modelName}) = |
|
375
|
OndeError_AlreadyLoaded; |
|
376
|
const factory OndeError.modelBuild({required String reason}) = |
|
377
|
OndeError_ModelBuild; |
|
378
|
const factory OndeError.inference({required String reason}) = |
|
379
|
OndeError_Inference; |
|
380
|
const factory OndeError.cancelled() = OndeError_Cancelled; |
|
381
|
const factory OndeError.other({required String reason}) = OndeError_Other; |
|
382
|
} |
|
383
|
|
|
384
|
/// Sampling parameters for text generation. All fields are optional — `None` |
|
385
|
/// means "use the engine default". |
|
386
|
class SamplingConfig { |
|
387
|
final double? temperature; |
|
388
|
final double? topP; |
|
389
|
final BigInt? topK; |
|
390
|
final double? minP; |
|
391
|
final BigInt? maxTokens; |
|
392
|
final double? frequencyPenalty; |
|
393
|
final double? presencePenalty; |
|
394
|
|
|
395
|
const SamplingConfig({ |
|
396
|
this.temperature, |
|
397
|
this.topP, |
|
398
|
this.topK, |
|
399
|
this.minP, |
|
400
|
this.maxTokens, |
|
401
|
this.frequencyPenalty, |
|
402
|
this.presencePenalty, |
|
403
|
}); |
|
404
|
|
|
405
|
@override |
|
406
|
int get hashCode => |
|
407
|
temperature.hashCode ^ |
|
408
|
topP.hashCode ^ |
|
409
|
topK.hashCode ^ |
|
410
|
minP.hashCode ^ |
|
411
|
maxTokens.hashCode ^ |
|
412
|
frequencyPenalty.hashCode ^ |
|
413
|
presencePenalty.hashCode; |
|
414
|
|
|
415
|
@override |
|
416
|
bool operator ==(Object other) => |
|
417
|
identical(this, other) || |
|
418
|
other is SamplingConfig && |
|
419
|
runtimeType == other.runtimeType && |
|
420
|
temperature == other.temperature && |
|
421
|
topP == other.topP && |
|
422
|
topK == other.topK && |
|
423
|
minP == other.minP && |
|
424
|
maxTokens == other.maxTokens && |
|
425
|
frequencyPenalty == other.frequencyPenalty && |
|
426
|
presencePenalty == other.presencePenalty; |
|
427
|
} |
|
428
|
|
|
429
|
/// A single streaming token chunk emitted during inference. |
|
430
|
class StreamChunk { |
|
431
|
/// The token text delta (may be empty on the final chunk). |
|
432
|
final String delta; |
|
433
|
|
|
434
|
/// `true` when this is the last chunk in the stream. |
|
435
|
final bool done; |
|
436
|
|
|
437
|
/// Finish reason (set only on the final chunk). |
|
438
|
final String? finishReason; |
|
439
|
|
|
440
|
const StreamChunk({ |
|
441
|
required this.delta, |
|
442
|
required this.done, |
|
443
|
this.finishReason, |
|
444
|
}); |
|
445
|
|
|
446
|
@override |
|
447
|
int get hashCode => delta.hashCode ^ done.hashCode ^ finishReason.hashCode; |
|
448
|
|
|
449
|
@override |
|
450
|
bool operator ==(Object other) => |
|
451
|
identical(this, other) || |
|
452
|
other is StreamChunk && |
|
453
|
runtimeType == other.runtimeType && |
|
454
|
delta == other.delta && |
|
455
|
done == other.done && |
|
456
|
finishReason == other.finishReason; |
|
457
|
} |
|
458
|
|
|
459
|
/// Structured tool-call request emitted by the model. |
|
460
|
class ToolCallInfo { |
|
461
|
final String id; |
|
462
|
final String functionName; |
|
463
|
final String arguments; |
|
464
|
|
|
465
|
const ToolCallInfo({ |
|
466
|
required this.id, |
|
467
|
required this.functionName, |
|
468
|
required this.arguments, |
|
469
|
}); |
|
470
|
|
|
471
|
@override |
|
472
|
int get hashCode => id.hashCode ^ functionName.hashCode ^ arguments.hashCode; |
|
473
|
|
|
474
|
@override |
|
475
|
bool operator ==(Object other) => |
|
476
|
identical(this, other) || |
|
477
|
other is ToolCallInfo && |
|
478
|
runtimeType == other.runtimeType && |
|
479
|
id == other.id && |
|
480
|
functionName == other.functionName && |
|
481
|
arguments == other.arguments; |
|
482
|
} |
|
483
|
|
|
484
|
/// Configuration for loading a pre-quantised UQFF model. |
|
485
|
class UqffModelConfig { |
|
486
|
/// Base HuggingFace repository ID or local model directory. |
|
487
|
final String modelId; |
|
488
|
|
|
489
|
/// UQFF shard filename(s), first shard, or shorthand such as `q4k` / `4`. |
|
490
|
final List<String> files; |
|
491
|
|
|
492
|
/// Human-friendly display name. |
|
493
|
final String displayName; |
|
494
|
|
|
495
|
/// Approximate memory footprint. |
|
496
|
final String approxMemory; |
|
497
|
|
|
498
|
/// Optional Jinja chat template override. |
|
499
|
final String? chatTemplate; |
|
500
|
|
|
501
|
const UqffModelConfig({ |
|
502
|
required this.modelId, |
|
503
|
required this.files, |
|
504
|
required this.displayName, |
|
505
|
required this.approxMemory, |
|
506
|
this.chatTemplate, |
|
507
|
}); |
|
508
|
|
|
509
|
@override |
|
510
|
int get hashCode => |
|
511
|
modelId.hashCode ^ |
|
512
|
files.hashCode ^ |
|
513
|
displayName.hashCode ^ |
|
514
|
approxMemory.hashCode ^ |
|
515
|
chatTemplate.hashCode; |
|
516
|
|
|
517
|
@override |
|
518
|
bool operator ==(Object other) => |
|
519
|
identical(this, other) || |
|
520
|
other is UqffModelConfig && |
|
521
|
runtimeType == other.runtimeType && |
|
522
|
modelId == other.modelId && |
|
523
|
files == other.files && |
|
524
|
displayName == other.displayName && |
|
525
|
approxMemory == other.approxMemory && |
|
526
|
chatTemplate == other.chatTemplate; |
|
527
|
} |