1use std::ffi::NulError;
2use std::num::NonZeroI32;
3use std::os::raw::c_int;
4use std::path::PathBuf;
5use std::string::FromUtf8Error;
6
7use crate::llama_batch::BatchAddError;
8
9pub type Result<TValue> = std::result::Result<TValue, LlamaCppError>;
11
12#[derive(Debug, Eq, PartialEq, thiserror::Error)]
14pub enum LlamaCppError {
15 #[error("BackendAlreadyInitialized")]
18 BackendAlreadyInitialized,
19 #[error("{0}")]
21 ChatTemplateError(#[from] ChatTemplateError),
22 #[error("{0}")]
24 DecodeError(#[from] DecodeError),
25 #[error("{0}")]
27 EncodeError(#[from] EncodeError),
28 #[error("{0}")]
30 LlamaModelLoadError(#[from] LlamaModelLoadError),
31 #[error("{0}")]
33 LlamaContextLoadError(#[from] LlamaContextLoadError),
34 #[error["{0}"]]
36 BatchAddError(#[from] BatchAddError),
37 #[error(transparent)]
39 EmbeddingError(#[from] EmbeddingsError),
40 #[error("Backend device {0} not found")]
43 BackendDeviceNotFound(usize),
44 #[error("Max devices exceeded. Max devices is {0}")]
46 MaxDevicesExceeded(usize),
47 #[error("JsonSchemaToGrammarError: {0}")]
49 JsonSchemaToGrammarError(String),
50}
51
52#[derive(Debug, Eq, PartialEq, thiserror::Error)]
54pub enum ChatTemplateError {
55 #[error("chat template not found - returned null pointer")]
57 MissingTemplate,
58
59 #[error("null byte in string {0}")]
61 NullError(#[from] NulError),
62
63 #[error(transparent)]
65 Utf8Error(#[from] std::str::Utf8Error),
66}
67
68#[derive(Debug, Eq, PartialEq, thiserror::Error)]
70pub enum MetaValError {
71 #[error("null byte in string {0}")]
73 NullError(#[from] NulError),
74
75 #[error("FromUtf8Error {0}")]
77 FromUtf8Error(#[from] FromUtf8Error),
78
79 #[error("Negative return value. Likely due to a missing index or key. Got return value: {0}")]
81 NegativeReturn(i32),
82}
83
84#[derive(Debug, Eq, PartialEq, thiserror::Error)]
86pub enum LlamaContextLoadError {
87 #[error("null reference from llama.cpp")]
89 NullReturn,
90}
91
92#[derive(Debug, Eq, PartialEq, thiserror::Error)]
94pub enum DecodeError {
95 #[error("Decode Error 1: NoKvCacheSlot")]
97 NoKvCacheSlot,
98 #[error("Decode Error -1: n_tokens == 0")]
100 NTokensZero,
101 #[error("Decode Error {0}: unknown")]
103 Unknown(c_int),
104}
105
106#[derive(Debug, Eq, PartialEq, thiserror::Error)]
108pub enum EncodeError {
109 #[error("Encode Error 1: NoKvCacheSlot")]
111 NoKvCacheSlot,
112 #[error("Encode Error -1: n_tokens == 0")]
114 NTokensZero,
115 #[error("Encode Error {0}: unknown")]
117 Unknown(c_int),
118}
119
120#[derive(Debug, Eq, PartialEq, thiserror::Error)]
122pub enum EmbeddingsError {
123 #[error("Embeddings weren't enabled in the context options")]
125 NotEnabled,
126 #[error("Logits were not enabled for the given token")]
128 LogitsNotEnabled,
129 #[error("Can't use sequence embeddings with a model supporting only LLAMA_POOLING_TYPE_NONE")]
131 NonePoolType,
132}
133
134#[derive(Debug, Eq, PartialEq, thiserror::Error)]
136pub enum GrammarError {
137 #[error("Grammar root not found in grammar string")]
139 RootNotFound,
140 #[error("Trigger word contains null bytes")]
142 TriggerWordNullBytes,
143 #[error("Grammar string or root contains null bytes")]
145 GrammarNullBytes,
146 #[error("String contains null bytes: {0}")]
148 NulError(#[from] std::ffi::NulError),
149 #[error("Grammar call returned null")]
151 NullGrammar,
152 #[error("Integer overflow: {0}")]
154 IntegerOverflow(String),
155 #[error("llguidance error: {0}")]
157 LlguidanceError(String),
158}
159
160#[derive(Debug, Eq, PartialEq, thiserror::Error)]
162pub enum SamplingError {
163 #[error("Integer overflow: {0}")]
165 IntegerOverflow(String),
166}
167
168impl From<NonZeroI32> for DecodeError {
170 fn from(value: NonZeroI32) -> Self {
171 match value.get() {
172 1 => DecodeError::NoKvCacheSlot,
173 -1 => DecodeError::NTokensZero,
174 i => DecodeError::Unknown(i),
175 }
176 }
177}
178
179impl From<NonZeroI32> for EncodeError {
181 fn from(value: NonZeroI32) -> Self {
182 match value.get() {
183 1 => EncodeError::NoKvCacheSlot,
184 -1 => EncodeError::NTokensZero,
185 i => EncodeError::Unknown(i),
186 }
187 }
188}
189
190#[derive(Debug, Eq, PartialEq, thiserror::Error)]
192pub enum LlamaModelLoadError {
193 #[error("null byte in string {0}")]
195 NullError(#[from] NulError),
196 #[error("null result from llama cpp")]
198 NullResult,
199 #[error("failed to convert path {0} to str")]
201 PathToStrError(PathBuf),
202}
203
204#[derive(Debug, Eq, PartialEq, thiserror::Error)]
206pub enum LlamaLoraAdapterInitError {
207 #[error("null byte in string {0}")]
209 NullError(#[from] NulError),
210 #[error("null result from llama cpp")]
212 NullResult,
213 #[error("failed to convert path {0} to str")]
215 PathToStrError(PathBuf),
216}
217
218#[derive(Debug, Eq, PartialEq, thiserror::Error)]
220pub enum LlamaLoraAdapterSetError {
221 #[error("error code from llama cpp")]
223 ErrorResult(i32),
224}
225
226#[derive(Debug, Eq, PartialEq, thiserror::Error)]
228pub enum LlamaLoraAdapterRemoveError {
229 #[error("error code from llama cpp")]
231 ErrorResult(i32),
232}
233
234#[derive(Debug, thiserror::Error, Clone)]
236#[non_exhaustive]
237pub enum TokenToStringError {
238 #[error("Unknown Token Type")]
240 UnknownTokenType,
241 #[error("Insufficient Buffer Space {0}")]
243 InsufficientBufferSpace(c_int),
244 #[error("FromUtf8Error {0}")]
246 FromUtf8Error(#[from] FromUtf8Error),
247}
248
249#[derive(Debug, thiserror::Error)]
251pub enum StringToTokenError {
252 #[error("{0}")]
254 NulError(#[from] NulError),
255 #[error("{0}")]
256 CIntConversionError(#[from] std::num::TryFromIntError),
258}
259
260#[derive(Debug, thiserror::Error)]
262pub enum NewLlamaChatMessageError {
263 #[error("{0}")]
265 NulError(#[from] NulError),
266}
267
268#[derive(Debug, thiserror::Error)]
270pub enum ApplyChatTemplateError {
271 #[error("{0}")]
273 NulError(#[from] NulError),
274 #[error("{0}")]
276 FromUtf8Error(#[from] FromUtf8Error),
277 #[error("null result from llama.cpp")]
279 NullResult,
280 #[error("ffi error {0}")]
282 FfiError(i32),
283 #[error("invalid grammar trigger data")]
285 InvalidGrammarTriggerType,
286}
287
288#[derive(Debug, thiserror::Error)]
290pub enum ChatParseError {
291 #[error("{0}")]
293 NulError(#[from] NulError),
294 #[error("{0}")]
296 Utf8Error(#[from] FromUtf8Error),
297 #[error("null result from llama.cpp")]
299 NullResult,
300 #[error("ffi error {0}")]
302 FfiError(i32),
303}
304
305#[derive(Debug, thiserror::Error)]
307pub enum SamplerAcceptError {
308 #[error("ffi error {0}")]
310 FfiError(i32),
311}
312
313#[derive(Debug, Eq, PartialEq, thiserror::Error)]
315pub enum ModelParamsError {
316 #[error("No available slot in override vector")]
318 NoAvailableSlot,
319 #[error("Override slot is not empty")]
321 SlotNotEmpty,
322 #[error("Invalid character in key: byte {byte}, {reason}")]
324 InvalidCharacterInKey {
325 byte: u8,
327 reason: String,
329 },
330}
331
332#[derive(Debug, Eq, PartialEq, thiserror::Error)]
334pub enum TokenSamplingError {
335 #[error("No token was selected by the sampler")]
337 NoTokenSelected,
338}
339
340#[cfg(test)]
341mod tests {
342 use std::num::NonZeroI32;
343
344 use super::{DecodeError, EncodeError};
345
346 #[test]
347 fn decode_error_no_kv_cache_slot() {
348 let error = DecodeError::from(NonZeroI32::new(1).expect("1 is non-zero"));
349
350 assert_eq!(error, DecodeError::NoKvCacheSlot);
351 assert_eq!(error.to_string(), "Decode Error 1: NoKvCacheSlot");
352 }
353
354 #[test]
355 fn decode_error_n_tokens_zero() {
356 let error = DecodeError::from(NonZeroI32::new(-1).expect("-1 is non-zero"));
357
358 assert_eq!(error, DecodeError::NTokensZero);
359 assert_eq!(error.to_string(), "Decode Error -1: n_tokens == 0");
360 }
361
362 #[test]
363 fn decode_error_unknown() {
364 let error = DecodeError::from(NonZeroI32::new(42).expect("42 is non-zero"));
365
366 assert_eq!(error, DecodeError::Unknown(42));
367 assert_eq!(error.to_string(), "Decode Error 42: unknown");
368 }
369
370 #[test]
371 fn encode_error_no_kv_cache_slot() {
372 let error = EncodeError::from(NonZeroI32::new(1).expect("1 is non-zero"));
373
374 assert_eq!(error, EncodeError::NoKvCacheSlot);
375 assert_eq!(error.to_string(), "Encode Error 1: NoKvCacheSlot");
376 }
377
378 #[test]
379 fn encode_error_n_tokens_zero() {
380 let error = EncodeError::from(NonZeroI32::new(-1).expect("-1 is non-zero"));
381
382 assert_eq!(error, EncodeError::NTokensZero);
383 assert_eq!(error.to_string(), "Encode Error -1: n_tokens == 0");
384 }
385
386 #[test]
387 fn encode_error_unknown() {
388 let error = EncodeError::from(NonZeroI32::new(99).expect("99 is non-zero"));
389
390 assert_eq!(error, EncodeError::Unknown(99));
391 assert_eq!(error.to_string(), "Encode Error 99: unknown");
392 }
393}