From 19ea0788c0b51a0105617e994217ccfaae809634 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 17:54:27 +0200 Subject: [PATCH 01/11] model-free gbnf validator --- .claude/rules/rust.md | 26 +- Cargo.lock | 28 + Cargo.toml | 6 + Makefile | 11 +- llama-cpp-bindings-build/src/build_gbnf.rs | 113 ++++ llama-cpp-bindings-build/src/build_ggml.rs | 119 ++++ llama-cpp-bindings-build/src/cmake_common.rs | 71 ++ llama-cpp-bindings-build/src/cmake_config.rs | 212 +----- .../src/ggml_cmake_options.rs | 127 ++++ .../src/ggml_system_paths.rs | 23 + llama-cpp-bindings-build/src/lib.rs | 15 + .../src/library_linking.rs | 21 + llama-cpp-bindings-sys/Cargo.toml | 15 +- llama-cpp-bindings-sys/wrapper_chat_apply.cpp | 17 +- llama-cpp-bindings-sys/wrapper_chat_apply.h | 2 +- llama-cpp-bindings-sys/wrapper_chat_parse.cpp | 202 ++---- llama-cpp-bindings-sys/wrapper_chat_parse.h | 16 +- llama-cpp-bindings-sys/wrapper_common.cpp | 326 +++------- llama-cpp-bindings-sys/wrapper_common.h | 48 +- llama-cpp-bindings-sys/wrapper_fit.cpp | 27 +- llama-cpp-bindings-sys/wrapper_fit.h | 8 +- llama-cpp-bindings-sys/wrapper_mtmd.cpp | 139 ++-- llama-cpp-bindings-sys/wrapper_mtmd.h | 28 +- llama-cpp-bindings-sys/wrapper_reasoning.cpp | 34 +- llama-cpp-bindings-sys/wrapper_reasoning.h | 4 +- llama-cpp-bindings-sys/wrapper_tool_calls.cpp | 34 +- llama-cpp-bindings-sys/wrapper_tool_calls.h | 4 +- llama-cpp-bindings-sys/wrapper_utils.h | 31 + llama-cpp-bindings-tests/Cargo.toml | 3 + .../build_user_prompt_with_media_marker.rs | 4 +- .../src/chunk_token_breakdown.rs | 4 +- .../src/prime_kv_cache.rs | 2 +- .../src/prime_kv_cache_with.rs | 4 +- .../tests/backend_initialization.rs | 4 +- .../chat_template_and_message_parsing.rs | 18 +- .../tests/embedding_and_encoder.rs | 8 +- .../tests/kv_cache_and_session.rs | 16 +- .../tests/model_loading_errors.rs | 8 +- .../tests/multimodal_audio.rs | 20 +- .../tests/multimodal_image_and_audio.rs | 16 +- .../tests/multimodal_vision.rs | 32 +- .../tests/reasoning_markers_and_tool_calls.rs | 18 +- .../sampling_and_constrained_decoding.rs | 16 +- .../tests/vocabulary_and_metadata.rs | 10 +- llama-cpp-bindings-types/src/lib.rs | 24 +- llama-cpp-bindings/Cargo.toml | 3 +- .../src/chat_message_parse_outcome.rs | 4 +- llama-cpp-bindings/src/context.rs | 176 ++--- llama-cpp-bindings/src/context/kv_cache.rs | 50 +- llama-cpp-bindings/src/context/params.rs | 8 +- llama-cpp-bindings/src/error.rs | 38 +- .../src/error/apply_chat_template_error.rs | 2 + llama-cpp-bindings/src/error/decode_error.rs | 2 + llama-cpp-bindings/src/error/encode_error.rs | 2 + .../src/error/eval_multimodal_chunks_error.rs | 2 +- llama-cpp-bindings/src/error/fit_error.rs | 2 + llama-cpp-bindings/src/error/grammar_error.rs | 2 + .../src/error/json_schema_to_grammar_error.rs | 2 + .../src/error/kv_cache_seq_add_error.rs | 2 + .../src/error/kv_cache_seq_div_error.rs | 2 + .../src/error/llama_context_load_error.rs | 2 + .../src/error/llama_model_load_error.rs | 2 + .../src/error/marker_detection_error.rs | 2 + .../src/error/parse_chat_message_error.rs | 2 + llama-cpp-bindings/src/error/sample_error.rs | 2 + .../src/error/sampler_accept_error.rs | 2 + .../src/error/sampler_apply_error.rs | 6 +- .../src/error/string_to_token_error.rs | 2 + ...ct_reasoning_markers_from_probe_renders.rs | 2 +- llama-cpp-bindings/src/ingest_prompt_chunk.rs | 6 +- .../src/json_schema_to_grammar.rs | 36 +- llama-cpp-bindings/src/lib.rs | 46 +- llama-cpp-bindings/src/llama_backend.rs | 10 +- .../src/llama_backend_device.rs | 3 +- llama-cpp-bindings/src/llguidance_sampler.rs | 6 +- llama-cpp-bindings/src/model.rs | 611 +++++++++--------- .../src/model/llama_chat_message.rs | 2 +- llama-cpp-bindings/src/model/params.rs | 97 +-- llama-cpp-bindings/src/mtmd.rs | 19 - llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs | 38 +- .../src/mtmd/mtmd_bitmap_error.rs | 2 + llama-cpp-bindings/src/mtmd/mtmd_context.rs | 117 ++-- .../src/mtmd/mtmd_default_marker.rs | 8 +- .../src/mtmd/mtmd_encode_error.rs | 2 + .../src/mtmd/mtmd_eval_error.rs | 2 + .../src/mtmd/mtmd_init_error.rs | 2 + .../src/mtmd/mtmd_input_chunk.rs | 45 +- .../src/mtmd/mtmd_tokenize_error.rs | 2 + .../src/sampled_token_classifier.rs | 21 +- llama-cpp-bindings/src/sampling.rs | 153 +++-- llama-cpp-bindings/src/token/data_array.rs | 32 +- .../src/tool_call_format/bracketed_args.rs | 20 +- .../src/tool_call_format/json_object.rs | 14 +- .../tool_call_format/key_value_xml_tags.rs | 20 +- .../src/tool_call_format/mod.rs | 51 +- .../src/tool_call_format/paired_quote_args.rs | 24 +- .../tool_call_format_outcome.rs | 4 +- .../src/tool_call_format/xml_function_tags.rs | 14 +- .../tool_call_template_overrides/detect.rs | 2 +- .../gemma4_call_block.rs | 14 +- .../glm47_key_value_tags.rs | 10 +- .../known_marker_candidates.rs | 4 +- .../mistral3_arrow_args.rs | 10 +- .../src/tool_call_template_overrides/mod.rs | 3 - .../qwen3_json_inside_tool_call.rs | 10 +- .../qwen_xml_tags.rs | 10 +- llama-cpp-error-recorder/src/lib.rs | 13 +- llama-cpp-gbnf-sys/Cargo.toml | 24 + llama-cpp-gbnf-sys/build.rs | 3 + llama-cpp-gbnf-sys/src/lib.rs | 64 ++ llama-cpp-gbnf-sys/wrapper_gbnf.cpp | 89 +++ llama-cpp-gbnf-sys/wrapper_gbnf.h | 46 ++ llama-cpp-gbnf/Cargo.toml | 21 + llama-cpp-gbnf/src/gbnf_grammar.rs | 176 +++++ llama-cpp-gbnf/src/gbnf_matcher.rs | 96 +++ llama-cpp-gbnf/src/gbnf_parse_error.rs | 17 + llama-cpp-gbnf/src/lib.rs | 16 + llama-cpp-gbnf/src/validation.rs | 5 + llama-cpp-ggml-sys/CMakeLists.txt | 9 + llama-cpp-ggml-sys/Cargo.toml | 28 + llama-cpp-ggml-sys/build.rs | 3 + llama-cpp-ggml-sys/src/lib.rs | 1 + llama-cpp-log-decoder/src/lib.rs | 9 +- llama-cpp-test-harness-macros/src/expand.rs | 18 +- llama-cpp-test-harness-macros/src/lib.rs | 9 +- llama-cpp-test-harness/src/execution_phase.rs | 4 +- .../src/harness_run_error.rs | 2 +- llama-cpp-test-harness/src/lib.rs | 28 +- llama-cpp-test-harness/src/llama_fixture.rs | 2 +- .../src/llama_tests_main_macro.rs | 2 +- llama-cpp-test-harness/src/load_key.rs | 4 +- llama-cpp-test-harness/src/phase_state.rs | 2 +- .../tests/harness_self_test.rs | 8 +- 133 files changed, 2519 insertions(+), 1883 deletions(-) create mode 100644 llama-cpp-bindings-build/src/build_gbnf.rs create mode 100644 llama-cpp-bindings-build/src/build_ggml.rs create mode 100644 llama-cpp-bindings-build/src/cmake_common.rs create mode 100644 llama-cpp-bindings-build/src/ggml_cmake_options.rs create mode 100644 llama-cpp-bindings-build/src/ggml_system_paths.rs create mode 100644 llama-cpp-gbnf-sys/Cargo.toml create mode 100644 llama-cpp-gbnf-sys/build.rs create mode 100644 llama-cpp-gbnf-sys/src/lib.rs create mode 100644 llama-cpp-gbnf-sys/wrapper_gbnf.cpp create mode 100644 llama-cpp-gbnf-sys/wrapper_gbnf.h create mode 100644 llama-cpp-gbnf/Cargo.toml create mode 100644 llama-cpp-gbnf/src/gbnf_grammar.rs create mode 100644 llama-cpp-gbnf/src/gbnf_matcher.rs create mode 100644 llama-cpp-gbnf/src/gbnf_parse_error.rs create mode 100644 llama-cpp-gbnf/src/lib.rs create mode 100644 llama-cpp-gbnf/src/validation.rs create mode 100644 llama-cpp-ggml-sys/CMakeLists.txt create mode 100644 llama-cpp-ggml-sys/Cargo.toml create mode 100644 llama-cpp-ggml-sys/build.rs create mode 100644 llama-cpp-ggml-sys/src/lib.rs diff --git a/.claude/rules/rust.md b/.claude/rules/rust.md index 4584b330..e791daaf 100644 --- a/.claude/rules/rust.md +++ b/.claude/rules/rust.md @@ -6,20 +6,10 @@ paths: # Rust Standards -- Do not inline import paths unless necessary. Prefer to use `use` statements in Rust files instead of inline paths to imported modules. The exception would be `error.rs` type modules that handle lib-level error structs. - Always use explicit lifetime variable names (do not use `'a` and such, use descriptive names like `'message` or similar) -- Always use explicit generic parameter names (never use single letter names like `T` for generics, prefix all of them with `T`, however). For example, use `TMessage` instead of `T`, etc. -- Do not use `pub(crate)` in Rust; in case of doubt, just make things public. -- In Rust, never ignore errors with `Err(_)`; always make sure you are matching an expected error variant instead. -- Never use `.expect`, or `.unwrap`. In Rust, if a function can fail, use a matching Result (can be from the anyhow crate) instead. In case of doubt on this, ask. Allow `.expect` in mutex lock poison checks, or when integrating CPP libraries into Rust. -- Always make sure mutex locks are held for the shortest possible time. -- Always specify Rust dependencies in root Cargo.toml, then use workspace versions of packages in workspace members. -- In Rust, when implementing a `new` method in a struct, prefer to use a struct with a parameter list instead of multiple function arguments. It should be easier to maintain. -- Always check the project with Clippy. -- Always format the code with `cargo fmt`. -- Each file must contain at most a single struct, or single enum. For readability split those into multiple modules. You can still keep multiple private function helpers. -- Never use Result<> as a function argument. -- Never forward Result in enums if you can instead create a targeted error enum. It is always better to signal the specific issue, so it can be handled downstream. +- Always use descriptive parameter names (never use single letter names for generics +- Each file must contain at most a single struct, or single enum, or a single public function (at most one of any of those). +- Each file must contain at most a single public item. You can still keep multiple private function helpers. Files need to be named after their public item. - Always destructure structs in arguments if possible. # Code Style @@ -29,8 +19,8 @@ Imports/uses must not be mixed with other kinds of rust syntax. Each file needs to follow this order: 1. `pub mod`/`mod` exports 2. vendor crate `use` -2. project crate `use` -3. local crate `use` -4. private function helpers -5. private struct helpers -6. single public export +3. project crate `use` +4. local crate `use` +5. private function helpers +6. private struct helpers +7. single public export diff --git a/Cargo.lock b/Cargo.lock index 3f4d22cd..f9312728 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1170,6 +1170,7 @@ dependencies = [ "llama-cpp-bindings-sys", "llama-cpp-bindings-types", "llama-cpp-error-recorder", + "llama-cpp-gbnf", "llama-cpp-log-decoder", "llguidance", "log", @@ -1198,6 +1199,7 @@ name = "llama-cpp-bindings-sys" version = "0.9.0" dependencies = [ "llama-cpp-bindings-build", + "llama-cpp-ggml-sys", ] [[package]] @@ -1206,9 +1208,12 @@ version = "0.9.0" dependencies = [ "anyhow", "encoding_rs", + "inventory", "llama-cpp-bindings", "llama-cpp-bindings-sys", + "llama-cpp-bindings-types", "llama-cpp-test-harness", + "llama-cpp-test-harness-macros", "serde_json", ] @@ -1225,6 +1230,29 @@ dependencies = [ name = "llama-cpp-error-recorder" version = "0.9.0" +[[package]] +name = "llama-cpp-gbnf" +version = "0.9.0" +dependencies = [ + "llama-cpp-gbnf-sys", + "thiserror", +] + +[[package]] +name = "llama-cpp-gbnf-sys" +version = "0.9.0" +dependencies = [ + "llama-cpp-bindings-build", + "llama-cpp-ggml-sys", +] + +[[package]] +name = "llama-cpp-ggml-sys" +version = "0.9.0" +dependencies = [ + "llama-cpp-bindings-build", +] + [[package]] name = "llama-cpp-log-decoder" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 0b78e734..313af03d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ members = [ "llama-cpp-bindings", "llama-cpp-bindings-tests", "llama-cpp-error-recorder", + "llama-cpp-ggml-sys", + "llama-cpp-gbnf-sys", + "llama-cpp-gbnf", "llama-cpp-log-decoder", "llama-cpp-test-harness", "llama-cpp-test-harness-macros", @@ -35,6 +38,9 @@ llama-cpp-bindings-build = { path = "llama-cpp-bindings-build", version = "=0.9. llama-cpp-bindings-sys = { path = "llama-cpp-bindings-sys", version = "=0.9.0" } llama-cpp-bindings-types = { path = "llama-cpp-bindings-types", version = "=0.9.0" } llama-cpp-error-recorder = { path = "llama-cpp-error-recorder", version = "=0.9.0" } +llama-cpp-gbnf = { path = "llama-cpp-gbnf", version = "=0.9.0" } +llama-cpp-gbnf-sys = { path = "llama-cpp-gbnf-sys", version = "=0.9.0" } +llama-cpp-ggml-sys = { path = "llama-cpp-ggml-sys", version = "=0.9.0" } llama-cpp-log-decoder = { path = "llama-cpp-log-decoder", version = "=0.9.0" } llama-cpp-test-harness = { path = "llama-cpp-test-harness", version = "=0.9.0" } llama-cpp-test-harness-macros = { path = "llama-cpp-test-harness-macros", version = "=0.9.0" } diff --git a/Makefile b/Makefile index 53f9e117..4078e981 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,14 @@ node_modules: package-lock.json package-lock.json: package.json npm install --package-lock-only +.PHONY: clean +clean: + cargo clean + rm -rf node_modules + .PHONY: clean.cmake clean.cmake: - rm -rf target/llama-cpp-cmake-build + rm -rf target/*/llama-cpp-cmake-build .PHONY: clippy clippy: @@ -28,6 +33,8 @@ coverage: node_modules --workspace-root $(CURDIR) \ --gated llama-cpp-bindings=98 \ --gated llama-cpp-error-recorder=100 \ + --gated llama-cpp-gbnf=100 \ + --gated llama-cpp-gbnf-sys=100 \ --gated llama-cpp-log-decoder=100 \ --gated llama-cpp-bindings-types=100 \ --gated llama-cpp-test-harness=99 \ @@ -83,4 +90,4 @@ test.llms: clippy test.harness test.unit .PHONY: test.unit test.unit: clippy - cargo test -p llama-cpp-log-decoder -p llama-cpp-bindings $(DEVICE_FEATURE) + cargo test -p llama-cpp-gbnf -p llama-cpp-gbnf-sys -p llama-cpp-log-decoder -p llama-cpp-bindings $(DEVICE_FEATURE) diff --git a/llama-cpp-bindings-build/src/build_gbnf.rs b/llama-cpp-bindings-build/src/build_gbnf.rs new file mode 100644 index 00000000..e8e49de9 --- /dev/null +++ b/llama-cpp-bindings-build/src/build_gbnf.rs @@ -0,0 +1,113 @@ +use std::env; +use std::path::Path; +use std::path::PathBuf; + +use crate::target_os::TargetOs; + +const LLAMA_SUBMODULE_RELATIVE_PATH: &str = "../llama-cpp-bindings-sys/llama.cpp"; + +const GRAMMAR_SOURCE_FILES: &[&str] = &[ + "src/llama-grammar.cpp", + "src/llama-vocab.cpp", + "src/unicode.cpp", + "src/unicode-data.cpp", + "src/llama-impl.cpp", +]; + +pub fn build_gbnf() { + let manifest_dir = + env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var is required"); + let target_triple = env::var("TARGET").expect("TARGET env var is required in build scripts"); + let target_os = TargetOs::from_target_triple(&target_triple) + .unwrap_or_else(|error| panic!("Failed to parse target OS: {error}")); + + let ggml_include = env::var("DEP_GGML_INCLUDE") + .expect("DEP_GGML_INCLUDE must be provided by llama-cpp-ggml-sys"); + let ggml_lib = + env::var("DEP_GGML_LIB").expect("DEP_GGML_LIB must be provided by llama-cpp-ggml-sys"); + + let manifest = PathBuf::from(&manifest_dir); + let llama_src = manifest.join(LLAMA_SUBMODULE_RELATIVE_PATH); + let grammar_source_dir = llama_src.join("src"); + + assert!( + grammar_source_dir.join("llama-grammar.cpp").is_file(), + "grammar source not found under {}; ensure the llama.cpp submodule is checked out", + grammar_source_dir.display() + ); + + register_rebuild_triggers(&manifest); + + compile_wrapper( + &manifest, + &llama_src, + &grammar_source_dir, + Path::new(&ggml_include), + &target_os, + ); + + emit_link_directives(Path::new(&ggml_lib), &target_os); +} + +fn compile_wrapper( + manifest: &Path, + llama_src: &Path, + grammar_source_dir: &Path, + ggml_include: &Path, + target_os: &TargetOs, +) { + let mut build = cc::Build::new(); + + build + .cpp(true) + .warnings(false) + .include(manifest) + .include(llama_src.join("include")) + .include(grammar_source_dir) + .include(llama_src.join("ggml/include")) + .include(ggml_include) + .flag_if_supported("-std=c++17") + .pic(true) + .file(manifest.join("wrapper_gbnf.cpp")); + + for source in GRAMMAR_SOURCE_FILES { + build.file(llama_src.join(source)); + } + + if target_os.is_msvc() { + build.flag("/std:c++17"); + build.flag("/EHsc"); + } + + build.compile("llama_cpp_gbnf_wrapper"); +} + +fn emit_link_directives(ggml_lib: &Path, target_os: &TargetOs) { + println!("cargo:rustc-link-search=native={}", ggml_lib.display()); + println!("cargo:rustc-link-lib=static=ggml-base"); + println!("cargo:rustc-link-lib=static=ggml-cpu"); + + match target_os { + TargetOs::Linux | TargetOs::Android => { + println!("cargo:rustc-link-lib=dylib=stdc++"); + } + TargetOs::Apple(_) => { + println!("cargo:rustc-link-lib=framework=Foundation"); + println!("cargo:rustc-link-lib=framework=Accelerate"); + println!("cargo:rustc-link-lib=dylib=c++"); + } + TargetOs::Windows(_) => {} + } +} + +fn register_rebuild_triggers(manifest: &Path) { + println!("cargo:rerun-if-changed=build.rs"); + println!( + "cargo:rerun-if-changed={}", + manifest.join("wrapper_gbnf.cpp").display() + ); + println!( + "cargo:rerun-if-changed={}", + manifest.join("wrapper_gbnf.h").display() + ); +} diff --git a/llama-cpp-bindings-build/src/build_ggml.rs b/llama-cpp-bindings-build/src/build_ggml.rs new file mode 100644 index 00000000..b4e003f4 --- /dev/null +++ b/llama-cpp-bindings-build/src/build_ggml.rs @@ -0,0 +1,119 @@ +use std::env; +use std::path::Path; +use std::path::PathBuf; + +use cmake::Config; + +use crate::cmake_common; +use crate::ggml_cmake_options; +use crate::target_os::TargetOs; + +const GGML_SUBMODULE_RELATIVE_PATH: &str = "../llama-cpp-bindings-sys/llama.cpp/ggml"; + +pub fn build_ggml() { + let manifest_dir = + env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var is required"); + let target_triple = env::var("TARGET").expect("TARGET env var is required in build scripts"); + let target_os = TargetOs::from_target_triple(&target_triple) + .unwrap_or_else(|error| panic!("Failed to parse target OS: {error}")); + let profile = env::var("LLAMA_LIB_PROFILE").unwrap_or_else(|_| "Release".to_string()); + + let wrapper_cmake_dir = PathBuf::from(&manifest_dir); + let ggml_src = wrapper_cmake_dir.join(GGML_SUBMODULE_RELATIVE_PATH); + + assert!( + ggml_src.join("CMakeLists.txt").is_file(), + "ggml source not found at {}; ensure the llama.cpp submodule is checked out", + ggml_src.display() + ); + + register_rebuild_triggers(&ggml_src); + + let install_dir = configure_and_install_ggml( + &wrapper_cmake_dir, + &ggml_src, + &target_triple, + &target_os, + &profile, + ); + + emit_metadata(&install_dir); +} + +fn configure_and_install_ggml( + wrapper_cmake_dir: &Path, + ggml_src: &Path, + target_triple: &str, + target_os: &TargetOs, + profile: &str, +) -> PathBuf { + let mut config = Config::new(wrapper_cmake_dir); + + config.define( + "GGML_SOURCE_DIR", + ggml_src + .to_str() + .expect("ggml source path must be valid UTF-8"), + ); + config.define("GGML_BUILD_TESTS", "OFF"); + config.define("GGML_BUILD_EXAMPLES", "OFF"); + config.cflag("-w"); + config.cxxflag("-w"); + + cmake_common::pass_cmake_env_vars(&mut config); + cmake_common::configure_compiler_launchers(&mut config); + cmake_common::configure_shared_libs(&mut config, false); + ggml_cmake_options::configure_cpu_features(&mut config, target_triple); + ggml_cmake_options::configure_gpu_backends(&mut config, target_os); + ggml_cmake_options::configure_openmp(&mut config, target_os); + + if let TargetOs::Apple(_) = target_os { + config.define("GGML_BLAS", "OFF"); + cmake_common::override_archive_commands_for_apple_ar(&mut config); + } + + config + .profile(profile) + .very_verbose(env::var("CMAKE_VERBOSE").is_ok()) + .always_configure(false); + + config.build() +} + +fn emit_metadata(install_dir: &Path) { + let lib_dir = resolve_lib_dir(install_dir); + + println!("cargo:root={}", install_dir.display()); + println!("cargo:include={}", install_dir.join("include").display()); + println!("cargo:lib={}", lib_dir.display()); + println!( + "cargo:cmake={}", + lib_dir.join("cmake").join("ggml").display() + ); +} + +fn resolve_lib_dir(install_dir: &Path) -> PathBuf { + let lib64 = install_dir.join("lib64"); + + if lib64.is_dir() { + lib64 + } else { + install_dir.join("lib") + } +} + +fn register_rebuild_triggers(ggml_src: &Path) { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-env-changed=LLAMA_LIB_PROFILE"); + println!("cargo:rerun-if-env-changed=LLAMA_DISABLE_CCACHE"); + println!("cargo:rerun-if-env-changed=CMAKE_VERBOSE"); + println!( + "cargo:rerun-if-changed={}", + ggml_src.join("CMakeLists.txt").display() + ); + println!("cargo:rerun-if-changed={}", ggml_src.join("src").display()); + println!( + "cargo:rerun-if-changed={}", + ggml_src.join("include").display() + ); +} diff --git a/llama-cpp-bindings-build/src/cmake_common.rs b/llama-cpp-bindings-build/src/cmake_common.rs new file mode 100644 index 00000000..d431a7eb --- /dev/null +++ b/llama-cpp-bindings-build/src/cmake_common.rs @@ -0,0 +1,71 @@ +use std::env; +use std::path::PathBuf; + +use cmake::Config; + +use crate::debug_log; + +pub fn configure_compiler_launchers(config: &mut Config) { + println!("cargo:rerun-if-env-changed=LLAMA_DISABLE_CCACHE"); + + if env::var("LLAMA_DISABLE_CCACHE").is_ok() { + return; + } + + let Some(ccache) = which("ccache") else { + return; + }; + + let ccache_str = ccache.display().to_string(); + debug_log!("Using ccache for compilation: {ccache_str}"); + + config.define("CMAKE_C_COMPILER_LAUNCHER", &ccache_str); + config.define("CMAKE_CXX_COMPILER_LAUNCHER", &ccache_str); + config.define("CMAKE_CUDA_COMPILER_LAUNCHER", &ccache_str); +} + +pub fn which(program: &str) -> Option { + let path = env::var_os("PATH")?; + + for entry in env::split_paths(&path) { + let candidate = entry.join(program); + + if candidate.is_file() { + return Some(candidate); + } + } + + None +} + +pub fn pass_cmake_env_vars(config: &mut Config) { + for (key, value) in env::vars() { + if key.starts_with("CMAKE_") { + config.define(&key, &value); + } + } +} + +pub fn configure_shared_libs(config: &mut Config, build_shared_libs: bool) { + config.define( + "BUILD_SHARED_LIBS", + if build_shared_libs { "ON" } else { "OFF" }, + ); +} + +pub fn override_archive_commands_for_apple_ar(config: &mut Config) { + for language in ["C", "CXX", "OBJC", "OBJCXX"] { + config.define( + format!("CMAKE_{language}_ARCHIVE_CREATE"), + " qc ", + ); + config.define( + format!("CMAKE_{language}_ARCHIVE_APPEND"), + " q ", + ); + config.define( + format!("CMAKE_{language}_ARCHIVE_FINISH"), + " ", + ); + } +} diff --git a/llama-cpp-bindings-build/src/cmake_config.rs b/llama-cpp-bindings-build/src/cmake_config.rs index 12faa145..95915f3a 100644 --- a/llama-cpp-bindings-build/src/cmake_config.rs +++ b/llama-cpp-bindings-build/src/cmake_config.rs @@ -5,17 +5,18 @@ use cmake::Config; use crate::BuildContext; use crate::android_ndk::AndroidNdk; -use crate::debug_log; +use crate::cmake_common; +use crate::ggml_cmake_options; use crate::target_os::{TargetOs, WindowsVariant}; pub fn configure_and_build(context: &BuildContext) -> PathBuf { let mut config = Config::new(&context.llama_src); configure_base_defines(&mut config); - pass_cmake_env_vars(&mut config); - configure_compiler_launchers(&mut config); - configure_cpu_features(&mut config, &context.target_triple); - configure_shared_libs(&mut config, context.build_shared_libs); + cmake_common::pass_cmake_env_vars(&mut config); + cmake_common::configure_compiler_launchers(&mut config); + ggml_cmake_options::configure_cpu_features(&mut config, &context.target_triple); + cmake_common::configure_shared_libs(&mut config, context.build_shared_libs); configure_platform_specific( &mut config, &context.target_os, @@ -23,9 +24,19 @@ pub fn configure_and_build(context: &BuildContext) -> PathBuf { &context.profile, context.android_ndk.as_ref(), ); - configure_gpu_backends(&mut config, &context.target_os); - configure_openmp(&mut config, &context.target_os); + ggml_cmake_options::configure_gpu_backends(&mut config, &context.target_os); + ggml_cmake_options::configure_openmp(&mut config, &context.target_os); configure_system_ggml(&mut config); + + if let Some(ggml) = context.ggml_system.as_ref() { + config.define( + "ggml_DIR", + ggml.cmake_dir + .to_str() + .expect("ggml cmake directory must be valid UTF-8"), + ); + } + let backends_dir = configure_dynamic_backends(&mut config, &context.cmake_dir); config.static_crt(context.static_crt); @@ -77,120 +88,6 @@ fn configure_base_defines(config: &mut Config) { config.cxxflag("-w"); } -fn configure_compiler_launchers(config: &mut Config) { - println!("cargo:rerun-if-env-changed=LLAMA_DISABLE_CCACHE"); - - if env::var("LLAMA_DISABLE_CCACHE").is_ok() { - return; - } - - let Some(ccache) = which("ccache") else { - return; - }; - - let ccache_str = ccache.display().to_string(); - debug_log!("Using ccache for compilation: {ccache_str}"); - - config.define("CMAKE_C_COMPILER_LAUNCHER", &ccache_str); - config.define("CMAKE_CXX_COMPILER_LAUNCHER", &ccache_str); - config.define("CMAKE_CUDA_COMPILER_LAUNCHER", &ccache_str); -} - -fn which(program: &str) -> Option { - let path = env::var_os("PATH")?; - - for entry in env::split_paths(&path) { - let candidate = entry.join(program); - - if candidate.is_file() { - return Some(candidate); - } - } - - None -} - -fn pass_cmake_env_vars(config: &mut Config) { - for (key, value) in env::vars() { - if key.starts_with("CMAKE_") { - config.define(&key, &value); - } - } -} - -fn configure_cpu_features(config: &mut Config, target_triple: &str) { - let target_cpu = env::var("CARGO_ENCODED_RUSTFLAGS") - .ok() - .and_then(|rustflags| { - rustflags - .split('\x1f') - .find(|flag| flag.contains("target-cpu=")) - .and_then(|flag| flag.split("target-cpu=").nth(1)) - .map(std::string::ToString::to_string) - }); - - if target_cpu.as_deref() == Some("native") { - debug_log!("Detected target-cpu=native, compiling with GGML_NATIVE"); - config.define("GGML_NATIVE", "ON"); - - return; - } - - config.define("GGML_NATIVE", "OFF"); - - if let Some(ref cpu) = target_cpu { - debug_log!("Setting baseline architecture: -march={}", cpu); - config.cflag(format!("-march={cpu}")); - config.cxxflag(format!("-march={cpu}")); - } - - let features = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or_default(); - debug_log!("Compiling with target features: {}", features); - - for feature in features.split(',') { - if let Some(ggml_flag) = map_cpu_feature_to_ggml(feature) { - config.define(ggml_flag, "ON"); - } - } - - if target_triple.contains("aarch64") - && target_triple.contains("linux") - && target_cpu.as_deref() != Some("native") - { - config.define("GGML_CPU_ARM_ARCH", "armv8-a"); - } -} - -fn map_cpu_feature_to_ggml(feature: &str) -> Option<&'static str> { - match feature { - "avx" => Some("GGML_AVX"), - "avx2" => Some("GGML_AVX2"), - "avx512bf16" => Some("GGML_AVX512_BF16"), - "avx512vbmi" => Some("GGML_AVX512_VBMI"), - "avx512vnni" => Some("GGML_AVX512_VNNI"), - "avxvnni" => Some("GGML_AVX_VNNI"), - "bmi2" => Some("GGML_BMI2"), - "f16c" => Some("GGML_F16C"), - "fma" => Some("GGML_FMA"), - "sse4.2" => Some("GGML_SSE42"), - _ => { - debug_log!( - "Unrecognized cpu feature: '{}' - skipping GGML config for it.", - feature - ); - - None - } - } -} - -fn configure_shared_libs(config: &mut Config, build_shared_libs: bool) { - config.define( - "BUILD_SHARED_LIBS", - if build_shared_libs { "ON" } else { "OFF" }, - ); -} - fn configure_platform_specific( config: &mut Config, target_os: &TargetOs, @@ -201,7 +98,7 @@ fn configure_platform_specific( match target_os { TargetOs::Apple(_) => { config.define("GGML_BLAS", "OFF"); - override_archive_commands_for_apple_ar(config); + cmake_common::override_archive_commands_for_apple_ar(config); } TargetOs::Windows(WindowsVariant::Msvc) => { config.cflag("/w"); @@ -259,23 +156,6 @@ fn configure_android_cmake(config: &mut Config, ndk: &AndroidNdk, _target_triple println!("cargo:rustc-link-lib=android"); } -fn override_archive_commands_for_apple_ar(config: &mut Config) { - for language in ["C", "CXX", "OBJC", "OBJCXX"] { - config.define( - format!("CMAKE_{language}_ARCHIVE_CREATE"), - " qc ", - ); - config.define( - format!("CMAKE_{language}_ARCHIVE_APPEND"), - " q ", - ); - config.define( - format!("CMAKE_{language}_ARCHIVE_FINISH"), - " ", - ); - } -} - fn configure_android_arch_flags(config: &mut Config, abi: &str) { match abi { "arm64-v8a" => { @@ -302,60 +182,6 @@ fn configure_android_arch_flags(config: &mut Config, abi: &str) { } } -fn configure_gpu_backends(config: &mut Config, target_os: &TargetOs) { - if cfg!(feature = "vulkan") { - config.define("GGML_VULKAN", "ON"); - configure_vulkan_linking(config, target_os); - } - - if cfg!(feature = "cuda") { - config.define("GGML_CUDA", "ON"); - - if cfg!(feature = "cuda-no-vmm") { - config.define("GGML_CUDA_NO_VMM", "ON"); - } - } - - if cfg!(feature = "rocm") { - config.define("GGML_HIP", "ON"); - } -} - -fn configure_vulkan_linking(config: &mut Config, target_os: &TargetOs) { - match target_os { - TargetOs::Windows(_) => { - let vulkan_path = env::var("VULKAN_SDK") - .expect("Please install Vulkan SDK and ensure that VULKAN_SDK env variable is set"); - let vulkan_lib_path = Path::new(&vulkan_path).join("Lib"); - - println!("cargo:rustc-link-search={}", vulkan_lib_path.display()); - println!("cargo:rustc-link-lib=vulkan-1"); - - // SAFETY: build scripts are single-threaded, so modifying env is safe. - unsafe { env::set_var("TrackFileAccess", "false") }; - - config.cflag("/FS"); - config.cxxflag("/FS"); - } - TargetOs::Linux => { - if let Ok(vulkan_path) = env::var("VULKAN_SDK") { - let vulkan_lib_path = Path::new(&vulkan_path).join("lib"); - - println!("cargo:rustc-link-search={}", vulkan_lib_path.display()); - } - - println!("cargo:rustc-link-lib=vulkan"); - } - _ => (), - } -} - -fn configure_openmp(config: &mut Config, target_os: &TargetOs) { - let openmp_enabled = cfg!(feature = "openmp") && !target_os.is_android(); - - config.define("GGML_OPENMP", if openmp_enabled { "ON" } else { "OFF" }); -} - fn configure_system_ggml(config: &mut Config) { if cfg!(feature = "system-ggml") { config.define("LLAMA_USE_SYSTEM_GGML", "ON"); diff --git a/llama-cpp-bindings-build/src/ggml_cmake_options.rs b/llama-cpp-bindings-build/src/ggml_cmake_options.rs new file mode 100644 index 00000000..4fe18f11 --- /dev/null +++ b/llama-cpp-bindings-build/src/ggml_cmake_options.rs @@ -0,0 +1,127 @@ +use std::env; +use std::path::Path; + +use cmake::Config; + +use crate::debug_log; +use crate::target_os::TargetOs; + +pub fn configure_cpu_features(config: &mut Config, target_triple: &str) { + let target_cpu = env::var("CARGO_ENCODED_RUSTFLAGS") + .ok() + .and_then(|rustflags| { + rustflags + .split('\x1f') + .find(|flag| flag.contains("target-cpu=")) + .and_then(|flag| flag.split("target-cpu=").nth(1)) + .map(std::string::ToString::to_string) + }); + + if target_cpu.as_deref() == Some("native") { + debug_log!("Detected target-cpu=native, compiling with GGML_NATIVE"); + config.define("GGML_NATIVE", "ON"); + + return; + } + + config.define("GGML_NATIVE", "OFF"); + + if let Some(ref cpu) = target_cpu { + debug_log!("Setting baseline architecture: -march={}", cpu); + config.cflag(format!("-march={cpu}")); + config.cxxflag(format!("-march={cpu}")); + } + + let features = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or_default(); + debug_log!("Compiling with target features: {}", features); + + for feature in features.split(',') { + if let Some(ggml_flag) = map_cpu_feature_to_ggml(feature) { + config.define(ggml_flag, "ON"); + } + } + + if target_triple.contains("aarch64") + && target_triple.contains("linux") + && target_cpu.as_deref() != Some("native") + { + config.define("GGML_CPU_ARM_ARCH", "armv8-a"); + } +} + +fn map_cpu_feature_to_ggml(feature: &str) -> Option<&'static str> { + match feature { + "avx" => Some("GGML_AVX"), + "avx2" => Some("GGML_AVX2"), + "avx512bf16" => Some("GGML_AVX512_BF16"), + "avx512vbmi" => Some("GGML_AVX512_VBMI"), + "avx512vnni" => Some("GGML_AVX512_VNNI"), + "avxvnni" => Some("GGML_AVX_VNNI"), + "bmi2" => Some("GGML_BMI2"), + "f16c" => Some("GGML_F16C"), + "fma" => Some("GGML_FMA"), + "sse4.2" => Some("GGML_SSE42"), + _ => { + debug_log!( + "Unrecognized cpu feature: '{}' - skipping GGML config for it.", + feature + ); + + None + } + } +} + +pub fn configure_gpu_backends(config: &mut Config, target_os: &TargetOs) { + if cfg!(feature = "vulkan") { + config.define("GGML_VULKAN", "ON"); + configure_vulkan_linking(config, target_os); + } + + if cfg!(feature = "cuda") { + config.define("GGML_CUDA", "ON"); + + if cfg!(feature = "cuda-no-vmm") { + config.define("GGML_CUDA_NO_VMM", "ON"); + } + } + + if cfg!(feature = "rocm") { + config.define("GGML_HIP", "ON"); + } +} + +fn configure_vulkan_linking(config: &mut Config, target_os: &TargetOs) { + match target_os { + TargetOs::Windows(_) => { + let vulkan_path = env::var("VULKAN_SDK") + .expect("Please install Vulkan SDK and ensure that VULKAN_SDK env variable is set"); + let vulkan_lib_path = Path::new(&vulkan_path).join("Lib"); + + println!("cargo:rustc-link-search={}", vulkan_lib_path.display()); + println!("cargo:rustc-link-lib=vulkan-1"); + + // SAFETY: build scripts are single-threaded, so modifying env is safe. + unsafe { env::set_var("TrackFileAccess", "false") }; + + config.cflag("/FS"); + config.cxxflag("/FS"); + } + TargetOs::Linux => { + if let Ok(vulkan_path) = env::var("VULKAN_SDK") { + let vulkan_lib_path = Path::new(&vulkan_path).join("lib"); + + println!("cargo:rustc-link-search={}", vulkan_lib_path.display()); + } + + println!("cargo:rustc-link-lib=vulkan"); + } + _ => (), + } +} + +pub fn configure_openmp(config: &mut Config, target_os: &TargetOs) { + let openmp_enabled = cfg!(feature = "openmp") && !target_os.is_android(); + + config.define("GGML_OPENMP", if openmp_enabled { "ON" } else { "OFF" }); +} diff --git a/llama-cpp-bindings-build/src/ggml_system_paths.rs b/llama-cpp-bindings-build/src/ggml_system_paths.rs new file mode 100644 index 00000000..624d8022 --- /dev/null +++ b/llama-cpp-bindings-build/src/ggml_system_paths.rs @@ -0,0 +1,23 @@ +use std::env; +use std::path::PathBuf; + +#[derive(Debug)] +pub struct GgmlSystemPaths { + pub cmake_dir: PathBuf, + pub lib_dir: PathBuf, +} + +impl GgmlSystemPaths { + pub fn from_env() -> Self { + Self { + cmake_dir: PathBuf::from( + env::var("DEP_GGML_CMAKE") + .expect("DEP_GGML_CMAKE must be provided by llama-cpp-ggml-sys"), + ), + lib_dir: PathBuf::from( + env::var("DEP_GGML_LIB") + .expect("DEP_GGML_LIB must be provided by llama-cpp-ggml-sys"), + ), + } + } +} diff --git a/llama-cpp-bindings-build/src/lib.rs b/llama-cpp-bindings-build/src/lib.rs index 48809244..2a8828e4 100644 --- a/llama-cpp-bindings-build/src/lib.rs +++ b/llama-cpp-bindings-build/src/lib.rs @@ -1,8 +1,13 @@ mod android_ndk; mod bindgen_config; +pub mod build_gbnf; +pub mod build_ggml; +mod cmake_common; mod cmake_config; mod cpp_wrapper; mod cpp_wrapper_mtmd; +mod ggml_cmake_options; +mod ggml_system_paths; mod glob_paths; mod library_asset_extraction; mod library_linking; @@ -16,6 +21,7 @@ use std::env; use std::path::{Path, PathBuf}; use android_ndk::AndroidNdk; +use ggml_system_paths::GgmlSystemPaths; use stable_cmake_build_dir::stable_cmake_build_dir; use target_os::TargetOs; @@ -40,6 +46,7 @@ pub struct BuildContext { pub profile: String, pub static_crt: bool, pub android_ndk: Option, + pub ggml_system: Option, } impl BuildContext { @@ -74,6 +81,12 @@ impl BuildContext { None }; + let ggml_system = if cfg!(feature = "system-ggml") { + Some(GgmlSystemPaths::from_env()) + } else { + None + }; + let cmake_dir = stable_cmake_build_dir( &target_dir, &target_triple, @@ -100,6 +113,7 @@ impl BuildContext { profile, static_crt, android_ndk, + ggml_system, } } } @@ -149,6 +163,7 @@ pub fn build() { &context.target_triple, context.build_shared_libs, &context.profile, + context.ggml_system.as_ref(), ); if context.build_shared_libs { diff --git a/llama-cpp-bindings-build/src/library_linking.rs b/llama-cpp-bindings-build/src/library_linking.rs index d834e9c2..a35bf6ef 100644 --- a/llama-cpp-bindings-build/src/library_linking.rs +++ b/llama-cpp-bindings-build/src/library_linking.rs @@ -2,6 +2,7 @@ use std::env; use std::path::Path; use crate::debug_log; +use crate::ggml_system_paths::GgmlSystemPaths; use crate::library_name_extraction::extract_lib_names; use crate::target_os::{AppleVariant, TargetOs, WindowsVariant}; @@ -12,9 +13,11 @@ pub fn link_libraries( target_triple: &str, build_shared_libs: bool, profile: &str, + ggml_system: Option<&GgmlSystemPaths>, ) { emit_search_paths(cmake_dir, build_dir); link_system_ggml_paths(build_dir); + emit_shared_ggml_search_path(ggml_system); link_cmake_built_libraries(cmake_dir, build_shared_libs, profile); link_cuda_libraries(build_shared_libs); link_rocm_libraries(build_shared_libs); @@ -22,6 +25,12 @@ pub fn link_libraries( link_platform_system_libraries(target_os); } +fn emit_shared_ggml_search_path(ggml_system: Option<&GgmlSystemPaths>) { + if let Some(ggml) = ggml_system { + println!("cargo:rustc-link-search=native={}", ggml.lib_dir.display()); + } +} + fn emit_search_paths(cmake_dir: &Path, build_dir: &Path) { println!( "cargo:rustc-link-search={}", @@ -123,6 +132,18 @@ fn link_system_ggml_libraries(link_kind: &str) { println!("cargo:rustc-link-lib={link_kind}=ggml"); println!("cargo:rustc-link-lib={link_kind}=ggml-base"); println!("cargo:rustc-link-lib={link_kind}=ggml-cpu"); + + if cfg!(feature = "cuda") { + println!("cargo:rustc-link-lib={link_kind}=ggml-cuda"); + } + + if cfg!(feature = "vulkan") { + println!("cargo:rustc-link-lib={link_kind}=ggml-vulkan"); + } + + if cfg!(feature = "rocm") { + println!("cargo:rustc-link-lib={link_kind}=ggml-hip"); + } } fn link_cuda_libraries(build_shared_libs: bool) { diff --git a/llama-cpp-bindings-sys/Cargo.toml b/llama-cpp-bindings-sys/Cargo.toml index 8546682f..06cc4df1 100644 --- a/llama-cpp-bindings-sys/Cargo.toml +++ b/llama-cpp-bindings-sys/Cargo.toml @@ -67,20 +67,19 @@ include = [ ] [dependencies] +llama-cpp-ggml-sys = { workspace = true } [build-dependencies] -llama-cpp-bindings-build = { workspace = true, features = [] } +llama-cpp-bindings-build = { workspace = true, features = ["system-ggml-static"] } [features] -cuda = ["llama-cpp-bindings-build/cuda"] -cuda-no-vmm = ["cuda", "llama-cpp-bindings-build/cuda-no-vmm"] +cuda = ["llama-cpp-bindings-build/cuda", "llama-cpp-ggml-sys/cuda"] +cuda-no-vmm = ["cuda", "llama-cpp-bindings-build/cuda-no-vmm", "llama-cpp-ggml-sys/cuda-no-vmm"] metal = ["llama-cpp-bindings-build/metal"] dynamic-link = ["llama-cpp-bindings-build/dynamic-link"] dynamic-backends = ["dynamic-link", "llama-cpp-bindings-build/dynamic-backends"] -vulkan = ["llama-cpp-bindings-build/vulkan"] -openmp = ["llama-cpp-bindings-build/openmp"] -rocm = ["llama-cpp-bindings-build/rocm"] +vulkan = ["llama-cpp-bindings-build/vulkan", "llama-cpp-ggml-sys/vulkan"] +openmp = ["llama-cpp-bindings-build/openmp", "llama-cpp-ggml-sys/openmp"] +rocm = ["llama-cpp-bindings-build/rocm", "llama-cpp-ggml-sys/rocm"] shared-stdcxx = ["llama-cpp-bindings-build/shared-stdcxx"] static-stdcxx = ["llama-cpp-bindings-build/static-stdcxx"] -system-ggml = ["llama-cpp-bindings-build/system-ggml"] -system-ggml-static = ["system-ggml", "llama-cpp-bindings-build/system-ggml-static"] diff --git a/llama-cpp-bindings-sys/wrapper_chat_apply.cpp b/llama-cpp-bindings-sys/wrapper_chat_apply.cpp index 9a6c81c3..46a696c3 100644 --- a/llama-cpp-bindings-sys/wrapper_chat_apply.cpp +++ b/llama-cpp-bindings-sys/wrapper_chat_apply.cpp @@ -87,19 +87,10 @@ extern "C" auto llama_rs_apply_chat_template( } return LLAMA_RS_APPLY_CHAT_TEMPLATE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_APPLY_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_APPLY_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_APPLY_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_APPLY_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_APPLY_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_APPLY_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_APPLY_CHAT_TEMPLATE_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_chat_apply.h b/llama-cpp-bindings-sys/wrapper_chat_apply.h index 62dc3f65..0e6f7236 100644 --- a/llama-cpp-bindings-sys/wrapper_chat_apply.h +++ b/llama-cpp-bindings-sys/wrapper_chat_apply.h @@ -19,7 +19,7 @@ typedef enum llama_rs_apply_chat_template_status { LLAMA_RS_APPLY_CHAT_TEMPLATE_MODEL_HAS_NO_VOCAB, LLAMA_RS_APPLY_CHAT_TEMPLATE_TEMPLATE_APPLICATION_FAILED, LLAMA_RS_APPLY_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_APPLY_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_APPLY_CHAT_TEMPLATE_THREW_CXX_EXCEPTION, } llama_rs_apply_chat_template_status; llama_rs_apply_chat_template_status llama_rs_apply_chat_template( diff --git a/llama-cpp-bindings-sys/wrapper_chat_parse.cpp b/llama-cpp-bindings-sys/wrapper_chat_parse.cpp index 3adc9396..5ceaadeb 100644 --- a/llama-cpp-bindings-sys/wrapper_chat_parse.cpp +++ b/llama-cpp-bindings-sys/wrapper_chat_parse.cpp @@ -85,20 +85,11 @@ extern "C" auto llama_rs_chat_parser_create( *out_parser = parser_handle.release(); return LLAMA_RS_CHAT_PARSER_CREATE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_CHAT_PARSER_CREATE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_CHAT_PARSER_CREATE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_CHAT_PARSER_CREATE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_CHAT_PARSER_CREATE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_CHAT_PARSER_CREATE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_CHAT_PARSER_CREATE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_CHAT_PARSER_CREATE_THREW_CXX_EXCEPTION); } } @@ -111,24 +102,11 @@ extern "C" auto llama_rs_chat_parser_free( try { const std::unique_ptr reclaimed(parser); return LLAMA_RS_CHAT_PARSER_FREE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_CHAT_PARSER_FREE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_CHAT_PARSER_FREE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_CHAT_PARSER_FREE_DESTRUCTOR_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_CHAT_PARSER_FREE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_CHAT_PARSER_FREE_DESTRUCTOR_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_CHAT_PARSER_FREE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_CHAT_PARSER_FREE_DESTRUCTOR_THREW_CXX_EXCEPTION); } } @@ -181,20 +159,11 @@ extern "C" auto llama_rs_parse_chat_message( *out_handle = handle.release(); return LLAMA_RS_PARSE_CHAT_MESSAGE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSE_CHAT_MESSAGE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_PARSE_CHAT_MESSAGE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_PARSE_CHAT_MESSAGE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_PARSE_CHAT_MESSAGE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_PARSE_CHAT_MESSAGE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSE_CHAT_MESSAGE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSE_CHAT_MESSAGE_THREW_CXX_EXCEPTION); } } @@ -207,24 +176,11 @@ extern "C" auto llama_rs_parsed_chat_free( try { const std::unique_ptr reclaimed(handle); return LLAMA_RS_PARSED_CHAT_FREE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_FREE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_FREE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_FREE_DESTRUCTOR_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_FREE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_FREE_DESTRUCTOR_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_FREE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_FREE_DESTRUCTOR_THREW_CXX_EXCEPTION); } } @@ -247,24 +203,11 @@ extern "C" auto llama_rs_parsed_chat_tool_call_count( try { *out_count = handle->message.tool_calls.size(); return LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_THREW_CXX_EXCEPTION); } } @@ -295,24 +238,11 @@ extern "C" auto llama_rs_parsed_chat_tool_call_id( return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_ERROR_STRING_ALLOCATION_FAILED; } return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_THREW_CXX_EXCEPTION); } } @@ -343,24 +273,11 @@ extern "C" auto llama_rs_parsed_chat_tool_call_name( return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_ERROR_STRING_ALLOCATION_FAILED; } return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_THREW_CXX_EXCEPTION); } } @@ -392,24 +309,11 @@ extern "C" auto llama_rs_parsed_chat_tool_call_arguments( return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_ERROR_STRING_ALLOCATION_FAILED; } return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_THREW_CXX_EXCEPTION); } } @@ -436,24 +340,11 @@ extern "C" auto llama_rs_parsed_chat_content( return LLAMA_RS_PARSED_CHAT_CONTENT_ERROR_STRING_ALLOCATION_FAILED; } return LLAMA_RS_PARSED_CHAT_CONTENT_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_CONTENT_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_CONTENT_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_CONTENT_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_CONTENT_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_CONTENT_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_CONTENT_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_CONTENT_THREW_CXX_EXCEPTION); } } @@ -480,23 +371,10 @@ extern "C" auto llama_rs_parsed_chat_reasoning_content( return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_ERROR_STRING_ALLOCATION_FAILED; } return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_chat_parse.h b/llama-cpp-bindings-sys/wrapper_chat_parse.h index d13d2c07..546ac187 100644 --- a/llama-cpp-bindings-sys/wrapper_chat_parse.h +++ b/llama-cpp-bindings-sys/wrapper_chat_parse.h @@ -23,7 +23,7 @@ typedef enum llama_rs_chat_parser_create_status { LLAMA_RS_CHAT_PARSER_CREATE_MODEL_HAS_NO_CHAT_TEMPLATE, LLAMA_RS_CHAT_PARSER_CREATE_MODEL_HAS_NO_VOCAB, LLAMA_RS_CHAT_PARSER_CREATE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_CHAT_PARSER_CREATE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_CHAT_PARSER_CREATE_THREW_CXX_EXCEPTION, } llama_rs_chat_parser_create_status; llama_rs_chat_parser_create_status llama_rs_chat_parser_create( @@ -50,7 +50,7 @@ typedef enum llama_rs_parse_chat_message_status { LLAMA_RS_PARSE_CHAT_MESSAGE_NULL_OUT_HANDLE_ARG, LLAMA_RS_PARSE_CHAT_MESSAGE_NULL_OUT_ERROR_ARG, LLAMA_RS_PARSE_CHAT_MESSAGE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSE_CHAT_MESSAGE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSE_CHAT_MESSAGE_THREW_CXX_EXCEPTION, } llama_rs_parse_chat_message_status; llama_rs_parse_chat_message_status llama_rs_parse_chat_message( @@ -76,7 +76,7 @@ typedef enum llama_rs_parsed_chat_tool_call_count_status { LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_NULL_HANDLE_ARG, LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_NULL_OUT_COUNT_ARG, LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_THREW_CXX_EXCEPTION, } llama_rs_parsed_chat_tool_call_count_status; llama_rs_parsed_chat_tool_call_count_status llama_rs_parsed_chat_tool_call_count( @@ -90,7 +90,7 @@ typedef enum llama_rs_parsed_chat_tool_call_id_status { LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_NULL_OUT_STRING_ARG, LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_INDEX_OUT_OF_BOUNDS, LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_THREW_CXX_EXCEPTION, } llama_rs_parsed_chat_tool_call_id_status; llama_rs_parsed_chat_tool_call_id_status llama_rs_parsed_chat_tool_call_id( @@ -105,7 +105,7 @@ typedef enum llama_rs_parsed_chat_tool_call_name_status { LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_NULL_OUT_STRING_ARG, LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_INDEX_OUT_OF_BOUNDS, LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_THREW_CXX_EXCEPTION, } llama_rs_parsed_chat_tool_call_name_status; llama_rs_parsed_chat_tool_call_name_status llama_rs_parsed_chat_tool_call_name( @@ -120,7 +120,7 @@ typedef enum llama_rs_parsed_chat_tool_call_arguments_status { LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_NULL_OUT_STRING_ARG, LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_INDEX_OUT_OF_BOUNDS, LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_THREW_CXX_EXCEPTION, } llama_rs_parsed_chat_tool_call_arguments_status; llama_rs_parsed_chat_tool_call_arguments_status llama_rs_parsed_chat_tool_call_arguments( @@ -134,7 +134,7 @@ typedef enum llama_rs_parsed_chat_content_status { LLAMA_RS_PARSED_CHAT_CONTENT_NULL_HANDLE_ARG, LLAMA_RS_PARSED_CHAT_CONTENT_NULL_OUT_STRING_ARG, LLAMA_RS_PARSED_CHAT_CONTENT_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSED_CHAT_CONTENT_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSED_CHAT_CONTENT_THREW_CXX_EXCEPTION, } llama_rs_parsed_chat_content_status; llama_rs_parsed_chat_content_status llama_rs_parsed_chat_content( @@ -147,7 +147,7 @@ typedef enum llama_rs_parsed_chat_reasoning_content_status { LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_NULL_HANDLE_ARG, LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_NULL_OUT_STRING_ARG, LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_THREW_CXX_EXCEPTION, } llama_rs_parsed_chat_reasoning_content_status; llama_rs_parsed_chat_reasoning_content_status llama_rs_parsed_chat_reasoning_content( diff --git a/llama-cpp-bindings-sys/wrapper_common.cpp b/llama-cpp-bindings-sys/wrapper_common.cpp index cc20c9af..d784d3cf 100644 --- a/llama-cpp-bindings-sys/wrapper_common.cpp +++ b/llama-cpp-bindings-sys/wrapper_common.cpp @@ -50,26 +50,15 @@ extern "C" auto llama_rs_json_schema_to_grammar( return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; } return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::invalid_argument & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_INVALID_SCHEMA; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION; + } catch (const std::invalid_argument & error) { + return llama_rs_capture_message(out_error, error.what()) + ? LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_INVALID_SCHEMA + : LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_THREW_CXX_EXCEPTION); } } @@ -98,23 +87,14 @@ extern "C" auto llama_rs_sampler_init_grammar( try { *out_sampler = llama_sampler_init_grammar(vocab, grammar_str, grammar_root); if (*out_sampler == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_RETURNED_NULL; + return LLAMA_RS_SAMPLER_INIT_GRAMMAR_COMPILATION_FAILED; } return LLAMA_RS_SAMPLER_INIT_GRAMMAR_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_THREW_CXX_EXCEPTION); } } @@ -166,23 +146,14 @@ extern "C" auto llama_rs_sampler_init_grammar_lazy( trigger_tokens, num_trigger_tokens); if (*out_sampler == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_RETURNED_NULL; + return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_COMPILATION_FAILED; } return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_THREW_CXX_EXCEPTION); } } @@ -218,64 +189,49 @@ extern "C" auto llama_rs_sampler_init_grammar_lazy_patterns( trigger_tokens, num_trigger_tokens); if (*out_sampler == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_RETURNED_NULL; + return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_COMPILATION_FAILED; } return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::regex_error & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_INVALID_TRIGGER_PATTERN; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_THREW_CXX_EXCEPTION; + } catch (const std::regex_error & error) { + return llama_rs_capture_message(out_error, error.what()) + ? LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_INVALID_TRIGGER_PATTERN + : LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_THREW_CXX_EXCEPTION); } } extern "C" auto llama_rs_memory_seq_pos_max( const struct llama_context * ctx, - llama_seq_id seq_id) -> llama_pos { + llama_seq_id seq_id) noexcept -> llama_pos { if (ctx == nullptr) { return -1; } - try { - auto * mem = llama_get_memory(ctx); - if (mem == nullptr) { - return -1; - } - uint32_t const n_seq_max = llama_n_seq_max(ctx); - if (seq_id < 0 || (uint32_t) seq_id >= n_seq_max) { - return -1; - } - - return llama_memory_seq_pos_max(mem, seq_id); - } catch (...) { + auto * mem = llama_get_memory(ctx); + if (mem == nullptr) { + return -1; + } + uint32_t const n_seq_max = llama_n_seq_max(ctx); + if (seq_id < 0 || (uint32_t) seq_id >= n_seq_max) { return -1; } + + return llama_memory_seq_pos_max(mem, seq_id); } extern "C" auto llama_rs_encode( struct llama_context * ctx, struct llama_batch batch, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error) -> llama_rs_encode_status { if (out_error != nullptr) { *out_error = nullptr; } - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = 0; + if (out_return_code != nullptr) { + *out_return_code = 0; } if (ctx == nullptr) { return LLAMA_RS_ENCODE_NULL_CTX_ARG; @@ -287,8 +243,8 @@ extern "C" auto llama_rs_encode( } int32_t const result = llama_encode(ctx, batch); if (result != 0) { - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = result; + if (out_return_code != nullptr) { + *out_return_code = result; } if (result == -2) { return LLAMA_RS_ENCODE_OUT_OF_MEMORY; @@ -296,27 +252,14 @@ extern "C" auto llama_rs_encode( if (result == -3) { return LLAMA_RS_ENCODE_COMPUTE_FAILED; } - return LLAMA_RS_ENCODE_VENDORED_RETURNED_NONZERO_CODE; + return LLAMA_RS_ENCODE_RETURNED_ERROR_CODE; } return LLAMA_RS_ENCODE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_ENCODE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_ENCODE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_ENCODE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_ENCODE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_ENCODE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_ENCODE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_ENCODE_THREW_CXX_EXCEPTION); } } @@ -345,24 +288,11 @@ extern "C" auto llama_rs_memory_seq_add( } llama_memory_seq_add(mem, seq_id, pos_start, pos_end, shift); return LLAMA_RS_MEMORY_SEQ_ADD_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_MEMORY_SEQ_ADD_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MEMORY_SEQ_ADD_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MEMORY_SEQ_ADD_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MEMORY_SEQ_ADD_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MEMORY_SEQ_ADD_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MEMORY_SEQ_ADD_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MEMORY_SEQ_ADD_THREW_CXX_EXCEPTION); } } @@ -391,24 +321,11 @@ extern "C" auto llama_rs_memory_seq_div( } llama_memory_seq_div(mem, seq_id, pos_start, pos_end, divisor); return LLAMA_RS_MEMORY_SEQ_DIV_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_MEMORY_SEQ_DIV_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MEMORY_SEQ_DIV_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MEMORY_SEQ_DIV_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MEMORY_SEQ_DIV_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MEMORY_SEQ_DIV_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MEMORY_SEQ_DIV_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MEMORY_SEQ_DIV_THREW_CXX_EXCEPTION); } } @@ -436,20 +353,11 @@ extern "C" auto llama_rs_sampler_sample( try { *out_token = llama_sampler_sample(sampler, ctx, idx); return LLAMA_RS_SAMPLER_SAMPLE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_SAMPLER_SAMPLE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_SAMPLE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_SAMPLE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_SAMPLE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_SAMPLE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_SAMPLER_SAMPLE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_SAMPLER_SAMPLE_THREW_CXX_EXCEPTION); } } @@ -469,20 +377,11 @@ extern "C" auto llama_rs_sampler_accept( try { llama_sampler_accept(sampler, token); return LLAMA_RS_SAMPLER_ACCEPT_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_SAMPLER_ACCEPT_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_ACCEPT_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_ACCEPT_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_ACCEPT_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_ACCEPT_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_SAMPLER_ACCEPT_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_SAMPLER_ACCEPT_THREW_CXX_EXCEPTION); } } @@ -509,23 +408,14 @@ extern "C" auto llama_rs_load_model_from_file( try { *out_model = llama_model_load_from_file(path, params); if (*out_model == nullptr) { - return LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_RETURNED_NULL; + return LLAMA_RS_LOAD_MODEL_FROM_FILE_LOAD_FAILED; } return LLAMA_RS_LOAD_MODEL_FROM_FILE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_LOAD_MODEL_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_LOAD_MODEL_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_LOAD_MODEL_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_LOAD_MODEL_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_LOAD_MODEL_FROM_FILE_THREW_CXX_EXCEPTION); } } @@ -552,36 +442,27 @@ extern "C" auto llama_rs_new_context_with_model( try { *out_ctx = llama_init_from_model(model, params); if (*out_ctx == nullptr) { - return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_RETURNED_NULL; + return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_CREATION_FAILED; } return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_NEW_CONTEXT_WITH_MODEL_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_NEW_CONTEXT_WITH_MODEL_THREW_CXX_EXCEPTION); } } extern "C" auto llama_rs_decode( struct llama_context * ctx, struct llama_batch batch, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error) -> llama_rs_decode_status { if (out_error != nullptr) { *out_error = nullptr; } - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = 0; + if (out_return_code != nullptr) { + *out_return_code = 0; } if (ctx == nullptr) { return LLAMA_RS_DECODE_NULL_CTX_ARG; @@ -592,8 +473,8 @@ extern "C" auto llama_rs_decode( try { int32_t const result = llama_decode(ctx, batch); if (result != 0) { - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = result; + if (out_return_code != nullptr) { + *out_return_code = result; } if (result == -2) { return LLAMA_RS_DECODE_OUT_OF_MEMORY; @@ -601,23 +482,14 @@ extern "C" auto llama_rs_decode( if (result == -3) { return LLAMA_RS_DECODE_COMPUTE_FAILED; } - return LLAMA_RS_DECODE_VENDORED_RETURNED_NONZERO_CODE; + return LLAMA_RS_DECODE_RETURNED_ERROR_CODE; } return LLAMA_RS_DECODE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_DECODE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_DECODE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_DECODE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_DECODE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_DECODE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_DECODE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_DECODE_THREW_CXX_EXCEPTION); } } @@ -654,20 +526,11 @@ extern "C" auto llama_rs_tokenize( vocab, text, text_len, tokens, n_tokens_max, add_special, parse_special); *out_returned_count = count; return LLAMA_RS_TOKENIZE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_TOKENIZE_THREW_CXX_EXCEPTION); } } @@ -690,19 +553,10 @@ extern "C" auto llama_rs_sampler_apply( try { llama_sampler_apply(sampler, data_array); return LLAMA_RS_SAMPLER_APPLY_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_SAMPLER_APPLY_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_APPLY_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_APPLY_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_SAMPLER_APPLY_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_SAMPLER_APPLY_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_SAMPLER_APPLY_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_SAMPLER_APPLY_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_common.h b/llama-cpp-bindings-sys/wrapper_common.h index 7896e200..c47c0e45 100644 --- a/llama-cpp-bindings-sys/wrapper_common.h +++ b/llama-cpp-bindings-sys/wrapper_common.h @@ -23,7 +23,7 @@ typedef enum llama_rs_json_schema_to_grammar_status { LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_NULL_OUT_ERROR_ARG, LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED, LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_INVALID_SCHEMA, - LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_THREW_CXX_EXCEPTION, } llama_rs_json_schema_to_grammar_status; llama_rs_json_schema_to_grammar_status llama_rs_json_schema_to_grammar( @@ -36,9 +36,9 @@ typedef enum llama_rs_sampler_init_grammar_status { LLAMA_RS_SAMPLER_INIT_GRAMMAR_OK = 0, LLAMA_RS_SAMPLER_INIT_GRAMMAR_NULL_OUT_SAMPLER_ARG, LLAMA_RS_SAMPLER_INIT_GRAMMAR_NULL_OUT_ERROR_ARG, - LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_RETURNED_NULL, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_COMPILATION_FAILED, LLAMA_RS_SAMPLER_INIT_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_THREW_CXX_EXCEPTION, } llama_rs_sampler_init_grammar_status; llama_rs_sampler_init_grammar_status llama_rs_sampler_init_grammar( @@ -52,9 +52,9 @@ typedef enum llama_rs_sampler_init_grammar_lazy_status { LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_OK = 0, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_NULL_OUT_SAMPLER_ARG, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_NULL_OUT_ERROR_ARG, - LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_RETURNED_NULL, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_COMPILATION_FAILED, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_THREW_CXX_EXCEPTION, } llama_rs_sampler_init_grammar_lazy_status; llama_rs_sampler_init_grammar_lazy_status llama_rs_sampler_init_grammar_lazy( @@ -72,10 +72,10 @@ typedef enum llama_rs_sampler_init_grammar_lazy_patterns_status { LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_OK = 0, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_NULL_OUT_SAMPLER_ARG, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_NULL_OUT_ERROR_ARG, - LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_RETURNED_NULL, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_COMPILATION_FAILED, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED, LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_INVALID_TRIGGER_PATTERN, - LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_THREW_CXX_EXCEPTION, } llama_rs_sampler_init_grammar_lazy_patterns_status; llama_rs_sampler_init_grammar_lazy_patterns_status llama_rs_sampler_init_grammar_lazy_patterns( @@ -94,7 +94,7 @@ typedef enum llama_rs_sampler_accept_status { LLAMA_RS_SAMPLER_ACCEPT_NULL_SAMPLER_ARG, LLAMA_RS_SAMPLER_ACCEPT_NULL_OUT_ERROR_ARG, LLAMA_RS_SAMPLER_ACCEPT_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_SAMPLER_ACCEPT_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_SAMPLER_ACCEPT_THREW_CXX_EXCEPTION, } llama_rs_sampler_accept_status; llama_rs_sampler_accept_status llama_rs_sampler_accept( @@ -109,7 +109,7 @@ typedef enum llama_rs_sampler_sample_status { LLAMA_RS_SAMPLER_SAMPLE_NULL_OUT_TOKEN_ARG, LLAMA_RS_SAMPLER_SAMPLE_NULL_OUT_ERROR_ARG, LLAMA_RS_SAMPLER_SAMPLE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_SAMPLER_SAMPLE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_SAMPLER_SAMPLE_THREW_CXX_EXCEPTION, } llama_rs_sampler_sample_status; llama_rs_sampler_sample_status llama_rs_sampler_sample( @@ -123,23 +123,23 @@ void llama_rs_string_free(char * ptr); llama_pos llama_rs_memory_seq_pos_max( const struct llama_context * ctx, - llama_seq_id seq_id); + llama_seq_id seq_id) LLAMA_RS_NOEXCEPT; typedef enum llama_rs_encode_status { LLAMA_RS_ENCODE_OK = 0, LLAMA_RS_ENCODE_NULL_CTX_ARG, LLAMA_RS_ENCODE_MODEL_HAS_NO_ENCODER, - LLAMA_RS_ENCODE_VENDORED_RETURNED_NONZERO_CODE, + LLAMA_RS_ENCODE_RETURNED_ERROR_CODE, LLAMA_RS_ENCODE_OUT_OF_MEMORY, LLAMA_RS_ENCODE_COMPUTE_FAILED, LLAMA_RS_ENCODE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_ENCODE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_ENCODE_THREW_CXX_EXCEPTION, } llama_rs_encode_status; llama_rs_encode_status llama_rs_encode( struct llama_context * ctx, struct llama_batch batch, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error); typedef enum llama_rs_memory_seq_add_status { @@ -148,7 +148,7 @@ typedef enum llama_rs_memory_seq_add_status { LLAMA_RS_MEMORY_SEQ_ADD_INCOMPATIBLE_ROPE_TYPE, LLAMA_RS_MEMORY_SEQ_ADD_NULL_MEM, LLAMA_RS_MEMORY_SEQ_ADD_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MEMORY_SEQ_ADD_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MEMORY_SEQ_ADD_THREW_CXX_EXCEPTION, } llama_rs_memory_seq_add_status; llama_rs_memory_seq_add_status llama_rs_memory_seq_add( @@ -165,7 +165,7 @@ typedef enum llama_rs_memory_seq_div_status { LLAMA_RS_MEMORY_SEQ_DIV_INCOMPATIBLE_ROPE_TYPE, LLAMA_RS_MEMORY_SEQ_DIV_NULL_MEM, LLAMA_RS_MEMORY_SEQ_DIV_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MEMORY_SEQ_DIV_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MEMORY_SEQ_DIV_THREW_CXX_EXCEPTION, } llama_rs_memory_seq_div_status; llama_rs_memory_seq_div_status llama_rs_memory_seq_div( @@ -181,9 +181,9 @@ typedef enum llama_rs_load_model_from_file_status { LLAMA_RS_LOAD_MODEL_FROM_FILE_NULL_PATH_ARG, LLAMA_RS_LOAD_MODEL_FROM_FILE_NULL_OUT_MODEL_ARG, LLAMA_RS_LOAD_MODEL_FROM_FILE_NULL_OUT_ERROR_ARG, - LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_RETURNED_NULL, + LLAMA_RS_LOAD_MODEL_FROM_FILE_LOAD_FAILED, LLAMA_RS_LOAD_MODEL_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_LOAD_MODEL_FROM_FILE_THREW_CXX_EXCEPTION, } llama_rs_load_model_from_file_status; llama_rs_load_model_from_file_status llama_rs_load_model_from_file( @@ -197,9 +197,9 @@ typedef enum llama_rs_new_context_with_model_status { LLAMA_RS_NEW_CONTEXT_WITH_MODEL_NULL_MODEL_ARG, LLAMA_RS_NEW_CONTEXT_WITH_MODEL_NULL_OUT_CTX_ARG, LLAMA_RS_NEW_CONTEXT_WITH_MODEL_NULL_OUT_ERROR_ARG, - LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_RETURNED_NULL, + LLAMA_RS_NEW_CONTEXT_WITH_MODEL_CREATION_FAILED, LLAMA_RS_NEW_CONTEXT_WITH_MODEL_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_NEW_CONTEXT_WITH_MODEL_THREW_CXX_EXCEPTION, } llama_rs_new_context_with_model_status; llama_rs_new_context_with_model_status llama_rs_new_context_with_model( @@ -212,17 +212,17 @@ typedef enum llama_rs_decode_status { LLAMA_RS_DECODE_OK = 0, LLAMA_RS_DECODE_NULL_CTX_ARG, LLAMA_RS_DECODE_NULL_OUT_ERROR_ARG, - LLAMA_RS_DECODE_VENDORED_RETURNED_NONZERO_CODE, + LLAMA_RS_DECODE_RETURNED_ERROR_CODE, LLAMA_RS_DECODE_OUT_OF_MEMORY, LLAMA_RS_DECODE_COMPUTE_FAILED, LLAMA_RS_DECODE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_DECODE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_DECODE_THREW_CXX_EXCEPTION, } llama_rs_decode_status; llama_rs_decode_status llama_rs_decode( struct llama_context * ctx, struct llama_batch batch, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error); typedef enum llama_rs_tokenize_status { @@ -232,7 +232,7 @@ typedef enum llama_rs_tokenize_status { LLAMA_RS_TOKENIZE_NULL_OUT_RETURNED_COUNT_ARG, LLAMA_RS_TOKENIZE_NULL_OUT_ERROR_ARG, LLAMA_RS_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_TOKENIZE_THREW_CXX_EXCEPTION, } llama_rs_tokenize_status; llama_rs_tokenize_status llama_rs_tokenize( @@ -252,7 +252,7 @@ typedef enum llama_rs_sampler_apply_status { LLAMA_RS_SAMPLER_APPLY_NULL_DATA_ARRAY_ARG, LLAMA_RS_SAMPLER_APPLY_NULL_OUT_ERROR_ARG, LLAMA_RS_SAMPLER_APPLY_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_SAMPLER_APPLY_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_SAMPLER_APPLY_THREW_CXX_EXCEPTION, } llama_rs_sampler_apply_status; llama_rs_sampler_apply_status llama_rs_sampler_apply( diff --git a/llama-cpp-bindings-sys/wrapper_fit.cpp b/llama-cpp-bindings-sys/wrapper_fit.cpp index 5360b337..1659c719 100644 --- a/llama-cpp-bindings-sys/wrapper_fit.cpp +++ b/llama-cpp-bindings-sys/wrapper_fit.cpp @@ -36,31 +36,18 @@ extern "C" auto llama_rs_fit_params( case COMMON_PARAMS_FIT_STATUS_SUCCESS: return LLAMA_RS_FIT_PARAMS_OK; case COMMON_PARAMS_FIT_STATUS_FAILURE: - return LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_FAILURE; + return LLAMA_RS_FIT_PARAMS_DOES_NOT_FIT; case COMMON_PARAMS_FIT_STATUS_ERROR: - return LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_ERROR; + return LLAMA_RS_FIT_PARAMS_HARD_ERROR; } if (out_unrecognized_status_code != nullptr) { *out_unrecognized_status_code = static_cast(status); } - return LLAMA_RS_FIT_PARAMS_VENDORED_RETURNED_UNRECOGNIZED_STATUS_CODE; - } catch (const std::bad_alloc &) { - return LLAMA_RS_FIT_PARAMS_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_FIT_PARAMS_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_FIT_PARAMS_VENDORED_THREW_CXX_EXCEPTION; + return LLAMA_RS_FIT_PARAMS_UNRECOGNIZED_STATUS_CODE; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_FIT_PARAMS_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_FIT_PARAMS_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_FIT_PARAMS_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_FIT_PARAMS_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_fit.h b/llama-cpp-bindings-sys/wrapper_fit.h index 9a6ac6ef..ac7c91f7 100644 --- a/llama-cpp-bindings-sys/wrapper_fit.h +++ b/llama-cpp-bindings-sys/wrapper_fit.h @@ -12,11 +12,11 @@ extern "C" { typedef enum llama_rs_fit_params_status { LLAMA_RS_FIT_PARAMS_OK = 0, - LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_FAILURE, - LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_ERROR, - LLAMA_RS_FIT_PARAMS_VENDORED_RETURNED_UNRECOGNIZED_STATUS_CODE, + LLAMA_RS_FIT_PARAMS_DOES_NOT_FIT, + LLAMA_RS_FIT_PARAMS_HARD_ERROR, + LLAMA_RS_FIT_PARAMS_UNRECOGNIZED_STATUS_CODE, LLAMA_RS_FIT_PARAMS_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_FIT_PARAMS_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_FIT_PARAMS_THREW_CXX_EXCEPTION, } llama_rs_fit_params_status; llama_rs_fit_params_status llama_rs_fit_params( diff --git a/llama-cpp-bindings-sys/wrapper_mtmd.cpp b/llama-cpp-bindings-sys/wrapper_mtmd.cpp index 1a562664..952892d5 100644 --- a/llama-cpp-bindings-sys/wrapper_mtmd.cpp +++ b/llama-cpp-bindings-sys/wrapper_mtmd.cpp @@ -33,28 +33,15 @@ extern "C" auto llama_rs_mtmd_init_from_file( try { struct mtmd_context * ctx = mtmd_init_from_file(mmproj_path, text_model, ctx_params); if (ctx == nullptr) { - return LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_RETURNED_NULL; + return LLAMA_RS_MTMD_INIT_FROM_FILE_INITIALIZATION_FAILED; } *out_ctx = ctx; return LLAMA_RS_MTMD_INIT_FROM_FILE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_MTMD_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MTMD_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MTMD_INIT_FROM_FILE_THREW_CXX_EXCEPTION); } } @@ -82,28 +69,15 @@ extern "C" auto llama_rs_mtmd_bitmap_init_from_file( mtmd_helper_bitmap_init_from_file(ctx, fname, false); struct mtmd_bitmap * bitmap = bitmap_wrapper.bitmap; if (bitmap == nullptr) { - return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_RETURNED_NULL; + return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_LOAD_FAILED; } *out_bitmap = bitmap; return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_THREW_CXX_EXCEPTION); } } @@ -140,46 +114,33 @@ extern "C" auto llama_rs_mtmd_tokenize( case 0: return LLAMA_RS_MTMD_TOKENIZE_OK; case 1: - return LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT; + return LLAMA_RS_MTMD_TOKENIZE_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT; case 2: - return LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_IMAGE_PREPROCESSING_ERROR; + return LLAMA_RS_MTMD_TOKENIZE_IMAGE_PREPROCESSING_ERROR; default: if (out_undocumented_return_code != nullptr) { *out_undocumented_return_code = result; } - return LLAMA_RS_MTMD_TOKENIZE_VENDORED_RETURNED_UNDOCUMENTED_NONZERO_CODE; - } - } catch (const std::bad_alloc &) { - return LLAMA_RS_MTMD_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED; - } + return LLAMA_RS_MTMD_TOKENIZE_UNDOCUMENTED_ERROR_CODE; } - return LLAMA_RS_MTMD_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MTMD_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MTMD_TOKENIZE_THREW_CXX_EXCEPTION); } } extern "C" auto llama_rs_mtmd_encode_chunk( struct mtmd_context * ctx, const struct mtmd_input_chunk * chunk, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error) -> llama_rs_mtmd_encode_chunk_status { if (out_error != nullptr) { *out_error = nullptr; } - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = 0; + if (out_return_code != nullptr) { + *out_return_code = 0; } if (ctx == nullptr) { return LLAMA_RS_MTMD_ENCODE_CHUNK_NULL_CTX_ARG; @@ -191,30 +152,17 @@ extern "C" auto llama_rs_mtmd_encode_chunk( try { int32_t const result = mtmd_encode_chunk(ctx, chunk); if (result != 0) { - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = result; + if (out_return_code != nullptr) { + *out_return_code = result; } - return LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_RETURNED_NONZERO_CODE; + return LLAMA_RS_MTMD_ENCODE_CHUNK_RETURNED_ERROR_CODE; } return LLAMA_RS_MTMD_ENCODE_CHUNK_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_MTMD_ENCODE_CHUNK_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_ENCODE_CHUNK_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_ENCODE_CHUNK_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MTMD_ENCODE_CHUNK_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MTMD_ENCODE_CHUNK_THREW_CXX_EXCEPTION); } } @@ -227,13 +175,13 @@ extern "C" auto llama_rs_mtmd_eval_chunk_single( int32_t n_batch, bool logits_last, llama_pos * out_new_n_past, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error) -> llama_rs_mtmd_eval_chunk_single_status { if (out_error != nullptr) { *out_error = nullptr; } - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = 0; + if (out_return_code != nullptr) { + *out_return_code = 0; } if (ctx == nullptr) { return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_NULL_MTMD_CTX_ARG; @@ -252,29 +200,16 @@ extern "C" auto llama_rs_mtmd_eval_chunk_single( int32_t const result = mtmd_helper_eval_chunk_single( ctx, lctx, chunk, n_past, seq_id, n_batch, logits_last, out_new_n_past); if (result != 0) { - if (out_vendored_return_code != nullptr) { - *out_vendored_return_code = result; + if (out_return_code != nullptr) { + *out_return_code = result; } - return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_RETURNED_NONZERO_CODE; + return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_RETURNED_ERROR_CODE; } return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & err) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string(err.what()); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - if (out_error != nullptr) { - *out_error = llama_rs_dup_string("unknown c++ exception"); - if (*out_error == nullptr) { - return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_ERROR_STRING_ALLOCATION_FAILED; - } - } - return LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_mtmd.h b/llama-cpp-bindings-sys/wrapper_mtmd.h index ac2f5314..10a9f355 100644 --- a/llama-cpp-bindings-sys/wrapper_mtmd.h +++ b/llama-cpp-bindings-sys/wrapper_mtmd.h @@ -16,9 +16,9 @@ typedef enum llama_rs_mtmd_init_from_file_status { LLAMA_RS_MTMD_INIT_FROM_FILE_NULL_MMPROJ_PATH_ARG, LLAMA_RS_MTMD_INIT_FROM_FILE_NULL_TEXT_MODEL_ARG, LLAMA_RS_MTMD_INIT_FROM_FILE_NULL_OUT_CTX_ARG, - LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_RETURNED_NULL, + LLAMA_RS_MTMD_INIT_FROM_FILE_INITIALIZATION_FAILED, LLAMA_RS_MTMD_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MTMD_INIT_FROM_FILE_THREW_CXX_EXCEPTION, } llama_rs_mtmd_init_from_file_status; llama_rs_mtmd_init_from_file_status llama_rs_mtmd_init_from_file( @@ -33,9 +33,9 @@ typedef enum llama_rs_mtmd_bitmap_init_from_file_status { LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_NULL_CTX_ARG, LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_NULL_FNAME_ARG, LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_NULL_OUT_BITMAP_ARG, - LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_RETURNED_NULL, + LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_LOAD_FAILED, LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_THREW_CXX_EXCEPTION, } llama_rs_mtmd_bitmap_init_from_file_status; llama_rs_mtmd_bitmap_init_from_file_status llama_rs_mtmd_bitmap_init_from_file( @@ -50,11 +50,11 @@ typedef enum llama_rs_mtmd_tokenize_status { LLAMA_RS_MTMD_TOKENIZE_NULL_OUTPUT_ARG, LLAMA_RS_MTMD_TOKENIZE_NULL_TEXT_ARG, LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO, - LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT, - LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_IMAGE_PREPROCESSING_ERROR, - LLAMA_RS_MTMD_TOKENIZE_VENDORED_RETURNED_UNDOCUMENTED_NONZERO_CODE, + LLAMA_RS_MTMD_TOKENIZE_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT, + LLAMA_RS_MTMD_TOKENIZE_IMAGE_PREPROCESSING_ERROR, + LLAMA_RS_MTMD_TOKENIZE_UNDOCUMENTED_ERROR_CODE, LLAMA_RS_MTMD_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MTMD_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MTMD_TOKENIZE_THREW_CXX_EXCEPTION, } llama_rs_mtmd_tokenize_status; llama_rs_mtmd_tokenize_status llama_rs_mtmd_tokenize( @@ -70,15 +70,15 @@ typedef enum llama_rs_mtmd_encode_chunk_status { LLAMA_RS_MTMD_ENCODE_CHUNK_OK = 0, LLAMA_RS_MTMD_ENCODE_CHUNK_NULL_CTX_ARG, LLAMA_RS_MTMD_ENCODE_CHUNK_NULL_CHUNK_ARG, - LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_RETURNED_NONZERO_CODE, + LLAMA_RS_MTMD_ENCODE_CHUNK_RETURNED_ERROR_CODE, LLAMA_RS_MTMD_ENCODE_CHUNK_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MTMD_ENCODE_CHUNK_THREW_CXX_EXCEPTION, } llama_rs_mtmd_encode_chunk_status; llama_rs_mtmd_encode_chunk_status llama_rs_mtmd_encode_chunk( struct mtmd_context * ctx, const struct mtmd_input_chunk * chunk, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error); typedef enum llama_rs_mtmd_eval_chunk_single_status { @@ -87,9 +87,9 @@ typedef enum llama_rs_mtmd_eval_chunk_single_status { LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_NULL_LLAMA_CTX_ARG, LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_NULL_CHUNK_ARG, LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_NULL_OUT_NEW_N_PAST_ARG, - LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_RETURNED_NONZERO_CODE, + LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_RETURNED_ERROR_CODE, LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_THREW_CXX_EXCEPTION, } llama_rs_mtmd_eval_chunk_single_status; llama_rs_mtmd_eval_chunk_single_status llama_rs_mtmd_eval_chunk_single( @@ -101,7 +101,7 @@ llama_rs_mtmd_eval_chunk_single_status llama_rs_mtmd_eval_chunk_single( int32_t n_batch, bool logits_last, llama_pos * out_new_n_past, - int32_t * out_vendored_return_code, + int32_t * out_return_code, char ** out_error); #ifdef __cplusplus diff --git a/llama-cpp-bindings-sys/wrapper_reasoning.cpp b/llama-cpp-bindings-sys/wrapper_reasoning.cpp index 5fcf9094..f314665e 100644 --- a/llama-cpp-bindings-sys/wrapper_reasoning.cpp +++ b/llama-cpp-bindings-sys/wrapper_reasoning.cpp @@ -129,20 +129,11 @@ extern "C" auto llama_rs_detect_reasoning_markers( *out_close = close_dup.release(); return LLAMA_RS_DETECT_REASONING_MARKERS_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_DETECT_REASONING_MARKERS_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_DETECT_REASONING_MARKERS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_DETECT_REASONING_MARKERS_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_DETECT_REASONING_MARKERS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_DETECT_REASONING_MARKERS_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_DETECT_REASONING_MARKERS_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_DETECT_REASONING_MARKERS_THREW_CXX_EXCEPTION); } } @@ -204,20 +195,11 @@ extern "C" auto llama_rs_render_chat_template( } return LLAMA_RS_RENDER_CHAT_TEMPLATE_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_RENDER_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_RENDER_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_RENDER_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_RENDER_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_RENDER_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_RENDER_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_RENDER_CHAT_TEMPLATE_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_reasoning.h b/llama-cpp-bindings-sys/wrapper_reasoning.h index acf38396..6fa3d049 100644 --- a/llama-cpp-bindings-sys/wrapper_reasoning.h +++ b/llama-cpp-bindings-sys/wrapper_reasoning.h @@ -14,7 +14,7 @@ typedef enum llama_rs_detect_reasoning_markers_status { LLAMA_RS_DETECT_REASONING_MARKERS_NULL_OUT_CLOSE_ARG, LLAMA_RS_DETECT_REASONING_MARKERS_NULL_OUT_ERROR_ARG, LLAMA_RS_DETECT_REASONING_MARKERS_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_DETECT_REASONING_MARKERS_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_DETECT_REASONING_MARKERS_THREW_CXX_EXCEPTION, } llama_rs_detect_reasoning_markers_status; llama_rs_detect_reasoning_markers_status llama_rs_detect_reasoning_markers( @@ -32,7 +32,7 @@ typedef enum llama_rs_render_chat_template_status { LLAMA_RS_RENDER_CHAT_TEMPLATE_MODEL_HAS_NO_CHAT_TEMPLATE, LLAMA_RS_RENDER_CHAT_TEMPLATE_MODEL_HAS_NO_VOCAB, LLAMA_RS_RENDER_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_RENDER_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_RENDER_CHAT_TEMPLATE_THREW_CXX_EXCEPTION, } llama_rs_render_chat_template_status; llama_rs_render_chat_template_status llama_rs_render_chat_template( diff --git a/llama-cpp-bindings-sys/wrapper_tool_calls.cpp b/llama-cpp-bindings-sys/wrapper_tool_calls.cpp index 0d3b7cc4..624b649a 100644 --- a/llama-cpp-bindings-sys/wrapper_tool_calls.cpp +++ b/llama-cpp-bindings-sys/wrapper_tool_calls.cpp @@ -162,20 +162,11 @@ extern "C" auto llama_rs_compute_tool_call_haystack( *out_haystack = haystack_dup; return LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_THREW_CXX_EXCEPTION); } } @@ -286,19 +277,10 @@ extern "C" auto llama_rs_diagnose_tool_call_synthetic_renders( *out_with_tools = b_dup.release(); return LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_OK; - } catch (const std::bad_alloc &) { - return LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_ERROR_STRING_ALLOCATION_FAILED; - } catch (const std::exception & ex) { - *out_error = llama_rs_dup_string(std::string(ex.what())); - if (*out_error == nullptr) { - return LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_VENDORED_THREW_CXX_EXCEPTION; } catch (...) { - *out_error = llama_rs_dup_string(std::string("unknown c++ exception")); - if (*out_error == nullptr) { - return LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_ERROR_STRING_ALLOCATION_FAILED; - } - return LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_VENDORED_THREW_CXX_EXCEPTION; + return llama_rs_capture_exception( + out_error, + LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_ERROR_STRING_ALLOCATION_FAILED, + LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_THREW_CXX_EXCEPTION); } } diff --git a/llama-cpp-bindings-sys/wrapper_tool_calls.h b/llama-cpp-bindings-sys/wrapper_tool_calls.h index 7c96c20b..d65c4ce1 100644 --- a/llama-cpp-bindings-sys/wrapper_tool_calls.h +++ b/llama-cpp-bindings-sys/wrapper_tool_calls.h @@ -13,7 +13,7 @@ typedef enum llama_rs_compute_tool_call_haystack_status { LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_NULL_OUT_HAYSTACK_ARG, LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_NULL_OUT_ERROR_ARG, LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_THREW_CXX_EXCEPTION, } llama_rs_compute_tool_call_haystack_status; llama_rs_compute_tool_call_haystack_status llama_rs_compute_tool_call_haystack( @@ -28,7 +28,7 @@ typedef enum llama_rs_diagnose_tool_call_synthetic_renders_status { LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_NULL_OUT_WITH_TOOLS_ARG, LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_NULL_OUT_ERROR_ARG, LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_ERROR_STRING_ALLOCATION_FAILED, - LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_VENDORED_THREW_CXX_EXCEPTION, + LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_THREW_CXX_EXCEPTION, } llama_rs_diagnose_tool_call_synthetic_renders_status; llama_rs_diagnose_tool_call_synthetic_renders_status llama_rs_diagnose_tool_call_synthetic_renders( diff --git a/llama-cpp-bindings-sys/wrapper_utils.h b/llama-cpp-bindings-sys/wrapper_utils.h index 96b7030d..36998071 100644 --- a/llama-cpp-bindings-sys/wrapper_utils.h +++ b/llama-cpp-bindings-sys/wrapper_utils.h @@ -3,6 +3,12 @@ #include #include +#ifdef __cplusplus +#define LLAMA_RS_NOEXCEPT noexcept +#else +#define LLAMA_RS_NOEXCEPT +#endif + typedef enum llama_rs_status { LLAMA_RS_STATUS_OK = 0, LLAMA_RS_STATUS_INVALID_ARGUMENT = -1, @@ -13,6 +19,7 @@ typedef enum llama_rs_status { #ifdef __cplusplus #include +#include #include #include @@ -26,4 +33,28 @@ static inline char * llama_rs_dup_string(const std::string & value) { return buffer; } +static inline bool llama_rs_capture_message(char ** out_error, const char * message) { + if (out_error == nullptr) { + return true; + } + *out_error = llama_rs_dup_string(message); + return *out_error != nullptr; +} + +template +static inline TStatus llama_rs_capture_exception( + char ** out_error, TStatus allocation_failed, TStatus threw_cxx_exception) { + try { + throw; + } catch (const std::bad_alloc &) { + return allocation_failed; + } catch (const std::exception & error) { + return llama_rs_capture_message(out_error, error.what()) ? threw_cxx_exception + : allocation_failed; + } catch (...) { + return llama_rs_capture_message(out_error, "unknown c++ exception") ? threw_cxx_exception + : allocation_failed; + } +} + #endif diff --git a/llama-cpp-bindings-tests/Cargo.toml b/llama-cpp-bindings-tests/Cargo.toml index 4ea1796d..c2a31a49 100644 --- a/llama-cpp-bindings-tests/Cargo.toml +++ b/llama-cpp-bindings-tests/Cargo.toml @@ -10,9 +10,12 @@ autotests = false [dependencies] anyhow = { workspace = true } encoding_rs = { workspace = true } +inventory = { workspace = true } llama-cpp-bindings = { workspace = true } llama-cpp-bindings-sys = { workspace = true } +llama-cpp-bindings-types = { workspace = true } llama-cpp-test-harness = { workspace = true } +llama-cpp-test-harness-macros = { workspace = true } serde_json = { workspace = true } [[test]] diff --git a/llama-cpp-bindings-tests/src/build_user_prompt_with_media_marker.rs b/llama-cpp-bindings-tests/src/build_user_prompt_with_media_marker.rs index 2b3fabf7..4d817215 100644 --- a/llama-cpp-bindings-tests/src/build_user_prompt_with_media_marker.rs +++ b/llama-cpp-bindings-tests/src/build_user_prompt_with_media_marker.rs @@ -1,7 +1,7 @@ use anyhow::Result; -use llama_cpp_bindings::model::LlamaChatMessage; use llama_cpp_bindings::model::LlamaModel; -use llama_cpp_bindings::mtmd::mtmd_default_marker; +use llama_cpp_bindings::model::llama_chat_message::LlamaChatMessage; +use llama_cpp_bindings::mtmd::mtmd_default_marker::mtmd_default_marker; /// # Errors /// diff --git a/llama-cpp-bindings-tests/src/chunk_token_breakdown.rs b/llama-cpp-bindings-tests/src/chunk_token_breakdown.rs index 8b07191e..c98098d8 100644 --- a/llama-cpp-bindings-tests/src/chunk_token_breakdown.rs +++ b/llama-cpp-bindings-tests/src/chunk_token_breakdown.rs @@ -1,7 +1,7 @@ use anyhow::Context; use anyhow::Result; -use llama_cpp_bindings::mtmd::MtmdInputChunkType; -use llama_cpp_bindings::mtmd::MtmdInputChunks; +use llama_cpp_bindings::mtmd::mtmd_input_chunk_type::MtmdInputChunkType; +use llama_cpp_bindings::mtmd::mtmd_input_chunks::MtmdInputChunks; pub struct ChunkTokenBreakdown { pub text: u64, diff --git a/llama-cpp-bindings-tests/src/prime_kv_cache.rs b/llama-cpp-bindings-tests/src/prime_kv_cache.rs index 4a797e6b..49cbd8fb 100644 --- a/llama-cpp-bindings-tests/src/prime_kv_cache.rs +++ b/llama-cpp-bindings-tests/src/prime_kv_cache.rs @@ -1,6 +1,6 @@ use anyhow::Result; use llama_cpp_bindings::context::LlamaContext; -use llama_cpp_test_harness::LlamaFixture; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; use crate::prime_kv_cache_with::prime_kv_cache_with; diff --git a/llama-cpp-bindings-tests/src/prime_kv_cache_with.rs b/llama-cpp-bindings-tests/src/prime_kv_cache_with.rs index cbca9334..d9c03314 100644 --- a/llama-cpp-bindings-tests/src/prime_kv_cache_with.rs +++ b/llama-cpp-bindings-tests/src/prime_kv_cache_with.rs @@ -1,8 +1,8 @@ use anyhow::Result; use llama_cpp_bindings::context::LlamaContext; use llama_cpp_bindings::llama_batch::LlamaBatch; -use llama_cpp_bindings::model::AddBos; -use llama_cpp_test_harness::LlamaFixture; +use llama_cpp_bindings::model::add_bos::AddBos; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; /// # Errors /// Forwards tokenization, batch construction, and [`LlamaContext::decode`] errors verbatim. diff --git a/llama-cpp-bindings-tests/tests/backend_initialization.rs b/llama-cpp-bindings-tests/tests/backend_initialization.rs index 36f82b10..6d012141 100644 --- a/llama-cpp-bindings-tests/tests/backend_initialization.rs +++ b/llama-cpp-bindings-tests/tests/backend_initialization.rs @@ -1,6 +1,6 @@ use anyhow::Result; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "Qwen3.5-0.8B-Q4_K_M.gguf"), diff --git a/llama-cpp-bindings-tests/tests/chat_template_and_message_parsing.rs b/llama-cpp-bindings-tests/tests/chat_template_and_message_parsing.rs index d21d00c4..995fe047 100644 --- a/llama-cpp-bindings-tests/tests/chat_template_and_message_parsing.rs +++ b/llama-cpp-bindings-tests/tests/chat_template_and_message_parsing.rs @@ -1,11 +1,11 @@ use anyhow::Result; use anyhow::bail; -use llama_cpp_bindings::ChatMessageParseOutcome; -use llama_cpp_bindings::ChatTemplateError; -use llama_cpp_bindings::model::LlamaChatMessage; +use llama_cpp_bindings::chat_message_parse_outcome::ChatMessageParseOutcome; +use llama_cpp_bindings::error::chat_template_error::ChatTemplateError; +use llama_cpp_bindings::model::llama_chat_message::LlamaChatMessage; use llama_cpp_bindings_tests::build_user_prompt_with_media_marker::build_user_prompt_with_media_marker; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/DeepSeek-R1-Distill-Llama-8B-GGUF", "DeepSeek-R1-Distill-Llama-8B-Q4_K_M.gguf"), @@ -429,7 +429,7 @@ fn parses_malformed_tools_json_returns_tools_json_invalid_error( assert!(matches!( result, - Err(llama_cpp_bindings::ParseChatMessageError::ToolsJsonInvalid( + Err(llama_cpp_bindings::error::parse_chat_message_error::ParseChatMessageError::ToolsJsonInvalid( _ )) )); @@ -481,7 +481,7 @@ fn parses_non_array_tools_json_returns_tools_json_not_array_error( assert!(matches!( result, - Err(llama_cpp_bindings::ParseChatMessageError::ToolsJsonNotArray) + Err(llama_cpp_bindings::error::parse_chat_message_error::ParseChatMessageError::ToolsJsonNotArray) )); Ok(()) } @@ -531,7 +531,7 @@ fn parses_with_tools_null_byte_returns_tools_json_invalid_error( assert!(matches!( result, - Err(llama_cpp_bindings::ParseChatMessageError::ToolsJsonInvalid( + Err(llama_cpp_bindings::error::parse_chat_message_error::ParseChatMessageError::ToolsJsonInvalid( _ )) )); @@ -583,7 +583,7 @@ fn parses_with_input_null_byte_returns_tools_serialization_error( assert!(matches!( result, - Err(llama_cpp_bindings::ParseChatMessageError::ToolsSerialization(_)) + Err(llama_cpp_bindings::error::parse_chat_message_error::ParseChatMessageError::ToolsSerialization(_)) )); Ok(()) } diff --git a/llama-cpp-bindings-tests/tests/embedding_and_encoder.rs b/llama-cpp-bindings-tests/tests/embedding_and_encoder.rs index f681f5b5..de8b925b 100644 --- a/llama-cpp-bindings-tests/tests/embedding_and_encoder.rs +++ b/llama-cpp-bindings-tests/tests/embedding_and_encoder.rs @@ -5,12 +5,12 @@ use anyhow::Context; use anyhow::Result; use anyhow::bail; use llama_cpp_bindings::context::LlamaContext; -use llama_cpp_bindings::ggml_time_us; +use llama_cpp_bindings::ggml_time_us::ggml_time_us; use llama_cpp_bindings::llama_batch::LlamaBatch; -use llama_cpp_bindings::model::AddBos; +use llama_cpp_bindings::model::add_bos::AddBos; use llama_cpp_bindings_tests::prime_kv_cache::prime_kv_cache; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; fn normalize(input: &[f32]) -> Vec { let magnitude = input diff --git a/llama-cpp-bindings-tests/tests/kv_cache_and_session.rs b/llama-cpp-bindings-tests/tests/kv_cache_and_session.rs index e6ad1e51..870ea57b 100644 --- a/llama-cpp-bindings-tests/tests/kv_cache_and_session.rs +++ b/llama-cpp-bindings-tests/tests/kv_cache_and_session.rs @@ -4,19 +4,19 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use anyhow::Result; -use llama_cpp_bindings::DecodeError; -use llama_cpp_bindings::LogitsError; use llama_cpp_bindings::context::LlamaContext; use llama_cpp_bindings::context::kv_cache::KvCacheConversionError; -use llama_cpp_bindings::error::KvCacheSeqAddError; -use llama_cpp_bindings::error::KvCacheSeqDivError; +use llama_cpp_bindings::error::decode_error::DecodeError; +use llama_cpp_bindings::error::kv_cache_seq_add_error::KvCacheSeqAddError; +use llama_cpp_bindings::error::kv_cache_seq_div_error::KvCacheSeqDivError; +use llama_cpp_bindings::error::logits_error::LogitsError; use llama_cpp_bindings::llama_batch::LlamaBatch; -use llama_cpp_bindings::model::AddBos; -use llama_cpp_bindings::model::LlamaLoraAdapter; +use llama_cpp_bindings::model::add_bos::AddBos; +use llama_cpp_bindings::model::llama_lora_adapter::LlamaLoraAdapter; use llama_cpp_bindings_tests::prime_kv_cache::prime_kv_cache; use llama_cpp_bindings_tests::prime_kv_cache_with::prime_kv_cache_with; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/DeepSeek-R1-Distill-Llama-8B-GGUF", "DeepSeek-R1-Distill-Llama-8B-Q4_K_M.gguf"), diff --git a/llama-cpp-bindings-tests/tests/model_loading_errors.rs b/llama-cpp-bindings-tests/tests/model_loading_errors.rs index 136ad7b4..d838e41e 100644 --- a/llama-cpp-bindings-tests/tests/model_loading_errors.rs +++ b/llama-cpp-bindings-tests/tests/model_loading_errors.rs @@ -2,12 +2,12 @@ use std::path::Path; use std::path::PathBuf; use anyhow::Result; -use llama_cpp_bindings::LlamaLoraAdapterInitError; -use llama_cpp_bindings::LlamaModelLoadError; +use llama_cpp_bindings::error::llama_lora_adapter_init_error::LlamaLoraAdapterInitError; +use llama_cpp_bindings::error::llama_model_load_error::LlamaModelLoadError; use llama_cpp_bindings::model::LlamaModel; use llama_cpp_bindings::model::params::LlamaModelParams; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "Qwen3.5-0.8B-Q4_K_M.gguf"), diff --git a/llama-cpp-bindings-tests/tests/multimodal_audio.rs b/llama-cpp-bindings-tests/tests/multimodal_audio.rs index 688fa2bd..5a1c02ca 100644 --- a/llama-cpp-bindings-tests/tests/multimodal_audio.rs +++ b/llama-cpp-bindings-tests/tests/multimodal_audio.rs @@ -1,21 +1,21 @@ use anyhow::Context; use anyhow::Result; -use llama_cpp_bindings::EvalMultimodalChunksParams; use llama_cpp_bindings::context::LlamaContext; +use llama_cpp_bindings::eval_multimodal_chunks_params::EvalMultimodalChunksParams; use llama_cpp_bindings::llama_batch::LlamaBatch; -use llama_cpp_bindings::model::LlamaChatMessage; -use llama_cpp_bindings::mtmd::MtmdBitmap; -use llama_cpp_bindings::mtmd::MtmdInputText; -use llama_cpp_bindings::mtmd::mtmd_default_marker; +use llama_cpp_bindings::model::llama_chat_message::LlamaChatMessage; +use llama_cpp_bindings::mtmd::mtmd_bitmap::MtmdBitmap; +use llama_cpp_bindings::mtmd::mtmd_default_marker::mtmd_default_marker; +use llama_cpp_bindings::mtmd::mtmd_input_text::MtmdInputText; use llama_cpp_bindings::sampling::LlamaSampler; use llama_cpp_bindings_tests::classify_sample_loop::ClassifySampleLoop; use llama_cpp_bindings_tests::fixtures_dir::fixtures_dir; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; -const TRANSCRIBE_SYSTEM_PROMPT: &str = "You are a speech transcription assistant. Transcribe the user's audio verbatim, \ - replying with only the exact words spoken."; -const TRANSCRIBE_INSTRUCTION: &str = "Transcribe the speech in this audio word for word."; +const TRANSCRIBE_SYSTEM_PROMPT: &str = + "You are a helpful assistant that can hear audio and write down the words that are spoken."; +const TRANSCRIBE_INSTRUCTION: &str = "What words are spoken in this audio?"; fn assert_audio_transcription_contains( fixture: &LlamaFixture<'_>, diff --git a/llama-cpp-bindings-tests/tests/multimodal_image_and_audio.rs b/llama-cpp-bindings-tests/tests/multimodal_image_and_audio.rs index f50c4b8a..4263e70a 100644 --- a/llama-cpp-bindings-tests/tests/multimodal_image_and_audio.rs +++ b/llama-cpp-bindings-tests/tests/multimodal_image_and_audio.rs @@ -1,20 +1,20 @@ use anyhow::Context; use anyhow::Result; -use llama_cpp_bindings::EvalMultimodalChunksParams; use llama_cpp_bindings::context::LlamaContext; +use llama_cpp_bindings::eval_multimodal_chunks_params::EvalMultimodalChunksParams; use llama_cpp_bindings::llama_batch::LlamaBatch; -use llama_cpp_bindings::model::LlamaChatMessage; use llama_cpp_bindings::model::LlamaModel; -use llama_cpp_bindings::mtmd::MtmdBitmap; -use llama_cpp_bindings::mtmd::MtmdContext; -use llama_cpp_bindings::mtmd::MtmdInputText; -use llama_cpp_bindings::mtmd::mtmd_default_marker; +use llama_cpp_bindings::model::llama_chat_message::LlamaChatMessage; +use llama_cpp_bindings::mtmd::mtmd_bitmap::MtmdBitmap; +use llama_cpp_bindings::mtmd::mtmd_context::MtmdContext; +use llama_cpp_bindings::mtmd::mtmd_default_marker::mtmd_default_marker; +use llama_cpp_bindings::mtmd::mtmd_input_text::MtmdInputText; use llama_cpp_bindings::sampling::LlamaSampler; use llama_cpp_bindings_tests::chunk_token_breakdown::ChunkTokenBreakdown; use llama_cpp_bindings_tests::classify_sample_loop::ClassifySampleLoop; use llama_cpp_bindings_tests::fixtures_dir::fixtures_dir; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; const MAX_GENERATED_TOKENS: i32 = 512; const DESCRIBE_INSTRUCTION: &str = diff --git a/llama-cpp-bindings-tests/tests/multimodal_vision.rs b/llama-cpp-bindings-tests/tests/multimodal_vision.rs index ab670ae2..47d2fc39 100644 --- a/llama-cpp-bindings-tests/tests/multimodal_vision.rs +++ b/llama-cpp-bindings-tests/tests/multimodal_vision.rs @@ -1,29 +1,29 @@ use anyhow::Context; use anyhow::Result; -use llama_cpp_bindings::EvalMultimodalChunksParams; -use llama_cpp_bindings::SampledToken; -use llama_cpp_bindings::SampledTokenClassifier; -use llama_cpp_bindings::TokenUsage; use llama_cpp_bindings::context::LlamaContext; +use llama_cpp_bindings::eval_multimodal_chunks_params::EvalMultimodalChunksParams; use llama_cpp_bindings::ingest_prompt_chunk::ingest_prompt_chunk; use llama_cpp_bindings::llama_batch::LlamaBatch; use llama_cpp_bindings::model::LlamaModel; -use llama_cpp_bindings::mtmd::MtmdBitmap; -use llama_cpp_bindings::mtmd::MtmdContext; -use llama_cpp_bindings::mtmd::MtmdContextParams; -use llama_cpp_bindings::mtmd::MtmdEvalError; -use llama_cpp_bindings::mtmd::MtmdInputChunkType; -use llama_cpp_bindings::mtmd::MtmdInputChunks; -use llama_cpp_bindings::mtmd::MtmdInputText; -use llama_cpp_bindings::mtmd::mtmd_default_marker; +use llama_cpp_bindings::mtmd::mtmd_bitmap::MtmdBitmap; +use llama_cpp_bindings::mtmd::mtmd_context::MtmdContext; +use llama_cpp_bindings::mtmd::mtmd_context_params::MtmdContextParams; +use llama_cpp_bindings::mtmd::mtmd_default_marker::mtmd_default_marker; +use llama_cpp_bindings::mtmd::mtmd_eval_error::MtmdEvalError; +use llama_cpp_bindings::mtmd::mtmd_input_chunk_type::MtmdInputChunkType; +use llama_cpp_bindings::mtmd::mtmd_input_chunks::MtmdInputChunks; +use llama_cpp_bindings::mtmd::mtmd_input_text::MtmdInputText; +use llama_cpp_bindings::sampled_token::SampledToken; +use llama_cpp_bindings::sampled_token_classifier::SampledTokenClassifier; use llama_cpp_bindings::sampling::LlamaSampler; use llama_cpp_bindings_sys::llama_pos; use llama_cpp_bindings_tests::build_user_prompt_with_media_marker::build_user_prompt_with_media_marker; use llama_cpp_bindings_tests::chunk_token_breakdown::ChunkTokenBreakdown; use llama_cpp_bindings_tests::classify_sample_loop::ClassifySampleLoop; use llama_cpp_bindings_tests::fixtures_dir::fixtures_dir; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_bindings_types::token_usage::TokenUsage; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "Qwen3.5-0.8B-Q4_K_M.gguf"), @@ -1415,7 +1415,9 @@ fn text_chunk_drives_marker_state_machine_to_reasoning(fixture: &LlamaFixture<'_ ingest_prompt_chunk(&mut classifier, &chunk)?; } - if classifier.current_section() != llama_cpp_bindings::SampledTokenSection::Reasoning { + if classifier.current_section() + != llama_cpp_bindings::sampled_token_section::SampledTokenSection::Reasoning + { anyhow::bail!( "text chunk replay must transition the classifier section to Reasoning when the \ prompt opens a `` block; got {:?}", diff --git a/llama-cpp-bindings-tests/tests/reasoning_markers_and_tool_calls.rs b/llama-cpp-bindings-tests/tests/reasoning_markers_and_tool_calls.rs index 8cb66d70..6ac1d130 100644 --- a/llama-cpp-bindings-tests/tests/reasoning_markers_and_tool_calls.rs +++ b/llama-cpp-bindings-tests/tests/reasoning_markers_and_tool_calls.rs @@ -1,19 +1,19 @@ use anyhow::Result; use anyhow::bail; -use llama_cpp_bindings::ChatMessageParseOutcome; -use llama_cpp_bindings::ParsedChatMessage; -use llama_cpp_bindings::TokenUsage; -use llama_cpp_bindings::ToolCallArgsShape; -use llama_cpp_bindings::ToolCallArguments; +use llama_cpp_bindings::chat_message_parse_outcome::ChatMessageParseOutcome; use llama_cpp_bindings::context::LlamaContext; use llama_cpp_bindings::llama_batch::LlamaBatch; -use llama_cpp_bindings::model::AddBos; -use llama_cpp_bindings::model::LlamaChatMessage; +use llama_cpp_bindings::model::add_bos::AddBos; +use llama_cpp_bindings::model::llama_chat_message::LlamaChatMessage; use llama_cpp_bindings::sampling::LlamaSampler; use llama_cpp_bindings_tests::classify_sample_loop::ClassifySampleLoop; use llama_cpp_bindings_tests::classify_sample_loop::ClassifySampleLoopOutcome; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_bindings_types::parsed_chat_message::ParsedChatMessage; +use llama_cpp_bindings_types::token_usage::TokenUsage; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; use serde_json::Value; use serde_json::json; diff --git a/llama-cpp-bindings-tests/tests/sampling_and_constrained_decoding.rs b/llama-cpp-bindings-tests/tests/sampling_and_constrained_decoding.rs index 6fbe461b..e6dbe49a 100644 --- a/llama-cpp-bindings-tests/tests/sampling_and_constrained_decoding.rs +++ b/llama-cpp-bindings-tests/tests/sampling_and_constrained_decoding.rs @@ -5,23 +5,23 @@ use std::time::Duration; use anyhow::Context as _; use anyhow::Result; -use llama_cpp_bindings::GrammarError; -use llama_cpp_bindings::SampledToken; use llama_cpp_bindings::context::LlamaContext; -use llama_cpp_bindings::ggml_time_us; -use llama_cpp_bindings::json_schema_to_grammar; +use llama_cpp_bindings::error::grammar_error::GrammarError; +use llama_cpp_bindings::ggml_time_us::ggml_time_us; +use llama_cpp_bindings::json_schema_to_grammar::json_schema_to_grammar; use llama_cpp_bindings::llama_batch::LlamaBatch; use llama_cpp_bindings::llguidance_sampler::create_llg_sampler; -use llama_cpp_bindings::model::AddBos; -use llama_cpp_bindings::model::LlamaChatMessage; +use llama_cpp_bindings::model::add_bos::AddBos; +use llama_cpp_bindings::model::llama_chat_message::LlamaChatMessage; +use llama_cpp_bindings::sampled_token::SampledToken; use llama_cpp_bindings::sampled_token_classifier::SampledTokenClassifier; use llama_cpp_bindings::sampled_token_section::SampledTokenSection; use llama_cpp_bindings::sampling::LlamaSampler; use llama_cpp_bindings::streaming_markers::StreamingMarkers; use llama_cpp_bindings::token::LlamaToken; use llama_cpp_bindings_tests::classify_sample_loop::ClassifySampleLoop; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/DeepSeek-R1-Distill-Llama-8B-GGUF", "DeepSeek-R1-Distill-Llama-8B-Q4_K_M.gguf"), diff --git a/llama-cpp-bindings-tests/tests/vocabulary_and_metadata.rs b/llama-cpp-bindings-tests/tests/vocabulary_and_metadata.rs index 81f55876..f8c77f82 100644 --- a/llama-cpp-bindings-tests/tests/vocabulary_and_metadata.rs +++ b/llama-cpp-bindings-tests/tests/vocabulary_and_metadata.rs @@ -3,13 +3,13 @@ use std::num::NonZeroU16; use std::pin::pin; use anyhow::Result; -use llama_cpp_bindings::SampledToken; use llama_cpp_bindings::context::params::LlamaContextParams; -use llama_cpp_bindings::max_devices; -use llama_cpp_bindings::model::AddBos; +use llama_cpp_bindings::max_devices::max_devices; +use llama_cpp_bindings::model::add_bos::AddBos; use llama_cpp_bindings::model::params::LlamaModelParams; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; +use llama_cpp_bindings::sampled_token::SampledToken; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/DeepSeek-R1-Distill-Llama-8B-GGUF", "DeepSeek-R1-Distill-Llama-8B-Q4_K_M.gguf"), diff --git a/llama-cpp-bindings-types/src/lib.rs b/llama-cpp-bindings-types/src/lib.rs index 194b43ca..f2a5e4f3 100644 --- a/llama-cpp-bindings-types/src/lib.rs +++ b/llama-cpp-bindings-types/src/lib.rs @@ -1,6 +1,13 @@ #![cfg_attr( not(test), - deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) )] pub mod bracketed_json_shape; @@ -17,18 +24,3 @@ pub mod tool_call_arguments; pub mod tool_call_markers; pub mod tool_call_value_quote; pub mod xml_tags_shape; - -pub use bracketed_json_shape::BracketedJsonShape; -pub use json_object_shape::JsonObjectShape; -pub use key_value_xml_tags_shape::KeyValueXmlTagsShape; -pub use paired_quote_shape::PairedQuoteShape; -pub use parsed_chat_message::ParsedChatMessage; -pub use parsed_tool_call::ParsedToolCall; -pub use reasoning_markers::ReasoningMarkers; -pub use token_usage::TokenUsage; -pub use token_usage_error::TokenUsageError; -pub use tool_call_args_shape::ToolCallArgsShape; -pub use tool_call_arguments::ToolCallArguments; -pub use tool_call_markers::ToolCallMarkers; -pub use tool_call_value_quote::ToolCallValueQuote; -pub use xml_tags_shape::XmlTagsShape; diff --git a/llama-cpp-bindings/Cargo.toml b/llama-cpp-bindings/Cargo.toml index dba9e380..d803c60f 100644 --- a/llama-cpp-bindings/Cargo.toml +++ b/llama-cpp-bindings/Cargo.toml @@ -12,6 +12,7 @@ enumflags2 = { workspace = true } llama-cpp-bindings-sys = { workspace = true } llama-cpp-bindings-types = { workspace = true } llama-cpp-error-recorder = { workspace = true } +llama-cpp-gbnf = { workspace = true } llama-cpp-log-decoder = { workspace = true } llguidance = { workspace = true } log = { workspace = true } @@ -36,8 +37,6 @@ rocm = ["llama-cpp-bindings-sys/rocm"] # Only has an impact on Android. android-shared-stdcxx = ["llama-cpp-bindings-sys/shared-stdcxx"] android-static-stdcxx = ["llama-cpp-bindings-sys/static-stdcxx"] -system-ggml = ["llama-cpp-bindings-sys/system-ggml"] -system-ggml-static = ["system-ggml", "llama-cpp-bindings-sys/system-ggml-static"] [target.'cfg(all(target_os = "macos", any(target_arch = "aarch64", target_arch = "arm64")))'.dependencies] llama-cpp-bindings-sys = { workspace = true, features = ["metal"] } diff --git a/llama-cpp-bindings/src/chat_message_parse_outcome.rs b/llama-cpp-bindings/src/chat_message_parse_outcome.rs index 6a6b77c5..9e8ed930 100644 --- a/llama-cpp-bindings/src/chat_message_parse_outcome.rs +++ b/llama-cpp-bindings/src/chat_message_parse_outcome.rs @@ -1,4 +1,4 @@ -use llama_cpp_bindings_types::ParsedChatMessage; +use llama_cpp_bindings_types::parsed_chat_message::ParsedChatMessage; use crate::raw_chat_message::RawChatMessage; @@ -10,7 +10,7 @@ pub enum ChatMessageParseOutcome { #[cfg(test)] mod tests { - use llama_cpp_bindings_types::ParsedChatMessage; + use llama_cpp_bindings_types::parsed_chat_message::ParsedChatMessage; use super::ChatMessageParseOutcome; use crate::raw_chat_message::RawChatMessage; diff --git a/llama-cpp-bindings/src/context.rs b/llama-cpp-bindings/src/context.rs index 4ec53b3d..17e9e2e2 100644 --- a/llama-cpp-bindings/src/context.rs +++ b/llama-cpp-bindings/src/context.rs @@ -8,17 +8,21 @@ use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering; use crate::context::params::LlamaContextParams; +use crate::error::decode_error::DecodeError; +use crate::error::embeddings_error::EmbeddingsError; +use crate::error::encode_error::EncodeError; +use crate::error::llama_context_load_error::LlamaContextLoadError; +use crate::error::llama_lora_adapter_remove_error::LlamaLoraAdapterRemoveError; +use crate::error::llama_lora_adapter_set_error::LlamaLoraAdapterSetError; +use crate::error::logits_error::LogitsError; use crate::llama_backend::LlamaBackend; use crate::llama_batch::LlamaBatch; -use crate::model::{LlamaLoraAdapter, LlamaModel}; +use crate::model::LlamaModel; +use crate::model::llama_lora_adapter::LlamaLoraAdapter; use crate::timing::LlamaTimings; use crate::token::LlamaToken; use crate::token::data::LlamaTokenData; use crate::token::data_array::LlamaTokenDataArray; -use crate::{ - DecodeError, EmbeddingsError, EncodeError, LlamaContextLoadError, LlamaLoraAdapterRemoveError, - LlamaLoraAdapterSetError, LogitsError, -}; const fn check_lora_set_result(err_code: i32) -> Result<(), LlamaLoraAdapterSetError> { if err_code != 0 { @@ -45,36 +49,32 @@ fn new_context_with_model_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_OK => { NonNull::new(out_ctx).ok_or(LlamaContextLoadError::Unconstructible) } - llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_CREATION_FAILED => { Err(LlamaContextLoadError::Unconstructible) } llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_ERROR_STRING_ALLOCATION_FAILED => { Err(LlamaContextLoadError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(LlamaContextLoadError::Reported { message }) } - other => { - unreachable!("llama_rs_new_context_with_model returned unrecognized status {other}") - } + other => Err(LlamaContextLoadError::UnrecognizedStatusCode { code: other }), } } fn decode_status_to_result( status: llama_cpp_bindings_sys::llama_rs_decode_status, - out_vendored_return_code: i32, + out_return_code: i32, out_error: *mut std::os::raw::c_char, ) -> Result<(), DecodeError> { match status { llama_cpp_bindings_sys::LLAMA_RS_DECODE_OK => Ok(()), - llama_cpp_bindings_sys::LLAMA_RS_DECODE_VENDORED_RETURNED_NONZERO_CODE => { - let code = NonZeroI32::new(out_vendored_return_code).unwrap_or_else(|| { - unreachable!( - "llama_rs_decode reported a nonzero return code but the value was zero" - ) - }); - Err(DecodeError::from(code)) + llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE => { + NonZeroI32::new(out_return_code).map_or( + Err(DecodeError::UnrecognizedStatusCode { code: status }), + |code| Err(DecodeError::from(code)), + ) } llama_cpp_bindings_sys::LLAMA_RS_DECODE_OUT_OF_MEMORY => { Err(DecodeError::DecodeOutOfMemory) @@ -83,17 +83,17 @@ fn decode_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_DECODE_ERROR_STRING_ALLOCATION_FAILED => { Err(DecodeError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_DECODE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_DECODE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(DecodeError::Reported { message }) } - other => unreachable!("llama_rs_decode returned unrecognized status {other}"), + other => Err(DecodeError::UnrecognizedStatusCode { code: other }), } } fn encode_status_to_result( status: llama_cpp_bindings_sys::llama_rs_encode_status, - out_vendored_return_code: i32, + out_return_code: i32, out_error: *mut std::os::raw::c_char, ) -> Result<(), EncodeError> { match status { @@ -101,13 +101,11 @@ fn encode_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_ENCODE_MODEL_HAS_NO_ENCODER => { Err(EncodeError::ModelHasNoEncoder) } - llama_cpp_bindings_sys::LLAMA_RS_ENCODE_VENDORED_RETURNED_NONZERO_CODE => { - let code = NonZeroI32::new(out_vendored_return_code).unwrap_or_else(|| { - unreachable!( - "llama_rs_encode reported a nonzero return code but the value was zero" - ) - }); - Err(EncodeError::from(code)) + llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE => { + NonZeroI32::new(out_return_code).map_or( + Err(EncodeError::UnrecognizedStatusCode { code: status }), + |code| Err(EncodeError::from(code)), + ) } llama_cpp_bindings_sys::LLAMA_RS_ENCODE_OUT_OF_MEMORY => { Err(EncodeError::EncodeOutOfMemory) @@ -116,11 +114,11 @@ fn encode_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_ENCODE_ERROR_STRING_ALLOCATION_FAILED => { Err(EncodeError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_ENCODE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_ENCODE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(EncodeError::Reported { message }) } - other => unreachable!("llama_rs_encode returned unrecognized status {other}"), + other => Err(EncodeError::UnrecognizedStatusCode { code: other }), } } @@ -288,17 +286,17 @@ impl<'model> LlamaContext<'model> { /// /// - `DecodeError` if the decoding failed. pub fn decode(&mut self, batch: &mut LlamaBatch) -> Result<(), DecodeError> { - let mut out_vendored_return_code: i32 = 0; + let mut out_return_code: i32 = 0; let mut out_error: *mut std::os::raw::c_char = std::ptr::null_mut(); let status = unsafe { llama_cpp_bindings_sys::llama_rs_decode( self.context.as_ptr(), batch.llama_batch, - &raw mut out_vendored_return_code, + &raw mut out_return_code, &raw mut out_error, ) }; - decode_status_to_result(status, out_vendored_return_code, out_error)?; + decode_status_to_result(status, out_return_code, out_error)?; self.initialized_logits .clone_from(&batch.initialized_logits); @@ -310,17 +308,17 @@ impl<'model> LlamaContext<'model> { /// /// - `EncodeError` if the encoding failed. pub fn encode(&mut self, batch: &mut LlamaBatch) -> Result<(), EncodeError> { - let mut out_vendored_return_code: i32 = 0; + let mut out_return_code: i32 = 0; let mut out_error: *mut std::os::raw::c_char = std::ptr::null_mut(); let status = unsafe { llama_cpp_bindings_sys::llama_rs_encode( self.context.as_ptr(), batch.llama_batch, - &raw mut out_vendored_return_code, + &raw mut out_return_code, &raw mut out_error, ) }; - encode_status_to_result(status, out_vendored_return_code, out_error)?; + encode_status_to_result(status, out_return_code, out_error)?; self.initialized_logits .clone_from(&batch.initialized_logits); @@ -515,12 +513,12 @@ impl Drop for LlamaContext<'_> { #[cfg(test)] mod unit_tests { - use crate::DecodeError; - use crate::EncodeError; - use crate::LlamaContextLoadError; - use crate::LlamaLoraAdapterRemoveError; - use crate::LlamaLoraAdapterSetError; - use crate::LogitsError; + use crate::error::decode_error::DecodeError; + use crate::error::encode_error::EncodeError; + use crate::error::llama_context_load_error::LlamaContextLoadError; + use crate::error::llama_lora_adapter_remove_error::LlamaLoraAdapterRemoveError; + use crate::error::llama_lora_adapter_set_error::LlamaLoraAdapterSetError; + use crate::error::logits_error::LogitsError; use super::{ check_lora_remove_result, check_lora_set_result, decode_status_to_result, @@ -564,9 +562,9 @@ mod unit_tests { } #[test] - fn new_context_vendored_returned_null_maps_unconstructible() { + fn new_context_creation_failed_maps_unconstructible() { let result = new_context_with_model_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_RETURNED_NULL, + llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_CREATION_FAILED, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -588,7 +586,7 @@ mod unit_tests { #[test] fn new_context_cxx_exception_maps_reported() { let result = new_context_with_model_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_NEW_CONTEXT_WITH_MODEL_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -602,19 +600,23 @@ mod unit_tests { } #[test] - #[should_panic(expected = "llama_rs_new_context_with_model returned unrecognized status")] - fn new_context_unrecognized_status_panics() { - let _result = new_context_with_model_status_to_result( - llama_cpp_bindings_sys::llama_rs_new_context_with_model_status::MAX, - std::ptr::null_mut(), - std::ptr::null_mut(), + fn new_context_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + new_context_with_model_status_to_result( + llama_cpp_bindings_sys::llama_rs_new_context_with_model_status::MAX, + std::ptr::null_mut(), + std::ptr::null_mut(), + ), + Err(LlamaContextLoadError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_new_context_with_model_status::MAX + }), ); } #[test] fn decode_nonzero_code_maps_from_code() { let result = decode_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_DECODE_VENDORED_RETURNED_NONZERO_CODE, + llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE, 1, std::ptr::null_mut(), ); @@ -658,7 +660,7 @@ mod unit_tests { #[test] fn decode_cxx_exception_maps_reported() { let result = decode_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_DECODE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_DECODE_THREW_CXX_EXCEPTION, 0, std::ptr::null_mut(), ); @@ -672,22 +674,30 @@ mod unit_tests { } #[test] - #[should_panic(expected = "llama_rs_decode reported a nonzero return code")] - fn decode_nonzero_code_with_zero_value_panics() { - let _result = decode_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_DECODE_VENDORED_RETURNED_NONZERO_CODE, - 0, - std::ptr::null_mut(), + fn decode_nonzero_code_with_zero_value_returns_unrecognized_status_error() { + assert_eq!( + decode_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE, + 0, + std::ptr::null_mut(), + ), + Err(DecodeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE, + }), ); } #[test] - #[should_panic(expected = "llama_rs_decode returned unrecognized status")] - fn decode_unrecognized_status_panics() { - let _result = decode_status_to_result( - llama_cpp_bindings_sys::llama_rs_decode_status::MAX, - 0, - std::ptr::null_mut(), + fn decode_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + decode_status_to_result( + llama_cpp_bindings_sys::llama_rs_decode_status::MAX, + 0, + std::ptr::null_mut(), + ), + Err(DecodeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_decode_status::MAX + }), ); } @@ -705,7 +715,7 @@ mod unit_tests { #[test] fn encode_nonzero_code_maps_from_code() { let result = encode_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_ENCODE_VENDORED_RETURNED_NONZERO_CODE, + llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE, 1, std::ptr::null_mut(), ); @@ -749,7 +759,7 @@ mod unit_tests { #[test] fn encode_cxx_exception_maps_reported() { let result = encode_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_ENCODE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_ENCODE_THREW_CXX_EXCEPTION, 0, std::ptr::null_mut(), ); @@ -763,22 +773,30 @@ mod unit_tests { } #[test] - #[should_panic(expected = "llama_rs_encode reported a nonzero return code")] - fn encode_nonzero_code_with_zero_value_panics() { - let _result = encode_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_ENCODE_VENDORED_RETURNED_NONZERO_CODE, - 0, - std::ptr::null_mut(), + fn encode_nonzero_code_with_zero_value_returns_unrecognized_status_error() { + assert_eq!( + encode_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE, + 0, + std::ptr::null_mut(), + ), + Err(EncodeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE, + }), ); } #[test] - #[should_panic(expected = "llama_rs_encode returned unrecognized status")] - fn encode_unrecognized_status_panics() { - let _result = encode_status_to_result( - llama_cpp_bindings_sys::llama_rs_encode_status::MAX, - 0, - std::ptr::null_mut(), + fn encode_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + encode_status_to_result( + llama_cpp_bindings_sys::llama_rs_encode_status::MAX, + 0, + std::ptr::null_mut(), + ), + Err(EncodeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_encode_status::MAX + }), ); } diff --git a/llama-cpp-bindings/src/context/kv_cache.rs b/llama-cpp-bindings/src/context/kv_cache.rs index 86d9e52b..dcb3c245 100644 --- a/llama-cpp-bindings/src/context/kv_cache.rs +++ b/llama-cpp-bindings/src/context/kv_cache.rs @@ -4,7 +4,8 @@ use std::os::raw::c_char; use std::ptr; use crate::context::LlamaContext; -use crate::error::{KvCacheSeqAddError, KvCacheSeqDivError}; +use crate::error::kv_cache_seq_add_error::KvCacheSeqAddError; +use crate::error::kv_cache_seq_div_error::KvCacheSeqDivError; use crate::ffi_error_reader::read_and_free_cpp_error; #[derive(Debug, Eq, PartialEq, thiserror::Error)] @@ -32,11 +33,11 @@ fn kv_cache_seq_add_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_ADD_ERROR_STRING_ALLOCATION_FAILED => { Err(KvCacheSeqAddError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_ADD_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_ADD_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(KvCacheSeqAddError::Reported { message }) } - other => unreachable!("llama_rs_memory_seq_add returned unrecognized status {other}"), + other => Err(KvCacheSeqAddError::UnrecognizedStatusCode { code: other }), } } @@ -55,11 +56,11 @@ fn kv_cache_seq_div_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_DIV_ERROR_STRING_ALLOCATION_FAILED => { Err(KvCacheSeqDivError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_DIV_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_DIV_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(KvCacheSeqDivError::Reported { message }) } - other => unreachable!("llama_rs_memory_seq_div returned unrecognized status {other}"), + other => Err(KvCacheSeqDivError::UnrecognizedStatusCode { code: other }), } } @@ -197,7 +198,8 @@ mod tests { use super::kv_cache_seq_add_status_to_result; use super::kv_cache_seq_div_status_to_result; - use crate::error::{KvCacheSeqAddError, KvCacheSeqDivError}; + use crate::error::kv_cache_seq_add_error::KvCacheSeqAddError; + use crate::error::kv_cache_seq_div_error::KvCacheSeqDivError; #[test] fn add_ok_status_maps_to_ok() { @@ -243,10 +245,10 @@ mod tests { } #[test] - fn add_vendored_exception_status_maps_to_reported_with_unknown_message() { + fn add_exception_status_maps_to_reported_with_unknown_message() { assert_eq!( kv_cache_seq_add_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_ADD_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_ADD_THREW_CXX_EXCEPTION, ptr::null_mut(), ), Err(KvCacheSeqAddError::Reported { @@ -256,11 +258,15 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_memory_seq_add returned unrecognized status")] - fn add_unrecognized_status_panics() { - let _ = kv_cache_seq_add_status_to_result( - llama_cpp_bindings_sys::llama_rs_memory_seq_add_status::MAX, - ptr::null_mut(), + fn add_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + kv_cache_seq_add_status_to_result( + llama_cpp_bindings_sys::llama_rs_memory_seq_add_status::MAX, + ptr::null_mut(), + ), + Err(KvCacheSeqAddError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_memory_seq_add_status::MAX + }), ); } @@ -308,10 +314,10 @@ mod tests { } #[test] - fn div_vendored_exception_status_maps_to_reported_with_unknown_message() { + fn div_exception_status_maps_to_reported_with_unknown_message() { assert_eq!( kv_cache_seq_div_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_DIV_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MEMORY_SEQ_DIV_THREW_CXX_EXCEPTION, ptr::null_mut(), ), Err(KvCacheSeqDivError::Reported { @@ -321,11 +327,15 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_memory_seq_div returned unrecognized status")] - fn div_unrecognized_status_panics() { - let _ = kv_cache_seq_div_status_to_result( - llama_cpp_bindings_sys::llama_rs_memory_seq_div_status::MAX, - ptr::null_mut(), + fn div_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + kv_cache_seq_div_status_to_result( + llama_cpp_bindings_sys::llama_rs_memory_seq_div_status::MAX, + ptr::null_mut(), + ), + Err(KvCacheSeqDivError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_memory_seq_div_status::MAX + }), ); } } diff --git a/llama-cpp-bindings/src/context/params.rs b/llama-cpp-bindings/src/context/params.rs index f5e553a6..e4222924 100644 --- a/llama-cpp-bindings/src/context/params.rs +++ b/llama-cpp-bindings/src/context/params.rs @@ -1,10 +1,10 @@ use std::fmt::Debug; use std::num::NonZeroU32; -pub use crate::context::kv_cache_type::KvCacheType; -pub use crate::context::llama_attention_type::LlamaAttentionType; -pub use crate::context::llama_pooling_type::LlamaPoolingType; -pub use crate::context::rope_scaling_type::RopeScalingType; +use crate::context::kv_cache_type::KvCacheType; +use crate::context::llama_attention_type::LlamaAttentionType; +use crate::context::llama_pooling_type::LlamaPoolingType; +use crate::context::rope_scaling_type::RopeScalingType; #[derive(Debug, Clone, Copy)] #[expect( diff --git a/llama-cpp-bindings/src/error.rs b/llama-cpp-bindings/src/error.rs index 6e653b10..29877f2b 100644 --- a/llama-cpp-bindings/src/error.rs +++ b/llama-cpp-bindings/src/error.rs @@ -36,42 +36,6 @@ pub mod token_to_string_error; pub mod tool_call_format_failure; pub mod xml_function_tags_failure; -pub use apply_chat_template_error::ApplyChatTemplateError; -pub use bracketed_args_failure::BracketedArgsFailure; -pub use chat_template_error::ChatTemplateError; -pub use decode_error::DecodeError; -pub use embeddings_error::EmbeddingsError; -pub use encode_error::EncodeError; -pub use eval_multimodal_chunks_error::EvalMultimodalChunksError; -pub use fit_error::FitError; -pub use grammar_error::GrammarError; -pub use grammar_runtime_error::GrammarRuntimeError; -pub use json_object_failure::JsonObjectFailure; -pub use json_schema_to_grammar_error::JsonSchemaToGrammarError; -pub use key_value_xml_tags_failure::KeyValueXmlTagsFailure; -pub use kv_cache_seq_add_error::KvCacheSeqAddError; -pub use kv_cache_seq_div_error::KvCacheSeqDivError; -pub use llama_context_load_error::LlamaContextLoadError; -pub use llama_cpp_error::LlamaCppError; -pub use llama_lora_adapter_init_error::LlamaLoraAdapterInitError; -pub use llama_lora_adapter_remove_error::LlamaLoraAdapterRemoveError; -pub use llama_lora_adapter_set_error::LlamaLoraAdapterSetError; -pub use llama_model_load_error::LlamaModelLoadError; -pub use logits_error::LogitsError; -pub use marker_detection_error::MarkerDetectionError; -pub use meta_val_error::MetaValError; -pub use model_params_error::ModelParamsError; -pub use new_llama_chat_message_error::NewLlamaChatMessageError; -pub use paired_quote_failure::PairedQuoteFailure; -pub use parse_chat_message_error::ParseChatMessageError; -pub use sample_error::SampleError; -pub use sampler_accept_error::SamplerAcceptError; -pub use sampler_apply_error::SamplerApplyError; -pub use sampling_error::SamplingError; -pub use string_to_token_error::StringToTokenError; -pub use token_sampling_error::TokenSamplingError; -pub use token_to_string_error::TokenToStringError; -pub use tool_call_format_failure::ToolCallFormatFailure; -pub use xml_function_tags_failure::XmlFunctionTagsFailure; +use crate::error::llama_cpp_error::LlamaCppError; pub type Result = std::result::Result; diff --git a/llama-cpp-bindings/src/error/apply_chat_template_error.rs b/llama-cpp-bindings/src/error/apply_chat_template_error.rs index 857d4b09..3ae79340 100644 --- a/llama-cpp-bindings/src/error/apply_chat_template_error.rs +++ b/llama-cpp-bindings/src/error/apply_chat_template_error.rs @@ -8,4 +8,6 @@ pub enum ApplyChatTemplateError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/decode_error.rs b/llama-cpp-bindings/src/error/decode_error.rs index 74121bc0..70d8b362 100644 --- a/llama-cpp-bindings/src/error/decode_error.rs +++ b/llama-cpp-bindings/src/error/decode_error.rs @@ -19,6 +19,8 @@ pub enum DecodeError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } impl From for DecodeError { diff --git a/llama-cpp-bindings/src/error/encode_error.rs b/llama-cpp-bindings/src/error/encode_error.rs index 022ac6d7..09869a7f 100644 --- a/llama-cpp-bindings/src/error/encode_error.rs +++ b/llama-cpp-bindings/src/error/encode_error.rs @@ -19,6 +19,8 @@ pub enum EncodeError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } impl From for EncodeError { diff --git a/llama-cpp-bindings/src/error/eval_multimodal_chunks_error.rs b/llama-cpp-bindings/src/error/eval_multimodal_chunks_error.rs index d5d485f7..3cea0415 100644 --- a/llama-cpp-bindings/src/error/eval_multimodal_chunks_error.rs +++ b/llama-cpp-bindings/src/error/eval_multimodal_chunks_error.rs @@ -1,4 +1,4 @@ -use crate::mtmd::MtmdEvalError; +use crate::mtmd::mtmd_eval_error::MtmdEvalError; use crate::mtmd::mtmd_input_chunk_type_error::MtmdInputChunkTypeError; #[derive(Debug, thiserror::Error)] diff --git a/llama-cpp-bindings/src/error/fit_error.rs b/llama-cpp-bindings/src/error/fit_error.rs index fbb809c5..86337996 100644 --- a/llama-cpp-bindings/src/error/fit_error.rs +++ b/llama-cpp-bindings/src/error/fit_error.rs @@ -10,4 +10,6 @@ pub enum FitError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/grammar_error.rs b/llama-cpp-bindings/src/error/grammar_error.rs index 260be503..0605683c 100644 --- a/llama-cpp-bindings/src/error/grammar_error.rs +++ b/llama-cpp-bindings/src/error/grammar_error.rs @@ -32,4 +32,6 @@ pub enum GrammarError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs b/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs index 897865b4..7bbe5052 100644 --- a/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs +++ b/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs @@ -13,4 +13,6 @@ pub enum JsonSchemaToGrammarError { Reported { message: String }, #[error("grammar returned by json_schema_to_grammar is not valid UTF-8")] GrammarNotUtf8(#[from] FromUtf8Error), + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs b/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs index 6be2db7b..64718a29 100644 --- a/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs +++ b/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs @@ -14,4 +14,6 @@ pub enum KvCacheSeqAddError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs b/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs index fe83023c..6e274f0f 100644 --- a/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs +++ b/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs @@ -14,4 +14,6 @@ pub enum KvCacheSeqDivError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/llama_context_load_error.rs b/llama-cpp-bindings/src/error/llama_context_load_error.rs index 40d42363..1e0189a5 100644 --- a/llama-cpp-bindings/src/error/llama_context_load_error.rs +++ b/llama-cpp-bindings/src/error/llama_context_load_error.rs @@ -6,4 +6,6 @@ pub enum LlamaContextLoadError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/llama_model_load_error.rs b/llama-cpp-bindings/src/error/llama_model_load_error.rs index a2e16b80..c106c938 100644 --- a/llama-cpp-bindings/src/error/llama_model_load_error.rs +++ b/llama-cpp-bindings/src/error/llama_model_load_error.rs @@ -15,4 +15,6 @@ pub enum LlamaModelLoadError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/marker_detection_error.rs b/llama-cpp-bindings/src/error/marker_detection_error.rs index 0a2d7773..ae266536 100644 --- a/llama-cpp-bindings/src/error/marker_detection_error.rs +++ b/llama-cpp-bindings/src/error/marker_detection_error.rs @@ -22,4 +22,6 @@ pub enum MarkerDetectionError { ToolCallTemplateNotUtf8(#[from] Utf8Error), #[error("the chat template could not be retrieved for tool-call marker detection: {0}")] ChatTemplateUnavailable(#[source] ChatTemplateError), + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/parse_chat_message_error.rs b/llama-cpp-bindings/src/error/parse_chat_message_error.rs index 6f68ec22..816472fb 100644 --- a/llama-cpp-bindings/src/error/parse_chat_message_error.rs +++ b/llama-cpp-bindings/src/error/parse_chat_message_error.rs @@ -35,4 +35,6 @@ pub enum ParseChatMessageError { MarkerDetection(#[from] MarkerDetectionError), #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/sample_error.rs b/llama-cpp-bindings/src/error/sample_error.rs index 522392df..889e6a6c 100644 --- a/llama-cpp-bindings/src/error/sample_error.rs +++ b/llama-cpp-bindings/src/error/sample_error.rs @@ -13,4 +13,6 @@ pub enum SampleError { GrammarCallbackFailed { message: String }, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/sampler_accept_error.rs b/llama-cpp-bindings/src/error/sampler_accept_error.rs index 6067540d..0df1db3f 100644 --- a/llama-cpp-bindings/src/error/sampler_accept_error.rs +++ b/llama-cpp-bindings/src/error/sampler_accept_error.rs @@ -6,4 +6,6 @@ pub enum SamplerAcceptError { GrammarStateCorrupted { message: String }, #[error("the grammar sampler callback failed during accept: {message}")] GrammarCallbackFailed { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/sampler_apply_error.rs b/llama-cpp-bindings/src/error/sampler_apply_error.rs index b7477e10..0a10f4d7 100644 --- a/llama-cpp-bindings/src/error/sampler_apply_error.rs +++ b/llama-cpp-bindings/src/error/sampler_apply_error.rs @@ -4,8 +4,8 @@ pub enum SamplerApplyError { NullSampler, #[error("the sampler ran out of memory while applying to the token data array")] NotEnoughMemory, - #[error( - "the vendored sampler threw a C++ exception while applying to the token data array: {message}" - )] + #[error("the sampler threw a C++ exception while applying to the token data array: {message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/error/string_to_token_error.rs b/llama-cpp-bindings/src/error/string_to_token_error.rs index 3a9b117d..6769bbba 100644 --- a/llama-cpp-bindings/src/error/string_to_token_error.rs +++ b/llama-cpp-bindings/src/error/string_to_token_error.rs @@ -10,4 +10,6 @@ pub enum StringToTokenError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/extract_reasoning_markers_from_probe_renders.rs b/llama-cpp-bindings/src/extract_reasoning_markers_from_probe_renders.rs index 9cc09995..1d90541b 100644 --- a/llama-cpp-bindings/src/extract_reasoning_markers_from_probe_renders.rs +++ b/llama-cpp-bindings/src/extract_reasoning_markers_from_probe_renders.rs @@ -1,6 +1,6 @@ use serde_json::json; -use crate::ReasoningMarkers; +use llama_cpp_bindings_types::reasoning_markers::ReasoningMarkers; const REASON_PROBE: &str = "__PADDLER_REASON_PROBE_3F4A8C__"; const RESPONSE_PROBE: &str = "__PADDLER_RESPONSE_PROBE_3F4A8C__"; diff --git a/llama-cpp-bindings/src/ingest_prompt_chunk.rs b/llama-cpp-bindings/src/ingest_prompt_chunk.rs index c83ff230..374dd916 100644 --- a/llama-cpp-bindings/src/ingest_prompt_chunk.rs +++ b/llama-cpp-bindings/src/ingest_prompt_chunk.rs @@ -1,6 +1,6 @@ -use crate::mtmd::MtmdInputChunk; -use crate::mtmd::MtmdInputChunkType; -use crate::mtmd::MtmdInputChunkTypeError; +use crate::mtmd::mtmd_input_chunk::MtmdInputChunk; +use crate::mtmd::mtmd_input_chunk_type::MtmdInputChunkType; +use crate::mtmd::mtmd_input_chunk_type_error::MtmdInputChunkTypeError; use crate::sampled_token_classifier::SampledTokenClassifier; /// # Errors diff --git a/llama-cpp-bindings/src/json_schema_to_grammar.rs b/llama-cpp-bindings/src/json_schema_to_grammar.rs index e544b66f..83abab8a 100644 --- a/llama-cpp-bindings/src/json_schema_to_grammar.rs +++ b/llama-cpp-bindings/src/json_schema_to_grammar.rs @@ -1,6 +1,6 @@ use std::ffi::{CStr, CString, c_char}; -use crate::error::JsonSchemaToGrammarError; +use crate::error::json_schema_to_grammar_error::JsonSchemaToGrammarError; use crate::ffi_error_reader::read_and_free_cpp_error; /// # Safety @@ -27,13 +27,11 @@ unsafe fn json_schema_to_grammar_status_to_result( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(JsonSchemaToGrammarError::InvalidSchema { message }) } - llama_cpp_bindings_sys::LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(JsonSchemaToGrammarError::Reported { message }) } - other => { - unreachable!("llama_rs_json_schema_to_grammar returned unrecognized status {other}") - } + other => Err(JsonSchemaToGrammarError::UnrecognizedStatusCode { code: other }), } } @@ -64,7 +62,7 @@ mod tests { use super::json_schema_to_grammar; use super::json_schema_to_grammar_status_to_result; - use crate::error::JsonSchemaToGrammarError; + use crate::error::json_schema_to_grammar_error::JsonSchemaToGrammarError; unsafe extern "C" { fn strdup(source: *const c_char) -> *mut c_char; @@ -149,10 +147,10 @@ mod tests { } #[test] - fn vendored_exception_status_returns_reported() { + fn exception_status_returns_reported() { let result = unsafe { json_schema_to_grammar_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_JSON_SCHEMA_TO_GRAMMAR_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), ) @@ -219,14 +217,18 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_json_schema_to_grammar returned unrecognized status")] - fn unrecognized_status_panics() { - let _result = unsafe { - json_schema_to_grammar_status_to_result( - llama_cpp_bindings_sys::llama_rs_json_schema_to_grammar_status::MAX, - std::ptr::null_mut(), - std::ptr::null_mut(), - ) - }; + fn unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + unsafe { + json_schema_to_grammar_status_to_result( + llama_cpp_bindings_sys::llama_rs_json_schema_to_grammar_status::MAX, + std::ptr::null_mut(), + std::ptr::null_mut(), + ) + }, + Err(JsonSchemaToGrammarError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_json_schema_to_grammar_status::MAX + }), + ); } } diff --git a/llama-cpp-bindings/src/lib.rs b/llama-cpp-bindings/src/lib.rs index 0ff8697f..36da848c 100644 --- a/llama-cpp-bindings/src/lib.rs +++ b/llama-cpp-bindings/src/lib.rs @@ -1,6 +1,13 @@ #![cfg_attr( not(test), - deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) )] pub mod batch_add_error; @@ -60,40 +67,3 @@ pub mod token; pub mod tool_call_format; pub mod tool_call_marker_pair; pub mod tool_call_template_overrides; - -pub use error::{ - ApplyChatTemplateError, ChatTemplateError, DecodeError, EmbeddingsError, EncodeError, - EvalMultimodalChunksError, GrammarError, JsonSchemaToGrammarError, KvCacheSeqAddError, - KvCacheSeqDivError, LlamaContextLoadError, LlamaCppError, LlamaLoraAdapterInitError, - LlamaLoraAdapterRemoveError, LlamaLoraAdapterSetError, LlamaModelLoadError, LogitsError, - MarkerDetectionError, MetaValError, ModelParamsError, NewLlamaChatMessageError, - ParseChatMessageError, Result, SampleError, SamplerAcceptError, SamplingError, - StringToTokenError, TokenSamplingError, TokenToStringError, -}; - -pub use chat_message_parse_outcome::ChatMessageParseOutcome; -pub use eval_multimodal_chunks_params::EvalMultimodalChunksParams; -pub use llama_backend_device::{LlamaBackendDevice, list_llama_ggml_backend_devices}; -pub use llama_backend_device_type::LlamaBackendDeviceType; -pub use llama_cpp_bindings_types::{ - BracketedJsonShape, KeyValueXmlTagsShape, PairedQuoteShape, ParsedChatMessage, ParsedToolCall, - ReasoningMarkers, TokenUsage, TokenUsageError, ToolCallArgsShape, ToolCallArguments, - ToolCallMarkers, ToolCallValueQuote, XmlTagsShape, -}; -pub use raw_chat_message::RawChatMessage; -pub use sampled_token::SampledToken; -pub use sampled_token_classifier::SampledTokenClassifier; -pub use sampled_token_section::SampledTokenSection; - -pub use ffi_status_is_ok::status_is_ok; -pub use ffi_status_to_i32::status_to_i32; -pub use ggml_time_us::ggml_time_us; -pub use ingest_prompt_chunk::ingest_prompt_chunk; -pub use json_schema_to_grammar::json_schema_to_grammar; -pub use llama_time_us::llama_time_us; -pub use max_devices::max_devices; -pub use mlock_supported::mlock_supported; -pub use mmap_supported::mmap_supported; - -pub use log_options::LogOptions; -pub use send_logs_to_log::send_logs_to_log; diff --git a/llama-cpp-bindings/src/llama_backend.rs b/llama-cpp-bindings/src/llama_backend.rs index 1990f117..98232122 100644 --- a/llama-cpp-bindings/src/llama_backend.rs +++ b/llama-cpp-bindings/src/llama_backend.rs @@ -3,7 +3,7 @@ use std::sync::atomic::Ordering::SeqCst; use llama_cpp_bindings_sys::ggml_log_level; -use crate::LlamaCppError; +use crate::error::llama_cpp_error::LlamaCppError; use crate::llama_backend_numa_strategy::NumaStrategy; #[derive(Eq, PartialEq, Debug)] @@ -12,7 +12,7 @@ pub struct LlamaBackend {} static LLAMA_BACKEND_INITIALIZED: AtomicBool = AtomicBool::new(false); impl LlamaBackend { - fn mark_init() -> crate::Result<()> { + fn mark_init() -> crate::error::Result<()> { match LLAMA_BACKEND_INITIALIZED.compare_exchange(false, true, SeqCst, SeqCst) { Ok(_was_uninitialized) => Ok(()), Err(_was_already_initialized) => Err(LlamaCppError::BackendAlreadyInitialized), @@ -21,7 +21,7 @@ impl LlamaBackend { /// # Errors /// Returns an error if the backend was already initialized. - pub fn init() -> crate::Result { + pub fn init() -> crate::error::Result { Self::mark_init()?; unsafe { llama_cpp_bindings_sys::llama_backend_init() } Ok(Self {}) @@ -29,7 +29,7 @@ impl LlamaBackend { /// # Errors /// Returns an error if the backend was already initialized. - pub fn init_numa(strategy: NumaStrategy) -> crate::Result { + pub fn init_numa(strategy: NumaStrategy) -> crate::error::Result { Self::mark_init()?; unsafe { llama_cpp_bindings_sys::llama_numa_init( @@ -80,7 +80,7 @@ mod tests { use serial_test::serial; use super::LlamaBackend; - use crate::LlamaCppError; + use crate::error::llama_cpp_error::LlamaCppError; #[test] fn void_log_callback_does_not_panic() { diff --git a/llama-cpp-bindings/src/llama_backend_device.rs b/llama-cpp-bindings/src/llama_backend_device.rs index aa7ce51f..0d4ce32d 100644 --- a/llama-cpp-bindings/src/llama_backend_device.rs +++ b/llama-cpp-bindings/src/llama_backend_device.rs @@ -1,9 +1,8 @@ use std::ffi::c_char; +use crate::llama_backend_device_type::LlamaBackendDeviceType; use crate::llama_backend_device_type::device_type_from_raw; -pub use crate::llama_backend_device_type::LlamaBackendDeviceType; - #[derive(Debug, Clone)] pub struct LlamaBackendDevice { pub index: usize, diff --git a/llama-cpp-bindings/src/llguidance_sampler.rs b/llama-cpp-bindings/src/llguidance_sampler.rs index 9cd28801..cffef7fd 100644 --- a/llama-cpp-bindings/src/llguidance_sampler.rs +++ b/llama-cpp-bindings/src/llguidance_sampler.rs @@ -1,11 +1,11 @@ use std::ffi::c_void; use std::sync::Arc; -use llama_cpp_error_recorder::RecordedError; -use llama_cpp_error_recorder::record; +use llama_cpp_error_recorder::record::record; +use llama_cpp_error_recorder::recorded_error::RecordedError; use toktrie::ApproximateTokEnv; -use crate::GrammarError; +use crate::error::grammar_error::GrammarError; use crate::grammar_matcher::GrammarMatcher; use crate::mask_outcome::MaskOutcome; use crate::model::LlamaModel; diff --git a/llama-cpp-bindings/src/model.rs b/llama-cpp-bindings/src/model.rs index 49f97f24..f5fd8a54 100644 --- a/llama-cpp-bindings/src/model.rs +++ b/llama-cpp-bindings/src/model.rs @@ -22,16 +22,32 @@ use toktrie::ApproximateTokEnv; use toktrie::TokRxInfo; use toktrie::TokTrie; -use llama_cpp_bindings_types::ParsedChatMessage; -use llama_cpp_bindings_types::ParsedToolCall; -use llama_cpp_bindings_types::ReasoningMarkers; -use llama_cpp_bindings_types::ToolCallArguments; -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::parsed_chat_message::ParsedChatMessage; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; +use llama_cpp_bindings_types::reasoning_markers::ReasoningMarkers; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; use crate::chat_message_parse_outcome::ChatMessageParseOutcome; +use crate::error::apply_chat_template_error::ApplyChatTemplateError; +use crate::error::chat_template_error::ChatTemplateError; +use crate::error::llama_lora_adapter_init_error::LlamaLoraAdapterInitError; +use crate::error::llama_model_load_error::LlamaModelLoadError; +use crate::error::marker_detection_error::MarkerDetectionError; +use crate::error::meta_val_error::MetaValError; +use crate::error::parse_chat_message_error::ParseChatMessageError; +use crate::error::string_to_token_error::StringToTokenError; +use crate::error::token_to_string_error::TokenToStringError; use crate::llama_backend::LlamaBackend; use crate::llama_token_attrs::LlamaTokenAttrs; use crate::llama_token_attrs_from_int_error::LlamaTokenAttrsFromIntError; +use crate::model::add_bos::AddBos; +use crate::model::llama_chat_message::LlamaChatMessage; +use crate::model::llama_chat_template::LlamaChatTemplate; +use crate::model::llama_lora_adapter::LlamaLoraAdapter; +use crate::model::rope_type::RopeType; +use crate::model::vocab_type::VocabType; +use crate::model::vocab_type_from_int_error::VocabTypeFromIntError; use crate::raw_chat_message::RawChatMessage; use crate::resolved_tool_call_markers::ResolvedToolCallMarkers; use crate::sampled_token::SampledToken; @@ -39,21 +55,8 @@ use crate::sampled_token_classifier::SampledTokenClassifier; use crate::streaming_markers::StreamingMarkers; use crate::token::LlamaToken; use crate::tool_call_format; -use crate::tool_call_format::ToolCallFormatOutcome; +use crate::tool_call_format::tool_call_format_outcome::ToolCallFormatOutcome; use crate::tool_call_template_overrides; -use crate::{ - ApplyChatTemplateError, ChatTemplateError, LlamaLoraAdapterInitError, LlamaModelLoadError, - MarkerDetectionError, MetaValError, ParseChatMessageError, StringToTokenError, - TokenToStringError, -}; - -pub use add_bos::AddBos; -pub use llama_chat_message::LlamaChatMessage; -pub use llama_chat_template::LlamaChatTemplate; -pub use llama_lora_adapter::LlamaLoraAdapter; -pub use rope_type::RopeType; -pub use vocab_type::VocabType; -pub use vocab_type_from_int_error::VocabTypeFromIntError; use params::LlamaModelParams; @@ -131,7 +134,7 @@ unsafe fn load_model_from_file_status_to_result( chat_parser: OnceLock::new(), }) } - llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_LOAD_FAILED => { if path.exists() { Err(LlamaModelLoadError::Unloadable) } else { @@ -141,13 +144,11 @@ unsafe fn load_model_from_file_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED => { Err(LlamaModelLoadError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(LlamaModelLoadError::Reported { message }) } - other => { - unreachable!("llama_rs_load_model_from_file returned unrecognized status {other}") - } + other => Err(LlamaModelLoadError::UnrecognizedStatusCode { code: other }), } } @@ -167,14 +168,12 @@ unsafe fn parse_chat_message_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_PARSE_CHAT_MESSAGE_ERROR_STRING_ALLOCATION_FAILED => { Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSE_CHAT_MESSAGE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSE_CHAT_MESSAGE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(*out_error) }; unsafe { *out_error = ptr::null_mut() }; Err(ParseChatMessageError::ParseFailed { message }) } - other => { - unreachable!("llama_rs_parse_chat_message returned unrecognized status {other}") - } + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -188,7 +187,7 @@ unsafe fn chat_parser_create_status_to_result( ) -> Result { match status { llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_OK => NonNull::new(parser).map_or_else( - || unreachable!("llama_rs_chat_parser_create returned OK with a null parser handle"), + || Err(ParseChatMessageError::UnrecognizedStatusCode { code: status }), |parser| Ok(ChatParserHandle { parser }), ), llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_MODEL_HAS_NO_CHAT_TEMPLATE => { @@ -200,14 +199,12 @@ unsafe fn chat_parser_create_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_ERROR_STRING_ALLOCATION_FAILED => { Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(*out_error) }; unsafe { *out_error = ptr::null_mut() }; Err(ParseChatMessageError::ParseFailed { message }) } - other => { - unreachable!("llama_rs_chat_parser_create returned unrecognized status {other}") - } + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -243,7 +240,7 @@ unsafe fn parsed_chat_free_status_to_result( (Ok(_), other) => { unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; unsafe { llama_cpp_bindings_sys::llama_rs_string_free(free_error) }; - unreachable!("llama_rs_parsed_chat_free returned unrecognized status {other}") + Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }) } (Err(parse_err), _) => { unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; @@ -309,13 +306,11 @@ unsafe fn apply_chat_template_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_APPLY_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED => { Err(ApplyChatTemplateError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_APPLY_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_APPLY_CHAT_TEMPLATE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ApplyChatTemplateError::Reported { message }) } - other => { - unreachable!("llama_rs_apply_chat_template returned unrecognized status {other}") - } + other => Err(ApplyChatTemplateError::UnrecognizedStatusCode { code: other }), } } @@ -871,7 +866,7 @@ impl LlamaModel { }; let template_str = template.to_str()?; - Ok(tool_call_template_overrides::detect(template_str)) + Ok(tool_call_template_overrides::detect::detect(template_str)) } /// # Errors @@ -915,7 +910,9 @@ impl LlamaModel { let reasoning_markers = self.reasoning_markers()?; - for candidate in tool_call_template_overrides::known_marker_candidates() { + for candidate in + tool_call_template_overrides::known_marker_candidates::known_marker_candidates() + { if let ToolCallFormatOutcome::Parsed(calls) = tool_call_format::try_parse(input, &candidate) { @@ -1139,11 +1136,11 @@ unsafe fn parsed_chat_content_status_to_result( unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_CONTENT_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_CONTENT_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => unreachable!("llama_rs_parsed_chat_content returned unrecognized status {other}"), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -1178,14 +1175,12 @@ unsafe fn parsed_chat_reasoning_content_status_to_result( unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => unreachable!( - "llama_rs_parsed_chat_reasoning_content returned unrecognized status {other}" - ), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -1218,14 +1213,12 @@ unsafe fn parsed_chat_tool_call_count_status_to_result( unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => unreachable!( - "llama_rs_parsed_chat_tool_call_count returned unrecognized status {other}" - ), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -1264,14 +1257,12 @@ unsafe fn parsed_chat_tool_call_id_status_to_result( unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => unreachable!( - "llama_rs_parsed_chat_tool_call_id returned unrecognized status {other}" - ), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -1312,14 +1303,12 @@ unsafe fn parsed_chat_tool_call_name_status_to_result( unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => unreachable!( - "llama_rs_parsed_chat_tool_call_name returned unrecognized status {other}" - ), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -1360,14 +1349,12 @@ unsafe fn parsed_chat_tool_call_arguments_status_to_result( unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; Err(ParseChatMessageError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => unreachable!( - "llama_rs_parsed_chat_tool_call_arguments returned unrecognized status {other}" - ), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), } } @@ -1465,13 +1452,11 @@ unsafe fn detect_reasoning_markers_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_DETECT_REASONING_MARKERS_ERROR_STRING_ALLOCATION_FAILED => { Err(MarkerDetectionError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_DETECT_REASONING_MARKERS_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_DETECT_REASONING_MARKERS_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ReasoningMarkerDetectionFailed { message }) } - other => unreachable!( - "llama_rs_detect_reasoning_markers returned unrecognized status {other}" - ), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), } } @@ -1533,13 +1518,11 @@ unsafe fn render_chat_template_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_RENDER_CHAT_TEMPLATE_ERROR_STRING_ALLOCATION_FAILED => { Err(MarkerDetectionError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_RENDER_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_RENDER_CHAT_TEMPLATE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ReasoningMarkerDetectionFailed { message }) } - other => { - unreachable!("llama_rs_render_chat_template returned unrecognized status {other}") - } + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), } } @@ -1626,13 +1609,11 @@ unsafe fn compute_tool_call_haystack_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_ERROR_STRING_ALLOCATION_FAILED => { Err(MarkerDetectionError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ToolCallHaystackComputationFailed { message }) } - other => unreachable!( - "llama_rs_compute_tool_call_haystack returned unrecognized status {other}" - ), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), } } @@ -1678,13 +1659,11 @@ unsafe fn diagnose_tool_call_synthetic_renders_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_ERROR_STRING_ALLOCATION_FAILED => { Err(MarkerDetectionError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ToolCallSyntheticRenderDiagnosisFailed { message }) } - other => unreachable!( - "llama_rs_diagnose_tool_call_synthetic_renders returned unrecognized status {other}" - ), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), } } @@ -1745,11 +1724,11 @@ unsafe fn tokenize_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED => { Err(StringToTokenError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_TOKENIZE_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(StringToTokenError::Reported { message }) } - other => unreachable!("llama_rs_tokenize returned unrecognized status {other}"), + other => Err(StringToTokenError::UnrecognizedStatusCode { code: other }), } } @@ -1871,7 +1850,7 @@ impl Drop for LlamaModel { #[cfg(test)] mod extract_meta_string_tests { use super::extract_meta_string; - use crate::MetaValError; + use crate::error::meta_val_error::MetaValError; #[test] fn returns_error_when_null_terminator_missing() { @@ -2000,10 +1979,13 @@ mod extract_meta_string_tests { #[test] fn tokenize_into_buffer_propagates_invocation_error() { let result = super::tokenize_into_buffer(8, |_tokens, _n_tokens_max| { - Err(crate::StringToTokenError::NotEnoughMemory) + Err(crate::error::string_to_token_error::StringToTokenError::NotEnoughMemory) }); - assert_eq!(result, Err(crate::StringToTokenError::NotEnoughMemory)); + assert_eq!( + result, + Err(crate::error::string_to_token_error::StringToTokenError::NotEnoughMemory) + ); } #[test] @@ -2015,11 +1997,14 @@ mod extract_meta_string_tests { if count == 0 { Ok(-20) } else { - Err(crate::StringToTokenError::NotEnoughMemory) + Err(crate::error::string_to_token_error::StringToTokenError::NotEnoughMemory) } }); - assert_eq!(result, Err(crate::StringToTokenError::NotEnoughMemory)); + assert_eq!( + result, + Err(crate::error::string_to_token_error::StringToTokenError::NotEnoughMemory) + ); assert_eq!(call_count.get(), 2); } @@ -2034,7 +2019,9 @@ mod extract_meta_string_tests { assert_eq!( result.unwrap_err(), - crate::StringToTokenError::CIntConversionError(usize::try_from(-5i32).unwrap_err()) + crate::error::string_to_token_error::StringToTokenError::CIntConversionError( + usize::try_from(-5i32).unwrap_err() + ) ); } @@ -2049,7 +2036,7 @@ mod extract_meta_string_tests { assert_eq!( result.unwrap_err(), - crate::MarkerDetectionError::MarkerUtf8Error( + crate::error::marker_detection_error::MarkerDetectionError::MarkerUtf8Error( String::from_utf8(vec![0xFF, 0xFE]).unwrap_err() ) ); @@ -2068,7 +2055,7 @@ mod extract_meta_string_tests { assert_eq!( result.unwrap_err(), - crate::MarkerDetectionError::MarkerUtf8Error( + crate::error::marker_detection_error::MarkerDetectionError::MarkerUtf8Error( String::from_utf8(vec![0xFF, 0xFE]).unwrap_err() ) ); @@ -2087,7 +2074,7 @@ mod extract_meta_string_tests { assert_eq!( result.unwrap_err(), - crate::MarkerDetectionError::MarkerUtf8Error( + crate::error::marker_detection_error::MarkerDetectionError::MarkerUtf8Error( String::from_utf8(vec![0xFF, 0xFE]).unwrap_err() ) ); @@ -2101,10 +2088,10 @@ mod ffi_status_mapping_tests { use std::path::Path; use std::ptr; - use llama_cpp_bindings_types::ParsedChatMessage; - use llama_cpp_bindings_types::ParsedToolCall; - use llama_cpp_bindings_types::ReasoningMarkers; - use llama_cpp_bindings_types::ToolCallArguments; + use llama_cpp_bindings_types::parsed_chat_message::ParsedChatMessage; + use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; + use llama_cpp_bindings_types::reasoning_markers::ReasoningMarkers; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; use super::ReasoningSplit; use super::chat_parser_create_status_to_result; @@ -2126,12 +2113,12 @@ mod ffi_status_mapping_tests { use super::render_chat_template_status_to_result; use super::split_reasoning_prefix; use super::tokenize_status_to_result; - use crate::ChatMessageParseOutcome; - use crate::LlamaModelLoadError; - use crate::MarkerDetectionError; - use crate::ParseChatMessageError; - use crate::RawChatMessage; - use crate::StringToTokenError; + use crate::chat_message_parse_outcome::ChatMessageParseOutcome; + use crate::error::llama_model_load_error::LlamaModelLoadError; + use crate::error::marker_detection_error::MarkerDetectionError; + use crate::error::parse_chat_message_error::ParseChatMessageError; + use crate::error::string_to_token_error::StringToTokenError; + use crate::raw_chat_message::RawChatMessage; #[test] fn cxx_exception_owns_out_error_classifies_each_failure_variant() { @@ -2168,10 +2155,10 @@ mod ffi_status_mapping_tests { } #[test] - fn load_model_from_file_vendored_returned_null_for_missing_path_is_file_not_found() { + fn load_model_from_file_load_failed_for_missing_path_is_file_not_found() { let result = unsafe { load_model_from_file_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_RETURNED_NULL, + llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_LOAD_FAILED, ptr::null_mut(), ptr::null_mut(), Path::new("/definitely/missing/model.gguf"), @@ -2204,7 +2191,7 @@ mod ffi_status_mapping_tests { fn load_model_from_file_cxx_exception_is_reported() { let result = unsafe { load_model_from_file_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_LOAD_MODEL_FROM_FILE_THREW_CXX_EXCEPTION, ptr::null_mut(), ptr::null_mut(), Path::new("/some/path"), @@ -2220,16 +2207,18 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_load_model_from_file returned unrecognized status")] - fn load_model_from_file_unrecognized_status_panics() { - let _ = unsafe { - load_model_from_file_status_to_result( - llama_cpp_bindings_sys::llama_rs_load_model_from_file_status::MAX, - ptr::null_mut(), - ptr::null_mut(), - Path::new("/some/path"), - ) - }; + fn load_model_from_file_unrecognized_status_returns_unrecognized_status_error() { + assert!(matches!( + unsafe { + load_model_from_file_status_to_result( + llama_cpp_bindings_sys::llama_rs_load_model_from_file_status::MAX, + ptr::null_mut(), + ptr::null_mut(), + Path::new("/some/path"), + ) + }, + Err(LlamaModelLoadError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2302,7 +2291,7 @@ mod ffi_status_mapping_tests { let mut out_error: *mut c_char = ptr::null_mut(); let result = unsafe { chat_parser_create_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_THREW_CXX_EXCEPTION, ptr::null_mut(), &raw mut out_error, ) @@ -2318,29 +2307,33 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_chat_parser_create returned OK with a null parser handle")] - fn chat_parser_create_ok_with_null_parser_panics() { + fn chat_parser_create_ok_with_null_parser_returns_unrecognized_status_error() { let mut out_error: *mut c_char = ptr::null_mut(); - let _ = unsafe { - chat_parser_create_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_OK, - ptr::null_mut(), - &raw mut out_error, - ) - }; + assert!(matches!( + unsafe { + chat_parser_create_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_OK, + ptr::null_mut(), + &raw mut out_error, + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] - #[should_panic(expected = "llama_rs_chat_parser_create returned unrecognized status")] - fn chat_parser_create_unrecognized_status_panics() { + fn chat_parser_create_unrecognized_status_returns_unrecognized_status_error() { let mut out_error: *mut c_char = ptr::null_mut(); - let _ = unsafe { - chat_parser_create_status_to_result( - llama_cpp_bindings_sys::llama_rs_chat_parser_create_status::MAX, - ptr::null_mut(), - &raw mut out_error, - ) - }; + assert!(matches!( + unsafe { + chat_parser_create_status_to_result( + llama_cpp_bindings_sys::llama_rs_chat_parser_create_status::MAX, + ptr::null_mut(), + &raw mut out_error, + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2365,7 +2358,7 @@ mod ffi_status_mapping_tests { let mut out_error: *mut c_char = ptr::null_mut(); let result = unsafe { parse_chat_message_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSE_CHAT_MESSAGE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSE_CHAT_MESSAGE_THREW_CXX_EXCEPTION, ptr::null_mut(), &raw mut out_error, ) @@ -2381,16 +2374,18 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_parse_chat_message returned unrecognized status")] - fn parse_chat_message_unrecognized_status_panics() { + fn parse_chat_message_unrecognized_status_returns_unrecognized_status_error() { let mut out_error: *mut c_char = ptr::null_mut(); - let _ = unsafe { - parse_chat_message_status_to_result( - llama_cpp_bindings_sys::llama_rs_parse_chat_message_status::MAX, - ptr::null_mut(), - &raw mut out_error, - ) - }; + assert!(matches!( + unsafe { + parse_chat_message_status_to_result( + llama_cpp_bindings_sys::llama_rs_parse_chat_message_status::MAX, + ptr::null_mut(), + &raw mut out_error, + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2465,17 +2460,19 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_parsed_chat_free returned unrecognized status")] - fn parsed_chat_free_unrecognized_status_panics() { + fn parsed_chat_free_unrecognized_status_returns_unrecognized_status_error() { let parsed = Ok(ParsedChatMessage::default()); - let _ = unsafe { - parsed_chat_free_status_to_result( - parsed, - llama_cpp_bindings_sys::llama_rs_parsed_chat_free_status::MAX, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + assert!(matches!( + unsafe { + parsed_chat_free_status_to_result( + parsed, + llama_cpp_bindings_sys::llama_rs_parsed_chat_free_status::MAX, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2511,7 +2508,7 @@ mod ffi_status_mapping_tests { fn parsed_chat_content_cxx_exception_is_reported() { let result = unsafe { parsed_chat_content_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_CONTENT_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_CONTENT_THREW_CXX_EXCEPTION, ptr::null_mut(), ptr::null_mut(), ) @@ -2526,15 +2523,17 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_parsed_chat_content returned unrecognized status")] - fn parsed_chat_content_unrecognized_status_panics() { - let _ = unsafe { - parsed_chat_content_status_to_result( - llama_cpp_bindings_sys::llama_rs_parsed_chat_content_status::MAX, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + fn parsed_chat_content_unrecognized_status_returns_unrecognized_status_error() { + assert!(matches!( + unsafe { + parsed_chat_content_status_to_result( + llama_cpp_bindings_sys::llama_rs_parsed_chat_content_status::MAX, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2570,7 +2569,7 @@ mod ffi_status_mapping_tests { fn parsed_chat_reasoning_content_cxx_exception_is_reported() { let result = unsafe { parsed_chat_reasoning_content_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_REASONING_CONTENT_THREW_CXX_EXCEPTION, ptr::null_mut(), ptr::null_mut(), ) @@ -2585,17 +2584,17 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic( - expected = "llama_rs_parsed_chat_reasoning_content returned unrecognized status" - )] - fn parsed_chat_reasoning_content_unrecognized_status_panics() { - let _ = unsafe { - parsed_chat_reasoning_content_status_to_result( - llama_cpp_bindings_sys::llama_rs_parsed_chat_reasoning_content_status::MAX, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + fn parsed_chat_reasoning_content_unrecognized_status_returns_error() { + assert!(matches!( + unsafe { + parsed_chat_reasoning_content_status_to_result( + llama_cpp_bindings_sys::llama_rs_parsed_chat_reasoning_content_status::MAX, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2631,7 +2630,7 @@ mod ffi_status_mapping_tests { fn parsed_chat_tool_call_count_cxx_exception_is_reported() { let result = unsafe { parsed_chat_tool_call_count_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_COUNT_THREW_CXX_EXCEPTION, 0, ptr::null_mut(), ) @@ -2646,15 +2645,17 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_parsed_chat_tool_call_count returned unrecognized status")] - fn parsed_chat_tool_call_count_unrecognized_status_panics() { - let _ = unsafe { - parsed_chat_tool_call_count_status_to_result( - llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_count_status::MAX, - 0, - ptr::null_mut(), - ) - }; + fn parsed_chat_tool_call_count_unrecognized_status_returns_unrecognized_status_error() { + assert!(matches!( + unsafe { + parsed_chat_tool_call_count_status_to_result( + llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_count_status::MAX, + 0, + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2709,7 +2710,7 @@ mod ffi_status_mapping_tests { fn parsed_chat_tool_call_id_cxx_exception_is_reported() { let result = unsafe { parsed_chat_tool_call_id_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ID_THREW_CXX_EXCEPTION, 0, ptr::null_mut(), ptr::null_mut(), @@ -2725,16 +2726,18 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_parsed_chat_tool_call_id returned unrecognized status")] - fn parsed_chat_tool_call_id_unrecognized_status_panics() { - let _ = unsafe { - parsed_chat_tool_call_id_status_to_result( - llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_id_status::MAX, - 0, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + fn parsed_chat_tool_call_id_unrecognized_status_returns_unrecognized_status_error() { + assert!(matches!( + unsafe { + parsed_chat_tool_call_id_status_to_result( + llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_id_status::MAX, + 0, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2789,7 +2792,7 @@ mod ffi_status_mapping_tests { fn parsed_chat_tool_call_name_cxx_exception_is_reported() { let result = unsafe { parsed_chat_tool_call_name_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_NAME_THREW_CXX_EXCEPTION, 0, ptr::null_mut(), ptr::null_mut(), @@ -2805,16 +2808,18 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_parsed_chat_tool_call_name returned unrecognized status")] - fn parsed_chat_tool_call_name_unrecognized_status_panics() { - let _ = unsafe { - parsed_chat_tool_call_name_status_to_result( - llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_name_status::MAX, - 0, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + fn parsed_chat_tool_call_name_unrecognized_status_returns_unrecognized_status_error() { + assert!(matches!( + unsafe { + parsed_chat_tool_call_name_status_to_result( + llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_name_status::MAX, + 0, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2869,7 +2874,7 @@ mod ffi_status_mapping_tests { fn parsed_chat_tool_call_arguments_cxx_exception_is_reported() { let result = unsafe { parsed_chat_tool_call_arguments_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_PARSED_CHAT_TOOL_CALL_ARGUMENTS_THREW_CXX_EXCEPTION, 0, ptr::null_mut(), ptr::null_mut(), @@ -2885,18 +2890,18 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic( - expected = "llama_rs_parsed_chat_tool_call_arguments returned unrecognized status" - )] - fn parsed_chat_tool_call_arguments_unrecognized_status_panics() { - let _ = unsafe { - parsed_chat_tool_call_arguments_status_to_result( - llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_arguments_status::MAX, - 0, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + fn parsed_chat_tool_call_arguments_unrecognized_status_returns_error() { + assert!(matches!( + unsafe { + parsed_chat_tool_call_arguments_status_to_result( + llama_cpp_bindings_sys::llama_rs_parsed_chat_tool_call_arguments_status::MAX, + 0, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(ParseChatMessageError::UnrecognizedStatusCode { .. }) + )); } #[test] @@ -2959,7 +2964,7 @@ mod ffi_status_mapping_tests { fn render_chat_template_status_cxx_exception_is_reported() { let result = unsafe { render_chat_template_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_RENDER_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_RENDER_CHAT_TEMPLATE_THREW_CXX_EXCEPTION, ptr::null(), ptr::null_mut(), ) @@ -2974,15 +2979,19 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_render_chat_template returned unrecognized status")] - fn render_chat_template_status_unrecognized_panics() { - let _ = unsafe { - render_chat_template_status_to_result( - llama_cpp_bindings_sys::llama_rs_render_chat_template_status::MAX, - ptr::null(), - ptr::null_mut(), - ) - }; + fn render_chat_template_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + unsafe { + render_chat_template_status_to_result( + llama_cpp_bindings_sys::llama_rs_render_chat_template_status::MAX, + ptr::null(), + ptr::null_mut(), + ) + }, + Err(MarkerDetectionError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_render_chat_template_status::MAX + }), + ); } #[test] @@ -3017,7 +3026,7 @@ mod ffi_status_mapping_tests { fn detect_reasoning_markers_cxx_exception_is_detection_failed() { let result = unsafe { detect_reasoning_markers_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_DETECT_REASONING_MARKERS_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_DETECT_REASONING_MARKERS_THREW_CXX_EXCEPTION, ptr::null(), ptr::null(), ptr::null_mut(), @@ -3033,16 +3042,20 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_detect_reasoning_markers returned unrecognized status")] - fn detect_reasoning_markers_unrecognized_status_panics() { - let _ = unsafe { - detect_reasoning_markers_status_to_result( - llama_cpp_bindings_sys::llama_rs_detect_reasoning_markers_status::MAX, - ptr::null(), - ptr::null(), - ptr::null_mut(), - ) - }; + fn detect_reasoning_markers_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + unsafe { + detect_reasoning_markers_status_to_result( + llama_cpp_bindings_sys::llama_rs_detect_reasoning_markers_status::MAX, + ptr::null(), + ptr::null(), + ptr::null_mut(), + ) + }, + Err(MarkerDetectionError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_detect_reasoning_markers_status::MAX + }), + ); } #[test] @@ -3075,7 +3088,7 @@ mod ffi_status_mapping_tests { fn compute_tool_call_haystack_cxx_exception_is_computation_failed() { let result = unsafe { compute_tool_call_haystack_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_COMPUTE_TOOL_CALL_HAYSTACK_THREW_CXX_EXCEPTION, ptr::null(), ptr::null_mut(), ) @@ -3090,15 +3103,19 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_compute_tool_call_haystack returned unrecognized status")] - fn compute_tool_call_haystack_unrecognized_status_panics() { - let _ = unsafe { - compute_tool_call_haystack_status_to_result( - llama_cpp_bindings_sys::llama_rs_compute_tool_call_haystack_status::MAX, - ptr::null(), - ptr::null_mut(), - ) - }; + fn compute_tool_call_haystack_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + unsafe { + compute_tool_call_haystack_status_to_result( + llama_cpp_bindings_sys::llama_rs_compute_tool_call_haystack_status::MAX, + ptr::null(), + ptr::null_mut(), + ) + }, + Err(MarkerDetectionError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_compute_tool_call_haystack_status::MAX + }), + ); } #[test] @@ -3133,7 +3150,7 @@ mod ffi_status_mapping_tests { fn diagnose_tool_call_synthetic_renders_cxx_exception_is_diagnosis_failed() { let result = unsafe { diagnose_tool_call_synthetic_renders_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_DIAGNOSE_TOOL_CALL_SYNTHETIC_RENDERS_THREW_CXX_EXCEPTION, ptr::null(), ptr::null(), ptr::null_mut(), @@ -3151,18 +3168,20 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic( - expected = "llama_rs_diagnose_tool_call_synthetic_renders returned unrecognized status" - )] - fn diagnose_tool_call_synthetic_renders_unrecognized_status_panics() { - let _ = unsafe { - diagnose_tool_call_synthetic_renders_status_to_result( - llama_cpp_bindings_sys::llama_rs_diagnose_tool_call_synthetic_renders_status::MAX, - ptr::null(), - ptr::null(), - ptr::null_mut(), - ) - }; + fn diagnose_tool_call_synthetic_renders_unrecognized_status_returns_error() { + assert_eq!( + unsafe { + diagnose_tool_call_synthetic_renders_status_to_result( + llama_cpp_bindings_sys::llama_rs_diagnose_tool_call_synthetic_renders_status::MAX, + ptr::null(), + ptr::null(), + ptr::null_mut(), + ) + }, + Err(MarkerDetectionError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_diagnose_tool_call_synthetic_renders_status::MAX, + }), + ); } #[test] @@ -3195,7 +3214,7 @@ mod ffi_status_mapping_tests { fn tokenize_cxx_exception_is_reported() { let result = unsafe { tokenize_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_TOKENIZE_THREW_CXX_EXCEPTION, 0, ptr::null_mut(), ) @@ -3210,15 +3229,19 @@ mod ffi_status_mapping_tests { } #[test] - #[should_panic(expected = "llama_rs_tokenize returned unrecognized status")] - fn tokenize_unrecognized_status_panics() { - let _ = unsafe { - tokenize_status_to_result( - llama_cpp_bindings_sys::llama_rs_tokenize_status::MAX, - 0, - ptr::null_mut(), - ) - }; + fn tokenize_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + unsafe { + tokenize_status_to_result( + llama_cpp_bindings_sys::llama_rs_tokenize_status::MAX, + 0, + ptr::null_mut(), + ) + }, + Err(StringToTokenError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_tokenize_status::MAX + }), + ); } #[test] @@ -3249,7 +3272,10 @@ mod ffi_status_mapping_tests { ) }; - assert_eq!(result, Err(crate::ApplyChatTemplateError::NoVocab)); + assert_eq!( + result, + Err(crate::error::apply_chat_template_error::ApplyChatTemplateError::NoVocab) + ); } #[test] @@ -3264,7 +3290,7 @@ mod ffi_status_mapping_tests { assert_eq!( result, - Err(crate::ApplyChatTemplateError::TemplateApplicationFailed) + Err(crate::error::apply_chat_template_error::ApplyChatTemplateError::TemplateApplicationFailed) ); } @@ -3278,7 +3304,10 @@ mod ffi_status_mapping_tests { ) }; - assert_eq!(result, Err(crate::ApplyChatTemplateError::NotEnoughMemory)); + assert_eq!( + result, + Err(crate::error::apply_chat_template_error::ApplyChatTemplateError::NotEnoughMemory) + ); } #[test] @@ -3290,7 +3319,7 @@ mod ffi_status_mapping_tests { let out_error = unsafe { strdup(message.as_ptr()) }; let result = unsafe { super::apply_chat_template_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_APPLY_CHAT_TEMPLATE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_APPLY_CHAT_TEMPLATE_THREW_CXX_EXCEPTION, ptr::null_mut(), out_error, ) @@ -3298,22 +3327,28 @@ mod ffi_status_mapping_tests { assert_eq!( result, - Err(crate::ApplyChatTemplateError::Reported { - message: "renderer exploded".to_owned() - }) + Err( + crate::error::apply_chat_template_error::ApplyChatTemplateError::Reported { + message: "renderer exploded".to_owned() + } + ) ); } #[test] - #[should_panic(expected = "llama_rs_apply_chat_template returned unrecognized status")] - fn apply_chat_template_unrecognized_status_panics() { - let _ = unsafe { - super::apply_chat_template_status_to_result( - llama_cpp_bindings_sys::llama_rs_apply_chat_template_status::MAX, - ptr::null_mut(), - ptr::null_mut(), - ) - }; + fn apply_chat_template_unrecognized_status_returns_unrecognized_status_error() { + assert_eq!( + unsafe { + super::apply_chat_template_status_to_result( + llama_cpp_bindings_sys::llama_rs_apply_chat_template_status::MAX, + ptr::null_mut(), + ptr::null_mut(), + ) + }, + Err(crate::error::apply_chat_template_error::ApplyChatTemplateError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_apply_chat_template_status::MAX + }), + ); } #[test] diff --git a/llama-cpp-bindings/src/model/llama_chat_message.rs b/llama-cpp-bindings/src/model/llama_chat_message.rs index 51e1f086..6f94ee9a 100644 --- a/llama-cpp-bindings/src/model/llama_chat_message.rs +++ b/llama-cpp-bindings/src/model/llama_chat_message.rs @@ -1,6 +1,6 @@ use std::ffi::CString; -use crate::NewLlamaChatMessageError; +use crate::error::new_llama_chat_message_error::NewLlamaChatMessageError; #[derive(Debug, Eq, PartialEq, Clone)] pub struct LlamaChatMessage { diff --git a/llama-cpp-bindings/src/model/params.rs b/llama-cpp-bindings/src/model/params.rs index 1506b564..60a0bb63 100644 --- a/llama-cpp-bindings/src/model/params.rs +++ b/llama-cpp-bindings/src/model/params.rs @@ -3,9 +3,10 @@ use std::fmt::{Debug, Formatter}; use std::pin::Pin; use std::ptr::null; -use crate::LlamaCppError; use crate::context::params::LlamaContextParams; -use crate::error::{FitError, ModelParamsError}; +use crate::error::fit_error::FitError; +use crate::error::llama_cpp_error::LlamaCppError; +use crate::error::model_params_error::ModelParamsError; use crate::model::llama_split_mode_parse_error::LlamaSplitModeParseError; use crate::model::params::fit_result::FitResult; use crate::model::params::kv_overrides::KvOverrides; @@ -266,7 +267,7 @@ impl LlamaModelParams { for dev in self.devices.iter_mut() { *dev = std::ptr::null_mut(); } - let max_devices = crate::max_devices().min(LLAMA_CPP_MAX_DEVICES); + let max_devices = crate::max_devices::max_devices().min(LLAMA_CPP_MAX_DEVICES); if devices.len() > max_devices { return Err(LlamaCppError::MaxDevicesExceeded(max_devices)); } @@ -290,13 +291,11 @@ fn fit_params_status_to_result( ) -> Result<(), FitError> { match status { llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_OK => Ok(()), - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_FAILURE => { + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_DOES_NOT_FIT => { Err(FitError::NoFittingMemoryLayout) } - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_ERROR => { - Err(FitError::Aborted) - } - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_RETURNED_UNRECOGNIZED_STATUS_CODE => { + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_HARD_ERROR => Err(FitError::Aborted), + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_UNRECOGNIZED_STATUS_CODE => { Err(FitError::UnknownStatus { code: out_unrecognized_status_code, }) @@ -304,18 +303,18 @@ fn fit_params_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_ERROR_STRING_ALLOCATION_FAILED => { Err(FitError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(FitError::Reported { message }) } - other => unreachable!("llama_rs_fit_params returned unrecognized wrapper status: {other}"), + other => Err(FitError::UnrecognizedStatusCode { code: other }), } } impl LlamaModelParams { /// # Errors /// - /// Returns one of the [`FitError`] variants matching the vendored wrapper's status code. + /// Returns one of the [`FitError`] variants matching the wrapper's status code. pub fn fit_params( mut self: Pin<&mut Self>, model_path: &CStr, @@ -563,7 +562,9 @@ mod tests { assert_eq!( std::mem::discriminant(&result.unwrap_err()), - std::mem::discriminant(&crate::LlamaCppError::BackendDeviceNotFound(0)), + std::mem::discriminant( + &crate::error::llama_cpp_error::LlamaCppError::BackendDeviceNotFound(0) + ), ); } @@ -586,7 +587,7 @@ mod tests { assert_eq!( result.unwrap_err(), - crate::error::ModelParamsError::SlotNotEmpty + crate::error::model_params_error::ModelParamsError::SlotNotEmpty ); } @@ -617,7 +618,7 @@ mod tests { assert_eq!( result.unwrap_err(), - crate::error::ModelParamsError::SlotNotEmpty + crate::error::model_params_error::ModelParamsError::SlotNotEmpty ); } @@ -670,10 +671,12 @@ mod tests { assert_eq!( std::mem::discriminant(&result.unwrap_err()), - std::mem::discriminant(&crate::error::ModelParamsError::InvalidCharacterInKey { - byte: 0, - reason: String::new(), - }), + std::mem::discriminant( + &crate::error::model_params_error::ModelParamsError::InvalidCharacterInKey { + byte: 0, + reason: String::new(), + } + ), ); } @@ -687,10 +690,12 @@ mod tests { assert_eq!( std::mem::discriminant(&result.unwrap_err()), - std::mem::discriminant(&crate::error::ModelParamsError::InvalidCharacterInKey { - byte: 0, - reason: String::new(), - }), + std::mem::discriminant( + &crate::error::model_params_error::ModelParamsError::InvalidCharacterInKey { + byte: 0, + reason: String::new(), + } + ), ); } @@ -708,7 +713,7 @@ mod tests { assert_eq!( result.unwrap_err(), - crate::error::ModelParamsError::NoAvailableSlot + crate::error::model_params_error::ModelParamsError::NoAvailableSlot ); } @@ -722,7 +727,7 @@ mod tests { assert_eq!( result.unwrap_err(), - crate::error::ModelParamsError::NoAvailableSlot + crate::error::model_params_error::ModelParamsError::NoAvailableSlot ); } @@ -730,13 +735,13 @@ mod tests { #[serial_test::serial] fn fit_params_invalid_model_path_returns_error() { use crate::context::params::LlamaContextParams; - use crate::error::FitError; + use crate::error::fit_error::FitError; use crate::llama_backend::LlamaBackend; let _backend = LlamaBackend::init(); let mut params = std::pin::pin!(LlamaModelParams::default()); let mut context_params = LlamaContextParams::default(); - let mut margins = vec![0usize; crate::max_devices()]; + let mut margins = vec![0usize; crate::max_devices::max_devices()]; let bogus_path = c"/nonexistent/path/to/model.gguf"; let result = params.as_mut().fit_params( @@ -767,36 +772,39 @@ mod tests { #[test] fn fit_params_status_reported_failure_returns_no_fitting_memory_layout() { let result = super::fit_params_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_FAILURE, + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_DOES_NOT_FIT, 0, std::ptr::null_mut(), ); - assert_eq!(result, Err(crate::error::FitError::NoFittingMemoryLayout)); + assert_eq!( + result, + Err(crate::error::fit_error::FitError::NoFittingMemoryLayout) + ); } #[test] fn fit_params_status_reported_error_returns_aborted() { let result = super::fit_params_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_REPORTED_ERROR, + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_HARD_ERROR, 0, std::ptr::null_mut(), ); - assert_eq!(result, Err(crate::error::FitError::Aborted)); + assert_eq!(result, Err(crate::error::fit_error::FitError::Aborted)); } #[test] fn fit_params_status_unrecognized_code_returns_unknown_status() { let result = super::fit_params_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_RETURNED_UNRECOGNIZED_STATUS_CODE, + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_UNRECOGNIZED_STATUS_CODE, 42, std::ptr::null_mut(), ); assert_eq!( result, - Err(crate::error::FitError::UnknownStatus { code: 42 }) + Err(crate::error::fit_error::FitError::UnknownStatus { code: 42 }) ); } @@ -808,32 +816,39 @@ mod tests { std::ptr::null_mut(), ); - assert_eq!(result, Err(crate::error::FitError::NotEnoughMemory)); + assert_eq!( + result, + Err(crate::error::fit_error::FitError::NotEnoughMemory) + ); } #[test] fn fit_params_status_cxx_exception_returns_reported_with_unknown_error() { let result = super::fit_params_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_FIT_PARAMS_THREW_CXX_EXCEPTION, 0, std::ptr::null_mut(), ); assert_eq!( result, - Err(crate::error::FitError::Reported { + Err(crate::error::fit_error::FitError::Reported { message: "unknown error".to_owned() }) ); } #[test] - #[should_panic(expected = "unrecognized wrapper status")] - fn fit_params_status_out_of_range_panics() { - let _ = super::fit_params_status_to_result( - llama_cpp_bindings_sys::llama_rs_fit_params_status::MAX, - 0, - std::ptr::null_mut(), + fn fit_params_status_out_of_range_returns_unrecognized_status_error() { + assert_eq!( + super::fit_params_status_to_result( + llama_cpp_bindings_sys::llama_rs_fit_params_status::MAX, + 0, + std::ptr::null_mut(), + ), + Err(crate::error::fit_error::FitError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_fit_params_status::MAX + }), ); } } diff --git a/llama-cpp-bindings/src/mtmd.rs b/llama-cpp-bindings/src/mtmd.rs index 989cf772..0e9d2123 100644 --- a/llama-cpp-bindings/src/mtmd.rs +++ b/llama-cpp-bindings/src/mtmd.rs @@ -16,22 +16,3 @@ pub mod mtmd_input_chunks; pub mod mtmd_input_chunks_error; pub mod mtmd_input_text; pub mod mtmd_tokenize_error; - -pub use image_chunk_batch_size_mismatch::ImageChunkBatchSizeMismatch; -pub use mtmd_bitmap::MtmdBitmap; -pub use mtmd_bitmap_error::MtmdBitmapError; -pub use mtmd_context::MtmdContext; -pub use mtmd_context_params::MtmdContextParams; -pub use mtmd_default_marker::mtmd_default_marker; -pub use mtmd_default_marker_error::MtmdDefaultMarkerError; -pub use mtmd_encode_error::MtmdEncodeError; -pub use mtmd_eval_error::MtmdEvalError; -pub use mtmd_init_error::MtmdInitError; -pub use mtmd_input_chunk::MtmdInputChunk; -pub use mtmd_input_chunk_error::MtmdInputChunkError; -pub use mtmd_input_chunk_type::MtmdInputChunkType; -pub use mtmd_input_chunk_type_error::MtmdInputChunkTypeError; -pub use mtmd_input_chunks::MtmdInputChunks; -pub use mtmd_input_chunks_error::MtmdInputChunksError; -pub use mtmd_input_text::MtmdInputText; -pub use mtmd_tokenize_error::MtmdTokenizeError; diff --git a/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs b/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs index 730b7b62..99623acf 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs @@ -41,7 +41,7 @@ unsafe fn from_file_status_to_result( })?; Ok(MtmdBitmap { bitmap }) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_LOAD_FAILED => { Err(MtmdBitmapError::FileUnreadable { path: PathBuf::from(path), }) @@ -49,13 +49,11 @@ unsafe fn from_file_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED => { Err(MtmdBitmapError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdBitmapError::Reported { message }) } - other => unreachable!( - "llama_rs_mtmd_bitmap_init_from_file returned unrecognized status: {other}" - ), + other => Err(MtmdBitmapError::UnrecognizedStatusCode { code: other }), } } @@ -327,10 +325,10 @@ mod tests { } #[test] - fn from_file_status_vendored_returned_null_returns_file_unreadable() { + fn from_file_status_load_failed_returns_file_unreadable() { let result = unsafe { super::from_file_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_RETURNED_NULL, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_LOAD_FAILED, std::ptr::null_mut(), std::ptr::null_mut(), "/missing/image.png", @@ -360,10 +358,10 @@ mod tests { } #[test] - fn from_file_status_vendored_threw_cxx_exception_returns_reported() { + fn from_file_status_threw_cxx_exception_returns_reported() { let result = unsafe { super::from_file_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), "/missing/image.png", @@ -379,15 +377,17 @@ mod tests { } #[test] - #[should_panic(expected = "returned unrecognized status")] - fn from_file_status_null_ctx_arg_panics_as_unreachable() { - let _result = unsafe { - super::from_file_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_NULL_CTX_ARG, - std::ptr::null_mut(), - std::ptr::null_mut(), - "/missing/image.png", - ) - }; + fn from_file_status_null_ctx_arg_returns_unrecognized_status_error_as_unreachable() { + assert!(matches!( + unsafe { + super::from_file_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_MTMD_BITMAP_INIT_FROM_FILE_NULL_CTX_ARG, + std::ptr::null_mut(), + std::ptr::null_mut(), + "/missing/image.png", + ) + }, + Err(MtmdBitmapError::UnrecognizedStatusCode { .. }) + )); } } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs index 36a756f5..05f8a2ca 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs @@ -18,4 +18,6 @@ pub enum MtmdBitmapError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_context.rs b/llama-cpp-bindings/src/mtmd/mtmd_context.rs index c552ff82..b2c36e6d 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_context.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_context.rs @@ -21,13 +21,13 @@ fn map_tokenize_status( ) -> Result<(), MtmdTokenizeError> { match status { llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_OK => Ok(()), - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT => { Err(MtmdTokenizeError::BitmapCountDoesNotMatchMarkerCount) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_IMAGE_PREPROCESSING_ERROR => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_IMAGE_PREPROCESSING_ERROR => { Err(MtmdTokenizeError::MediaPreprocessingFailed) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_RETURNED_UNDOCUMENTED_NONZERO_CODE => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_UNDOCUMENTED_ERROR_CODE => { Err(MtmdTokenizeError::UnknownStatus { code: undocumented_return_code, }) @@ -35,35 +35,32 @@ fn map_tokenize_status( llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_ERROR_STRING_ALLOCATION_FAILED => { Err(MtmdTokenizeError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdTokenizeError::Reported { message }) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO => unreachable!("llama_rs_mtmd_tokenize NULL_BITMAPS_ARG: Rust always passes a non-null bitmaps pointer when count > 0"), - other => unreachable!("llama_rs_mtmd_tokenize returned unrecognized status: {other}"), + other => Err(MtmdTokenizeError::UnrecognizedStatusCode { code: other }), } } fn map_encode_chunk_status( status: llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk_status, - vendored_return_code: i32, + return_code: i32, out_error: *mut c_char, ) -> Result<(), MtmdEncodeError> { match status { llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_OK => Ok(()), - llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_RETURNED_NONZERO_CODE => { - Err(MtmdEncodeError::EncodingFailed { - code: vendored_return_code, - }) + llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_RETURNED_ERROR_CODE => { + Err(MtmdEncodeError::EncodingFailed { code: return_code }) } llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_ERROR_STRING_ALLOCATION_FAILED => { Err(MtmdEncodeError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdEncodeError::Reported { message }) } - other => unreachable!("llama_rs_mtmd_encode_chunk returned unrecognized status: {other}"), + other => Err(MtmdEncodeError::UnrecognizedStatusCode { code: other }), } } @@ -80,7 +77,7 @@ fn map_init_from_file_status( })?; Ok(MtmdContext { context }) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_INITIALIZATION_FAILED => { Err(MtmdInitError::Unloadable { path: std::path::PathBuf::from(mmproj_path), }) @@ -88,13 +85,11 @@ fn map_init_from_file_status( llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_ERROR_STRING_ALLOCATION_FAILED => { Err(MtmdInitError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdInitError::Reported { message }) } - other => { - unreachable!("llama_rs_mtmd_init_from_file returned unrecognized status: {other}") - } + other => Err(MtmdInitError::UnrecognizedStatusCode { code: other }), } } @@ -210,19 +205,19 @@ impl MtmdContext { /// /// Returns an [`MtmdEncodeError`] variant matching the wrapper's status code. pub fn encode_chunk(&self, chunk: &MtmdInputChunk) -> Result<(), MtmdEncodeError> { - let mut out_vendored_return_code: i32 = 0; + let mut out_return_code: i32 = 0; let mut out_error: *mut c_char = std::ptr::null_mut(); let status = unsafe { llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk( self.context.as_ptr(), chunk.chunk.as_ptr(), - &raw mut out_vendored_return_code, + &raw mut out_return_code, &raw mut out_error, ) }; - map_encode_chunk_status(status, out_vendored_return_code, out_error) + map_encode_chunk_status(status, out_return_code, out_error) } } @@ -244,7 +239,7 @@ mod unit_tests { #[test] fn tokenize_status_maps_bitmap_count_mismatch() { let result = map_tokenize_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_BITMAP_COUNT_DOES_NOT_MATCH_MARKER_COUNT, 0, std::ptr::null_mut(), ); @@ -258,7 +253,7 @@ mod unit_tests { #[test] fn tokenize_status_maps_media_preprocessing_failed() { let result = map_tokenize_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_REPORTED_IMAGE_PREPROCESSING_ERROR, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_IMAGE_PREPROCESSING_ERROR, 0, std::ptr::null_mut(), ); @@ -269,7 +264,7 @@ mod unit_tests { #[test] fn tokenize_status_maps_unknown_status_with_value() { let result = map_tokenize_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_RETURNED_UNDOCUMENTED_NONZERO_CODE, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_UNDOCUMENTED_ERROR_CODE, 42, std::ptr::null_mut(), ); @@ -302,7 +297,7 @@ mod unit_tests { #[test] fn encode_chunk_status_maps_encoding_failed_with_code() { let result = map_encode_chunk_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_RETURNED_NONZERO_CODE, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_RETURNED_ERROR_CODE, 5, std::ptr::null_mut(), ); @@ -324,7 +319,7 @@ mod unit_tests { #[test] fn tokenize_status_maps_cxx_exception_to_reported() { let result = map_tokenize_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_THREW_CXX_EXCEPTION, 0, std::ptr::null_mut(), ); @@ -338,22 +333,30 @@ mod unit_tests { } #[test] - #[should_panic(expected = "NULL_BITMAPS_ARG")] - fn tokenize_status_null_bitmaps_arg_panics() { - let _result = map_tokenize_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO, - 0, - std::ptr::null_mut(), + fn tokenize_status_null_bitmaps_arg_returns_unrecognized_status_error() { + assert_eq!( + map_tokenize_status( + llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO, + 0, + std::ptr::null_mut(), + ), + Err(MtmdTokenizeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO, + }), ); } #[test] - #[should_panic(expected = "llama_rs_mtmd_tokenize returned unrecognized status")] - fn tokenize_status_unrecognized_panics() { - let _result = map_tokenize_status( - llama_cpp_bindings_sys::llama_rs_mtmd_tokenize_status::MAX, - 0, - std::ptr::null_mut(), + fn tokenize_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + map_tokenize_status( + llama_cpp_bindings_sys::llama_rs_mtmd_tokenize_status::MAX, + 0, + std::ptr::null_mut(), + ), + Err(MtmdTokenizeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_mtmd_tokenize_status::MAX + }), ); } @@ -371,7 +374,7 @@ mod unit_tests { #[test] fn encode_chunk_status_maps_cxx_exception_to_reported() { let result = map_encode_chunk_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_ENCODE_CHUNK_THREW_CXX_EXCEPTION, 0, std::ptr::null_mut(), ); @@ -385,12 +388,16 @@ mod unit_tests { } #[test] - #[should_panic(expected = "llama_rs_mtmd_encode_chunk returned unrecognized status")] - fn encode_chunk_status_unrecognized_panics() { - let _result = map_encode_chunk_status( - llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk_status::MAX, - 0, - std::ptr::null_mut(), + fn encode_chunk_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + map_encode_chunk_status( + llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk_status::MAX, + 0, + std::ptr::null_mut(), + ), + Err(MtmdEncodeError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk_status::MAX + }), ); } @@ -426,7 +433,7 @@ mod unit_tests { #[test] fn init_from_file_status_maps_cxx_exception_to_reported() { let result = map_init_from_file_status( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_INIT_FROM_FILE_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), "mmproj.gguf", @@ -441,13 +448,15 @@ mod unit_tests { } #[test] - #[should_panic(expected = "llama_rs_mtmd_init_from_file returned unrecognized status")] - fn init_from_file_status_unrecognized_panics() { - let _result = map_init_from_file_status( - llama_cpp_bindings_sys::llama_rs_mtmd_init_from_file_status::MAX, - std::ptr::null_mut(), - std::ptr::null_mut(), - "mmproj.gguf", - ); + fn init_from_file_status_unrecognized_returns_unrecognized_status_error() { + assert!(matches!( + map_init_from_file_status( + llama_cpp_bindings_sys::llama_rs_mtmd_init_from_file_status::MAX, + std::ptr::null_mut(), + std::ptr::null_mut(), + "mmproj.gguf", + ), + Err(MtmdInitError::UnrecognizedStatusCode { .. }) + )); } } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_default_marker.rs b/llama-cpp-bindings/src/mtmd/mtmd_default_marker.rs index 780eb447..46e79927 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_default_marker.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_default_marker.rs @@ -12,9 +12,9 @@ unsafe fn marker_bytes_to_str( /// # Errors /// /// Returns [`MtmdDefaultMarkerError::NotUtf8`] if llama.cpp's `mtmd_default_marker` -/// returns bytes that are not valid UTF-8. The marker is a fixed ASCII constant in -/// the vendored library; surfacing the error keeps the failure explicit rather than -/// papering over it with a substituted literal. +/// returns bytes that are not valid UTF-8. The marker is a fixed ASCII constant; +/// surfacing the error keeps the failure explicit rather than papering over it with +/// a substituted literal. pub fn mtmd_default_marker() -> Result<&'static str, MtmdDefaultMarkerError> { unsafe { marker_bytes_to_str(llama_cpp_bindings_sys::mtmd_default_marker()) } } @@ -29,7 +29,7 @@ mod tests { #[test] fn returns_non_empty_marker() { - let marker = mtmd_default_marker().expect("vendored marker must be valid UTF-8"); + let marker = mtmd_default_marker().expect("marker must be valid UTF-8"); assert!(!marker.is_empty()); } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs index 55f5da42..e1e49815 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs @@ -6,4 +6,6 @@ pub enum MtmdEncodeError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs index 318015a2..30097cd6 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs @@ -16,4 +16,6 @@ pub enum MtmdEvalError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs index da2e37bf..fa91b27e 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs @@ -12,4 +12,6 @@ pub enum MtmdInitError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs b/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs index 3496ae4f..639aa5eb 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs @@ -37,26 +37,24 @@ const unsafe fn tokens_from_raw_ptr<'chunk>( fn eval_chunk_single_status_to_result( status: llama_cpp_bindings_sys::llama_rs_mtmd_eval_chunk_single_status, final_position: llama_cpp_bindings_sys::llama_pos, - out_vendored_return_code: i32, + out_return_code: i32, out_error: *mut c_char, ) -> Result { match status { llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_OK => Ok(final_position), - llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_RETURNED_NONZERO_CODE => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_RETURNED_ERROR_CODE => { Err(MtmdEvalError::EvalFailed { - code: out_vendored_return_code, + code: out_return_code, }) } llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_ERROR_STRING_ALLOCATION_FAILED => { Err(MtmdEvalError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdEvalError::Reported { message }) } - other => { - unreachable!("llama_rs_mtmd_eval_chunk_single returned unrecognized status: {other}") - } + other => Err(MtmdEvalError::UnrecognizedStatusCode { code: other }), } } @@ -170,7 +168,7 @@ impl MtmdInputChunk { } let mut final_position: llama_cpp_bindings_sys::llama_pos = start_position; - let mut out_vendored_return_code: i32 = 0; + let mut out_return_code: i32 = 0; let mut out_error: *mut c_char = std::ptr::null_mut(); let status = unsafe { @@ -183,17 +181,12 @@ impl MtmdInputChunk { n_batch, logits_last, &raw mut final_position, - &raw mut out_vendored_return_code, + &raw mut out_return_code, &raw mut out_error, ) }; - eval_chunk_single_status_to_result( - status, - final_position, - out_vendored_return_code, - out_error, - ) + eval_chunk_single_status_to_result(status, final_position, out_return_code, out_error) } } @@ -248,7 +241,7 @@ mod unit_tests { #[test] fn eval_chunk_single_status_nonzero_code_maps_to_eval_failed() { let result = eval_chunk_single_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_RETURNED_NONZERO_CODE, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_RETURNED_ERROR_CODE, 0, -3, std::ptr::null_mut(), @@ -272,7 +265,7 @@ mod unit_tests { #[test] fn eval_chunk_single_status_cxx_exception_reports_unknown_error_for_null() { let result = eval_chunk_single_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_MTMD_EVAL_CHUNK_SINGLE_THREW_CXX_EXCEPTION, 0, 0, std::ptr::null_mut(), @@ -287,13 +280,17 @@ mod unit_tests { } #[test] - #[should_panic(expected = "llama_rs_mtmd_eval_chunk_single returned unrecognized status")] - fn eval_chunk_single_status_unrecognized_panics() { - let _ = eval_chunk_single_status_to_result( - llama_cpp_bindings_sys::llama_rs_mtmd_eval_chunk_single_status::MAX, - 0, - 0, - std::ptr::null_mut(), + fn eval_chunk_single_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + eval_chunk_single_status_to_result( + llama_cpp_bindings_sys::llama_rs_mtmd_eval_chunk_single_status::MAX, + 0, + 0, + std::ptr::null_mut(), + ), + Err(MtmdEvalError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_mtmd_eval_chunk_single_status::MAX + }), ); } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs index 901e4489..3e23cea9 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs @@ -16,4 +16,6 @@ pub enum MtmdTokenizeError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the FFI wrapper returned an unrecognized status code {code}")] + UnrecognizedStatusCode { code: u32 }, } diff --git a/llama-cpp-bindings/src/sampled_token_classifier.rs b/llama-cpp-bindings/src/sampled_token_classifier.rs index c3499e37..9012c7fd 100644 --- a/llama-cpp-bindings/src/sampled_token_classifier.rs +++ b/llama-cpp-bindings/src/sampled_token_classifier.rs @@ -3,29 +3,28 @@ use std::collections::VecDeque; use llama_cpp_bindings_sys::llama_pos; use llama_cpp_bindings_sys::llama_seq_id; -use llama_cpp_bindings_types::TokenUsage; -use llama_cpp_bindings_types::TokenUsageError; +use llama_cpp_bindings_types::token_usage::TokenUsage; +use llama_cpp_bindings_types::token_usage_error::TokenUsageError; use crate::batch_add_error::BatchAddError; use crate::context::LlamaContext; -use crate::error::EvalMultimodalChunksError; -use crate::error::SampleError; -use crate::error::TokenToStringError; +use crate::error::eval_multimodal_chunks_error::EvalMultimodalChunksError; +use crate::error::sample_error::SampleError; +use crate::error::token_to_string_error::TokenToStringError; use crate::eval_multimodal_chunks_params::EvalMultimodalChunksParams; +use crate::ingest_outcome::IngestOutcome; use crate::llama_batch::LlamaBatch; use crate::marker_kind::MarkerKind; use crate::model::LlamaModel; -use crate::mtmd::MtmdContext; -use crate::mtmd::MtmdInputChunks; +use crate::mtmd::mtmd_context::MtmdContext; +use crate::mtmd::mtmd_input_chunks::MtmdInputChunks; use crate::sampled_token::SampledToken; +use crate::sampled_token_section::SampledTokenSection; use crate::sampling::LlamaSampler; use crate::streaming_json_probe::JsonProbeOutcome; use crate::streaming_markers::StreamingMarkers; use crate::token::LlamaToken; -pub use crate::ingest_outcome::IngestOutcome; -pub use crate::sampled_token_section::SampledTokenSection; - #[derive(Clone, Debug)] struct PendingToken { token: LlamaToken, @@ -563,7 +562,7 @@ mod tests { pending: std::collections::VecDeque::new(), section: SampledTokenSection::Pending, pending_prompt_tokens: 0, - usage: llama_cpp_bindings_types::TokenUsage::new(), + usage: llama_cpp_bindings_types::token_usage::TokenUsage::new(), probe_mode: ProbeMode::Idle, } } diff --git a/llama-cpp-bindings/src/sampling.rs b/llama-cpp-bindings/src/sampling.rs index d2be11f7..7b6e43b9 100644 --- a/llama-cpp-bindings/src/sampling.rs +++ b/llama-cpp-bindings/src/sampling.rs @@ -2,16 +2,21 @@ use std::borrow::Borrow; use std::ffi::{CString, c_char}; use std::fmt::{Debug, Formatter}; -use llama_cpp_error_recorder::ErrorScope; -use llama_cpp_error_recorder::RecordedError; +use llama_cpp_error_recorder::error_scope::ErrorScope; +use llama_cpp_error_recorder::recorded_error::RecordedError; +use llama_cpp_gbnf::gbnf_grammar::GbnfGrammar; +use llama_cpp_gbnf::gbnf_parse_error::GbnfParseError; use crate::context::LlamaContext; +use crate::error::grammar_error::GrammarError; +use crate::error::sample_error::SampleError; +use crate::error::sampler_accept_error::SamplerAcceptError; +use crate::error::sampling_error::SamplingError; use crate::ffi_error_reader::read_and_free_cpp_error; use crate::model::LlamaModel; use crate::token::LlamaToken; use crate::token::data_array::LlamaTokenDataArray; use crate::token::logit_bias::LlamaLogitBias; -use crate::{GrammarError, SampleError, SamplerAcceptError, SamplingError}; fn check_sampler_accept_status( status: llama_cpp_bindings_sys::llama_rs_sampler_accept_status, @@ -22,11 +27,11 @@ fn check_sampler_accept_status( llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_ERROR_STRING_ALLOCATION_FAILED => { Err(SamplerAcceptError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(SamplerAcceptError::GrammarStateCorrupted { message }) } - other => unreachable!("llama_rs_sampler_accept returned unrecognized status {other}"), + other => Err(SamplerAcceptError::UnrecognizedStatusCode { code: other }), } } @@ -40,11 +45,11 @@ fn sampler_sample_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_ERROR_STRING_ALLOCATION_FAILED => { Err(SampleError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(SampleError::Reported { message }) } - other => unreachable!("llama_rs_sampler_sample returned unrecognized status {other}"), + other => Err(SampleError::UnrecognizedStatusCode { code: other }), } } @@ -55,19 +60,17 @@ fn sampler_init_grammar_status_to_result( ) -> Result { match status { llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_OK => Ok(LlamaSampler { sampler }), - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_COMPILATION_FAILED => { Err(GrammarError::GrammarMalformed) } llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_ERROR_STRING_ALLOCATION_FAILED => { Err(GrammarError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(GrammarError::Reported { message }) } - other => { - unreachable!("llama_rs_sampler_init_grammar returned unrecognized status {other}") - } + other => Err(GrammarError::UnrecognizedStatusCode { code: other }), } } @@ -80,18 +83,18 @@ fn sampler_init_grammar_lazy_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_OK => { Ok(LlamaSampler { sampler }) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_COMPILATION_FAILED => { Err(GrammarError::LazyGrammarMalformed) } llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_ERROR_STRING_ALLOCATION_FAILED => { Err(GrammarError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(GrammarError::Reported { message }) } other => { - unreachable!("llama_rs_sampler_init_grammar_lazy returned unrecognized status {other}") + Err(GrammarError::UnrecognizedStatusCode { code: other }) } } } @@ -105,7 +108,7 @@ fn sampler_init_grammar_lazy_patterns_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_OK => { Ok(LlamaSampler { sampler }) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_RETURNED_NULL => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_COMPILATION_FAILED => { Err(GrammarError::LazyPatternsGrammarMalformed) } llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_ERROR_STRING_ALLOCATION_FAILED => { @@ -115,13 +118,11 @@ fn sampler_init_grammar_lazy_patterns_status_to_result( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(GrammarError::InvalidTriggerPattern { message }) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_THREW_CXX_EXCEPTION => { let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(GrammarError::Reported { message }) } - other => unreachable!( - "llama_rs_sampler_init_grammar_lazy_patterns returned unrecognized status {other}" - ), + other => Err(GrammarError::UnrecognizedStatusCode { code: other }), } } @@ -451,7 +452,9 @@ impl LlamaSampler { grammar_str: &str, grammar_root: &str, ) -> Result<(CString, CString), GrammarError> { - if !grammar_str.contains(grammar_root) { + if let Err(GbnfParseError::RootSymbolMissing { .. }) = + GbnfGrammar::parse(grammar_str, grammar_root) + { return Err(GrammarError::RootNotFound); } @@ -593,14 +596,14 @@ mod tests { use std::ffi::CString; use std::mem::Discriminant; - use llama_cpp_error_recorder::RecordedError; + use llama_cpp_error_recorder::recorded_error::RecordedError; use super::LlamaSampler; use super::grammar_callback_error_to_accept_result; use super::grammar_callback_error_to_result; - use crate::GrammarError; - use crate::SampleError; - use crate::SamplerAcceptError; + use crate::error::grammar_error::GrammarError; + use crate::error::sample_error::SampleError; + use crate::error::sampler_accept_error::SamplerAcceptError; #[test] fn grammar_callback_error_to_result_maps_recorded_error() { @@ -758,8 +761,8 @@ mod tests { #[test] fn apply_with_null_sampler_surfaces_sampler_apply_error() { - use crate::error::SampleError; - use crate::error::SamplerApplyError; + use crate::error::sample_error::SampleError; + use crate::error::sampler_apply_error::SamplerApplyError; use crate::token::LlamaToken; use crate::token::data::LlamaTokenData; use crate::token::data_array::LlamaTokenDataArray; @@ -888,7 +891,7 @@ mod tests { #[test] fn check_sampler_accept_status_exception_maps_to_typed_variant() { let err = super::check_sampler_accept_status( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_THREW_CXX_EXCEPTION, std::ptr::null_mut(), ) .unwrap_err(); @@ -911,11 +914,15 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_sampler_accept returned unrecognized status")] - fn check_sampler_accept_status_unrecognized_panics() { - let _result = super::check_sampler_accept_status( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_NULL_SAMPLER_ARG, - std::ptr::null_mut(), + fn check_sampler_accept_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + super::check_sampler_accept_status( + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_NULL_SAMPLER_ARG, + std::ptr::null_mut(), + ), + Err(SamplerAcceptError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_NULL_SAMPLER_ARG + }), ); } @@ -933,7 +940,7 @@ mod tests { #[test] fn sampler_sample_status_exception_maps_to_reported() { let result = super::sampler_sample_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_THREW_CXX_EXCEPTION, -1, std::ptr::null_mut(), ); @@ -947,19 +954,23 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_sampler_sample returned unrecognized status")] - fn sampler_sample_status_unrecognized_panics() { - let _result = super::sampler_sample_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_NULL_CTX_ARG, - -1, - std::ptr::null_mut(), + fn sampler_sample_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + super::sampler_sample_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_NULL_CTX_ARG, + -1, + std::ptr::null_mut(), + ), + Err(SampleError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_NULL_CTX_ARG + }), ); } #[test] fn sampler_init_grammar_status_null_maps_to_grammar_malformed() { let result = super::sampler_init_grammar_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_RETURNED_NULL, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_COMPILATION_FAILED, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -981,7 +992,7 @@ mod tests { #[test] fn sampler_init_grammar_status_exception_maps_to_reported() { let result = super::sampler_init_grammar_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -995,19 +1006,21 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_sampler_init_grammar returned unrecognized status")] - fn sampler_init_grammar_status_unrecognized_panics() { - let _result = super::sampler_init_grammar_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_NULL_OUT_SAMPLER_ARG, - std::ptr::null_mut(), - std::ptr::null_mut(), - ); + fn sampler_init_grammar_status_unrecognized_returns_unrecognized_status_error() { + assert!(matches!( + super::sampler_init_grammar_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_NULL_OUT_SAMPLER_ARG, + std::ptr::null_mut(), + std::ptr::null_mut(), + ), + Err(GrammarError::UnrecognizedStatusCode { .. }) + )); } #[test] fn sampler_init_grammar_lazy_status_null_maps_to_lazy_grammar_malformed() { let result = super::sampler_init_grammar_lazy_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_RETURNED_NULL, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_COMPILATION_FAILED, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -1029,7 +1042,7 @@ mod tests { #[test] fn sampler_init_grammar_lazy_status_exception_maps_to_reported() { let result = super::sampler_init_grammar_lazy_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -1043,19 +1056,21 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_sampler_init_grammar_lazy returned unrecognized status")] - fn sampler_init_grammar_lazy_status_unrecognized_panics() { - let _result = super::sampler_init_grammar_lazy_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_NULL_OUT_SAMPLER_ARG, - std::ptr::null_mut(), - std::ptr::null_mut(), - ); + fn sampler_init_grammar_lazy_status_unrecognized_returns_unrecognized_status_error() { + assert!(matches!( + super::sampler_init_grammar_lazy_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_NULL_OUT_SAMPLER_ARG, + std::ptr::null_mut(), + std::ptr::null_mut(), + ), + Err(GrammarError::UnrecognizedStatusCode { .. }) + )); } #[test] fn sampler_init_grammar_lazy_patterns_status_null_maps_to_lazy_patterns_grammar_malformed() { let result = super::sampler_init_grammar_lazy_patterns_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_RETURNED_NULL, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_COMPILATION_FAILED, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -1080,7 +1095,7 @@ mod tests { #[test] fn sampler_init_grammar_lazy_patterns_status_exception_maps_to_reported() { let result = super::sampler_init_grammar_lazy_patterns_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_THREW_CXX_EXCEPTION, std::ptr::null_mut(), std::ptr::null_mut(), ); @@ -1094,15 +1109,15 @@ mod tests { } #[test] - #[should_panic( - expected = "llama_rs_sampler_init_grammar_lazy_patterns returned unrecognized status" - )] - fn sampler_init_grammar_lazy_patterns_status_unrecognized_panics() { - let _result = super::sampler_init_grammar_lazy_patterns_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_NULL_OUT_SAMPLER_ARG, - std::ptr::null_mut(), - std::ptr::null_mut(), - ); + fn sampler_init_grammar_lazy_patterns_status_unrecognized_returns_error() { + assert!(matches!( + super::sampler_init_grammar_lazy_patterns_status_to_result( + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_INIT_GRAMMAR_LAZY_PATTERNS_NULL_OUT_SAMPLER_ARG, + std::ptr::null_mut(), + std::ptr::null_mut(), + ), + Err(GrammarError::UnrecognizedStatusCode { .. }) + )); } #[test] diff --git a/llama-cpp-bindings/src/token/data_array.rs b/llama-cpp-bindings/src/token/data_array.rs index 8d66cfb6..f989565b 100644 --- a/llama-cpp-bindings/src/token/data_array.rs +++ b/llama-cpp-bindings/src/token/data_array.rs @@ -1,7 +1,7 @@ use std::ptr; -use crate::error::SamplerApplyError; -use crate::error::TokenSamplingError; +use crate::error::sampler_apply_error::SamplerApplyError; +use crate::error::token_sampling_error::TokenSamplingError; use crate::sampling::LlamaSampler; use crate::token::data::LlamaTokenData; @@ -19,13 +19,11 @@ fn sampler_apply_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_APPLY_ERROR_STRING_ALLOCATION_FAILED => { Err(SamplerApplyError::NotEnoughMemory) } - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_APPLY_VENDORED_THREW_CXX_EXCEPTION => { + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_APPLY_THREW_CXX_EXCEPTION => { let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(SamplerApplyError::Reported { message }) } - other => { - unreachable!("llama_rs_sampler_apply returned unrecognized status {other}") - } + other => Err(SamplerApplyError::UnrecognizedStatusCode { code: other }), } } @@ -118,8 +116,8 @@ impl LlamaTokenDataArray { /// # Errors /// - /// Returns [`SamplerApplyError`] if the sampler pointer is null, the vendored - /// sampler runs out of memory, or it throws a C++ exception while applying. + /// Returns [`SamplerApplyError`] if the sampler pointer is null, the sampler + /// runs out of memory, or it throws a C++ exception while applying. pub fn apply_sampler(&mut self, sampler: &LlamaSampler) -> Result<(), SamplerApplyError> { unsafe { self.modify_as_c_llama_token_data_array(|c_llama_token_data_array| { @@ -162,7 +160,7 @@ impl LlamaTokenDataArray { #[cfg(test)] mod tests { - use crate::error::SamplerApplyError; + use crate::error::sampler_apply_error::SamplerApplyError; use crate::token::LlamaToken; use crate::token::data::LlamaTokenData; @@ -184,7 +182,7 @@ mod tests { fn sampler_apply_status_cxx_exception_returns_reported_with_unknown_message() { assert_eq!( sampler_apply_status_to_result( - llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_APPLY_VENDORED_THREW_CXX_EXCEPTION, + llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_APPLY_THREW_CXX_EXCEPTION, std::ptr::null_mut(), ), Err(SamplerApplyError::Reported { @@ -194,11 +192,15 @@ mod tests { } #[test] - #[should_panic(expected = "llama_rs_sampler_apply returned unrecognized status")] - fn sampler_apply_status_unrecognized_panics() { - let _ = sampler_apply_status_to_result( - llama_cpp_bindings_sys::llama_rs_sampler_apply_status::MAX, - std::ptr::null_mut(), + fn sampler_apply_status_unrecognized_returns_unrecognized_status_error() { + assert_eq!( + sampler_apply_status_to_result( + llama_cpp_bindings_sys::llama_rs_sampler_apply_status::MAX, + std::ptr::null_mut(), + ), + Err(SamplerApplyError::UnrecognizedStatusCode { + code: llama_cpp_bindings_sys::llama_rs_sampler_apply_status::MAX + }), ); } diff --git a/llama-cpp-bindings/src/tool_call_format/bracketed_args.rs b/llama-cpp-bindings/src/tool_call_format/bracketed_args.rs index 53c5d868..5f179895 100644 --- a/llama-cpp-bindings/src/tool_call_format/bracketed_args.rs +++ b/llama-cpp-bindings/src/tool_call_format/bracketed_args.rs @@ -1,9 +1,9 @@ -use llama_cpp_bindings_types::BracketedJsonShape; -use llama_cpp_bindings_types::ParsedToolCall; -use llama_cpp_bindings_types::ToolCallArguments; -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::bracketed_json_shape::BracketedJsonShape; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; -use crate::error::BracketedArgsFailure; +use crate::error::bracketed_args_failure::BracketedArgsFailure; enum ParseStep<'body> { Done, @@ -109,14 +109,14 @@ pub fn parse( #[cfg(test)] mod tests { - use llama_cpp_bindings_types::BracketedJsonShape; - use llama_cpp_bindings_types::ToolCallArgsShape; - use llama_cpp_bindings_types::ToolCallArguments; - use llama_cpp_bindings_types::ToolCallMarkers; + use llama_cpp_bindings_types::bracketed_json_shape::BracketedJsonShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; use serde_json::json; use super::parse; - use crate::error::BracketedArgsFailure; + use crate::error::bracketed_args_failure::BracketedArgsFailure; fn mistral3_markers() -> ToolCallMarkers { ToolCallMarkers { diff --git a/llama-cpp-bindings/src/tool_call_format/json_object.rs b/llama-cpp-bindings/src/tool_call_format/json_object.rs index 19c206bd..1d04f2de 100644 --- a/llama-cpp-bindings/src/tool_call_format/json_object.rs +++ b/llama-cpp-bindings/src/tool_call_format/json_object.rs @@ -1,8 +1,8 @@ -use llama_cpp_bindings_types::JsonObjectShape; -use llama_cpp_bindings_types::ParsedToolCall; -use llama_cpp_bindings_types::ToolCallArguments; +use llama_cpp_bindings_types::json_object_shape::JsonObjectShape; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; -use crate::error::JsonObjectFailure; +use crate::error::json_object_failure::JsonObjectFailure; fn try_parse_one_object( input: &str, @@ -78,12 +78,12 @@ pub fn parse( #[cfg(test)] mod tests { - use llama_cpp_bindings_types::JsonObjectShape; - use llama_cpp_bindings_types::ToolCallArguments; + use llama_cpp_bindings_types::json_object_shape::JsonObjectShape; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; use serde_json::json; use super::parse; - use crate::error::JsonObjectFailure; + use crate::error::json_object_failure::JsonObjectFailure; fn qwen3_shape() -> JsonObjectShape { JsonObjectShape { diff --git a/llama-cpp-bindings/src/tool_call_format/key_value_xml_tags.rs b/llama-cpp-bindings/src/tool_call_format/key_value_xml_tags.rs index d69e1f26..09d8be79 100644 --- a/llama-cpp-bindings/src/tool_call_format/key_value_xml_tags.rs +++ b/llama-cpp-bindings/src/tool_call_format/key_value_xml_tags.rs @@ -1,12 +1,12 @@ -use llama_cpp_bindings_types::KeyValueXmlTagsShape; -use llama_cpp_bindings_types::ParsedToolCall; -use llama_cpp_bindings_types::ToolCallArguments; -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::key_value_xml_tags_shape::KeyValueXmlTagsShape; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; use nom::IResult; use nom::Parser; use nom::bytes::complete::take_until; -use crate::error::KeyValueXmlTagsFailure; +use crate::error::key_value_xml_tags_failure::KeyValueXmlTagsFailure; enum ParseStep<'body> { Done, @@ -172,14 +172,14 @@ pub fn parse( #[cfg(test)] mod tests { - use llama_cpp_bindings_types::KeyValueXmlTagsShape; - use llama_cpp_bindings_types::ToolCallArgsShape; - use llama_cpp_bindings_types::ToolCallArguments; - use llama_cpp_bindings_types::ToolCallMarkers; + use llama_cpp_bindings_types::key_value_xml_tags_shape::KeyValueXmlTagsShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; use serde_json::json; use super::parse; - use crate::error::KeyValueXmlTagsFailure; + use crate::error::key_value_xml_tags_failure::KeyValueXmlTagsFailure; fn glm47_markers() -> ToolCallMarkers { ToolCallMarkers { diff --git a/llama-cpp-bindings/src/tool_call_format/mod.rs b/llama-cpp-bindings/src/tool_call_format/mod.rs index 0cbafd8e..8aa36c66 100644 --- a/llama-cpp-bindings/src/tool_call_format/mod.rs +++ b/llama-cpp-bindings/src/tool_call_format/mod.rs @@ -5,12 +5,11 @@ pub mod paired_quote_args; pub mod tool_call_format_outcome; pub mod xml_function_tags; -pub use self::tool_call_format_outcome::ToolCallFormatOutcome; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; -use llama_cpp_bindings_types::ToolCallArgsShape; -use llama_cpp_bindings_types::ToolCallMarkers; - -use crate::error::ToolCallFormatFailure; +use crate::error::tool_call_format_failure::ToolCallFormatFailure; +use crate::tool_call_format::tool_call_format_outcome::ToolCallFormatOutcome; #[must_use] pub fn try_parse(body: &str, markers: &ToolCallMarkers) -> ToolCallFormatOutcome { @@ -43,21 +42,21 @@ pub fn try_parse(body: &str, markers: &ToolCallMarkers) -> ToolCallFormatOutcome #[cfg(test)] mod tests { - use llama_cpp_bindings_types::BracketedJsonShape; - use llama_cpp_bindings_types::KeyValueXmlTagsShape; - use llama_cpp_bindings_types::PairedQuoteShape; - use llama_cpp_bindings_types::ParsedToolCall; - use llama_cpp_bindings_types::ToolCallArgsShape; - use llama_cpp_bindings_types::ToolCallArguments; - use llama_cpp_bindings_types::ToolCallMarkers; - use llama_cpp_bindings_types::ToolCallValueQuote; - use llama_cpp_bindings_types::XmlTagsShape; + use llama_cpp_bindings_types::bracketed_json_shape::BracketedJsonShape; + use llama_cpp_bindings_types::key_value_xml_tags_shape::KeyValueXmlTagsShape; + use llama_cpp_bindings_types::paired_quote_shape::PairedQuoteShape; + use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; + use llama_cpp_bindings_types::tool_call_value_quote::ToolCallValueQuote; + use llama_cpp_bindings_types::xml_tags_shape::XmlTagsShape; use serde_json::json; - use super::ToolCallFormatOutcome; + use super::tool_call_format_outcome::ToolCallFormatOutcome; use super::try_parse; - use crate::error::BracketedArgsFailure; - use crate::error::ToolCallFormatFailure; + use crate::error::bracketed_args_failure::BracketedArgsFailure; + use crate::error::tool_call_format_failure::ToolCallFormatFailure; fn mistral3_markers() -> ToolCallMarkers { ToolCallMarkers { @@ -230,7 +229,7 @@ mod tests { #[test] fn try_parse_returns_no_match_for_plain_content_under_every_known_shape() { - use crate::tool_call_template_overrides::known_marker_candidates; + use crate::tool_call_template_overrides::known_marker_candidates::known_marker_candidates; let plain_content = "Sorry, I cannot help with that request."; @@ -245,9 +244,9 @@ mod tests { #[test] fn duck_type_resolves_qwen_xml_input_via_xml_tags_shape_first() { - use llama_cpp_bindings_types::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; - use crate::tool_call_template_overrides::known_marker_candidates; + use crate::tool_call_template_overrides::known_marker_candidates::known_marker_candidates; let qwen_input = "\n\ \n\ @@ -288,9 +287,9 @@ mod tests { #[test] fn duck_type_resolves_glm_input_via_key_value_xml_tags_shape() { - use llama_cpp_bindings_types::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; - use crate::tool_call_template_overrides::known_marker_candidates; + use crate::tool_call_template_overrides::known_marker_candidates::known_marker_candidates; let glm_input = "get_weather\ location\ @@ -327,9 +326,9 @@ mod tests { #[test] fn duck_type_resolves_mistral_input_via_bracketed_json_shape() { - use llama_cpp_bindings_types::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; - use crate::tool_call_template_overrides::known_marker_candidates; + use crate::tool_call_template_overrides::known_marker_candidates::known_marker_candidates; let mistral_input = r#"[TOOL_CALLS]get_weather[ARGS]{"location":"Paris"}"#; @@ -362,9 +361,9 @@ mod tests { #[test] fn duck_type_resolves_gemma_input_via_paired_quote_shape() { - use llama_cpp_bindings_types::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; - use crate::tool_call_template_overrides::known_marker_candidates; + use crate::tool_call_template_overrides::known_marker_candidates::known_marker_candidates; let gemma_input = "<|tool_call>call:get_weather{location:<|\"|>Paris<|\"|>}"; diff --git a/llama-cpp-bindings/src/tool_call_format/paired_quote_args.rs b/llama-cpp-bindings/src/tool_call_format/paired_quote_args.rs index 8e1f21a5..3fb3241f 100644 --- a/llama-cpp-bindings/src/tool_call_format/paired_quote_args.rs +++ b/llama-cpp-bindings/src/tool_call_format/paired_quote_args.rs @@ -1,10 +1,10 @@ -use llama_cpp_bindings_types::PairedQuoteShape; -use llama_cpp_bindings_types::ParsedToolCall; -use llama_cpp_bindings_types::ToolCallArguments; -use llama_cpp_bindings_types::ToolCallMarkers; -use llama_cpp_bindings_types::ToolCallValueQuote; +use llama_cpp_bindings_types::paired_quote_shape::PairedQuoteShape; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; +use llama_cpp_bindings_types::tool_call_value_quote::ToolCallValueQuote; -use crate::error::PairedQuoteFailure; +use crate::error::paired_quote_failure::PairedQuoteFailure; enum ParseStep<'body> { Done, @@ -217,15 +217,15 @@ pub fn parse( #[cfg(test)] mod tests { - use llama_cpp_bindings_types::PairedQuoteShape; - use llama_cpp_bindings_types::ToolCallArgsShape; - use llama_cpp_bindings_types::ToolCallArguments; - use llama_cpp_bindings_types::ToolCallMarkers; - use llama_cpp_bindings_types::ToolCallValueQuote; + use llama_cpp_bindings_types::paired_quote_shape::PairedQuoteShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; + use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; + use llama_cpp_bindings_types::tool_call_value_quote::ToolCallValueQuote; use serde_json::json; use super::parse; - use crate::error::PairedQuoteFailure; + use crate::error::paired_quote_failure::PairedQuoteFailure; fn gemma4_markers() -> ToolCallMarkers { ToolCallMarkers { diff --git a/llama-cpp-bindings/src/tool_call_format/tool_call_format_outcome.rs b/llama-cpp-bindings/src/tool_call_format/tool_call_format_outcome.rs index 1791071c..17f9ab86 100644 --- a/llama-cpp-bindings/src/tool_call_format/tool_call_format_outcome.rs +++ b/llama-cpp-bindings/src/tool_call_format/tool_call_format_outcome.rs @@ -1,6 +1,6 @@ -use llama_cpp_bindings_types::ParsedToolCall; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; -use crate::error::ToolCallFormatFailure; +use crate::error::tool_call_format_failure::ToolCallFormatFailure; #[derive(Debug, Eq, PartialEq)] pub enum ToolCallFormatOutcome { diff --git a/llama-cpp-bindings/src/tool_call_format/xml_function_tags.rs b/llama-cpp-bindings/src/tool_call_format/xml_function_tags.rs index 8027d3cd..bc6ae7fa 100644 --- a/llama-cpp-bindings/src/tool_call_format/xml_function_tags.rs +++ b/llama-cpp-bindings/src/tool_call_format/xml_function_tags.rs @@ -1,11 +1,11 @@ -use llama_cpp_bindings_types::ParsedToolCall; -use llama_cpp_bindings_types::ToolCallArguments; -use llama_cpp_bindings_types::XmlTagsShape; +use llama_cpp_bindings_types::parsed_tool_call::ParsedToolCall; +use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; +use llama_cpp_bindings_types::xml_tags_shape::XmlTagsShape; use nom::IResult; use nom::Parser; use nom::bytes::complete::take_until; -use crate::error::XmlFunctionTagsFailure; +use crate::error::xml_function_tags_failure::XmlFunctionTagsFailure; const fn shape_is_complete(shape: &XmlTagsShape) -> bool { !shape.function_open_prefix.is_empty() @@ -174,12 +174,12 @@ pub fn parse( #[cfg(test)] mod tests { - use llama_cpp_bindings_types::ToolCallArguments; - use llama_cpp_bindings_types::XmlTagsShape; + use llama_cpp_bindings_types::tool_call_arguments::ToolCallArguments; + use llama_cpp_bindings_types::xml_tags_shape::XmlTagsShape; use serde_json::json; use super::parse; - use crate::error::XmlFunctionTagsFailure; + use crate::error::xml_function_tags_failure::XmlFunctionTagsFailure; fn xml_shape() -> XmlTagsShape { XmlTagsShape { diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/detect.rs b/llama-cpp-bindings/src/tool_call_template_overrides/detect.rs index 6ee29061..cb2cf945 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/detect.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/detect.rs @@ -1,4 +1,4 @@ -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; use crate::tool_call_template_overrides::gemma4_call_block::Gemma4CallBlockOverride; use crate::tool_call_template_overrides::glm47_key_value_tags::Glm47KeyValueTagsOverride; diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/gemma4_call_block.rs b/llama-cpp-bindings/src/tool_call_template_overrides/gemma4_call_block.rs index 2f206d99..4520442c 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/gemma4_call_block.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/gemma4_call_block.rs @@ -1,7 +1,7 @@ -use llama_cpp_bindings_types::PairedQuoteShape; -use llama_cpp_bindings_types::ToolCallArgsShape; -use llama_cpp_bindings_types::ToolCallMarkers; -use llama_cpp_bindings_types::ToolCallValueQuote; +use llama_cpp_bindings_types::paired_quote_shape::PairedQuoteShape; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; +use llama_cpp_bindings_types::tool_call_value_quote::ToolCallValueQuote; pub struct Gemma4CallBlockOverride; @@ -34,14 +34,14 @@ impl Gemma4CallBlockOverride { #[cfg(test)] mod tests { - use llama_cpp_bindings_types::ToolCallArgsShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; use super::Gemma4CallBlockOverride; #[test] fn detects_gemma4_template_with_tool_call_call_literal() { - use llama_cpp_bindings_types::PairedQuoteShape; - use llama_cpp_bindings_types::ToolCallValueQuote; + use llama_cpp_bindings_types::paired_quote_shape::PairedQuoteShape; + use llama_cpp_bindings_types::tool_call_value_quote::ToolCallValueQuote; let template = "...{{- '<|tool_call>call:' + function['name'] + '{' -}}..."; let markers = diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/glm47_key_value_tags.rs b/llama-cpp-bindings/src/tool_call_template_overrides/glm47_key_value_tags.rs index c10ae862..7e16bcd3 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/glm47_key_value_tags.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/glm47_key_value_tags.rs @@ -1,6 +1,6 @@ -use llama_cpp_bindings_types::KeyValueXmlTagsShape; -use llama_cpp_bindings_types::ToolCallArgsShape; -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::key_value_xml_tags_shape::KeyValueXmlTagsShape; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; pub struct Glm47KeyValueTagsOverride; @@ -32,8 +32,8 @@ impl Glm47KeyValueTagsOverride { #[cfg(test)] mod tests { - use llama_cpp_bindings_types::KeyValueXmlTagsShape; - use llama_cpp_bindings_types::ToolCallArgsShape; + use llama_cpp_bindings_types::key_value_xml_tags_shape::KeyValueXmlTagsShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; use super::Glm47KeyValueTagsOverride; diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/known_marker_candidates.rs b/llama-cpp-bindings/src/tool_call_template_overrides/known_marker_candidates.rs index 735836f6..e651dd58 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/known_marker_candidates.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/known_marker_candidates.rs @@ -1,4 +1,4 @@ -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; use crate::tool_call_template_overrides::gemma4_call_block::Gemma4CallBlockOverride; use crate::tool_call_template_overrides::glm47_key_value_tags::Glm47KeyValueTagsOverride; @@ -21,7 +21,7 @@ pub fn known_marker_candidates() -> Vec { mod tests { use std::collections::HashSet; - use llama_cpp_bindings_types::ToolCallArgsShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; use super::known_marker_candidates; diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/mistral3_arrow_args.rs b/llama-cpp-bindings/src/tool_call_template_overrides/mistral3_arrow_args.rs index 5b41f827..1cd9b273 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/mistral3_arrow_args.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/mistral3_arrow_args.rs @@ -1,6 +1,6 @@ -use llama_cpp_bindings_types::BracketedJsonShape; -use llama_cpp_bindings_types::ToolCallArgsShape; -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::bracketed_json_shape::BracketedJsonShape; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; pub struct Mistral3ArrowArgsOverride; @@ -29,8 +29,8 @@ impl Mistral3ArrowArgsOverride { #[cfg(test)] mod tests { - use llama_cpp_bindings_types::BracketedJsonShape; - use llama_cpp_bindings_types::ToolCallArgsShape; + use llama_cpp_bindings_types::bracketed_json_shape::BracketedJsonShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; use super::Mistral3ArrowArgsOverride; diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/mod.rs b/llama-cpp-bindings/src/tool_call_template_overrides/mod.rs index b8717ad5..f71cc295 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/mod.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/mod.rs @@ -5,6 +5,3 @@ pub mod known_marker_candidates; pub mod mistral3_arrow_args; pub mod qwen3_json_inside_tool_call; pub mod qwen_xml_tags; - -pub use detect::detect; -pub use known_marker_candidates::known_marker_candidates; diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/qwen3_json_inside_tool_call.rs b/llama-cpp-bindings/src/tool_call_template_overrides/qwen3_json_inside_tool_call.rs index 65909d83..15453c2e 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/qwen3_json_inside_tool_call.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/qwen3_json_inside_tool_call.rs @@ -1,6 +1,6 @@ -use llama_cpp_bindings_types::JsonObjectShape; -use llama_cpp_bindings_types::ToolCallArgsShape; -use llama_cpp_bindings_types::ToolCallMarkers; +use llama_cpp_bindings_types::json_object_shape::JsonObjectShape; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; pub struct Qwen3JsonInsideToolCallOverride; @@ -34,8 +34,8 @@ impl Qwen3JsonInsideToolCallOverride { #[cfg(test)] mod tests { - use llama_cpp_bindings_types::JsonObjectShape; - use llama_cpp_bindings_types::ToolCallArgsShape; + use llama_cpp_bindings_types::json_object_shape::JsonObjectShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; use super::Qwen3JsonInsideToolCallOverride; diff --git a/llama-cpp-bindings/src/tool_call_template_overrides/qwen_xml_tags.rs b/llama-cpp-bindings/src/tool_call_template_overrides/qwen_xml_tags.rs index f2ca276f..4ec1d8f8 100644 --- a/llama-cpp-bindings/src/tool_call_template_overrides/qwen_xml_tags.rs +++ b/llama-cpp-bindings/src/tool_call_template_overrides/qwen_xml_tags.rs @@ -1,6 +1,6 @@ -use llama_cpp_bindings_types::ToolCallArgsShape; -use llama_cpp_bindings_types::ToolCallMarkers; -use llama_cpp_bindings_types::XmlTagsShape; +use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; +use llama_cpp_bindings_types::tool_call_markers::ToolCallMarkers; +use llama_cpp_bindings_types::xml_tags_shape::XmlTagsShape; pub struct QwenXmlTagsOverride; @@ -32,8 +32,8 @@ impl QwenXmlTagsOverride { #[cfg(test)] mod tests { - use llama_cpp_bindings_types::ToolCallArgsShape; - use llama_cpp_bindings_types::XmlTagsShape; + use llama_cpp_bindings_types::tool_call_args_shape::ToolCallArgsShape; + use llama_cpp_bindings_types::xml_tags_shape::XmlTagsShape; use super::QwenXmlTagsOverride; diff --git a/llama-cpp-error-recorder/src/lib.rs b/llama-cpp-error-recorder/src/lib.rs index 42dcf41a..1f45894a 100644 --- a/llama-cpp-error-recorder/src/lib.rs +++ b/llama-cpp-error-recorder/src/lib.rs @@ -1,6 +1,13 @@ #![cfg_attr( not(test), - deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) )] mod frame_stack; @@ -8,7 +15,3 @@ mod frame_stack; pub mod error_scope; pub mod record; pub mod recorded_error; - -pub use error_scope::ErrorScope; -pub use record::record; -pub use recorded_error::RecordedError; diff --git a/llama-cpp-gbnf-sys/Cargo.toml b/llama-cpp-gbnf-sys/Cargo.toml new file mode 100644 index 00000000..2cc28072 --- /dev/null +++ b/llama-cpp-gbnf-sys/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "llama-cpp-gbnf-sys" +description = "Raw FFI to the vendored llama.cpp GBNF grammar parser and validator" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +links = "llama_cpp_gbnf" + +[dependencies] +llama-cpp-ggml-sys = { workspace = true } + +[build-dependencies] +llama-cpp-bindings-build = { workspace = true } + +[lints.rust] +unsafe_op_in_unsafe_fn = "warn" +unused_qualifications = "warn" + +[lints.clippy] +all = { level = "deny", priority = -1 } +pedantic = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } +module_name_repetitions = "allow" diff --git a/llama-cpp-gbnf-sys/build.rs b/llama-cpp-gbnf-sys/build.rs new file mode 100644 index 00000000..176745d6 --- /dev/null +++ b/llama-cpp-gbnf-sys/build.rs @@ -0,0 +1,3 @@ +fn main() { + llama_cpp_bindings_build::build_gbnf::build_gbnf(); +} diff --git a/llama-cpp-gbnf-sys/src/lib.rs b/llama-cpp-gbnf-sys/src/lib.rs new file mode 100644 index 00000000..00c098f9 --- /dev/null +++ b/llama-cpp-gbnf-sys/src/lib.rs @@ -0,0 +1,64 @@ +use core::ffi::c_char; + +#[repr(C)] +pub struct llama_grammar { + _opaque: [u8; 0], +} + +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LlamaRsGbnfParseStatus { + Ok = 0, + SyntaxError, + EmptyRuleSet, + RootSymbolMissing, + LeftRecursion, +} + +unsafe extern "C" { + pub fn llama_rs_gbnf_parse( + grammar_str: *const c_char, + grammar_root: *const c_char, + out_grammar: *mut *mut llama_grammar, + ) -> LlamaRsGbnfParseStatus; + + pub fn llama_rs_gbnf_accept_str( + grammar: *mut llama_grammar, + piece: *const c_char, + piece_len: usize, + ); + + pub fn llama_rs_gbnf_is_accepting(grammar: *mut llama_grammar) -> bool; + + pub fn llama_rs_gbnf_is_rejected(grammar: *mut llama_grammar) -> bool; + + pub fn llama_rs_gbnf_clone(grammar: *const llama_grammar) -> *mut llama_grammar; + + pub fn llama_rs_gbnf_free(grammar: *mut llama_grammar); +} + +#[cfg(test)] +mod tests { + use std::ffi::CString; + use std::ptr; + + use super::LlamaRsGbnfParseStatus; + use super::llama_grammar; + use super::llama_rs_gbnf_free; + use super::llama_rs_gbnf_parse; + + #[test] + fn parse_and_free_links_against_grammar_engine() { + let grammar = CString::new(r#"root ::= "ok""#).expect("grammar has no NUL"); + let root = CString::new("root").expect("root has no NUL"); + let mut out_grammar: *mut llama_grammar = ptr::null_mut(); + + let status = + unsafe { llama_rs_gbnf_parse(grammar.as_ptr(), root.as_ptr(), &raw mut out_grammar) }; + + assert_eq!(status, LlamaRsGbnfParseStatus::Ok); + assert!(!out_grammar.is_null()); + + unsafe { llama_rs_gbnf_free(out_grammar) }; + } +} diff --git a/llama-cpp-gbnf-sys/wrapper_gbnf.cpp b/llama-cpp-gbnf-sys/wrapper_gbnf.cpp new file mode 100644 index 00000000..9eb461f1 --- /dev/null +++ b/llama-cpp-gbnf-sys/wrapper_gbnf.cpp @@ -0,0 +1,89 @@ +#include "wrapper_gbnf.h" + +#include "llama-grammar.h" +#include "unicode.h" + +#include +#include +#include + +extern "C" { + +llama_rs_gbnf_parse_status llama_rs_gbnf_parse( + const char * grammar_str, + const char * grammar_root, + struct llama_grammar ** out_grammar) noexcept { + llama_grammar_parser parser(nullptr); + + if (!parser.parse(grammar_str)) { + return LLAMA_RS_GBNF_PARSE_SYNTAX_ERROR; + } + + if (parser.rules.empty()) { + return LLAMA_RS_GBNF_PARSE_EMPTY_RULE_SET; + } + + const auto root_iterator = parser.symbol_ids.find(grammar_root); + + if (root_iterator == parser.symbol_ids.end()) { + return LLAMA_RS_GBNF_PARSE_ROOT_SYMBOL_MISSING; + } + + auto grammar_rules = parser.c_rules(); + llama_grammar * grammar = llama_grammar_init_impl( + nullptr, + grammar_rules.data(), + grammar_rules.size(), + root_iterator->second); + + if (grammar == nullptr) { + return LLAMA_RS_GBNF_PARSE_LEFT_RECURSION; + } + + *out_grammar = grammar; + + return LLAMA_RS_GBNF_PARSE_OK; +} + +void llama_rs_gbnf_accept_str( + struct llama_grammar * grammar, + const char * piece, + size_t piece_len) noexcept { + const std::string input(piece, piece_len); + const std::vector code_points = unicode_cpts_from_utf8(input); + auto & stacks = llama_grammar_get_stacks(grammar); + + for (const uint32_t code_point : code_points) { + if (stacks.empty()) { + break; + } + + llama_grammar_accept(grammar, code_point); + } +} + +bool llama_rs_gbnf_is_accepting(struct llama_grammar * grammar) noexcept { + auto & stacks = llama_grammar_get_stacks(grammar); + + for (const auto & stack : stacks) { + if (stack.empty()) { + return true; + } + } + + return false; +} + +bool llama_rs_gbnf_is_rejected(struct llama_grammar * grammar) noexcept { + return llama_grammar_get_stacks(grammar).empty(); +} + +struct llama_grammar * llama_rs_gbnf_clone(const struct llama_grammar * grammar) noexcept { + return llama_grammar_clone_impl(*grammar); +} + +void llama_rs_gbnf_free(struct llama_grammar * grammar) noexcept { + llama_grammar_free_impl(grammar); +} + +} diff --git a/llama-cpp-gbnf-sys/wrapper_gbnf.h b/llama-cpp-gbnf-sys/wrapper_gbnf.h new file mode 100644 index 00000000..0926b5ef --- /dev/null +++ b/llama-cpp-gbnf-sys/wrapper_gbnf.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +#define LLAMA_RS_GBNF_NOEXCEPT noexcept +#else +#define LLAMA_RS_GBNF_NOEXCEPT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct llama_grammar; + +typedef enum llama_rs_gbnf_parse_status { + LLAMA_RS_GBNF_PARSE_OK = 0, + LLAMA_RS_GBNF_PARSE_SYNTAX_ERROR, + LLAMA_RS_GBNF_PARSE_EMPTY_RULE_SET, + LLAMA_RS_GBNF_PARSE_ROOT_SYMBOL_MISSING, + LLAMA_RS_GBNF_PARSE_LEFT_RECURSION, +} llama_rs_gbnf_parse_status; + +llama_rs_gbnf_parse_status llama_rs_gbnf_parse( + const char * grammar_str, + const char * grammar_root, + struct llama_grammar ** out_grammar) LLAMA_RS_GBNF_NOEXCEPT; + +void llama_rs_gbnf_accept_str( + struct llama_grammar * grammar, + const char * piece, + size_t piece_len) LLAMA_RS_GBNF_NOEXCEPT; + +bool llama_rs_gbnf_is_accepting(struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; + +bool llama_rs_gbnf_is_rejected(struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; + +struct llama_grammar * llama_rs_gbnf_clone(const struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; + +void llama_rs_gbnf_free(struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; + +#ifdef __cplusplus +} +#endif diff --git a/llama-cpp-gbnf/Cargo.toml b/llama-cpp-gbnf/Cargo.toml new file mode 100644 index 00000000..b9c2b44e --- /dev/null +++ b/llama-cpp-gbnf/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "llama-cpp-gbnf" +description = "Standalone, model-free GBNF grammar validator built on llama.cpp's real parser" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +llama-cpp-gbnf-sys = { workspace = true } +thiserror = { workspace = true } + +[lints.rust] +unsafe_op_in_unsafe_fn = "warn" +unused_qualifications = "warn" + +[lints.clippy] +all = { level = "deny", priority = -1 } +pedantic = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } +module_name_repetitions = "allow" diff --git a/llama-cpp-gbnf/src/gbnf_grammar.rs b/llama-cpp-gbnf/src/gbnf_grammar.rs new file mode 100644 index 00000000..80bccf81 --- /dev/null +++ b/llama-cpp-gbnf/src/gbnf_grammar.rs @@ -0,0 +1,176 @@ +use std::ffi::CString; +use std::ptr; + +use llama_cpp_gbnf_sys::LlamaRsGbnfParseStatus; +use llama_cpp_gbnf_sys::llama_grammar; +use llama_cpp_gbnf_sys::llama_rs_gbnf_clone; +use llama_cpp_gbnf_sys::llama_rs_gbnf_free; +use llama_cpp_gbnf_sys::llama_rs_gbnf_parse; + +use crate::gbnf_matcher::GbnfMatcher; +use crate::gbnf_parse_error::GbnfParseError; +use crate::validation::Validation; + +fn parse_status_to_result( + status: LlamaRsGbnfParseStatus, + grammar: *mut llama_grammar, + root: &str, +) -> Result<*mut llama_grammar, GbnfParseError> { + match status { + LlamaRsGbnfParseStatus::Ok => Ok(grammar), + LlamaRsGbnfParseStatus::SyntaxError => Err(GbnfParseError::SyntaxError), + LlamaRsGbnfParseStatus::EmptyRuleSet => Err(GbnfParseError::EmptyRuleSet), + LlamaRsGbnfParseStatus::RootSymbolMissing => Err(GbnfParseError::RootSymbolMissing { + root: root.to_owned(), + }), + LlamaRsGbnfParseStatus::LeftRecursion => Err(GbnfParseError::LeftRecursion), + } +} + +#[derive(Debug)] +pub struct GbnfGrammar { + handle: *mut llama_grammar, +} + +impl GbnfGrammar { + /// # Errors + /// + /// Returns [`GbnfParseError`] when the grammar or root contains a NUL byte, + /// or the grammar parser rejects the grammar. + pub fn parse(grammar: &str, root: &str) -> Result { + let grammar_cstring = + CString::new(grammar).map_err(GbnfParseError::GrammarStringNulByte)?; + let root_cstring = CString::new(root).map_err(GbnfParseError::RootNameNulByte)?; + + let mut handle: *mut llama_grammar = ptr::null_mut(); + + let status = unsafe { + llama_rs_gbnf_parse( + grammar_cstring.as_ptr(), + root_cstring.as_ptr(), + &raw mut handle, + ) + }; + + Ok(Self { + handle: parse_status_to_result(status, handle, root)?, + }) + } + + #[must_use] + pub fn matcher(&self) -> GbnfMatcher { + let initial = unsafe { llama_rs_gbnf_clone(self.handle) }; + + unsafe { GbnfMatcher::new(initial) } + } + + #[must_use] + pub fn matches(&self, text: &str) -> Validation { + let mut matcher = self.matcher(); + + matcher.feed_str(text); + + if !matcher.is_rejected() && matcher.is_accepting() { + Validation::Accepted + } else { + Validation::Rejected + } + } +} + +impl Drop for GbnfGrammar { + fn drop(&mut self) { + unsafe { llama_rs_gbnf_free(self.handle) }; + } +} + +#[cfg(test)] +mod tests { + use std::ffi::CString; + use std::mem::discriminant; + + use super::GbnfGrammar; + use crate::gbnf_parse_error::GbnfParseError; + use crate::validation::Validation; + + #[test] + fn empty_grammar_returns_empty_rule_set() { + let error = GbnfGrammar::parse("", "root").expect_err("empty grammar is rejected"); + + assert_eq!(error, GbnfParseError::EmptyRuleSet); + } + + #[test] + fn left_recursive_grammar_returns_left_recursion() { + let error = GbnfGrammar::parse(r#"root ::= root "x""#, "root") + .expect_err("left recursion is rejected"); + + assert_eq!(error, GbnfParseError::LeftRecursion); + } + + #[test] + fn valid_grammar_parses() { + GbnfGrammar::parse(r#"root ::= "yes" | "no""#, "root").expect("valid grammar parses"); + } + + #[test] + fn malformed_grammar_returns_syntax_error() { + let error = GbnfGrammar::parse("root ::= (", "root").expect_err("malformed is rejected"); + + assert_eq!(error, GbnfParseError::SyntaxError); + } + + #[test] + fn missing_root_returns_root_symbol_missing() { + let error = + GbnfGrammar::parse(r#"expr ::= "x""#, "root").expect_err("missing root is rejected"); + + assert_eq!( + error, + GbnfParseError::RootSymbolMissing { + root: "root".to_owned() + } + ); + } + + #[test] + fn grammar_with_nul_byte_returns_grammar_string_nul_byte() { + let error = + GbnfGrammar::parse("root ::= \"a\0b\"", "root").expect_err("nul byte is rejected"); + let representative = + GbnfParseError::GrammarStringNulByte(CString::new(b"a\0b".to_vec()).unwrap_err()); + + assert_eq!(discriminant(&error), discriminant(&representative)); + } + + #[test] + fn root_with_nul_byte_returns_root_name_nul_byte() { + let error = + GbnfGrammar::parse(r#"root ::= "x""#, "ro\0ot").expect_err("nul byte is rejected"); + let representative = + GbnfParseError::RootNameNulByte(CString::new(b"ro\0ot".to_vec()).unwrap_err()); + + assert_eq!(discriminant(&error), discriminant(&representative)); + } + + #[test] + fn matches_accepts_text_in_the_language() { + let grammar = GbnfGrammar::parse(r"root ::= [0-9]+", "root").expect("grammar parses"); + + assert_eq!(grammar.matches("123"), Validation::Accepted); + } + + #[test] + fn matches_rejects_text_outside_the_language() { + let grammar = GbnfGrammar::parse(r"root ::= [0-9]+", "root").expect("grammar parses"); + + assert_eq!(grammar.matches("12a"), Validation::Rejected); + } + + #[test] + fn matches_rejects_incomplete_text() { + let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); + + assert_eq!(grammar.matches("ye"), Validation::Rejected); + } +} diff --git a/llama-cpp-gbnf/src/gbnf_matcher.rs b/llama-cpp-gbnf/src/gbnf_matcher.rs new file mode 100644 index 00000000..864eb8e6 --- /dev/null +++ b/llama-cpp-gbnf/src/gbnf_matcher.rs @@ -0,0 +1,96 @@ +use core::ffi::c_char; + +use llama_cpp_gbnf_sys::llama_grammar; +use llama_cpp_gbnf_sys::llama_rs_gbnf_accept_str; +use llama_cpp_gbnf_sys::llama_rs_gbnf_clone; +use llama_cpp_gbnf_sys::llama_rs_gbnf_free; +use llama_cpp_gbnf_sys::llama_rs_gbnf_is_accepting; +use llama_cpp_gbnf_sys::llama_rs_gbnf_is_rejected; + +pub struct GbnfMatcher { + initial: *mut llama_grammar, + current: *mut llama_grammar, +} + +impl GbnfMatcher { + /// # Safety + /// + /// `initial` must be a non-null grammar handle produced by the grammar + /// parser; `GbnfMatcher` takes ownership of it and frees it on drop. + #[must_use] + pub unsafe fn new(initial: *mut llama_grammar) -> Self { + let current = unsafe { llama_rs_gbnf_clone(initial) }; + + Self { initial, current } + } + + pub fn feed_str(&mut self, piece: &str) { + unsafe { + llama_rs_gbnf_accept_str(self.current, piece.as_ptr().cast::(), piece.len()); + } + } + + #[must_use] + pub fn is_accepting(&self) -> bool { + unsafe { llama_rs_gbnf_is_accepting(self.current) } + } + + #[must_use] + pub fn is_rejected(&self) -> bool { + unsafe { llama_rs_gbnf_is_rejected(self.current) } + } + + pub fn reset(&mut self) { + unsafe { llama_rs_gbnf_free(self.current) }; + self.current = unsafe { llama_rs_gbnf_clone(self.initial) }; + } +} + +impl Drop for GbnfMatcher { + fn drop(&mut self) { + unsafe { llama_rs_gbnf_free(self.current) }; + unsafe { llama_rs_gbnf_free(self.initial) }; + } +} + +#[cfg(test)] +mod tests { + use crate::gbnf_grammar::GbnfGrammar; + + #[test] + fn incremental_feed_reaches_accepting_only_when_complete() { + let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); + let mut matcher = grammar.matcher(); + + matcher.feed_str("ye"); + assert!(!matcher.is_accepting()); + assert!(!matcher.is_rejected()); + + matcher.feed_str("s"); + assert!(matcher.is_accepting()); + } + + #[test] + fn feeding_a_violating_piece_rejects() { + let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); + let mut matcher = grammar.matcher(); + + matcher.feed_str("no"); + assert!(matcher.is_rejected()); + } + + #[test] + fn reset_restores_the_initial_state() { + let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); + let mut matcher = grammar.matcher(); + + matcher.feed_str("no"); + assert!(matcher.is_rejected()); + + matcher.reset(); + assert!(!matcher.is_rejected()); + + matcher.feed_str("yes"); + assert!(matcher.is_accepting()); + } +} diff --git a/llama-cpp-gbnf/src/gbnf_parse_error.rs b/llama-cpp-gbnf/src/gbnf_parse_error.rs new file mode 100644 index 00000000..b76ad933 --- /dev/null +++ b/llama-cpp-gbnf/src/gbnf_parse_error.rs @@ -0,0 +1,17 @@ +use std::ffi::NulError; + +#[derive(Debug, thiserror::Error, PartialEq, Eq)] +pub enum GbnfParseError { + #[error("grammar string contains an interior NUL byte")] + GrammarStringNulByte(#[source] NulError), + #[error("grammar root name contains an interior NUL byte")] + RootNameNulByte(#[source] NulError), + #[error("grammar has a syntax error and could not be parsed")] + SyntaxError, + #[error("grammar defines no rules")] + EmptyRuleSet, + #[error("grammar does not define the root symbol {root:?}")] + RootSymbolMissing { root: String }, + #[error("grammar is left-recursive and cannot be compiled into a matcher")] + LeftRecursion, +} diff --git a/llama-cpp-gbnf/src/lib.rs b/llama-cpp-gbnf/src/lib.rs new file mode 100644 index 00000000..c939b52f --- /dev/null +++ b/llama-cpp-gbnf/src/lib.rs @@ -0,0 +1,16 @@ +#![cfg_attr( + not(test), + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) +)] + +pub mod gbnf_grammar; +pub mod gbnf_matcher; +pub mod gbnf_parse_error; +pub mod validation; diff --git a/llama-cpp-gbnf/src/validation.rs b/llama-cpp-gbnf/src/validation.rs new file mode 100644 index 00000000..2222afc8 --- /dev/null +++ b/llama-cpp-gbnf/src/validation.rs @@ -0,0 +1,5 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Validation { + Accepted, + Rejected, +} diff --git a/llama-cpp-ggml-sys/CMakeLists.txt b/llama-cpp-ggml-sys/CMakeLists.txt new file mode 100644 index 00000000..974c0a00 --- /dev/null +++ b/llama-cpp-ggml-sys/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.14) + +project(llama_cpp_ggml_sys C CXX ASM) + +if(NOT DEFINED GGML_SOURCE_DIR) + message(FATAL_ERROR "GGML_SOURCE_DIR must point at the vendored llama.cpp/ggml directory") +endif() + +add_subdirectory(${GGML_SOURCE_DIR} ggml-build) diff --git a/llama-cpp-ggml-sys/Cargo.toml b/llama-cpp-ggml-sys/Cargo.toml new file mode 100644 index 00000000..198088fe --- /dev/null +++ b/llama-cpp-ggml-sys/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "llama-cpp-ggml-sys" +description = "Builds the vendored llama.cpp ggml library once from the shared submodule for reuse" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +links = "ggml" + +[build-dependencies] +llama-cpp-bindings-build = { workspace = true } + +[features] +cuda = ["llama-cpp-bindings-build/cuda"] +cuda-no-vmm = ["llama-cpp-bindings-build/cuda-no-vmm"] +vulkan = ["llama-cpp-bindings-build/vulkan"] +rocm = ["llama-cpp-bindings-build/rocm"] +openmp = ["llama-cpp-bindings-build/openmp"] + +[lints.rust] +unsafe_op_in_unsafe_fn = "warn" +unused_qualifications = "warn" + +[lints.clippy] +all = { level = "deny", priority = -1 } +pedantic = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } +module_name_repetitions = "allow" diff --git a/llama-cpp-ggml-sys/build.rs b/llama-cpp-ggml-sys/build.rs new file mode 100644 index 00000000..d0eeffeb --- /dev/null +++ b/llama-cpp-ggml-sys/build.rs @@ -0,0 +1,3 @@ +fn main() { + llama_cpp_bindings_build::build_ggml::build_ggml(); +} diff --git a/llama-cpp-ggml-sys/src/lib.rs b/llama-cpp-ggml-sys/src/lib.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/llama-cpp-ggml-sys/src/lib.rs @@ -0,0 +1 @@ + diff --git a/llama-cpp-log-decoder/src/lib.rs b/llama-cpp-log-decoder/src/lib.rs index 45be7b52..da73fce8 100644 --- a/llama-cpp-log-decoder/src/lib.rs +++ b/llama-cpp-log-decoder/src/lib.rs @@ -1,6 +1,13 @@ #![cfg_attr( not(test), - deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) )] pub mod decode_anomaly; diff --git a/llama-cpp-test-harness-macros/src/expand.rs b/llama-cpp-test-harness-macros/src/expand.rs index f4da0bd2..dfb413c7 100644 --- a/llama-cpp-test-harness-macros/src/expand.rs +++ b/llama-cpp-test-harness-macros/src/expand.rs @@ -79,13 +79,13 @@ fn split_fn_and_pass_through(items: Vec) -> syn::Result<(ItemFn, Vec fn build_model_source_literal(source: &ParsedSource) -> TokenStream { match source { ParsedSource::HuggingFace { repo, file } => quote! { - ::llama_cpp_test_harness::ModelSource::HuggingFace { + ::llama_cpp_test_harness::model_source::ModelSource::HuggingFace { repo: #repo, file: #file, } }, ParsedSource::LocalPath(path) => quote! { - ::llama_cpp_test_harness::ModelSource::LocalPath(#path) + ::llama_cpp_test_harness::model_source::ModelSource::LocalPath(#path) }, } } @@ -94,13 +94,13 @@ fn build_mmproj_source_literal(source: Option<&ParsedSource>) -> TokenStream { match source { None => quote! { ::core::option::Option::None }, Some(ParsedSource::HuggingFace { repo, file }) => quote! { - ::core::option::Option::Some(::llama_cpp_test_harness::MmprojSource::HuggingFace { + ::core::option::Option::Some(::llama_cpp_test_harness::mmproj_source::MmprojSource::HuggingFace { repo: #repo, file: #file, }) }, Some(ParsedSource::LocalPath(path)) => quote! { - ::core::option::Option::Some(::llama_cpp_test_harness::MmprojSource::LocalPath(#path)) + ::core::option::Option::Some(::llama_cpp_test_harness::mmproj_source::MmprojSource::LocalPath(#path)) }, } } @@ -127,19 +127,19 @@ fn build_registration(args: &ParsedArgs, fn_name: &Ident) -> TokenStream { ); quote! { - ::llama_cpp_test_harness::inventory::submit! { - ::llama_cpp_test_harness::LlamaTestRegistration { + ::inventory::submit! { + ::llama_cpp_test_harness::llama_test_registration::LlamaTestRegistration { name: #trial_name, - key: ::llama_cpp_test_harness::LoadKey { + key: ::llama_cpp_test_harness::load_key::LoadKey { model_source: #model_source_literal, mmproj_source: #mmproj_source_literal, - model_load_params: ::llama_cpp_test_harness::ModelLoadParams { + model_load_params: ::llama_cpp_test_harness::model_load_params::ModelLoadParams { n_gpu_layers: #gpu_layers, use_mmap: #use_mmap, use_mlock: #use_mlock, }, }, - context_params: ::llama_cpp_test_harness::ContextParams { + context_params: ::llama_cpp_test_harness::context_params::ContextParams { n_ctx: #context_size, n_batch: #logical_batch, n_ubatch: #physical_batch, diff --git a/llama-cpp-test-harness-macros/src/lib.rs b/llama-cpp-test-harness-macros/src/lib.rs index 45a42cb6..a115dae3 100644 --- a/llama-cpp-test-harness-macros/src/lib.rs +++ b/llama-cpp-test-harness-macros/src/lib.rs @@ -1,6 +1,13 @@ #![cfg_attr( not(test), - deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) )] mod expand; diff --git a/llama-cpp-test-harness/src/execution_phase.rs b/llama-cpp-test-harness/src/execution_phase.rs index 6892889d..fd4bbd90 100644 --- a/llama-cpp-test-harness/src/execution_phase.rs +++ b/llama-cpp-test-harness/src/execution_phase.rs @@ -6,10 +6,10 @@ use libtest_mimic::Failed; use libtest_mimic::Trial; use llama_cpp_bindings::llama_backend::LlamaBackend; -use crate::ModelSource; use crate::llama_fixture::LlamaFixture; use crate::llama_test_registration::LlamaTestRegistration; use crate::load_key::LoadKey; +use crate::model_source::ModelSource; use crate::phase_state::PhaseState; fn source_label(source: ModelSource) -> String { @@ -83,9 +83,9 @@ impl ExecutionPhase { #[cfg(test)] mod tests { - use crate::ModelSource; use crate::load_key::LoadKey; use crate::model_load_params::ModelLoadParams; + use crate::model_source::ModelSource; use super::ExecutionPhase; diff --git a/llama-cpp-test-harness/src/harness_run_error.rs b/llama-cpp-test-harness/src/harness_run_error.rs index 55a21c5b..a2d2b066 100644 --- a/llama-cpp-test-harness/src/harness_run_error.rs +++ b/llama-cpp-test-harness/src/harness_run_error.rs @@ -1,4 +1,4 @@ -use llama_cpp_bindings::error::LlamaCppError; +use llama_cpp_bindings::error::llama_cpp_error::LlamaCppError; use thiserror::Error; use crate::harness_arguments_error::HarnessArgumentsError; diff --git a/llama-cpp-test-harness/src/lib.rs b/llama-cpp-test-harness/src/lib.rs index bcdeec72..b7f28eb7 100644 --- a/llama-cpp-test-harness/src/lib.rs +++ b/llama-cpp-test-harness/src/lib.rs @@ -1,6 +1,13 @@ #![cfg_attr( not(test), - deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) + deny( + clippy::unwrap_used, + clippy::expect_used, + clippy::panic, + clippy::unreachable, + clippy::todo, + clippy::unimplemented + ) )] pub mod context_params; @@ -24,22 +31,3 @@ pub mod run; pub mod run_to_conclusions; #[cfg(test)] mod test_backend_gate; - -pub use crate::context_params::ContextParams; -pub use crate::execution_phase::ExecutionPhase; -pub use crate::execution_plan::ExecutionPlan; -pub use crate::llama_fixture::LlamaFixture; -pub use crate::llama_test_fn::LlamaTestFn; -pub use crate::llama_test_registration::LlamaTestRegistration; -pub use crate::load_key::LoadKey; -pub use crate::mmproj_source::MmprojSource; -pub use crate::model_load_params::ModelLoadParams; -pub use crate::model_source::ModelSource; -pub use crate::no_op::no_op; -pub use crate::phase_state::PhaseState; -pub use crate::run::run; -pub use crate::run_to_conclusions::run_to_conclusions; -pub use llama_cpp_test_harness_macros::llama_test; - -#[doc(hidden)] -pub use inventory; diff --git a/llama-cpp-test-harness/src/llama_fixture.rs b/llama-cpp-test-harness/src/llama_fixture.rs index f427f8aa..150899b8 100644 --- a/llama-cpp-test-harness/src/llama_fixture.rs +++ b/llama-cpp-test-harness/src/llama_fixture.rs @@ -4,7 +4,7 @@ use anyhow::Result; use llama_cpp_bindings::context::LlamaContext; use llama_cpp_bindings::llama_backend::LlamaBackend; use llama_cpp_bindings::model::LlamaModel; -use llama_cpp_bindings::mtmd::MtmdContext; +use llama_cpp_bindings::mtmd::mtmd_context::MtmdContext; use crate::context_params::ContextParams; diff --git a/llama-cpp-test-harness/src/llama_tests_main_macro.rs b/llama-cpp-test-harness/src/llama_tests_main_macro.rs index 18ed6dab..5ae5434a 100644 --- a/llama-cpp-test-harness/src/llama_tests_main_macro.rs +++ b/llama-cpp-test-harness/src/llama_tests_main_macro.rs @@ -2,7 +2,7 @@ macro_rules! llama_tests_main { () => { fn main() -> ::std::process::ExitCode { - $crate::run() + $crate::run::run() } }; } diff --git a/llama-cpp-test-harness/src/load_key.rs b/llama-cpp-test-harness/src/load_key.rs index 5fad7200..60aedd33 100644 --- a/llama-cpp-test-harness/src/load_key.rs +++ b/llama-cpp-test-harness/src/load_key.rs @@ -3,8 +3,8 @@ use std::sync::Arc; use anyhow::Result; use llama_cpp_bindings::llama_backend::LlamaBackend; use llama_cpp_bindings::model::LlamaModel; -use llama_cpp_bindings::mtmd::MtmdContext; -use llama_cpp_bindings::mtmd::MtmdContextParams; +use llama_cpp_bindings::mtmd::mtmd_context::MtmdContext; +use llama_cpp_bindings::mtmd::mtmd_context_params::MtmdContextParams; use crate::mmproj_source::MmprojSource; use crate::model_load_params::ModelLoadParams; diff --git a/llama-cpp-test-harness/src/phase_state.rs b/llama-cpp-test-harness/src/phase_state.rs index 1993d6a0..5aa52f8a 100644 --- a/llama-cpp-test-harness/src/phase_state.rs +++ b/llama-cpp-test-harness/src/phase_state.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use llama_cpp_bindings::llama_backend::LlamaBackend; use llama_cpp_bindings::model::LlamaModel; -use llama_cpp_bindings::mtmd::MtmdContext; +use llama_cpp_bindings::mtmd::mtmd_context::MtmdContext; pub struct PhaseState { pub mtmd_context: Option, diff --git a/llama-cpp-test-harness/tests/harness_self_test.rs b/llama-cpp-test-harness/tests/harness_self_test.rs index 333e0f4a..3f8f49a6 100644 --- a/llama-cpp-test-harness/tests/harness_self_test.rs +++ b/llama-cpp-test-harness/tests/harness_self_test.rs @@ -2,10 +2,10 @@ use std::process::ExitCode; use anyhow::Result; use anyhow::bail; -use llama_cpp_test_harness::LlamaFixture; -use llama_cpp_test_harness::llama_test; -use llama_cpp_test_harness::no_op; -use llama_cpp_test_harness::run_to_conclusions; +use llama_cpp_test_harness::llama_fixture::LlamaFixture; +use llama_cpp_test_harness::no_op::no_op; +use llama_cpp_test_harness::run_to_conclusions::run_to_conclusions; +use llama_cpp_test_harness_macros::llama_test; #[llama_test( model_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "Qwen3.5-0.8B-Q4_K_M.gguf"), From 2a92d776f4dd43ccf00b8af38e39f9d4214190e7 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 18:38:39 +0200 Subject: [PATCH 02/11] Fix cross-platform CI: drop unused wrapper includes, link ggml-metal on Apple, forward-slash ggml source path --- llama-cpp-bindings-build/src/build_ggml.rs | 11 +++++------ llama-cpp-bindings-build/src/library_linking.rs | 17 +++++++++++++---- llama-cpp-bindings-sys/wrapper_chat_apply.cpp | 2 -- llama-cpp-bindings-sys/wrapper_chat_parse.cpp | 2 -- llama-cpp-bindings-sys/wrapper_common.cpp | 2 -- llama-cpp-bindings-sys/wrapper_fit.cpp | 2 -- llama-cpp-bindings-sys/wrapper_mtmd.cpp | 3 --- llama-cpp-bindings-sys/wrapper_reasoning.cpp | 2 -- llama-cpp-bindings-sys/wrapper_tool_calls.cpp | 2 -- 9 files changed, 18 insertions(+), 25 deletions(-) diff --git a/llama-cpp-bindings-build/src/build_ggml.rs b/llama-cpp-bindings-build/src/build_ggml.rs index b4e003f4..51f69882 100644 --- a/llama-cpp-bindings-build/src/build_ggml.rs +++ b/llama-cpp-bindings-build/src/build_ggml.rs @@ -49,12 +49,11 @@ fn configure_and_install_ggml( ) -> PathBuf { let mut config = Config::new(wrapper_cmake_dir); - config.define( - "GGML_SOURCE_DIR", - ggml_src - .to_str() - .expect("ggml source path must be valid UTF-8"), - ); + let ggml_source_dir = ggml_src + .to_str() + .expect("ggml source path must be valid UTF-8") + .replace('\\', "/"); + config.define("GGML_SOURCE_DIR", &ggml_source_dir); config.define("GGML_BUILD_TESTS", "OFF"); config.define("GGML_BUILD_EXAMPLES", "OFF"); config.cflag("-w"); diff --git a/llama-cpp-bindings-build/src/library_linking.rs b/llama-cpp-bindings-build/src/library_linking.rs index a35bf6ef..f84f390b 100644 --- a/llama-cpp-bindings-build/src/library_linking.rs +++ b/llama-cpp-bindings-build/src/library_linking.rs @@ -18,7 +18,7 @@ pub fn link_libraries( emit_search_paths(cmake_dir, build_dir); link_system_ggml_paths(build_dir); emit_shared_ggml_search_path(ggml_system); - link_cmake_built_libraries(cmake_dir, build_shared_libs, profile); + link_cmake_built_libraries(cmake_dir, build_shared_libs, profile, target_os); link_cuda_libraries(build_shared_libs); link_rocm_libraries(build_shared_libs); link_openmp(target_triple); @@ -74,7 +74,12 @@ fn link_system_ggml_paths(build_dir: &Path) { } } -fn link_cmake_built_libraries(cmake_dir: &Path, build_shared_libs: bool, profile: &str) { +fn link_cmake_built_libraries( + cmake_dir: &Path, + build_shared_libs: bool, + profile: &str, + target_os: &TargetOs, +) { let link_kind = if build_shared_libs { "dylib" } else if cfg!(feature = "system-ggml-static") { @@ -89,7 +94,7 @@ fn link_cmake_built_libraries(cmake_dir: &Path, build_shared_libs: bool, profile assert!(!lib_names.is_empty(), "no libraries found in build output"); link_llama_common_internal_libraries(cmake_dir, profile); - link_system_ggml_libraries(link_kind); + link_system_ggml_libraries(link_kind, target_os); for lib_name in lib_names { let link = format!("cargo:rustc-link-lib={link_kind}={lib_name}"); @@ -124,7 +129,7 @@ fn emit_search_path_with_profile(lib_dir: &Path, profile: &str) { } } -fn link_system_ggml_libraries(link_kind: &str) { +fn link_system_ggml_libraries(link_kind: &str, target_os: &TargetOs) { if !cfg!(feature = "system-ggml") { return; } @@ -144,6 +149,10 @@ fn link_system_ggml_libraries(link_kind: &str) { if cfg!(feature = "rocm") { println!("cargo:rustc-link-lib={link_kind}=ggml-hip"); } + + if let TargetOs::Apple(_) = target_os { + println!("cargo:rustc-link-lib={link_kind}=ggml-metal"); + } } fn link_cuda_libraries(build_shared_libs: bool) { diff --git a/llama-cpp-bindings-sys/wrapper_chat_apply.cpp b/llama-cpp-bindings-sys/wrapper_chat_apply.cpp index 46a696c3..2ded0b76 100644 --- a/llama-cpp-bindings-sys/wrapper_chat_apply.cpp +++ b/llama-cpp-bindings-sys/wrapper_chat_apply.cpp @@ -8,9 +8,7 @@ #include "wrapper_utils.h" #include -#include #include -#include #include #include #include diff --git a/llama-cpp-bindings-sys/wrapper_chat_parse.cpp b/llama-cpp-bindings-sys/wrapper_chat_parse.cpp index 5ceaadeb..7021728e 100644 --- a/llama-cpp-bindings-sys/wrapper_chat_parse.cpp +++ b/llama-cpp-bindings-sys/wrapper_chat_parse.cpp @@ -10,9 +10,7 @@ #include "wrapper_utils.h" #include -#include #include -#include #include #include diff --git a/llama-cpp-bindings-sys/wrapper_common.cpp b/llama-cpp-bindings-sys/wrapper_common.cpp index d784d3cf..aa45db18 100644 --- a/llama-cpp-bindings-sys/wrapper_common.cpp +++ b/llama-cpp-bindings-sys/wrapper_common.cpp @@ -3,10 +3,8 @@ #include #include #include -#include #include #include -#include #include #include #include diff --git a/llama-cpp-bindings-sys/wrapper_fit.cpp b/llama-cpp-bindings-sys/wrapper_fit.cpp index 1659c719..9d021d8a 100644 --- a/llama-cpp-bindings-sys/wrapper_fit.cpp +++ b/llama-cpp-bindings-sys/wrapper_fit.cpp @@ -5,8 +5,6 @@ #include #include -#include -#include #include "llama.cpp/common/fit.h" diff --git a/llama-cpp-bindings-sys/wrapper_mtmd.cpp b/llama-cpp-bindings-sys/wrapper_mtmd.cpp index 952892d5..02d1862b 100644 --- a/llama-cpp-bindings-sys/wrapper_mtmd.cpp +++ b/llama-cpp-bindings-sys/wrapper_mtmd.cpp @@ -6,9 +6,6 @@ #include #include -#include -#include -#include extern "C" auto llama_rs_mtmd_init_from_file( const char * mmproj_path, diff --git a/llama-cpp-bindings-sys/wrapper_reasoning.cpp b/llama-cpp-bindings-sys/wrapper_reasoning.cpp index f314665e..3b1b0bea 100644 --- a/llama-cpp-bindings-sys/wrapper_reasoning.cpp +++ b/llama-cpp-bindings-sys/wrapper_reasoning.cpp @@ -7,9 +7,7 @@ #include #include "wrapper_utils.h" -#include #include -#include #include #include diff --git a/llama-cpp-bindings-sys/wrapper_tool_calls.cpp b/llama-cpp-bindings-sys/wrapper_tool_calls.cpp index 624b649a..d716f8c3 100644 --- a/llama-cpp-bindings-sys/wrapper_tool_calls.cpp +++ b/llama-cpp-bindings-sys/wrapper_tool_calls.cpp @@ -9,9 +9,7 @@ #include "llama.cpp/include/llama.h" #include "wrapper_utils.h" -#include #include -#include #include using wrapper_helpers::token_text_or_empty; From 7eb1ef90facea7e940989f63e9b8fdf8773bbbf7 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 18:50:14 +0200 Subject: [PATCH 03/11] Use i64 for UnrecognizedStatusCode code so it fits MSVC signed enum aliases --- llama-cpp-bindings/src/context.rs | 40 +++++++--- llama-cpp-bindings/src/context/kv_cache.rs | 12 ++- .../src/error/apply_chat_template_error.rs | 2 +- llama-cpp-bindings/src/error/decode_error.rs | 2 +- llama-cpp-bindings/src/error/encode_error.rs | 2 +- llama-cpp-bindings/src/error/fit_error.rs | 2 +- llama-cpp-bindings/src/error/grammar_error.rs | 2 +- .../src/error/json_schema_to_grammar_error.rs | 2 +- .../src/error/kv_cache_seq_add_error.rs | 2 +- .../src/error/kv_cache_seq_div_error.rs | 2 +- .../src/error/llama_context_load_error.rs | 2 +- .../src/error/llama_model_load_error.rs | 2 +- .../src/error/marker_detection_error.rs | 2 +- .../src/error/parse_chat_message_error.rs | 2 +- llama-cpp-bindings/src/error/sample_error.rs | 2 +- .../src/error/sampler_accept_error.rs | 2 +- .../src/error/sampler_apply_error.rs | 2 +- .../src/error/string_to_token_error.rs | 2 +- .../src/json_schema_to_grammar.rs | 8 +- llama-cpp-bindings/src/model.rs | 74 ++++++++++++------- llama-cpp-bindings/src/model/params.rs | 6 +- llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs | 2 +- .../src/mtmd/mtmd_bitmap_error.rs | 2 +- llama-cpp-bindings/src/mtmd/mtmd_context.rs | 20 +++-- .../src/mtmd/mtmd_encode_error.rs | 2 +- .../src/mtmd/mtmd_eval_error.rs | 2 +- .../src/mtmd/mtmd_init_error.rs | 2 +- .../src/mtmd/mtmd_input_chunk.rs | 8 +- .../src/mtmd/mtmd_tokenize_error.rs | 2 +- llama-cpp-bindings/src/sampling.rs | 20 +++-- llama-cpp-bindings/src/token/data_array.rs | 6 +- 31 files changed, 150 insertions(+), 88 deletions(-) diff --git a/llama-cpp-bindings/src/context.rs b/llama-cpp-bindings/src/context.rs index 17e9e2e2..f41bc5b1 100644 --- a/llama-cpp-bindings/src/context.rs +++ b/llama-cpp-bindings/src/context.rs @@ -59,7 +59,9 @@ fn new_context_with_model_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(LlamaContextLoadError::Reported { message }) } - other => Err(LlamaContextLoadError::UnrecognizedStatusCode { code: other }), + other => Err(LlamaContextLoadError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -71,8 +73,12 @@ fn decode_status_to_result( match status { llama_cpp_bindings_sys::LLAMA_RS_DECODE_OK => Ok(()), llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE => { - NonZeroI32::new(out_return_code).map_or( - Err(DecodeError::UnrecognizedStatusCode { code: status }), + NonZeroI32::new(out_return_code).map_or_else( + || { + Err(DecodeError::UnrecognizedStatusCode { + code: i64::from(status), + }) + }, |code| Err(DecodeError::from(code)), ) } @@ -87,7 +93,9 @@ fn decode_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(DecodeError::Reported { message }) } - other => Err(DecodeError::UnrecognizedStatusCode { code: other }), + other => Err(DecodeError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -102,8 +110,12 @@ fn encode_status_to_result( Err(EncodeError::ModelHasNoEncoder) } llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE => { - NonZeroI32::new(out_return_code).map_or( - Err(EncodeError::UnrecognizedStatusCode { code: status }), + NonZeroI32::new(out_return_code).map_or_else( + || { + Err(EncodeError::UnrecognizedStatusCode { + code: i64::from(status), + }) + }, |code| Err(EncodeError::from(code)), ) } @@ -118,7 +130,9 @@ fn encode_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(EncodeError::Reported { message }) } - other => Err(EncodeError::UnrecognizedStatusCode { code: other }), + other => Err(EncodeError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -608,7 +622,9 @@ mod unit_tests { std::ptr::null_mut(), ), Err(LlamaContextLoadError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_new_context_with_model_status::MAX + code: i64::from( + llama_cpp_bindings_sys::llama_rs_new_context_with_model_status::MAX + ) }), ); } @@ -682,7 +698,7 @@ mod unit_tests { std::ptr::null_mut(), ), Err(DecodeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE, + code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE) }), ); } @@ -696,7 +712,7 @@ mod unit_tests { std::ptr::null_mut(), ), Err(DecodeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_decode_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_decode_status::MAX) }), ); } @@ -781,7 +797,7 @@ mod unit_tests { std::ptr::null_mut(), ), Err(EncodeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE, + code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE) }), ); } @@ -795,7 +811,7 @@ mod unit_tests { std::ptr::null_mut(), ), Err(EncodeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_encode_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_encode_status::MAX) }), ); } diff --git a/llama-cpp-bindings/src/context/kv_cache.rs b/llama-cpp-bindings/src/context/kv_cache.rs index dcb3c245..997c9b3f 100644 --- a/llama-cpp-bindings/src/context/kv_cache.rs +++ b/llama-cpp-bindings/src/context/kv_cache.rs @@ -37,7 +37,9 @@ fn kv_cache_seq_add_status_to_result( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(KvCacheSeqAddError::Reported { message }) } - other => Err(KvCacheSeqAddError::UnrecognizedStatusCode { code: other }), + other => Err(KvCacheSeqAddError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -60,7 +62,9 @@ fn kv_cache_seq_div_status_to_result( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(KvCacheSeqDivError::Reported { message }) } - other => Err(KvCacheSeqDivError::UnrecognizedStatusCode { code: other }), + other => Err(KvCacheSeqDivError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -265,7 +269,7 @@ mod tests { ptr::null_mut(), ), Err(KvCacheSeqAddError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_memory_seq_add_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_memory_seq_add_status::MAX) }), ); } @@ -334,7 +338,7 @@ mod tests { ptr::null_mut(), ), Err(KvCacheSeqDivError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_memory_seq_div_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_memory_seq_div_status::MAX) }), ); } diff --git a/llama-cpp-bindings/src/error/apply_chat_template_error.rs b/llama-cpp-bindings/src/error/apply_chat_template_error.rs index 3ae79340..a742b681 100644 --- a/llama-cpp-bindings/src/error/apply_chat_template_error.rs +++ b/llama-cpp-bindings/src/error/apply_chat_template_error.rs @@ -9,5 +9,5 @@ pub enum ApplyChatTemplateError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/decode_error.rs b/llama-cpp-bindings/src/error/decode_error.rs index 70d8b362..9cfac07f 100644 --- a/llama-cpp-bindings/src/error/decode_error.rs +++ b/llama-cpp-bindings/src/error/decode_error.rs @@ -20,7 +20,7 @@ pub enum DecodeError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } impl From for DecodeError { diff --git a/llama-cpp-bindings/src/error/encode_error.rs b/llama-cpp-bindings/src/error/encode_error.rs index 09869a7f..5863841c 100644 --- a/llama-cpp-bindings/src/error/encode_error.rs +++ b/llama-cpp-bindings/src/error/encode_error.rs @@ -20,7 +20,7 @@ pub enum EncodeError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } impl From for EncodeError { diff --git a/llama-cpp-bindings/src/error/fit_error.rs b/llama-cpp-bindings/src/error/fit_error.rs index 86337996..1525bfd8 100644 --- a/llama-cpp-bindings/src/error/fit_error.rs +++ b/llama-cpp-bindings/src/error/fit_error.rs @@ -11,5 +11,5 @@ pub enum FitError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/grammar_error.rs b/llama-cpp-bindings/src/error/grammar_error.rs index 0605683c..1097ae38 100644 --- a/llama-cpp-bindings/src/error/grammar_error.rs +++ b/llama-cpp-bindings/src/error/grammar_error.rs @@ -33,5 +33,5 @@ pub enum GrammarError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs b/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs index 7bbe5052..7d66db25 100644 --- a/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs +++ b/llama-cpp-bindings/src/error/json_schema_to_grammar_error.rs @@ -14,5 +14,5 @@ pub enum JsonSchemaToGrammarError { #[error("grammar returned by json_schema_to_grammar is not valid UTF-8")] GrammarNotUtf8(#[from] FromUtf8Error), #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs b/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs index 64718a29..f3d60475 100644 --- a/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs +++ b/llama-cpp-bindings/src/error/kv_cache_seq_add_error.rs @@ -15,5 +15,5 @@ pub enum KvCacheSeqAddError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs b/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs index 6e274f0f..b676c6ed 100644 --- a/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs +++ b/llama-cpp-bindings/src/error/kv_cache_seq_div_error.rs @@ -15,5 +15,5 @@ pub enum KvCacheSeqDivError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/llama_context_load_error.rs b/llama-cpp-bindings/src/error/llama_context_load_error.rs index 1e0189a5..fecc7778 100644 --- a/llama-cpp-bindings/src/error/llama_context_load_error.rs +++ b/llama-cpp-bindings/src/error/llama_context_load_error.rs @@ -7,5 +7,5 @@ pub enum LlamaContextLoadError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/llama_model_load_error.rs b/llama-cpp-bindings/src/error/llama_model_load_error.rs index c106c938..62390a0a 100644 --- a/llama-cpp-bindings/src/error/llama_model_load_error.rs +++ b/llama-cpp-bindings/src/error/llama_model_load_error.rs @@ -16,5 +16,5 @@ pub enum LlamaModelLoadError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/marker_detection_error.rs b/llama-cpp-bindings/src/error/marker_detection_error.rs index ae266536..f0aec6e1 100644 --- a/llama-cpp-bindings/src/error/marker_detection_error.rs +++ b/llama-cpp-bindings/src/error/marker_detection_error.rs @@ -23,5 +23,5 @@ pub enum MarkerDetectionError { #[error("the chat template could not be retrieved for tool-call marker detection: {0}")] ChatTemplateUnavailable(#[source] ChatTemplateError), #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/parse_chat_message_error.rs b/llama-cpp-bindings/src/error/parse_chat_message_error.rs index 816472fb..461d47f8 100644 --- a/llama-cpp-bindings/src/error/parse_chat_message_error.rs +++ b/llama-cpp-bindings/src/error/parse_chat_message_error.rs @@ -36,5 +36,5 @@ pub enum ParseChatMessageError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/sample_error.rs b/llama-cpp-bindings/src/error/sample_error.rs index 889e6a6c..d7dc6476 100644 --- a/llama-cpp-bindings/src/error/sample_error.rs +++ b/llama-cpp-bindings/src/error/sample_error.rs @@ -14,5 +14,5 @@ pub enum SampleError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/sampler_accept_error.rs b/llama-cpp-bindings/src/error/sampler_accept_error.rs index 0df1db3f..6ebcacfd 100644 --- a/llama-cpp-bindings/src/error/sampler_accept_error.rs +++ b/llama-cpp-bindings/src/error/sampler_accept_error.rs @@ -7,5 +7,5 @@ pub enum SamplerAcceptError { #[error("the grammar sampler callback failed during accept: {message}")] GrammarCallbackFailed { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/sampler_apply_error.rs b/llama-cpp-bindings/src/error/sampler_apply_error.rs index 0a10f4d7..65e291ae 100644 --- a/llama-cpp-bindings/src/error/sampler_apply_error.rs +++ b/llama-cpp-bindings/src/error/sampler_apply_error.rs @@ -7,5 +7,5 @@ pub enum SamplerApplyError { #[error("the sampler threw a C++ exception while applying to the token data array: {message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/string_to_token_error.rs b/llama-cpp-bindings/src/error/string_to_token_error.rs index 6769bbba..ef022fa5 100644 --- a/llama-cpp-bindings/src/error/string_to_token_error.rs +++ b/llama-cpp-bindings/src/error/string_to_token_error.rs @@ -11,5 +11,5 @@ pub enum StringToTokenError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/json_schema_to_grammar.rs b/llama-cpp-bindings/src/json_schema_to_grammar.rs index 83abab8a..6f7b237c 100644 --- a/llama-cpp-bindings/src/json_schema_to_grammar.rs +++ b/llama-cpp-bindings/src/json_schema_to_grammar.rs @@ -31,7 +31,9 @@ unsafe fn json_schema_to_grammar_status_to_result( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(JsonSchemaToGrammarError::Reported { message }) } - other => Err(JsonSchemaToGrammarError::UnrecognizedStatusCode { code: other }), + other => Err(JsonSchemaToGrammarError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -227,7 +229,9 @@ mod tests { ) }, Err(JsonSchemaToGrammarError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_json_schema_to_grammar_status::MAX + code: i64::from( + llama_cpp_bindings_sys::llama_rs_json_schema_to_grammar_status::MAX + ) }), ); } diff --git a/llama-cpp-bindings/src/model.rs b/llama-cpp-bindings/src/model.rs index f5fd8a54..f06fbcd6 100644 --- a/llama-cpp-bindings/src/model.rs +++ b/llama-cpp-bindings/src/model.rs @@ -148,7 +148,9 @@ unsafe fn load_model_from_file_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(LlamaModelLoadError::Reported { message }) } - other => Err(LlamaModelLoadError::UnrecognizedStatusCode { code: other }), + other => Err(LlamaModelLoadError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -173,7 +175,9 @@ unsafe fn parse_chat_message_status_to_result( unsafe { *out_error = ptr::null_mut() }; Err(ParseChatMessageError::ParseFailed { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -187,7 +191,11 @@ unsafe fn chat_parser_create_status_to_result( ) -> Result { match status { llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_OK => NonNull::new(parser).map_or_else( - || Err(ParseChatMessageError::UnrecognizedStatusCode { code: status }), + || { + Err(ParseChatMessageError::UnrecognizedStatusCode { + code: i64::from(status), + }) + }, |parser| Ok(ChatParserHandle { parser }), ), llama_cpp_bindings_sys::LLAMA_RS_CHAT_PARSER_CREATE_MODEL_HAS_NO_CHAT_TEMPLATE => { @@ -204,7 +212,9 @@ unsafe fn chat_parser_create_status_to_result( unsafe { *out_error = ptr::null_mut() }; Err(ParseChatMessageError::ParseFailed { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -240,7 +250,9 @@ unsafe fn parsed_chat_free_status_to_result( (Ok(_), other) => { unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; unsafe { llama_cpp_bindings_sys::llama_rs_string_free(free_error) }; - Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }) + Err(ParseChatMessageError::UnrecognizedStatusCode { + code: i64::from(other), + }) } (Err(parse_err), _) => { unsafe { llama_cpp_bindings_sys::llama_rs_string_free(out_error) }; @@ -310,7 +322,9 @@ unsafe fn apply_chat_template_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ApplyChatTemplateError::Reported { message }) } - other => Err(ApplyChatTemplateError::UnrecognizedStatusCode { code: other }), + other => Err(ApplyChatTemplateError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -1140,7 +1154,9 @@ unsafe fn parsed_chat_content_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -1180,7 +1196,7 @@ unsafe fn parsed_chat_reasoning_content_status_to_result( unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1218,7 +1234,7 @@ unsafe fn parsed_chat_tool_call_count_status_to_result( unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1262,7 +1278,7 @@ unsafe fn parsed_chat_tool_call_id_status_to_result( unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1308,7 +1324,7 @@ unsafe fn parsed_chat_tool_call_name_status_to_result( unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1354,7 +1370,7 @@ unsafe fn parsed_chat_tool_call_arguments_status_to_result( unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(ParseChatMessageError::Reported { message }) } - other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: other }), + other => Err(ParseChatMessageError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1456,7 +1472,7 @@ unsafe fn detect_reasoning_markers_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ReasoningMarkerDetectionFailed { message }) } - other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1522,7 +1538,9 @@ unsafe fn render_chat_template_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ReasoningMarkerDetectionFailed { message }) } - other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -1613,7 +1631,7 @@ unsafe fn compute_tool_call_haystack_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ToolCallHaystackComputationFailed { message }) } - other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1663,7 +1681,7 @@ unsafe fn diagnose_tool_call_synthetic_renders_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(MarkerDetectionError::ToolCallSyntheticRenderDiagnosisFailed { message }) } - other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: other }), + other => Err(MarkerDetectionError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -1728,7 +1746,9 @@ unsafe fn tokenize_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(StringToTokenError::Reported { message }) } - other => Err(StringToTokenError::UnrecognizedStatusCode { code: other }), + other => Err(StringToTokenError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -2989,7 +3009,7 @@ mod ffi_status_mapping_tests { ) }, Err(MarkerDetectionError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_render_chat_template_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_render_chat_template_status::MAX) }), ); } @@ -3053,7 +3073,9 @@ mod ffi_status_mapping_tests { ) }, Err(MarkerDetectionError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_detect_reasoning_markers_status::MAX + code: i64::from( + llama_cpp_bindings_sys::llama_rs_detect_reasoning_markers_status::MAX + ) }), ); } @@ -3113,7 +3135,9 @@ mod ffi_status_mapping_tests { ) }, Err(MarkerDetectionError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_compute_tool_call_haystack_status::MAX + code: i64::from( + llama_cpp_bindings_sys::llama_rs_compute_tool_call_haystack_status::MAX + ) }), ); } @@ -3178,9 +3202,7 @@ mod ffi_status_mapping_tests { ptr::null_mut(), ) }, - Err(MarkerDetectionError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_diagnose_tool_call_synthetic_renders_status::MAX, - }), + Err(MarkerDetectionError::UnrecognizedStatusCode { code: i64::from(llama_cpp_bindings_sys::llama_rs_diagnose_tool_call_synthetic_renders_status::MAX) }), ); } @@ -3239,7 +3261,7 @@ mod ffi_status_mapping_tests { ) }, Err(StringToTokenError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_tokenize_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_tokenize_status::MAX) }), ); } @@ -3345,9 +3367,7 @@ mod ffi_status_mapping_tests { ptr::null_mut(), ) }, - Err(crate::error::apply_chat_template_error::ApplyChatTemplateError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_apply_chat_template_status::MAX - }), + Err(crate::error::apply_chat_template_error::ApplyChatTemplateError::UnrecognizedStatusCode { code: i64::from(llama_cpp_bindings_sys::llama_rs_apply_chat_template_status::MAX) }), ); } diff --git a/llama-cpp-bindings/src/model/params.rs b/llama-cpp-bindings/src/model/params.rs index 60a0bb63..2a2d7b6a 100644 --- a/llama-cpp-bindings/src/model/params.rs +++ b/llama-cpp-bindings/src/model/params.rs @@ -307,7 +307,9 @@ fn fit_params_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(FitError::Reported { message }) } - other => Err(FitError::UnrecognizedStatusCode { code: other }), + other => Err(FitError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -847,7 +849,7 @@ mod tests { std::ptr::null_mut(), ), Err(crate::error::fit_error::FitError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_fit_params_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_fit_params_status::MAX) }), ); } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs b/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs index 99623acf..efa59dc6 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_bitmap.rs @@ -53,7 +53,7 @@ unsafe fn from_file_status_to_result( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdBitmapError::Reported { message }) } - other => Err(MtmdBitmapError::UnrecognizedStatusCode { code: other }), + other => Err(MtmdBitmapError::UnrecognizedStatusCode { code: i64::from(other) }), } } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs index 05f8a2ca..50cfe897 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_bitmap_error.rs @@ -19,5 +19,5 @@ pub enum MtmdBitmapError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_context.rs b/llama-cpp-bindings/src/mtmd/mtmd_context.rs index b2c36e6d..ace4c67e 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_context.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_context.rs @@ -39,7 +39,9 @@ fn map_tokenize_status( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdTokenizeError::Reported { message }) } - other => Err(MtmdTokenizeError::UnrecognizedStatusCode { code: other }), + other => Err(MtmdTokenizeError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -60,7 +62,9 @@ fn map_encode_chunk_status( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdEncodeError::Reported { message }) } - other => Err(MtmdEncodeError::UnrecognizedStatusCode { code: other }), + other => Err(MtmdEncodeError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -89,7 +93,9 @@ fn map_init_from_file_status( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdInitError::Reported { message }) } - other => Err(MtmdInitError::UnrecognizedStatusCode { code: other }), + other => Err(MtmdInitError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -340,9 +346,7 @@ mod unit_tests { 0, std::ptr::null_mut(), ), - Err(MtmdTokenizeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO, - }), + Err(MtmdTokenizeError::UnrecognizedStatusCode { code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_MTMD_TOKENIZE_NULL_BITMAPS_ARG_WHEN_NUM_BITMAPS_NONZERO) }), ); } @@ -355,7 +359,7 @@ mod unit_tests { std::ptr::null_mut(), ), Err(MtmdTokenizeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_mtmd_tokenize_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_mtmd_tokenize_status::MAX) }), ); } @@ -396,7 +400,7 @@ mod unit_tests { std::ptr::null_mut(), ), Err(MtmdEncodeError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_mtmd_encode_chunk_status::MAX) }), ); } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs index e1e49815..9ca5cdda 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_encode_error.rs @@ -7,5 +7,5 @@ pub enum MtmdEncodeError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs index 30097cd6..c9d28a00 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_eval_error.rs @@ -17,5 +17,5 @@ pub enum MtmdEvalError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs index fa91b27e..d8f53193 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_init_error.rs @@ -13,5 +13,5 @@ pub enum MtmdInitError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs b/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs index 639aa5eb..6d48a538 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_input_chunk.rs @@ -54,7 +54,9 @@ fn eval_chunk_single_status_to_result( let message = unsafe { read_and_free_cpp_error(out_error) }; Err(MtmdEvalError::Reported { message }) } - other => Err(MtmdEvalError::UnrecognizedStatusCode { code: other }), + other => Err(MtmdEvalError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -289,7 +291,9 @@ mod unit_tests { std::ptr::null_mut(), ), Err(MtmdEvalError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_mtmd_eval_chunk_single_status::MAX + code: i64::from( + llama_cpp_bindings_sys::llama_rs_mtmd_eval_chunk_single_status::MAX + ) }), ); } diff --git a/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs b/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs index 3e23cea9..815b14f4 100644 --- a/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs +++ b/llama-cpp-bindings/src/mtmd/mtmd_tokenize_error.rs @@ -17,5 +17,5 @@ pub enum MtmdTokenizeError { #[error("{message}")] Reported { message: String }, #[error("the FFI wrapper returned an unrecognized status code {code}")] - UnrecognizedStatusCode { code: u32 }, + UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/sampling.rs b/llama-cpp-bindings/src/sampling.rs index 7b6e43b9..88711eed 100644 --- a/llama-cpp-bindings/src/sampling.rs +++ b/llama-cpp-bindings/src/sampling.rs @@ -31,7 +31,9 @@ fn check_sampler_accept_status( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(SamplerAcceptError::GrammarStateCorrupted { message }) } - other => Err(SamplerAcceptError::UnrecognizedStatusCode { code: other }), + other => Err(SamplerAcceptError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -49,7 +51,9 @@ fn sampler_sample_status_to_result( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(SampleError::Reported { message }) } - other => Err(SampleError::UnrecognizedStatusCode { code: other }), + other => Err(SampleError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -70,7 +74,9 @@ fn sampler_init_grammar_status_to_result( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(GrammarError::Reported { message }) } - other => Err(GrammarError::UnrecognizedStatusCode { code: other }), + other => Err(GrammarError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -94,7 +100,7 @@ fn sampler_init_grammar_lazy_status_to_result( Err(GrammarError::Reported { message }) } other => { - Err(GrammarError::UnrecognizedStatusCode { code: other }) + Err(GrammarError::UnrecognizedStatusCode { code: i64::from(other) }) } } } @@ -122,7 +128,7 @@ fn sampler_init_grammar_lazy_patterns_status_to_result( let message = unsafe { read_and_free_cpp_error(error_ptr) }; Err(GrammarError::Reported { message }) } - other => Err(GrammarError::UnrecognizedStatusCode { code: other }), + other => Err(GrammarError::UnrecognizedStatusCode { code: i64::from(other) }), } } @@ -921,7 +927,7 @@ mod tests { std::ptr::null_mut(), ), Err(SamplerAcceptError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_NULL_SAMPLER_ARG + code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_ACCEPT_NULL_SAMPLER_ARG) }), ); } @@ -962,7 +968,7 @@ mod tests { std::ptr::null_mut(), ), Err(SampleError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_NULL_CTX_ARG + code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_SAMPLER_SAMPLE_NULL_CTX_ARG) }), ); } diff --git a/llama-cpp-bindings/src/token/data_array.rs b/llama-cpp-bindings/src/token/data_array.rs index f989565b..218cc4b5 100644 --- a/llama-cpp-bindings/src/token/data_array.rs +++ b/llama-cpp-bindings/src/token/data_array.rs @@ -23,7 +23,9 @@ fn sampler_apply_status_to_result( let message = unsafe { crate::ffi_error_reader::read_and_free_cpp_error(out_error) }; Err(SamplerApplyError::Reported { message }) } - other => Err(SamplerApplyError::UnrecognizedStatusCode { code: other }), + other => Err(SamplerApplyError::UnrecognizedStatusCode { + code: i64::from(other), + }), } } @@ -199,7 +201,7 @@ mod tests { std::ptr::null_mut(), ), Err(SamplerApplyError::UnrecognizedStatusCode { - code: llama_cpp_bindings_sys::llama_rs_sampler_apply_status::MAX + code: i64::from(llama_cpp_bindings_sys::llama_rs_sampler_apply_status::MAX) }), ); } From 165631138d5a6189093e54ff42dce3ae908cd911 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 19:07:49 +0200 Subject: [PATCH 04/11] Dead-strip unreferenced code on MSVC so the gbnf-sys minimal build links --- .cargo/config.toml | 2 ++ llama-cpp-bindings-build/src/build_gbnf.rs | 1 + 2 files changed, 3 insertions(+) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..38cae240 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.'cfg(target_env = "msvc")'] +rustflags = ["-C", "link-arg=/OPT:REF"] diff --git a/llama-cpp-bindings-build/src/build_gbnf.rs b/llama-cpp-bindings-build/src/build_gbnf.rs index e8e49de9..01646a62 100644 --- a/llama-cpp-bindings-build/src/build_gbnf.rs +++ b/llama-cpp-bindings-build/src/build_gbnf.rs @@ -77,6 +77,7 @@ fn compile_wrapper( if target_os.is_msvc() { build.flag("/std:c++17"); build.flag("/EHsc"); + build.flag("/Gy"); } build.compile("llama_cpp_gbnf_wrapper"); From 64a1dd8047afd62aaeddaa175ee26743f21c1da5 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 20:22:22 +0200 Subject: [PATCH 05/11] Reuse the shared libllama for the gbnf grammar wrapper so it links on all platforms --- .cargo/config.toml | 2 - Cargo.lock | 2 +- llama-cpp-bindings-build/src/build_gbnf.rs | 52 ++-------------------- llama-cpp-gbnf-sys/Cargo.toml | 2 +- llama-cpp-gbnf-sys/src/lib.rs | 2 + 5 files changed, 7 insertions(+), 53 deletions(-) delete mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 38cae240..00000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.'cfg(target_env = "msvc")'] -rustflags = ["-C", "link-arg=/OPT:REF"] diff --git a/Cargo.lock b/Cargo.lock index f9312728..f427c000 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1243,7 +1243,7 @@ name = "llama-cpp-gbnf-sys" version = "0.9.0" dependencies = [ "llama-cpp-bindings-build", - "llama-cpp-ggml-sys", + "llama-cpp-bindings-sys", ] [[package]] diff --git a/llama-cpp-bindings-build/src/build_gbnf.rs b/llama-cpp-bindings-build/src/build_gbnf.rs index 01646a62..a7e5acf4 100644 --- a/llama-cpp-bindings-build/src/build_gbnf.rs +++ b/llama-cpp-bindings-build/src/build_gbnf.rs @@ -6,14 +6,6 @@ use crate::target_os::TargetOs; const LLAMA_SUBMODULE_RELATIVE_PATH: &str = "../llama-cpp-bindings-sys/llama.cpp"; -const GRAMMAR_SOURCE_FILES: &[&str] = &[ - "src/llama-grammar.cpp", - "src/llama-vocab.cpp", - "src/unicode.cpp", - "src/unicode-data.cpp", - "src/llama-impl.cpp", -]; - pub fn build_gbnf() { let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var is required"); @@ -21,39 +13,25 @@ pub fn build_gbnf() { let target_os = TargetOs::from_target_triple(&target_triple) .unwrap_or_else(|error| panic!("Failed to parse target OS: {error}")); - let ggml_include = env::var("DEP_GGML_INCLUDE") - .expect("DEP_GGML_INCLUDE must be provided by llama-cpp-ggml-sys"); - let ggml_lib = - env::var("DEP_GGML_LIB").expect("DEP_GGML_LIB must be provided by llama-cpp-ggml-sys"); - let manifest = PathBuf::from(&manifest_dir); let llama_src = manifest.join(LLAMA_SUBMODULE_RELATIVE_PATH); let grammar_source_dir = llama_src.join("src"); assert!( - grammar_source_dir.join("llama-grammar.cpp").is_file(), - "grammar source not found under {}; ensure the llama.cpp submodule is checked out", + grammar_source_dir.join("llama-grammar.h").is_file(), + "grammar headers not found under {}; ensure the llama.cpp submodule is checked out", grammar_source_dir.display() ); register_rebuild_triggers(&manifest); - compile_wrapper( - &manifest, - &llama_src, - &grammar_source_dir, - Path::new(&ggml_include), - &target_os, - ); - - emit_link_directives(Path::new(&ggml_lib), &target_os); + compile_wrapper(&manifest, &llama_src, &grammar_source_dir, &target_os); } fn compile_wrapper( manifest: &Path, llama_src: &Path, grammar_source_dir: &Path, - ggml_include: &Path, target_os: &TargetOs, ) { let mut build = cc::Build::new(); @@ -65,42 +43,18 @@ fn compile_wrapper( .include(llama_src.join("include")) .include(grammar_source_dir) .include(llama_src.join("ggml/include")) - .include(ggml_include) .flag_if_supported("-std=c++17") .pic(true) .file(manifest.join("wrapper_gbnf.cpp")); - for source in GRAMMAR_SOURCE_FILES { - build.file(llama_src.join(source)); - } - if target_os.is_msvc() { build.flag("/std:c++17"); build.flag("/EHsc"); - build.flag("/Gy"); } build.compile("llama_cpp_gbnf_wrapper"); } -fn emit_link_directives(ggml_lib: &Path, target_os: &TargetOs) { - println!("cargo:rustc-link-search=native={}", ggml_lib.display()); - println!("cargo:rustc-link-lib=static=ggml-base"); - println!("cargo:rustc-link-lib=static=ggml-cpu"); - - match target_os { - TargetOs::Linux | TargetOs::Android => { - println!("cargo:rustc-link-lib=dylib=stdc++"); - } - TargetOs::Apple(_) => { - println!("cargo:rustc-link-lib=framework=Foundation"); - println!("cargo:rustc-link-lib=framework=Accelerate"); - println!("cargo:rustc-link-lib=dylib=c++"); - } - TargetOs::Windows(_) => {} - } -} - fn register_rebuild_triggers(manifest: &Path) { println!("cargo:rerun-if-changed=build.rs"); println!( diff --git a/llama-cpp-gbnf-sys/Cargo.toml b/llama-cpp-gbnf-sys/Cargo.toml index 2cc28072..32a85042 100644 --- a/llama-cpp-gbnf-sys/Cargo.toml +++ b/llama-cpp-gbnf-sys/Cargo.toml @@ -8,7 +8,7 @@ repository.workspace = true links = "llama_cpp_gbnf" [dependencies] -llama-cpp-ggml-sys = { workspace = true } +llama-cpp-bindings-sys = { workspace = true } [build-dependencies] llama-cpp-bindings-build = { workspace = true } diff --git a/llama-cpp-gbnf-sys/src/lib.rs b/llama-cpp-gbnf-sys/src/lib.rs index 00c098f9..bf2065a2 100644 --- a/llama-cpp-gbnf-sys/src/lib.rs +++ b/llama-cpp-gbnf-sys/src/lib.rs @@ -1,5 +1,7 @@ use core::ffi::c_char; +use llama_cpp_bindings_sys as _; + #[repr(C)] pub struct llama_grammar { _opaque: [u8; 0], From d229881f5df94aad9b8af6a32d075a17eadfe719 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 21:58:53 +0200 Subject: [PATCH 06/11] Link the shared-build ggml statically so dynamic-link configurations resolve --- llama-cpp-bindings-build/src/library_linking.rs | 10 +++++++++- llama-cpp-gbnf/src/gbnf_parse_error.rs | 17 ----------------- 2 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 llama-cpp-gbnf/src/gbnf_parse_error.rs diff --git a/llama-cpp-bindings-build/src/library_linking.rs b/llama-cpp-bindings-build/src/library_linking.rs index f84f390b..67549d54 100644 --- a/llama-cpp-bindings-build/src/library_linking.rs +++ b/llama-cpp-bindings-build/src/library_linking.rs @@ -90,11 +90,19 @@ fn link_cmake_built_libraries( "static" }; + let ggml_link_kind = if cfg!(feature = "system-ggml-static") { + "static" + } else if build_shared_libs || cfg!(feature = "system-ggml") { + "dylib" + } else { + "static" + }; + let lib_names = extract_lib_names(cmake_dir, build_shared_libs); assert!(!lib_names.is_empty(), "no libraries found in build output"); link_llama_common_internal_libraries(cmake_dir, profile); - link_system_ggml_libraries(link_kind, target_os); + link_system_ggml_libraries(ggml_link_kind, target_os); for lib_name in lib_names { let link = format!("cargo:rustc-link-lib={link_kind}={lib_name}"); diff --git a/llama-cpp-gbnf/src/gbnf_parse_error.rs b/llama-cpp-gbnf/src/gbnf_parse_error.rs deleted file mode 100644 index b76ad933..00000000 --- a/llama-cpp-gbnf/src/gbnf_parse_error.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::ffi::NulError; - -#[derive(Debug, thiserror::Error, PartialEq, Eq)] -pub enum GbnfParseError { - #[error("grammar string contains an interior NUL byte")] - GrammarStringNulByte(#[source] NulError), - #[error("grammar root name contains an interior NUL byte")] - RootNameNulByte(#[source] NulError), - #[error("grammar has a syntax error and could not be parsed")] - SyntaxError, - #[error("grammar defines no rules")] - EmptyRuleSet, - #[error("grammar does not define the root symbol {root:?}")] - RootSymbolMissing { root: String }, - #[error("grammar is left-recursive and cannot be compiled into a matcher")] - LeftRecursion, -} From 99a81db7e6809b676674a16125be49cceb5264ff Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 21:58:53 +0200 Subject: [PATCH 07/11] Surface grammar-engine allocation failures as typed errors instead of terminating --- Makefile | 3 +- llama-cpp-bindings-build/src/build_gbnf.rs | 36 ++++-- llama-cpp-bindings/src/sampling.rs | 4 +- llama-cpp-gbnf-sys/Cargo.toml | 3 + llama-cpp-gbnf-sys/alloc_fault.cpp | 84 ++++++++++++++ llama-cpp-gbnf-sys/alloc_fault.h | 25 +++++ llama-cpp-gbnf-sys/src/lib.rs | 24 +++- llama-cpp-gbnf-sys/wrapper_gbnf.cpp | 123 ++++++++++++++------ llama-cpp-gbnf-sys/wrapper_gbnf.h | 18 ++- llama-cpp-gbnf/Cargo.toml | 3 + llama-cpp-gbnf/src/gbnf_error.rs | 19 ++++ llama-cpp-gbnf/src/gbnf_grammar.rs | 125 +++++++++++++++------ llama-cpp-gbnf/src/gbnf_matcher.rs | 118 ++++++++++++++----- llama-cpp-gbnf/src/lib.rs | 2 +- 14 files changed, 472 insertions(+), 115 deletions(-) create mode 100644 llama-cpp-gbnf-sys/alloc_fault.cpp create mode 100644 llama-cpp-gbnf-sys/alloc_fault.h create mode 100644 llama-cpp-gbnf/src/gbnf_error.rs diff --git a/Makefile b/Makefile index 4078e981..f826ab87 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ TEST_DEVICE ?= DEVICE_FEATURE = $(if $(TEST_DEVICE),--features $(TEST_DEVICE),) +FAULT_INJECTION_FEATURE = --features llama-cpp-gbnf/fault-injection node_modules: package-lock.json npm ci @@ -25,7 +26,7 @@ clippy: .PHONY: coverage coverage: node_modules cargo llvm-cov clean --workspace - cargo llvm-cov --no-report --no-fail-fast --workspace $(DEVICE_FEATURE) + cargo llvm-cov --no-report --no-fail-fast --workspace $(FAULT_INJECTION_FEATURE) $(DEVICE_FEATURE) cargo llvm-cov report --json --output-path target/llvm-cov.json cargo llvm-cov report --lcov --output-path target/lcov.info cargo llvm-cov report diff --git a/llama-cpp-bindings-build/src/build_gbnf.rs b/llama-cpp-bindings-build/src/build_gbnf.rs index a7e5acf4..a7d65283 100644 --- a/llama-cpp-bindings-build/src/build_gbnf.rs +++ b/llama-cpp-bindings-build/src/build_gbnf.rs @@ -4,6 +4,7 @@ use std::path::PathBuf; use crate::target_os::TargetOs; +const LLAMA_BINDINGS_SYS_RELATIVE_PATH: &str = "../llama-cpp-bindings-sys"; const LLAMA_SUBMODULE_RELATIVE_PATH: &str = "../llama-cpp-bindings-sys/llama.cpp"; pub fn build_gbnf() { @@ -15,6 +16,7 @@ pub fn build_gbnf() { let manifest = PathBuf::from(&manifest_dir); let llama_src = manifest.join(LLAMA_SUBMODULE_RELATIVE_PATH); + let bindings_sys = manifest.join(LLAMA_BINDINGS_SYS_RELATIVE_PATH); let grammar_source_dir = llama_src.join("src"); assert!( @@ -25,21 +27,31 @@ pub fn build_gbnf() { register_rebuild_triggers(&manifest); - compile_wrapper(&manifest, &llama_src, &grammar_source_dir, &target_os); + compile_wrapper( + &manifest, + &llama_src, + &bindings_sys, + &grammar_source_dir, + &target_os, + ); } fn compile_wrapper( manifest: &Path, llama_src: &Path, + bindings_sys: &Path, grammar_source_dir: &Path, target_os: &TargetOs, ) { + let fault_injection = env::var_os("CARGO_FEATURE_FAULT_INJECTION").is_some(); + let mut build = cc::Build::new(); build .cpp(true) .warnings(false) .include(manifest) + .include(bindings_sys) .include(llama_src.join("include")) .include(grammar_source_dir) .include(llama_src.join("ggml/include")) @@ -47,6 +59,11 @@ fn compile_wrapper( .pic(true) .file(manifest.join("wrapper_gbnf.cpp")); + if fault_injection { + build.define("GBNF_FAULT_INJECTION", None); + build.file(manifest.join("alloc_fault.cpp")); + } + if target_os.is_msvc() { build.flag("/std:c++17"); build.flag("/EHsc"); @@ -57,12 +74,13 @@ fn compile_wrapper( fn register_rebuild_triggers(manifest: &Path) { println!("cargo:rerun-if-changed=build.rs"); - println!( - "cargo:rerun-if-changed={}", - manifest.join("wrapper_gbnf.cpp").display() - ); - println!( - "cargo:rerun-if-changed={}", - manifest.join("wrapper_gbnf.h").display() - ); + + for source in [ + "wrapper_gbnf.cpp", + "wrapper_gbnf.h", + "alloc_fault.cpp", + "alloc_fault.h", + ] { + println!("cargo:rerun-if-changed={}", manifest.join(source).display()); + } } diff --git a/llama-cpp-bindings/src/sampling.rs b/llama-cpp-bindings/src/sampling.rs index 88711eed..696aff71 100644 --- a/llama-cpp-bindings/src/sampling.rs +++ b/llama-cpp-bindings/src/sampling.rs @@ -4,8 +4,8 @@ use std::fmt::{Debug, Formatter}; use llama_cpp_error_recorder::error_scope::ErrorScope; use llama_cpp_error_recorder::recorded_error::RecordedError; +use llama_cpp_gbnf::gbnf_error::GbnfError; use llama_cpp_gbnf::gbnf_grammar::GbnfGrammar; -use llama_cpp_gbnf::gbnf_parse_error::GbnfParseError; use crate::context::LlamaContext; use crate::error::grammar_error::GrammarError; @@ -458,7 +458,7 @@ impl LlamaSampler { grammar_str: &str, grammar_root: &str, ) -> Result<(CString, CString), GrammarError> { - if let Err(GbnfParseError::RootSymbolMissing { .. }) = + if let Err(GbnfError::RootSymbolMissing { .. }) = GbnfGrammar::parse(grammar_str, grammar_root) { return Err(GrammarError::RootNotFound); diff --git a/llama-cpp-gbnf-sys/Cargo.toml b/llama-cpp-gbnf-sys/Cargo.toml index 32a85042..a7b10b1c 100644 --- a/llama-cpp-gbnf-sys/Cargo.toml +++ b/llama-cpp-gbnf-sys/Cargo.toml @@ -13,6 +13,9 @@ llama-cpp-bindings-sys = { workspace = true } [build-dependencies] llama-cpp-bindings-build = { workspace = true } +[features] +fault-injection = [] + [lints.rust] unsafe_op_in_unsafe_fn = "warn" unused_qualifications = "warn" diff --git a/llama-cpp-gbnf-sys/alloc_fault.cpp b/llama-cpp-gbnf-sys/alloc_fault.cpp new file mode 100644 index 00000000..b56fc4e1 --- /dev/null +++ b/llama-cpp-gbnf-sys/alloc_fault.cpp @@ -0,0 +1,84 @@ +#include "alloc_fault.h" + +#include +#include +#include + +namespace { + +thread_local bool alloc_fault_armed = false; +thread_local std::size_t alloc_fault_ops_to_skip = 0; +thread_local int alloc_fault_region_depth = 0; +thread_local bool alloc_fault_current_op_fails = false; + +void * alloc_fault_allocate(std::size_t size) { + if (alloc_fault_armed && alloc_fault_region_depth > 0 && alloc_fault_current_op_fails) { + throw std::bad_alloc(); + } + + void * pointer = std::malloc(size == 0 ? 1 : size); + + if (pointer == nullptr) { + throw std::bad_alloc(); + } + + return pointer; +} + +} // namespace + +extern "C" void gbnf_alloc_fault_arm(std::size_t skip_ops) { + alloc_fault_armed = true; + alloc_fault_ops_to_skip = skip_ops; +} + +extern "C" void gbnf_alloc_fault_disarm(void) { + alloc_fault_armed = false; + alloc_fault_ops_to_skip = 0; + alloc_fault_current_op_fails = false; +} + +extern "C" void gbnf_alloc_fault_region_enter(void) { + if (alloc_fault_region_depth == 0 && alloc_fault_armed) { + if (alloc_fault_ops_to_skip > 0) { + alloc_fault_ops_to_skip -= 1; + alloc_fault_current_op_fails = false; + } else { + alloc_fault_current_op_fails = true; + } + } + + alloc_fault_region_depth += 1; +} + +extern "C" void gbnf_alloc_fault_region_exit(void) { + alloc_fault_region_depth -= 1; + + if (alloc_fault_region_depth == 0) { + alloc_fault_current_op_fails = false; + } +} + +void * operator new(std::size_t size) { + return alloc_fault_allocate(size); +} + +void * operator new[](std::size_t size) { + return alloc_fault_allocate(size); +} + +void operator delete(void * pointer) noexcept { + std::free(pointer); +} + +void operator delete[](void * pointer) noexcept { + std::free(pointer); +} + +void operator delete(void * pointer, std::size_t) noexcept { + std::free(pointer); +} + +void operator delete[](void * pointer, std::size_t) noexcept { + std::free(pointer); +} diff --git a/llama-cpp-gbnf-sys/alloc_fault.h b/llama-cpp-gbnf-sys/alloc_fault.h new file mode 100644 index 00000000..41c60fef --- /dev/null +++ b/llama-cpp-gbnf-sys/alloc_fault.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef GBNF_FAULT_INJECTION + +void gbnf_alloc_fault_arm(size_t skip_ops); +void gbnf_alloc_fault_disarm(void); +void gbnf_alloc_fault_region_enter(void); +void gbnf_alloc_fault_region_exit(void); + +#else + +static inline void gbnf_alloc_fault_region_enter(void) {} +static inline void gbnf_alloc_fault_region_exit(void) {} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/llama-cpp-gbnf-sys/src/lib.rs b/llama-cpp-gbnf-sys/src/lib.rs index bf2065a2..48d806c1 100644 --- a/llama-cpp-gbnf-sys/src/lib.rs +++ b/llama-cpp-gbnf-sys/src/lib.rs @@ -15,6 +15,16 @@ pub enum LlamaRsGbnfParseStatus { EmptyRuleSet, RootSymbolMissing, LeftRecursion, + AllocationFailed, + ThrewCxxException, +} + +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LlamaRsGbnfRuntimeStatus { + Ok = 0, + AllocationFailed, + ThrewCxxException, } unsafe extern "C" { @@ -28,17 +38,27 @@ unsafe extern "C" { grammar: *mut llama_grammar, piece: *const c_char, piece_len: usize, - ); + ) -> LlamaRsGbnfRuntimeStatus; pub fn llama_rs_gbnf_is_accepting(grammar: *mut llama_grammar) -> bool; pub fn llama_rs_gbnf_is_rejected(grammar: *mut llama_grammar) -> bool; - pub fn llama_rs_gbnf_clone(grammar: *const llama_grammar) -> *mut llama_grammar; + pub fn llama_rs_gbnf_clone( + grammar: *const llama_grammar, + out_clone: *mut *mut llama_grammar, + ) -> LlamaRsGbnfRuntimeStatus; pub fn llama_rs_gbnf_free(grammar: *mut llama_grammar); } +#[cfg(feature = "fault-injection")] +unsafe extern "C" { + pub fn gbnf_alloc_fault_arm(skip_ops: usize); + + pub fn gbnf_alloc_fault_disarm(); +} + #[cfg(test)] mod tests { use std::ffi::CString; diff --git a/llama-cpp-gbnf-sys/wrapper_gbnf.cpp b/llama-cpp-gbnf-sys/wrapper_gbnf.cpp index 9eb461f1..79367478 100644 --- a/llama-cpp-gbnf-sys/wrapper_gbnf.cpp +++ b/llama-cpp-gbnf-sys/wrapper_gbnf.cpp @@ -1,5 +1,8 @@ #include "wrapper_gbnf.h" +#include "alloc_fault.h" +#include "wrapper_utils.h" + #include "llama-grammar.h" #include "unicode.h" @@ -7,58 +10,95 @@ #include #include +namespace { + +struct fault_region { + fault_region() { + gbnf_alloc_fault_region_enter(); + } + + ~fault_region() { + gbnf_alloc_fault_region_exit(); + } + + fault_region(const fault_region &) = delete; + fault_region & operator=(const fault_region &) = delete; + fault_region(fault_region &&) = delete; + fault_region & operator=(fault_region &&) = delete; +}; + +} // namespace + extern "C" { llama_rs_gbnf_parse_status llama_rs_gbnf_parse( const char * grammar_str, const char * grammar_root, - struct llama_grammar ** out_grammar) noexcept { - llama_grammar_parser parser(nullptr); + struct llama_grammar ** out_grammar) { + try { + llama_grammar_parser parser(nullptr); - if (!parser.parse(grammar_str)) { - return LLAMA_RS_GBNF_PARSE_SYNTAX_ERROR; - } + if (!parser.parse(grammar_str)) { + return LLAMA_RS_GBNF_PARSE_SYNTAX_ERROR; + } - if (parser.rules.empty()) { - return LLAMA_RS_GBNF_PARSE_EMPTY_RULE_SET; - } + if (parser.rules.empty()) { + return LLAMA_RS_GBNF_PARSE_EMPTY_RULE_SET; + } - const auto root_iterator = parser.symbol_ids.find(grammar_root); + const auto root_iterator = parser.symbol_ids.find(grammar_root); - if (root_iterator == parser.symbol_ids.end()) { - return LLAMA_RS_GBNF_PARSE_ROOT_SYMBOL_MISSING; - } + if (root_iterator == parser.symbol_ids.end()) { + return LLAMA_RS_GBNF_PARSE_ROOT_SYMBOL_MISSING; + } - auto grammar_rules = parser.c_rules(); - llama_grammar * grammar = llama_grammar_init_impl( - nullptr, - grammar_rules.data(), - grammar_rules.size(), - root_iterator->second); + const fault_region region; + auto grammar_rules = parser.c_rules(); + llama_grammar * grammar = llama_grammar_init_impl( + nullptr, + grammar_rules.data(), + grammar_rules.size(), + root_iterator->second); - if (grammar == nullptr) { - return LLAMA_RS_GBNF_PARSE_LEFT_RECURSION; - } + if (grammar == nullptr) { + return LLAMA_RS_GBNF_PARSE_LEFT_RECURSION; + } - *out_grammar = grammar; + *out_grammar = grammar; - return LLAMA_RS_GBNF_PARSE_OK; + return LLAMA_RS_GBNF_PARSE_OK; + } catch (...) { + return llama_rs_capture_exception( + nullptr, + LLAMA_RS_GBNF_PARSE_ALLOCATION_FAILED, + LLAMA_RS_GBNF_PARSE_THREW_CXX_EXCEPTION); + } } -void llama_rs_gbnf_accept_str( +llama_rs_gbnf_runtime_status llama_rs_gbnf_accept_str( struct llama_grammar * grammar, const char * piece, - size_t piece_len) noexcept { - const std::string input(piece, piece_len); - const std::vector code_points = unicode_cpts_from_utf8(input); - auto & stacks = llama_grammar_get_stacks(grammar); - - for (const uint32_t code_point : code_points) { - if (stacks.empty()) { - break; + size_t piece_len) { + try { + const fault_region region; + const std::string input(piece, piece_len); + const std::vector code_points = unicode_cpts_from_utf8(input); + auto & stacks = llama_grammar_get_stacks(grammar); + + for (const uint32_t code_point : code_points) { + if (stacks.empty()) { + break; + } + + llama_grammar_accept(grammar, code_point); } - llama_grammar_accept(grammar, code_point); + return LLAMA_RS_GBNF_RUNTIME_OK; + } catch (...) { + return llama_rs_capture_exception( + nullptr, + LLAMA_RS_GBNF_RUNTIME_ALLOCATION_FAILED, + LLAMA_RS_GBNF_RUNTIME_THREW_CXX_EXCEPTION); } } @@ -78,8 +118,21 @@ bool llama_rs_gbnf_is_rejected(struct llama_grammar * grammar) noexcept { return llama_grammar_get_stacks(grammar).empty(); } -struct llama_grammar * llama_rs_gbnf_clone(const struct llama_grammar * grammar) noexcept { - return llama_grammar_clone_impl(*grammar); +llama_rs_gbnf_runtime_status llama_rs_gbnf_clone( + const struct llama_grammar * grammar, + struct llama_grammar ** out_clone) { + try { + const fault_region region; + + *out_clone = llama_grammar_clone_impl(*grammar); + + return LLAMA_RS_GBNF_RUNTIME_OK; + } catch (...) { + return llama_rs_capture_exception( + nullptr, + LLAMA_RS_GBNF_RUNTIME_ALLOCATION_FAILED, + LLAMA_RS_GBNF_RUNTIME_THREW_CXX_EXCEPTION); + } } void llama_rs_gbnf_free(struct llama_grammar * grammar) noexcept { diff --git a/llama-cpp-gbnf-sys/wrapper_gbnf.h b/llama-cpp-gbnf-sys/wrapper_gbnf.h index 0926b5ef..40e6f804 100644 --- a/llama-cpp-gbnf-sys/wrapper_gbnf.h +++ b/llama-cpp-gbnf-sys/wrapper_gbnf.h @@ -21,23 +21,33 @@ typedef enum llama_rs_gbnf_parse_status { LLAMA_RS_GBNF_PARSE_EMPTY_RULE_SET, LLAMA_RS_GBNF_PARSE_ROOT_SYMBOL_MISSING, LLAMA_RS_GBNF_PARSE_LEFT_RECURSION, + LLAMA_RS_GBNF_PARSE_ALLOCATION_FAILED, + LLAMA_RS_GBNF_PARSE_THREW_CXX_EXCEPTION, } llama_rs_gbnf_parse_status; +typedef enum llama_rs_gbnf_runtime_status { + LLAMA_RS_GBNF_RUNTIME_OK = 0, + LLAMA_RS_GBNF_RUNTIME_ALLOCATION_FAILED, + LLAMA_RS_GBNF_RUNTIME_THREW_CXX_EXCEPTION, +} llama_rs_gbnf_runtime_status; + llama_rs_gbnf_parse_status llama_rs_gbnf_parse( const char * grammar_str, const char * grammar_root, - struct llama_grammar ** out_grammar) LLAMA_RS_GBNF_NOEXCEPT; + struct llama_grammar ** out_grammar); -void llama_rs_gbnf_accept_str( +llama_rs_gbnf_runtime_status llama_rs_gbnf_accept_str( struct llama_grammar * grammar, const char * piece, - size_t piece_len) LLAMA_RS_GBNF_NOEXCEPT; + size_t piece_len); bool llama_rs_gbnf_is_accepting(struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; bool llama_rs_gbnf_is_rejected(struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; -struct llama_grammar * llama_rs_gbnf_clone(const struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; +llama_rs_gbnf_runtime_status llama_rs_gbnf_clone( + const struct llama_grammar * grammar, + struct llama_grammar ** out_clone); void llama_rs_gbnf_free(struct llama_grammar * grammar) LLAMA_RS_GBNF_NOEXCEPT; diff --git a/llama-cpp-gbnf/Cargo.toml b/llama-cpp-gbnf/Cargo.toml index b9c2b44e..ebe2d1db 100644 --- a/llama-cpp-gbnf/Cargo.toml +++ b/llama-cpp-gbnf/Cargo.toml @@ -10,6 +10,9 @@ repository.workspace = true llama-cpp-gbnf-sys = { workspace = true } thiserror = { workspace = true } +[features] +fault-injection = ["llama-cpp-gbnf-sys/fault-injection"] + [lints.rust] unsafe_op_in_unsafe_fn = "warn" unused_qualifications = "warn" diff --git a/llama-cpp-gbnf/src/gbnf_error.rs b/llama-cpp-gbnf/src/gbnf_error.rs new file mode 100644 index 00000000..f1504e38 --- /dev/null +++ b/llama-cpp-gbnf/src/gbnf_error.rs @@ -0,0 +1,19 @@ +use std::ffi::NulError; + +#[derive(Debug, thiserror::Error, PartialEq, Eq)] +pub enum GbnfError { + #[error("grammar string contains an interior NUL byte")] + GrammarStringNulByte(#[source] NulError), + #[error("grammar root name contains an interior NUL byte")] + RootNameNulByte(#[source] NulError), + #[error("grammar has a syntax error and could not be parsed")] + SyntaxError, + #[error("grammar defines no rules")] + EmptyRuleSet, + #[error("grammar does not define the root symbol {root:?}")] + RootSymbolMissing { root: String }, + #[error("grammar is left-recursive and cannot be compiled into a matcher")] + LeftRecursion, + #[error("the grammar engine could not allocate memory")] + AllocationFailed, +} diff --git a/llama-cpp-gbnf/src/gbnf_grammar.rs b/llama-cpp-gbnf/src/gbnf_grammar.rs index 80bccf81..9b91e697 100644 --- a/llama-cpp-gbnf/src/gbnf_grammar.rs +++ b/llama-cpp-gbnf/src/gbnf_grammar.rs @@ -3,27 +3,29 @@ use std::ptr; use llama_cpp_gbnf_sys::LlamaRsGbnfParseStatus; use llama_cpp_gbnf_sys::llama_grammar; -use llama_cpp_gbnf_sys::llama_rs_gbnf_clone; use llama_cpp_gbnf_sys::llama_rs_gbnf_free; use llama_cpp_gbnf_sys::llama_rs_gbnf_parse; +use crate::gbnf_error::GbnfError; use crate::gbnf_matcher::GbnfMatcher; -use crate::gbnf_parse_error::GbnfParseError; use crate::validation::Validation; fn parse_status_to_result( status: LlamaRsGbnfParseStatus, grammar: *mut llama_grammar, root: &str, -) -> Result<*mut llama_grammar, GbnfParseError> { +) -> Result<*mut llama_grammar, GbnfError> { match status { LlamaRsGbnfParseStatus::Ok => Ok(grammar), - LlamaRsGbnfParseStatus::SyntaxError => Err(GbnfParseError::SyntaxError), - LlamaRsGbnfParseStatus::EmptyRuleSet => Err(GbnfParseError::EmptyRuleSet), - LlamaRsGbnfParseStatus::RootSymbolMissing => Err(GbnfParseError::RootSymbolMissing { + LlamaRsGbnfParseStatus::SyntaxError => Err(GbnfError::SyntaxError), + LlamaRsGbnfParseStatus::EmptyRuleSet => Err(GbnfError::EmptyRuleSet), + LlamaRsGbnfParseStatus::RootSymbolMissing => Err(GbnfError::RootSymbolMissing { root: root.to_owned(), }), - LlamaRsGbnfParseStatus::LeftRecursion => Err(GbnfParseError::LeftRecursion), + LlamaRsGbnfParseStatus::LeftRecursion => Err(GbnfError::LeftRecursion), + LlamaRsGbnfParseStatus::AllocationFailed | LlamaRsGbnfParseStatus::ThrewCxxException => { + Err(GbnfError::AllocationFailed) + } } } @@ -35,12 +37,11 @@ pub struct GbnfGrammar { impl GbnfGrammar { /// # Errors /// - /// Returns [`GbnfParseError`] when the grammar or root contains a NUL byte, - /// or the grammar parser rejects the grammar. - pub fn parse(grammar: &str, root: &str) -> Result { - let grammar_cstring = - CString::new(grammar).map_err(GbnfParseError::GrammarStringNulByte)?; - let root_cstring = CString::new(root).map_err(GbnfParseError::RootNameNulByte)?; + /// Returns [`GbnfError`] when the grammar or root contains a NUL byte, the + /// grammar parser rejects the grammar, or the grammar engine cannot allocate. + pub fn parse(grammar: &str, root: &str) -> Result { + let grammar_cstring = CString::new(grammar).map_err(GbnfError::GrammarStringNulByte)?; + let root_cstring = CString::new(root).map_err(GbnfError::RootNameNulByte)?; let mut handle: *mut llama_grammar = ptr::null_mut(); @@ -57,23 +58,27 @@ impl GbnfGrammar { }) } - #[must_use] - pub fn matcher(&self) -> GbnfMatcher { - let initial = unsafe { llama_rs_gbnf_clone(self.handle) }; - - unsafe { GbnfMatcher::new(initial) } + /// # Errors + /// + /// Returns [`GbnfError::AllocationFailed`] when the grammar engine cannot + /// allocate the matcher state. + pub fn matcher(&self) -> Result, GbnfError> { + unsafe { GbnfMatcher::new(self.handle) } } - #[must_use] - pub fn matches(&self, text: &str) -> Validation { - let mut matcher = self.matcher(); + /// # Errors + /// + /// Returns [`GbnfError::AllocationFailed`] when the grammar engine cannot + /// allocate while matching `text`. + pub fn matches(&self, text: &str) -> Result { + let mut matcher = self.matcher()?; - matcher.feed_str(text); + matcher.feed_str(text)?; if !matcher.is_rejected() && matcher.is_accepting() { - Validation::Accepted + Ok(Validation::Accepted) } else { - Validation::Rejected + Ok(Validation::Rejected) } } } @@ -90,14 +95,14 @@ mod tests { use std::mem::discriminant; use super::GbnfGrammar; - use crate::gbnf_parse_error::GbnfParseError; + use crate::gbnf_error::GbnfError; use crate::validation::Validation; #[test] fn empty_grammar_returns_empty_rule_set() { let error = GbnfGrammar::parse("", "root").expect_err("empty grammar is rejected"); - assert_eq!(error, GbnfParseError::EmptyRuleSet); + assert_eq!(error, GbnfError::EmptyRuleSet); } #[test] @@ -105,7 +110,7 @@ mod tests { let error = GbnfGrammar::parse(r#"root ::= root "x""#, "root") .expect_err("left recursion is rejected"); - assert_eq!(error, GbnfParseError::LeftRecursion); + assert_eq!(error, GbnfError::LeftRecursion); } #[test] @@ -117,7 +122,7 @@ mod tests { fn malformed_grammar_returns_syntax_error() { let error = GbnfGrammar::parse("root ::= (", "root").expect_err("malformed is rejected"); - assert_eq!(error, GbnfParseError::SyntaxError); + assert_eq!(error, GbnfError::SyntaxError); } #[test] @@ -127,7 +132,7 @@ mod tests { assert_eq!( error, - GbnfParseError::RootSymbolMissing { + GbnfError::RootSymbolMissing { root: "root".to_owned() } ); @@ -138,7 +143,7 @@ mod tests { let error = GbnfGrammar::parse("root ::= \"a\0b\"", "root").expect_err("nul byte is rejected"); let representative = - GbnfParseError::GrammarStringNulByte(CString::new(b"a\0b".to_vec()).unwrap_err()); + GbnfError::GrammarStringNulByte(CString::new(b"a\0b".to_vec()).unwrap_err()); assert_eq!(discriminant(&error), discriminant(&representative)); } @@ -148,7 +153,7 @@ mod tests { let error = GbnfGrammar::parse(r#"root ::= "x""#, "ro\0ot").expect_err("nul byte is rejected"); let representative = - GbnfParseError::RootNameNulByte(CString::new(b"ro\0ot".to_vec()).unwrap_err()); + GbnfError::RootNameNulByte(CString::new(b"ro\0ot".to_vec()).unwrap_err()); assert_eq!(discriminant(&error), discriminant(&representative)); } @@ -157,20 +162,72 @@ mod tests { fn matches_accepts_text_in_the_language() { let grammar = GbnfGrammar::parse(r"root ::= [0-9]+", "root").expect("grammar parses"); - assert_eq!(grammar.matches("123"), Validation::Accepted); + assert_eq!( + grammar.matches("123").expect("engine allocates"), + Validation::Accepted + ); } #[test] fn matches_rejects_text_outside_the_language() { let grammar = GbnfGrammar::parse(r"root ::= [0-9]+", "root").expect("grammar parses"); - assert_eq!(grammar.matches("12a"), Validation::Rejected); + assert_eq!( + grammar.matches("12a").expect("engine allocates"), + Validation::Rejected + ); } #[test] fn matches_rejects_incomplete_text() { let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); - assert_eq!(grammar.matches("ye"), Validation::Rejected); + assert_eq!( + grammar.matches("ye").expect("engine allocates"), + Validation::Rejected + ); + } + + #[cfg(feature = "fault-injection")] + #[test] + fn parse_reports_allocation_failure_when_building_the_grammar() { + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_arm(0) }; + let result = GbnfGrammar::parse(r#"root ::= "ok""#, "root"); + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_disarm() }; + + assert_eq!( + result.expect_err("building the grammar fails under an armed fault"), + GbnfError::AllocationFailed + ); + } + + #[cfg(feature = "fault-injection")] + #[test] + fn matches_reports_allocation_failure_when_cloning_the_matcher() { + let grammar = GbnfGrammar::parse(r#"root ::= "ok""#, "root").expect("grammar parses"); + + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_arm(0) }; + let result = grammar.matches("ok"); + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_disarm() }; + + assert_eq!( + result.expect_err("cloning the matcher fails under an armed fault"), + GbnfError::AllocationFailed + ); + } + + #[cfg(feature = "fault-injection")] + #[test] + fn matches_reports_allocation_failure_when_feeding_text() { + let grammar = GbnfGrammar::parse(r#"root ::= "ok""#, "root").expect("grammar parses"); + + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_arm(1) }; + let result = grammar.matches("ok"); + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_disarm() }; + + assert_eq!( + result.expect_err("feeding text fails under an armed fault"), + GbnfError::AllocationFailed + ); } } diff --git a/llama-cpp-gbnf/src/gbnf_matcher.rs b/llama-cpp-gbnf/src/gbnf_matcher.rs index 864eb8e6..8703732c 100644 --- a/llama-cpp-gbnf/src/gbnf_matcher.rs +++ b/llama-cpp-gbnf/src/gbnf_matcher.rs @@ -1,5 +1,8 @@ use core::ffi::c_char; +use std::marker::PhantomData; +use std::ptr; +use llama_cpp_gbnf_sys::LlamaRsGbnfRuntimeStatus; use llama_cpp_gbnf_sys::llama_grammar; use llama_cpp_gbnf_sys::llama_rs_gbnf_accept_str; use llama_cpp_gbnf_sys::llama_rs_gbnf_clone; @@ -7,27 +10,62 @@ use llama_cpp_gbnf_sys::llama_rs_gbnf_free; use llama_cpp_gbnf_sys::llama_rs_gbnf_is_accepting; use llama_cpp_gbnf_sys::llama_rs_gbnf_is_rejected; -pub struct GbnfMatcher { - initial: *mut llama_grammar, +use crate::gbnf_error::GbnfError; + +const fn runtime_status_to_result(status: LlamaRsGbnfRuntimeStatus) -> Result<(), GbnfError> { + match status { + LlamaRsGbnfRuntimeStatus::Ok => Ok(()), + LlamaRsGbnfRuntimeStatus::AllocationFailed + | LlamaRsGbnfRuntimeStatus::ThrewCxxException => Err(GbnfError::AllocationFailed), + } +} + +fn clone_handle(grammar: *const llama_grammar) -> Result<*mut llama_grammar, GbnfError> { + let mut out_clone: *mut llama_grammar = ptr::null_mut(); + + let status = unsafe { llama_rs_gbnf_clone(grammar, &raw mut out_clone) }; + + runtime_status_to_result(status)?; + + Ok(out_clone) +} + +pub struct GbnfMatcher<'grammar> { + source: *mut llama_grammar, current: *mut llama_grammar, + borrowed_grammar: PhantomData<&'grammar llama_grammar>, } -impl GbnfMatcher { +impl GbnfMatcher<'_> { /// # Safety /// - /// `initial` must be a non-null grammar handle produced by the grammar - /// parser; `GbnfMatcher` takes ownership of it and frees it on drop. - #[must_use] - pub unsafe fn new(initial: *mut llama_grammar) -> Self { - let current = unsafe { llama_rs_gbnf_clone(initial) }; - - Self { initial, current } + /// `source` must be a valid grammar handle that stays alive for the entire + /// `'grammar` lifetime. The matcher clones it and never frees `source`. + /// + /// # Errors + /// + /// Returns [`GbnfError::AllocationFailed`] when the grammar engine cannot + /// allocate the initial matcher state. + pub(crate) unsafe fn new(source: *mut llama_grammar) -> Result { + let current = clone_handle(source)?; + + Ok(Self { + source, + current, + borrowed_grammar: PhantomData, + }) } - pub fn feed_str(&mut self, piece: &str) { - unsafe { - llama_rs_gbnf_accept_str(self.current, piece.as_ptr().cast::(), piece.len()); - } + /// # Errors + /// + /// Returns [`GbnfError::AllocationFailed`] when the grammar engine cannot + /// allocate while advancing over `piece`. + pub fn feed_str(&mut self, piece: &str) -> Result<(), GbnfError> { + let status = unsafe { + llama_rs_gbnf_accept_str(self.current, piece.as_ptr().cast::(), piece.len()) + }; + + runtime_status_to_result(status) } #[must_use] @@ -40,57 +78,83 @@ impl GbnfMatcher { unsafe { llama_rs_gbnf_is_rejected(self.current) } } - pub fn reset(&mut self) { + /// # Errors + /// + /// Returns [`GbnfError::AllocationFailed`] when the grammar engine cannot + /// allocate a fresh copy of the initial matcher state. + pub fn reset(&mut self) -> Result<(), GbnfError> { + let fresh = clone_handle(self.source)?; + unsafe { llama_rs_gbnf_free(self.current) }; - self.current = unsafe { llama_rs_gbnf_clone(self.initial) }; + + self.current = fresh; + + Ok(()) } } -impl Drop for GbnfMatcher { +impl Drop for GbnfMatcher<'_> { fn drop(&mut self) { unsafe { llama_rs_gbnf_free(self.current) }; - unsafe { llama_rs_gbnf_free(self.initial) }; } } #[cfg(test)] mod tests { + #[cfg(feature = "fault-injection")] + use crate::gbnf_error::GbnfError; use crate::gbnf_grammar::GbnfGrammar; #[test] fn incremental_feed_reaches_accepting_only_when_complete() { let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); - let mut matcher = grammar.matcher(); + let mut matcher = grammar.matcher().expect("matcher clones"); - matcher.feed_str("ye"); + matcher.feed_str("ye").expect("engine allocates"); assert!(!matcher.is_accepting()); assert!(!matcher.is_rejected()); - matcher.feed_str("s"); + matcher.feed_str("s").expect("engine allocates"); assert!(matcher.is_accepting()); } #[test] fn feeding_a_violating_piece_rejects() { let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); - let mut matcher = grammar.matcher(); + let mut matcher = grammar.matcher().expect("matcher clones"); - matcher.feed_str("no"); + matcher.feed_str("no").expect("engine allocates"); assert!(matcher.is_rejected()); } #[test] fn reset_restores_the_initial_state() { let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); - let mut matcher = grammar.matcher(); + let mut matcher = grammar.matcher().expect("matcher clones"); - matcher.feed_str("no"); + matcher.feed_str("no").expect("engine allocates"); assert!(matcher.is_rejected()); - matcher.reset(); + matcher.reset().expect("engine allocates"); assert!(!matcher.is_rejected()); - matcher.feed_str("yes"); + matcher.feed_str("yes").expect("engine allocates"); assert!(matcher.is_accepting()); } + + #[cfg(feature = "fault-injection")] + #[test] + fn reset_reports_allocation_failure_when_cloning_fails() { + let grammar = GbnfGrammar::parse(r#"root ::= "yes""#, "root").expect("grammar parses"); + let mut matcher = grammar.matcher().expect("matcher clones"); + + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_arm(0) }; + let result = matcher.reset(); + unsafe { llama_cpp_gbnf_sys::gbnf_alloc_fault_disarm() }; + + assert_eq!( + result.expect_err("cloning fails under an armed fault"), + GbnfError::AllocationFailed + ); + } } diff --git a/llama-cpp-gbnf/src/lib.rs b/llama-cpp-gbnf/src/lib.rs index c939b52f..bcfd76eb 100644 --- a/llama-cpp-gbnf/src/lib.rs +++ b/llama-cpp-gbnf/src/lib.rs @@ -10,7 +10,7 @@ ) )] +pub mod gbnf_error; pub mod gbnf_grammar; pub mod gbnf_matcher; -pub mod gbnf_parse_error; pub mod validation; From e27ed7bf1733af91ce4fa8ab5fde90e7118bf6cc Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 22:31:47 +0200 Subject: [PATCH 08/11] Close the unbalanced parenthesis in the Rust parameter-names rule --- .claude/rules/rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/rules/rust.md b/.claude/rules/rust.md index e791daaf..5c9f05b2 100644 --- a/.claude/rules/rust.md +++ b/.claude/rules/rust.md @@ -7,7 +7,7 @@ paths: # Rust Standards - Always use explicit lifetime variable names (do not use `'a` and such, use descriptive names like `'message` or similar) -- Always use descriptive parameter names (never use single letter names for generics +- Always use descriptive parameter names (never use single letter names for generics) - Each file must contain at most a single struct, or single enum, or a single public function (at most one of any of those). - Each file must contain at most a single public item. You can still keep multiple private function helpers. Files need to be named after their public item. - Always destructure structs in arguments if possible. From fd32484e0114b5cf3660d0a6c661f994a6647970 Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 22:31:47 +0200 Subject: [PATCH 09/11] Map a zero decode/encode return code to a dedicated error instead of unrecognized-status --- llama-cpp-bindings/src/context.rs | 12 ++---------- llama-cpp-bindings/src/error/decode_error.rs | 2 ++ llama-cpp-bindings/src/error/encode_error.rs | 2 ++ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/llama-cpp-bindings/src/context.rs b/llama-cpp-bindings/src/context.rs index f41bc5b1..6cc7df3b 100644 --- a/llama-cpp-bindings/src/context.rs +++ b/llama-cpp-bindings/src/context.rs @@ -74,11 +74,7 @@ fn decode_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_DECODE_OK => Ok(()), llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE => { NonZeroI32::new(out_return_code).map_or_else( - || { - Err(DecodeError::UnrecognizedStatusCode { - code: i64::from(status), - }) - }, + || Err(DecodeError::ReturnedErrorCodeWasZero), |code| Err(DecodeError::from(code)), ) } @@ -111,11 +107,7 @@ fn encode_status_to_result( } llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE => { NonZeroI32::new(out_return_code).map_or_else( - || { - Err(EncodeError::UnrecognizedStatusCode { - code: i64::from(status), - }) - }, + || Err(EncodeError::ReturnedErrorCodeWasZero), |code| Err(EncodeError::from(code)), ) } diff --git a/llama-cpp-bindings/src/error/decode_error.rs b/llama-cpp-bindings/src/error/decode_error.rs index 9cfac07f..4f0d6d4f 100644 --- a/llama-cpp-bindings/src/error/decode_error.rs +++ b/llama-cpp-bindings/src/error/decode_error.rs @@ -19,6 +19,8 @@ pub enum DecodeError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the decode wrapper reported a returned error code but the return code was zero")] + ReturnedErrorCodeWasZero, #[error("the FFI wrapper returned an unrecognized status code {code}")] UnrecognizedStatusCode { code: i64 }, } diff --git a/llama-cpp-bindings/src/error/encode_error.rs b/llama-cpp-bindings/src/error/encode_error.rs index 5863841c..e01e7953 100644 --- a/llama-cpp-bindings/src/error/encode_error.rs +++ b/llama-cpp-bindings/src/error/encode_error.rs @@ -19,6 +19,8 @@ pub enum EncodeError { NotEnoughMemory, #[error("{message}")] Reported { message: String }, + #[error("the encode wrapper reported a returned error code but the return code was zero")] + ReturnedErrorCodeWasZero, #[error("the FFI wrapper returned an unrecognized status code {code}")] UnrecognizedStatusCode { code: i64 }, } From be9fb9bc57ef444e5369ece36d42981713109a0e Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Thu, 2 Jul 2026 22:41:36 +0200 Subject: [PATCH 10/11] Update decode/encode zero-return-code tests for the dedicated error variant --- llama-cpp-bindings/src/context.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/llama-cpp-bindings/src/context.rs b/llama-cpp-bindings/src/context.rs index 6cc7df3b..8fc2f28b 100644 --- a/llama-cpp-bindings/src/context.rs +++ b/llama-cpp-bindings/src/context.rs @@ -682,16 +682,14 @@ mod unit_tests { } #[test] - fn decode_nonzero_code_with_zero_value_returns_unrecognized_status_error() { + fn decode_returned_error_code_with_zero_return_value_maps_to_dedicated_error() { assert_eq!( decode_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE, 0, std::ptr::null_mut(), ), - Err(DecodeError::UnrecognizedStatusCode { - code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_DECODE_RETURNED_ERROR_CODE) - }), + Err(DecodeError::ReturnedErrorCodeWasZero), ); } @@ -781,16 +779,14 @@ mod unit_tests { } #[test] - fn encode_nonzero_code_with_zero_value_returns_unrecognized_status_error() { + fn encode_returned_error_code_with_zero_return_value_maps_to_dedicated_error() { assert_eq!( encode_status_to_result( llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE, 0, std::ptr::null_mut(), ), - Err(EncodeError::UnrecognizedStatusCode { - code: i64::from(llama_cpp_bindings_sys::LLAMA_RS_ENCODE_RETURNED_ERROR_CODE) - }), + Err(EncodeError::ReturnedErrorCodeWasZero), ); } From 48821509226655a1cc44c536dcd111d2b4974dba Mon Sep 17 00:00:00 2001 From: Mateusz Charytoniuk Date: Fri, 3 Jul 2026 01:06:22 +0200 Subject: [PATCH 11/11] Right-size multimodal eval_chunks context to 2048 so the 35B tests fit alongside GPU desktop overhead --- llama-cpp-bindings-tests/tests/multimodal_vision.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llama-cpp-bindings-tests/tests/multimodal_vision.rs b/llama-cpp-bindings-tests/tests/multimodal_vision.rs index 47d2fc39..e61aed08 100644 --- a/llama-cpp-bindings-tests/tests/multimodal_vision.rs +++ b/llama-cpp-bindings-tests/tests/multimodal_vision.rs @@ -694,7 +694,7 @@ fn eval_chunks_returns_batch_size_exceeds_context_limit_for_huge_batch( n_gpu_layers = 999, use_mmap = true, use_mlock = false, - n_ctx = 8192, + n_ctx = 2048, n_batch = 512, n_ubatch = 512, mmproj_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "mmproj-F16.gguf"), @@ -704,7 +704,7 @@ fn eval_chunks_returns_batch_size_exceeds_context_limit_for_huge_batch( n_gpu_layers = 999, use_mmap = true, use_mlock = false, - n_ctx = 8192, + n_ctx = 2048, n_batch = 512, n_ubatch = 512, mmproj_source = HuggingFace("unsloth/Qwen3.6-35B-A3B-GGUF", "mmproj-F16.gguf"), @@ -753,7 +753,7 @@ fn eval_chunks_with_standard_image(fixture: &LlamaFixture<'_>) -> Result<()> { n_gpu_layers = 999, use_mmap = true, use_mlock = false, - n_ctx = 8192, + n_ctx = 2048, n_batch = 512, n_ubatch = 512, mmproj_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "mmproj-F16.gguf"), @@ -763,7 +763,7 @@ fn eval_chunks_with_standard_image(fixture: &LlamaFixture<'_>) -> Result<()> { n_gpu_layers = 999, use_mmap = true, use_mlock = false, - n_ctx = 8192, + n_ctx = 2048, n_batch = 512, n_ubatch = 512, mmproj_source = HuggingFace("unsloth/Qwen3.6-35B-A3B-GGUF", "mmproj-F16.gguf"), @@ -787,7 +787,7 @@ fn eval_chunks_with_varied_dimensions(fixture: &LlamaFixture<'_>) -> Result<()> n_gpu_layers = 999, use_mmap = true, use_mlock = false, - n_ctx = 8192, + n_ctx = 2048, n_batch = 512, n_ubatch = 512, mmproj_source = HuggingFace("unsloth/Qwen3.5-0.8B-GGUF", "mmproj-F16.gguf"), @@ -797,7 +797,7 @@ fn eval_chunks_with_varied_dimensions(fixture: &LlamaFixture<'_>) -> Result<()> n_gpu_layers = 999, use_mmap = true, use_mlock = false, - n_ctx = 8192, + n_ctx = 2048, n_batch = 512, n_ubatch = 512, mmproj_source = HuggingFace("unsloth/Qwen3.6-35B-A3B-GGUF", "mmproj-F16.gguf"),