#![doc = include_str!("../README.md")]
#![allow(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(test, allow(clippy::unwrap_used))]
#![cfg_attr(test, allow(clippy::expect_used))]
#![cfg_attr(test, allow(clippy::arithmetic_side_effects))]
#![cfg_attr(test, allow(clippy::indexing_slicing))]
#![cfg_attr(test, allow(clippy::panic))]
#![cfg_attr(test, allow(clippy::panic_in_result_fn))]
#![cfg_attr(test, allow(clippy::as_conversions))]
#![cfg_attr(test, allow(clippy::float_cmp))]
#![cfg_attr(test, allow(clippy::float_cmp_const))]
#![cfg_attr(test, allow(clippy::cast_possible_truncation))]
#![cfg_attr(test, allow(clippy::cast_possible_wrap))]
#![cfg_attr(test, allow(clippy::cast_precision_loss))]
#![cfg_attr(test, allow(clippy::cast_sign_loss))]
#![cfg_attr(test, allow(clippy::integer_division))]
#![cfg_attr(test, allow(clippy::shadow_reuse))]
#![cfg_attr(test, allow(clippy::shadow_same))]
#![cfg_attr(test, allow(clippy::shadow_unrelated))]
#![cfg_attr(test, allow(clippy::missing_errors_doc))]
#![cfg_attr(test, allow(clippy::missing_panics_doc))]
#![cfg_attr(test, allow(clippy::trivially_copy_pass_by_ref))]
#![cfg_attr(test, allow(clippy::needless_pass_by_value))]
#![cfg_attr(test, allow(unused_results))]
#[cfg(not(feature = "std"))]
use core::panic::PanicInfo;
#[cfg(not(feature = "std"))]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
pub mod control_types;
pub mod llmosafe_classifier;
pub mod llmosafe_detection;
pub mod llmosafe_integration;
pub mod llmosafe_kernel;
pub mod llmosafe_memory;
pub mod llmosafe_pid;
pub mod llmosafe_pipeline;
pub mod llmosafe_sifter;
#[cfg(feature = "std")]
pub mod llmosafe_body;
pub use control_types::{ControlSignal, DesignAssuranceLevel, OverrideFlags, PidInput};
#[cfg(feature = "std")]
pub use llmosafe_body::BodyOutput;
#[cfg(feature = "std")]
pub use llmosafe_body::ResourceGuard;
#[cfg(feature = "std")]
pub use llmosafe_detection::DetectionResult;
pub use llmosafe_detection::{
AdversarialDetector, ConfidenceTracker, CusumDetector, DriftDetector, RepetitionDetector,
};
#[cfg(feature = "std")]
pub use llmosafe_integration::SafetyContext;
pub use llmosafe_integration::{EscalationPolicy, EscalationReason, PressureLevel, SafetyDecision};
pub use llmosafe_kernel::KernelOutput;
pub use llmosafe_kernel::{
CognitiveEntropy, CognitiveStability, DynamicStabilityMonitor, KernelError, ReasoningLoop,
SiftedProof, SiftedSynapse, StabilityResult, Synapse, ValidatedProof, ValidatedSynapse,
DETECTION_FLAGS_MASK, FLAG_ADVERSARIAL, FLAG_ANOMALY, FLAG_DECAYING, FLAG_DRIFTING,
FLAG_LOW_CONFIDENCE, FLAG_STUCK, PRESSURE_THRESHOLD, STABILITY_THRESHOLD,
};
pub use llmosafe_memory::MemoryOutput;
pub use llmosafe_memory::WorkingMemory;
pub use llmosafe_pid::{
apply_safety_overrides, compute_pid_score, compute_pid_score_pure, pid_risk_to_decision,
PidConfig, PidState,
};
#[cfg(feature = "std")]
pub use llmosafe_pipeline::STAGE_BODY;
pub use llmosafe_pipeline::{
CognitivePipeline, MemoryStats, PipelineConfig, PipelineResult, STAGE_DETECTION, STAGE_KERNEL,
STAGE_MEMORY, STAGE_MONITOR, STAGE_SIFT,
};
pub use llmosafe_sifter::SifterOutput;
#[allow(deprecated)]
pub use llmosafe_sifter::{
calculate_halo_signal, calculate_utility, get_bias_breakdown, sift_perceptions, sift_text,
BiasBreakdown,
};
#[cfg(feature = "std")]
#[allow(unsafe_code)]
#[allow(clippy::missing_safety_doc)]
#[allow(clippy::as_conversions, clippy::indexing_slicing)]
pub mod c_abi {
use std::sync::Mutex;
use crate::llmosafe_body::ResourceGuard;
use crate::llmosafe_integration::SafetyDecision;
use crate::llmosafe_kernel::Synapse;
use crate::llmosafe_memory;
use crate::llmosafe_pipeline::{CognitivePipeline, PipelineConfig, PipelineResult};
const ARENA_SIZE: usize = 16;
const MAX_OBJECTIVE_LEN: usize = 1024;
const ARENA_INDEX_MASK: usize = 0xF;
const GEN_SHIFT: usize = 4;
#[allow(dead_code)]
struct PipelineSlot {
pipeline: CognitivePipeline<'static, 64, 10>,
objective_buf: Box<[u8; MAX_OBJECTIVE_LEN]>,
last_result: Option<PipelineResult>,
generation: u64,
}
static NEXT_GENERATION: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
fn pack_handle(index: usize, generation: u64) -> usize {
index | ((generation as usize) << GEN_SHIFT)
}
fn unpack_handle(handle: usize) -> (usize, u64) {
let index = handle & ARENA_INDEX_MASK;
let generation = (handle >> GEN_SHIFT) as u64;
(index, generation)
}
fn lock_arena() -> std::sync::MutexGuard<'static, [Option<PipelineSlot>; ARENA_SIZE]> {
PIPELINE_ARENA.lock().unwrap_or_else(|e| {
tracing::warn!(
target: "llmosafe::c_abi",
"PIPELINE_ARENA mutex poisoned (prior panic detected), recovering inner state"
);
e.into_inner()
})
}
static PIPELINE_ARENA: Mutex<[Option<PipelineSlot>; ARENA_SIZE]> = Mutex::new([
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None,
]);
unsafe fn store_objective(buf: &mut Box<[u8; MAX_OBJECTIVE_LEN]>, input: &str) -> &'static str {
let mut len = input.len().min(MAX_OBJECTIVE_LEN - 1);
while !input.is_char_boundary(len) {
len = len.saturating_sub(1);
}
buf[..len].copy_from_slice(&input.as_bytes()[..len]);
buf[len] = 0;
let len_val = len;
core::str::from_utf8_unchecked(core::slice::from_raw_parts(buf.as_ptr(), len_val))
}
fn decision_to_code(decision: &SafetyDecision) -> i32 {
match decision {
SafetyDecision::Proceed => 0,
SafetyDecision::Warn(_) => 1,
SafetyDecision::Escalate { .. } => 2,
SafetyDecision::Halt(err, _) => i32::from(*err),
SafetyDecision::Exit(_) => -8,
}
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_create(objective_ptr: *const u8, objective_len: usize) -> usize {
if objective_ptr.is_null() || objective_len == 0 || objective_len > MAX_OBJECTIVE_LEN {
return usize::MAX;
}
let slice = unsafe { core::slice::from_raw_parts(objective_ptr, objective_len) };
let input_str = std::str::from_utf8(slice).unwrap_or("safety");
let mut objective_buf = Box::new([0u8; MAX_OBJECTIVE_LEN]);
let objective = unsafe { store_objective(&mut objective_buf, input_str) };
let config = PipelineConfig::default();
let pipeline = match CognitivePipeline::<'static, 64, 10>::with_config(objective, config) {
Ok(p) => p,
Err(_) => return usize::MAX,
};
let gen = NEXT_GENERATION.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
for (i, slot) in arena.iter_mut().enumerate() {
if slot.is_none() {
*slot = Some(PipelineSlot {
pipeline,
objective_buf,
last_result: None,
generation: gen,
});
return pack_handle(i, gen);
}
}
usize::MAX
}
fn get_validated_slot(
arena: &mut [Option<PipelineSlot>; ARENA_SIZE],
handle: usize,
) -> Option<&mut PipelineSlot> {
let (index, generation) = unpack_handle(handle);
if index >= ARENA_SIZE {
return None;
}
match &mut arena[index] {
Some(slot) if slot.generation == generation => Some(slot),
_ => None,
}
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_sift_and_process(
handle: usize,
text_ptr: *const u8,
text_len: usize,
) -> i32 {
if text_ptr.is_null()
|| text_len == 0
|| text_len > isize::MAX as usize
|| text_len > 10 * 1024 * 1024
{
return -9;
}
let slice = unsafe { core::slice::from_raw_parts(text_ptr, text_len) };
let text = String::from_utf8_lossy(slice);
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let slot = match get_validated_slot(&mut arena, handle) {
Some(s) => s,
None => return -9,
};
let result = slot.pipeline.process(&text);
let code = decision_to_code(&result.decision);
slot.last_result = Some(result);
code
}
#[no_mangle]
pub extern "C" fn llmosafe_get_decision(handle: usize) -> i32 {
let arena = lock_arena();
let (index, generation) = unpack_handle(handle);
if index >= ARENA_SIZE {
return -9;
}
arena[index]
.as_ref()
.filter(|s| s.generation == generation)
.map_or(-9, |slot| {
slot.last_result
.as_ref()
.map_or(-9, |r| decision_to_code(&r.decision))
})
}
#[no_mangle]
pub extern "C" fn llmosafe_get_classifier_score(instance_id: u32) -> f64 {
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return f64::NAN;
}
arena[index]
.as_ref()
.filter(|s| s.generation == generation)
.map_or_else(
|| f64::NAN,
|slot| {
slot.last_result
.as_ref()
.map_or_else(|| f64::NAN, |r| f64::from(r.classifier_score))
},
)
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_pid_state(
instance_id: u32,
acute: *mut f64,
chronic: *mut f64,
pressure: *mut f64,
) -> u32 {
if acute.is_null() || chronic.is_null() || pressure.is_null() {
return 1;
}
let arena = lock_arena();
let handle = instance_id as usize;
let (index, generation) = unpack_handle(handle);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let state = slot.pipeline.pid_state();
unsafe {
std::ptr::write_unaligned(acute, state.acute_entropy as f64);
std::ptr::write_unaligned(chronic, state.chronic_entropy as f64);
std::ptr::write_unaligned(pressure, state.prev_pressure_norm as f64);
}
0
}
#[no_mangle]
pub extern "C" fn llmosafe_destroy(handle: usize) {
let (index, generation) = unpack_handle(handle);
if index >= ARENA_SIZE {
return;
}
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
match &arena[index] {
Some(slot) if slot.generation == generation => {
arena[index] = None;
}
_ => {}
}
}
#[no_mangle]
pub extern "C" fn llmosafe_process_synapse(synapse_bits: u128) -> i32 {
llmosafe_memory::cognitive_memory::process_state_update(synapse_bits)
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_calculate_halo(text_ptr: *const u8, text_len: usize) -> u16 {
let max_text_len = 10 * 1024 * 1024;
if text_ptr.is_null()
|| text_len == 0
|| text_len > isize::MAX as usize
|| text_len > max_text_len
{
return u16::MAX;
}
let slice = unsafe { core::slice::from_raw_parts(text_ptr, text_len) };
let text = String::from_utf8_lossy(slice);
let (sifted, _proof) = crate::llmosafe_sifter::sift_text(&text);
sifted.raw_entropy()
}
#[no_mangle]
pub extern "C" fn llmosafe_check_resources(ceiling_mb: u32) -> i32 {
let ceiling_bytes = (ceiling_mb as usize).saturating_mul(1024 * 1024);
let guard = ResourceGuard::new(ceiling_bytes);
match guard.check() {
Ok(_) => 0,
Err(e) => i32::from(e),
}
}
#[no_mangle]
pub extern "C" fn llmosafe_get_resource_pressure(ceiling_mb: u32) -> u8 {
let ceiling_bytes = (ceiling_mb as usize).saturating_mul(1024 * 1024);
if ceiling_bytes == 0 {
return 100;
}
let guard = ResourceGuard::new(ceiling_bytes);
guard.pressure()
}
#[no_mangle]
pub extern "C" fn llmosafe_get_stability(synapse_bits: u128) -> i32 {
let synapse = Synapse::from_raw_u128(synapse_bits);
match synapse.validate() {
Ok(()) => 0,
Err(e) => i32::from(e),
}
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_memory_stats(
instance_id: u32,
mean: *mut f64,
variance: *mut f64,
trend: *mut f64,
drifting: *mut u32,
) -> u32 {
if mean.is_null() || variance.is_null() || trend.is_null() || drifting.is_null() {
return 1;
}
let arena = lock_arena();
let handle = instance_id as usize;
let (index, generation) = unpack_handle(handle);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let stats = slot.pipeline.memory_stats();
unsafe {
std::ptr::write_unaligned(mean, stats.mean);
std::ptr::write_unaligned(variance, stats.variance);
std::ptr::write_unaligned(trend, stats.trend);
std::ptr::write_unaligned(drifting, stats.is_drifting as u32);
}
0
}
#[no_mangle]
pub extern "C" fn llmosafe_get_system_cpu_load() -> u8 {
ResourceGuard::system_cpu_load()
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_kernel_output(
instance_id: u32,
error_out: *mut f32,
is_stable_out: *mut u8,
depth_out: *mut u32,
) -> i32 {
if error_out.is_null() || is_stable_out.is_null() || depth_out.is_null() {
return -9;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return -9;
}
arena[index]
.as_ref()
.filter(|s| s.generation == generation)
.and_then(|slot| slot.last_result.as_ref())
.and_then(|r| r.kernel_output())
.map_or(-9, |ko| {
unsafe {
std::ptr::write_unaligned(error_out, ko.error_kernel);
std::ptr::write_unaligned(is_stable_out, if ko.is_stable { 1 } else { 0 });
std::ptr::write_unaligned(depth_out, ko.depth as u32);
}
0
})
}
#[no_mangle]
pub extern "C" fn llmosafe_get_body_pressure(instance_id: u32) -> u32 {
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return u32::MAX;
}
arena[index]
.as_ref()
.filter(|s| s.generation == generation)
.map_or(u32::MAX, |slot| {
slot.last_result
.as_ref()
.map_or(u32::MAX, |r| u32::from(r.body_pressure()))
})
}
#[no_mangle]
pub extern "C" fn llmosafe_combined_risk_bits(synapse_bits: u128) -> u16 {
let synapse = Synapse::from_raw_u128(synapse_bits);
synapse.combined_risk_bits()
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_entropy(instance_id: u32, out: *mut u16) -> i32 {
if out.is_null() {
return 2;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let entropy = match slot.last_result.as_ref() {
Some(r) => r.entropy,
None => return 3,
};
unsafe {
std::ptr::write_unaligned(out, entropy);
}
0
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_surprise(instance_id: u32, out: *mut u16) -> i32 {
if out.is_null() {
return 2;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let surprise = match slot.last_result.as_ref() {
Some(r) => r.surprise,
None => return 3,
};
unsafe {
std::ptr::write_unaligned(out, surprise);
}
0
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_detection_flags(instance_id: u32, out: *mut u8) -> i32 {
if out.is_null() {
return 2;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let flags = match slot.last_result.as_ref() {
Some(r) => r.detection_flags,
None => return 3,
};
unsafe {
std::ptr::write_unaligned(out, flags);
}
0
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_oov_ratio(instance_id: u32, out: *mut u8) -> i32 {
if out.is_null() {
return 2;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let oov = match slot.last_result.as_ref() {
Some(r) => r.oov_ratio,
None => return 3,
};
unsafe {
std::ptr::write_unaligned(out, oov);
}
0
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_stages_executed(instance_id: u32, out: *mut u8) -> i32 {
if out.is_null() {
return 2;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let stages = match slot.last_result.as_ref() {
Some(r) => r.stages_executed,
None => return 3,
};
unsafe {
std::ptr::write_unaligned(out, stages);
}
0
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_get_step_count(instance_id: u32, out: *mut u32) -> i32 {
if out.is_null() {
return 2;
}
let arena = lock_arena();
let (index, generation) = unpack_handle(instance_id as usize);
if index >= ARENA_SIZE {
return 1;
}
let slot = match &arena[index] {
Some(s) if s.generation == generation => s,
_ => return 1,
};
let steps = match slot.last_result.as_ref() {
Some(r) => r.step_count as u32,
None => return 3,
};
unsafe {
std::ptr::write_unaligned(out, steps);
}
0
}
#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn llmosafe_process_with_pressure(
handle: usize,
text_ptr: *const u8,
text_len: usize,
body_entropy: u16,
pressure: u8,
) -> i32 {
if text_ptr.is_null()
|| text_len == 0
|| text_len > isize::MAX as usize
|| text_len > 10 * 1024 * 1024
{
return -9;
}
let slice = unsafe { core::slice::from_raw_parts(text_ptr, text_len) };
let text = String::from_utf8_lossy(slice);
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let slot = match get_validated_slot(&mut arena, handle) {
Some(s) => s,
None => return -9,
};
let result = slot
.pipeline
.process_with_pressure(&text, body_entropy, pressure);
let code = decision_to_code(&result.decision);
slot.last_result = Some(result);
code
}
#[no_mangle]
pub extern "C" fn llmosafe_reset_detectors(handle: usize) -> u32 {
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
match get_validated_slot(&mut arena, handle) {
Some(s) => {
s.pipeline.reset_detectors();
0
}
None => 1,
}
}
#[no_mangle]
pub extern "C" fn llmosafe_reset_full(handle: usize) -> u32 {
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
match get_validated_slot(&mut arena, handle) {
Some(s) => {
s.pipeline.reset_full();
0
}
None => 1,
}
}
#[no_mangle]
pub extern "C" fn llmosafe_configure(
instance_id: u32,
dal_level: u8,
use_detection_gate: u32,
_memory_depth: u32,
) -> u32 {
let dal = match dal_level {
0 => crate::control_types::DesignAssuranceLevel::A,
1 => crate::control_types::DesignAssuranceLevel::B,
2 => crate::control_types::DesignAssuranceLevel::C,
3 => crate::control_types::DesignAssuranceLevel::D,
_ => crate::control_types::DesignAssuranceLevel::E,
};
let mut arena = PIPELINE_ARENA
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let handle = instance_id as usize;
let (index, generation) = unpack_handle(handle);
if index >= ARENA_SIZE {
return 1;
}
match arena[index].as_mut() {
Some(slot) if slot.generation == generation => {
slot.pipeline.esc_policy.dal = dal;
slot.pipeline.use_detection_gate = use_detection_gate != 0;
0
}
_ => 1,
}
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "std")]
#[test]
fn test_c_abi_process_synapse_valid_bits() {
let bits = 400u128;
let result = crate::c_abi::llmosafe_process_synapse(bits);
assert_eq!(result, 0);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_calculate_halo_null_pointer() {
let result = crate::c_abi::llmosafe_calculate_halo(std::ptr::null(), 10);
assert_eq!(
result,
u16::MAX,
"null pointer should return u16::MAX error sentinel"
);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_calculate_halo_zero_length() {
let data = b"Hello";
let result = crate::c_abi::llmosafe_calculate_halo(data.as_ptr(), 0);
assert_eq!(
result,
u16::MAX,
"zero length should return u16::MAX error sentinel"
);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_calculate_halo_large_length() {
let data = b"Hello";
let result =
crate::c_abi::llmosafe_calculate_halo(data.as_ptr(), (isize::MAX as usize) + 1);
assert_eq!(
result,
u16::MAX,
"overflow length should return u16::MAX error sentinel"
);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_check_resources_ceiling_zero() {
let result = crate::c_abi::llmosafe_check_resources(0);
assert_eq!(result, -5);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_invalid_utf8() {
let invalid_data = b"Hello\\xFFWorld\\0";
let result =
crate::c_abi::llmosafe_calculate_halo(invalid_data.as_ptr(), invalid_data.len());
let _ = result;
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_resource_pressure() {
let pressure = crate::c_abi::llmosafe_get_resource_pressure(1024);
assert!(pressure <= 100);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_stability_valid() {
let valid_bits = 400u128;
let result = crate::c_abi::llmosafe_get_stability(valid_bits);
assert_eq!(result, 0);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_stability_unstable() {
let unstable_bits = 50001u128;
let result = crate::c_abi::llmosafe_get_stability(unstable_bits);
assert_eq!(result, -2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_system_cpu_load() {
let load = crate::c_abi::llmosafe_get_system_cpu_load();
assert!(load <= 100);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_environmental_entropy() {
let entropy = crate::llmosafe_body::llmosafe_get_environmental_entropy();
let _ = entropy;
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_create_valid() {
let objective = b"test objective";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_create_null_pointer() {
let handle = crate::c_abi::llmosafe_create(std::ptr::null(), 10);
assert_eq!(handle, usize::MAX);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_create_zero_length() {
let objective = b"test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), 0);
assert_eq!(handle, usize::MAX);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_create_overflow_length() {
let objective = b"test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), (isize::MAX as usize) + 1);
assert_eq!(handle, usize::MAX);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_create_invalid_utf8_truncation() {
let mut s = String::new();
for _ in 0..1020 {
s.push('a');
}
s.push('🌍'); assert_eq!(s.len(), 1024);
let handle = crate::c_abi::llmosafe_create(s.as_bytes().as_ptr(), s.len());
assert!(handle != usize::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_sift_and_process_valid() {
let objective = b"safety analysis";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"a completely normal sentence about everyday topics";
let code = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
assert!((-8..=2).contains(&code));
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_sift_and_process_invalid_handle() {
let text = b"some text";
let code = crate::c_abi::llmosafe_sift_and_process(999, text.as_ptr(), text.len());
assert_eq!(code, -9);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_sift_and_process_null_pointer() {
let objective = b"test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let code = crate::c_abi::llmosafe_sift_and_process(handle, std::ptr::null(), 10);
assert_eq!(code, -9);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_sift_and_process_zero_length() {
let objective = b"test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"data";
let code = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), 0);
assert_eq!(code, -9);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_decision_after_process() {
let objective = b"test objective";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"checking safety of input data here";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let decision = crate::c_abi::llmosafe_get_decision(handle);
assert!((-8..=2).contains(&decision));
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_decision_before_process() {
let objective = b"test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let decision = crate::c_abi::llmosafe_get_decision(handle);
assert_eq!(decision, -9);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_decision_invalid_handle() {
let decision = crate::c_abi::llmosafe_get_decision(999);
assert_eq!(decision, -9);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_destroy_valid() {
let objective = b"test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
crate::c_abi::llmosafe_destroy(handle);
let decision = crate::c_abi::llmosafe_get_decision(handle);
assert_eq!(decision, -9);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_destroy_invalid_handle_no_crash() {
crate::c_abi::llmosafe_destroy(999);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_destroy_double_no_crash() {
let objective = b"test double destroy";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
crate::c_abi::llmosafe_destroy(handle);
crate::c_abi::llmosafe_destroy(handle); }
#[cfg(feature = "std")]
#[test]
fn test_c_abi_create_process_destroy_cycle() {
let objective = b"cycle test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text1 = b"first observation for the pipeline test";
let code1 = crate::c_abi::llmosafe_sift_and_process(handle, text1.as_ptr(), text1.len());
assert!((-8..=2).contains(&code1));
let decision1 = crate::c_abi::llmosafe_get_decision(handle);
assert_eq!(code1, decision1);
let text2 = b"second observation for continued testing";
let code2 = crate::c_abi::llmosafe_sift_and_process(handle, text2.as_ptr(), text2.len());
assert!((-8..=2).contains(&code2));
let decision2 = crate::c_abi::llmosafe_get_decision(handle);
assert_eq!(code2, decision2);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_arena_slot_reuse() {
let obj = b"reuse";
let h1 = crate::c_abi::llmosafe_create(obj.as_ptr(), obj.len());
assert!(h1 != usize::MAX);
crate::c_abi::llmosafe_destroy(h1);
let h2 = crate::c_abi::llmosafe_create(obj.as_ptr(), obj.len());
assert!(h2 != usize::MAX);
let text = b"test observation for stale handle check";
let code = crate::c_abi::llmosafe_sift_and_process(h1, text.as_ptr(), text.len());
assert_eq!(code, -9);
crate::c_abi::llmosafe_destroy(h2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_arena_exhaustion() {
let objective = b"exhaust";
let mut handles = Vec::new();
for _ in 0..16 {
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
handles.push(handle);
}
let fail = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert_eq!(fail, usize::MAX);
for h in handles {
crate::c_abi::llmosafe_destroy(h);
}
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_decision_code_correspondence() {
let objective = b"mapping test objective string";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let safe_text = b"the weather forecast indicates mild temperatures";
let code =
crate::c_abi::llmosafe_sift_and_process(handle, safe_text.as_ptr(), safe_text.len());
assert!((-8..=2).contains(&code));
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_classifier_score_invalid_handle() {
let score = crate::c_abi::llmosafe_get_classifier_score(u32::MAX);
assert!(
score.is_nan(),
"invalid handle should return NaN, got {score}"
);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_classifier_score_no_result() {
let objective = b"classifier test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let score = crate::c_abi::llmosafe_get_classifier_score(handle as u32);
assert!(score.is_nan(), "no result should return NaN, got {score}");
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_classifier_score_valid() {
let objective = b"classifier valid test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"checking classifier scoring for this input text here";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let score = crate::c_abi::llmosafe_get_classifier_score(handle as u32);
assert!(score.is_finite());
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_pid_state_null_pointer() {
let mut acute = 0.0f64;
let result = crate::c_abi::llmosafe_get_pid_state(
0,
std::ptr::null_mut(),
&raw mut acute,
&raw mut acute,
);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_pid_state_invalid_handle() {
let mut acute = 0.0f64;
let mut chronic = 0.0f64;
let mut pressure = 0.0f64;
let result = crate::c_abi::llmosafe_get_pid_state(
u32::MAX,
&raw mut acute,
&raw mut chronic,
&raw mut pressure,
);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_pid_state_valid() {
let objective = b"pid state test str";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"testing pid state retrieval from pipeline after processing";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut acute = -999.0f64;
let mut chronic = -999.0f64;
let mut pressure = -999.0f64;
let result = crate::c_abi::llmosafe_get_pid_state(
handle as u32,
&raw mut acute,
&raw mut chronic,
&raw mut pressure,
);
assert_eq!(result, 0);
assert!(acute > -999.0);
assert!(chronic > -999.0);
assert!(pressure != -999.0);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_memory_stats_null_pointer() {
let mut mean = 0.0f64;
let result = crate::c_abi::llmosafe_get_memory_stats(
0,
std::ptr::null_mut(),
&raw mut mean,
&raw mut mean,
std::ptr::null_mut(),
);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_memory_stats_invalid_handle() {
let mut mean = 0.0f64;
let mut var = 0.0f64;
let mut trend = 0.0f64;
let mut drifting = 0u32;
let result = crate::c_abi::llmosafe_get_memory_stats(
u32::MAX,
&raw mut mean,
&raw mut var,
&raw mut trend,
&raw mut drifting,
);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_memory_stats_valid() {
let objective = b"memory stats test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"testing memory statistics after pipeline processing";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut mean = f64::NAN;
let mut var = f64::NAN;
let mut trend = f64::NAN;
let mut drifting = u32::MAX;
let result = crate::c_abi::llmosafe_get_memory_stats(
handle as u32,
&raw mut mean,
&raw mut var,
&raw mut trend,
&raw mut drifting,
);
assert_eq!(result, 0);
assert!(mean.is_finite());
assert!(var.is_finite());
assert!(trend.is_finite());
assert_ne!(drifting, u32::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_kernel_output_null_pointer() {
let mut err = 0.0f32;
let mut depth = 0u32;
let result = crate::c_abi::llmosafe_get_kernel_output(
0,
&raw mut err,
std::ptr::null_mut(),
&raw mut depth,
);
assert_eq!(result, -9);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_kernel_output_invalid_handle() {
let mut err = 0.0f32;
let mut stable = 0u8;
let mut depth = 0u32;
let result = crate::c_abi::llmosafe_get_kernel_output(
u32::MAX,
&raw mut err,
&raw mut stable,
&raw mut depth,
);
assert_eq!(result, -9);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_kernel_output_valid() {
let objective = b"kernel output test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"testing kernel output retrieval with pipeline execution";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut err = f32::NAN;
let mut stable = 99u8;
let mut depth = u32::MAX;
let result = crate::c_abi::llmosafe_get_kernel_output(
handle as u32,
&raw mut err,
&raw mut stable,
&raw mut depth,
);
if result == 0 {
assert!(err.is_finite());
assert!(stable <= 1);
assert_ne!(depth, u32::MAX);
} else {
assert_eq!(result, -9);
}
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_body_pressure_invalid_handle() {
let p = crate::c_abi::llmosafe_get_body_pressure(u32::MAX);
assert_eq!(p, u32::MAX);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_body_pressure_no_result() {
let objective = b"body pressure test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let p = crate::c_abi::llmosafe_get_body_pressure(handle as u32);
assert_eq!(p, u32::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_body_pressure_valid() {
let objective = b"body pressure valid";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"checking body pressure readings after processing";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let p = crate::c_abi::llmosafe_get_body_pressure(handle as u32);
assert!(p == u32::MAX || p <= 100);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_combined_risk_bits_valid() {
let bits = crate::c_abi::llmosafe_combined_risk_bits(400u128);
let _ = bits;
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_combined_risk_bits_zero() {
let bits = crate::c_abi::llmosafe_combined_risk_bits(0u128);
let _ = bits;
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_entropy_null_pointer() {
let result = crate::c_abi::llmosafe_get_entropy(0, std::ptr::null_mut());
assert_eq!(result, 2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_entropy_invalid_handle() {
let mut out = 0u16;
let result = crate::c_abi::llmosafe_get_entropy(u32::MAX, &raw mut out);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_entropy_no_result() {
let objective = b"entropy no result test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let mut out = 0u16;
let result = crate::c_abi::llmosafe_get_entropy(handle as u32, &raw mut out);
assert_eq!(result, 3);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_entropy_valid() {
let objective = b"entropy valid test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"validating entropy field retrieval from pipeline result";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut out = u16::MAX;
let result = crate::c_abi::llmosafe_get_entropy(handle as u32, &raw mut out);
assert_eq!(result, 0);
assert_ne!(out, u16::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_surprise_null_pointer() {
let result = crate::c_abi::llmosafe_get_surprise(0, std::ptr::null_mut());
assert_eq!(result, 2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_surprise_invalid_handle() {
let mut out = 0u16;
let result = crate::c_abi::llmosafe_get_surprise(u32::MAX, &raw mut out);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_surprise_no_result() {
let objective = b"surprise no result test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let mut out = 0u16;
let result = crate::c_abi::llmosafe_get_surprise(handle as u32, &raw mut out);
assert_eq!(result, 3);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_surprise_valid() {
let objective = b"surprise valid test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"retrieving surprise field from latest processing result";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut out = u16::MAX;
let result = crate::c_abi::llmosafe_get_surprise(handle as u32, &raw mut out);
assert_eq!(result, 0);
assert_ne!(out, u16::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_detection_flags_null_pointer() {
let result = crate::c_abi::llmosafe_get_detection_flags(0, std::ptr::null_mut());
assert_eq!(result, 2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_detection_flags_invalid_handle() {
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_detection_flags(u32::MAX, &raw mut out);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_detection_flags_no_result() {
let objective = b"detection flags no res";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_detection_flags(handle as u32, &raw mut out);
assert_eq!(result, 3);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_detection_flags_valid() {
let objective = b"detection flags valid";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"testing detection flags retrieval from pipeline run";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut out = 0xFFu8;
let result = crate::c_abi::llmosafe_get_detection_flags(handle as u32, &raw mut out);
assert_eq!(result, 0);
assert_ne!(out, 0xFF);
assert!(out <= 0x3F);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_oov_ratio_null_pointer() {
let result = crate::c_abi::llmosafe_get_oov_ratio(0, std::ptr::null_mut());
assert_eq!(result, 2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_oov_ratio_invalid_handle() {
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_oov_ratio(u32::MAX, &raw mut out);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_oov_ratio_no_result() {
let objective = b"oov ratio no result";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_oov_ratio(handle as u32, &raw mut out);
assert_eq!(result, 3);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_oov_ratio_valid() {
let objective = b"oov ratio valid test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"checking out of vocabulary ratio after text analysis";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut out = 0xFFu8;
let result = crate::c_abi::llmosafe_get_oov_ratio(handle as u32, &raw mut out);
assert_eq!(result, 0);
assert_ne!(out, 0xFF);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_stages_executed_null_pointer() {
let result = crate::c_abi::llmosafe_get_stages_executed(0, std::ptr::null_mut());
assert_eq!(result, 2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_stages_executed_invalid_handle() {
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_stages_executed(u32::MAX, &raw mut out);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_stages_executed_no_result() {
let objective = b"stages no result test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_stages_executed(handle as u32, &raw mut out);
assert_eq!(result, 3);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_stages_executed_valid() {
let objective = b"stages executed valid";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"verifying stages executed bitmask after pipeline completes";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut out = 0u8;
let result = crate::c_abi::llmosafe_get_stages_executed(handle as u32, &raw mut out);
assert_eq!(result, 0);
assert!(out & 0x01 != 0);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_step_count_null_pointer() {
let result = crate::c_abi::llmosafe_get_step_count(0, std::ptr::null_mut());
assert_eq!(result, 2);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_step_count_invalid_handle() {
let mut out = 0u32;
let result = crate::c_abi::llmosafe_get_step_count(u32::MAX, &raw mut out);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_step_count_no_result() {
let objective = b"step count no result";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let mut out = 0u32;
let result = crate::c_abi::llmosafe_get_step_count(handle as u32, &raw mut out);
assert_eq!(result, 3);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_get_step_count_valid() {
let objective = b"step count valid test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"counting reasoning steps after pipeline processed this text";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let mut out = u32::MAX;
let result = crate::c_abi::llmosafe_get_step_count(handle as u32, &raw mut out);
assert_eq!(result, 0);
assert_ne!(out, u32::MAX);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_process_with_pressure_null_pointer() {
let objective = b"pressure null test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let code =
crate::c_abi::llmosafe_process_with_pressure(handle, std::ptr::null(), 10, 50u16, 25u8);
assert_eq!(code, -9);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_process_with_pressure_zero_length() {
let objective = b"pressure zero len";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"some text";
let code =
crate::c_abi::llmosafe_process_with_pressure(handle, text.as_ptr(), 0, 50u16, 25u8);
assert_eq!(code, -9);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_process_with_pressure_invalid_handle() {
let text = b"testing pressure processing with invalid handle";
let code = crate::c_abi::llmosafe_process_with_pressure(
usize::MAX,
text.as_ptr(),
text.len(),
50u16,
25u8,
);
assert_eq!(code, -9);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_process_with_pressure_valid() {
let objective = b"pressure valid test str";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"testing the process with pressure function using valid data";
let code = crate::c_abi::llmosafe_process_with_pressure(
handle,
text.as_ptr(),
text.len(),
400u16,
30u8,
);
assert!((-8..=2).contains(&code));
let bp = crate::c_abi::llmosafe_get_body_pressure(handle as u32);
assert!(bp <= 100);
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_reset_detectors_invalid_handle() {
let result = crate::c_abi::llmosafe_reset_detectors(usize::MAX);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_reset_detectors_valid() {
let objective = b"reset detectors test";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"test observation for reset detectors function test";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let result = crate::c_abi::llmosafe_reset_detectors(handle);
assert_eq!(result, 0);
let text2 = b"another observation after resetting pipeline detectors";
let code = crate::c_abi::llmosafe_sift_and_process(handle, text2.as_ptr(), text2.len());
assert!((-8..=2).contains(&code));
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_reset_full_invalid_handle() {
let result = crate::c_abi::llmosafe_reset_full(usize::MAX);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_reset_full_valid() {
let objective = b"reset full test str";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let text = b"first observation for full reset of the pipeline test";
let _ = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
let result = crate::c_abi::llmosafe_reset_full(handle);
assert_eq!(result, 0);
let text2 = b"another observation after a full reset of pipeline";
let code = crate::c_abi::llmosafe_sift_and_process(handle, text2.as_ptr(), text2.len());
assert!((-8..=2).contains(&code));
crate::c_abi::llmosafe_destroy(handle);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_configure_invalid_handle() {
let result = crate::c_abi::llmosafe_configure(u32::MAX, 2, 1, 64);
assert_eq!(result, 1);
}
#[cfg(feature = "std")]
#[test]
fn test_c_abi_configure_valid() {
let objective = b"configure test str";
let handle = crate::c_abi::llmosafe_create(objective.as_ptr(), objective.len());
assert!(handle != usize::MAX);
let result = crate::c_abi::llmosafe_configure(handle as u32, 2, 1, 64);
assert_eq!(result, 0);
let text = b"testing pipeline operation after runtime configuration change";
let code = crate::c_abi::llmosafe_sift_and_process(handle, text.as_ptr(), text.len());
assert!((-8..=2).contains(&code));
crate::c_abi::llmosafe_destroy(handle);
}
}