use super::{
NemoFlowEventSubscriberCb, NemoFlowFreeFn, NemoFlowJsonCb, NemoFlowLlmConditionalCb,
NemoFlowLlmExecInterceptCb, NemoFlowLlmRequestCb, NemoFlowLlmRequestInterceptCb,
NemoFlowStatus, NemoFlowToolConditionalCb, NemoFlowToolExecInterceptCb, NemoFlowToolSanitizeCb,
c_char, c_str_to_string, clear_last_error, core_registry_api, core_subscriber_api,
set_last_error, status_from_error, wrap_event_subscriber, wrap_llm_conditional_fn,
wrap_llm_exec_intercept_fn, wrap_llm_request_intercept_fn, wrap_llm_response_fn,
wrap_llm_sanitize_request_fn, wrap_llm_stream_exec_intercept_fn, wrap_tool_conditional_fn,
wrap_tool_exec_intercept_fn, wrap_tool_request_intercept_fn, wrap_tool_sanitize_fn,
};
fn parse_scope_uuid(scope_uuid: *const c_char) -> Result<uuid::Uuid, NemoFlowStatus> {
let uuid_str = c_str_to_string(scope_uuid)?;
uuid::Uuid::parse_str(&uuid_str).map_err(|e| {
set_last_error(&format!("invalid scope UUID: {e}"));
NemoFlowStatus::InvalidArg
})
}
macro_rules! ffi_scope_guardrail_tool_api {
($(#[$reg_doc:meta])* $register_name:ident,
$(#[$dereg_doc:meta])* $deregister_name:ident,
$core_register:path, $core_deregister:path, $wrapper:ident) => {
$(#[$reg_doc])*
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $register_name(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
cb: NemoFlowToolSanitizeCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = $wrapper(cb, user_data, free_fn);
match $core_register(&uuid, &name, priority, wrapped) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
$(#[$dereg_doc])*
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $deregister_name(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match $core_deregister(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
};
}
ffi_scope_guardrail_tool_api!(
nemo_flow_scope_register_tool_sanitize_request_guardrail,
nemo_flow_scope_deregister_tool_sanitize_request_guardrail,
core_registry_api::scope_register_tool_sanitize_request_guardrail,
core_registry_api::scope_deregister_tool_sanitize_request_guardrail,
wrap_tool_sanitize_fn
);
ffi_scope_guardrail_tool_api!(
nemo_flow_scope_register_tool_sanitize_response_guardrail,
nemo_flow_scope_deregister_tool_sanitize_response_guardrail,
core_registry_api::scope_register_tool_sanitize_response_guardrail,
core_registry_api::scope_deregister_tool_sanitize_response_guardrail,
wrap_tool_sanitize_fn
);
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_tool_conditional_execution_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
cb: NemoFlowToolConditionalCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = wrap_tool_conditional_fn(cb, user_data, free_fn);
match core_registry_api::scope_register_tool_conditional_execution_guardrail(
&uuid, &name, priority, wrapped,
) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_tool_conditional_execution_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_tool_conditional_execution_guardrail(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
macro_rules! ffi_scope_intercept_tool_api {
($(#[$reg_doc:meta])* $register_name:ident,
$(#[$dereg_doc:meta])* $deregister_name:ident,
$core_register:path, $core_deregister:path, $wrapper:ident) => {
$(#[$reg_doc])*
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $register_name(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
break_chain: bool,
cb: NemoFlowToolSanitizeCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = $wrapper(cb, user_data, free_fn);
match $core_register(&uuid, &name, priority, break_chain, wrapped) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
$(#[$dereg_doc])*
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $deregister_name(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match $core_deregister(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
};
}
ffi_scope_intercept_tool_api!(
nemo_flow_scope_register_tool_request_intercept,
nemo_flow_scope_deregister_tool_request_intercept,
core_registry_api::scope_register_tool_request_intercept,
core_registry_api::scope_deregister_tool_request_intercept,
wrap_tool_request_intercept_fn
);
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_tool_execution_intercept(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
exec_cb: NemoFlowToolExecInterceptCb,
exec_user_data: *mut libc::c_void,
exec_free: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let exec = wrap_tool_exec_intercept_fn(exec_cb, exec_user_data, exec_free);
match core_registry_api::scope_register_tool_execution_intercept(&uuid, &name, priority, exec) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_tool_execution_intercept(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_tool_execution_intercept(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_llm_sanitize_request_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
cb: NemoFlowLlmRequestCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = wrap_llm_sanitize_request_fn(cb, user_data, free_fn);
match core_registry_api::scope_register_llm_sanitize_request_guardrail(
&uuid, &name, priority, wrapped,
) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_llm_sanitize_request_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_llm_sanitize_request_guardrail(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_llm_sanitize_response_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
cb: NemoFlowJsonCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = wrap_llm_response_fn(cb, user_data, free_fn);
match core_registry_api::scope_register_llm_sanitize_response_guardrail(
&uuid, &name, priority, wrapped,
) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_llm_sanitize_response_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_llm_sanitize_response_guardrail(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_llm_conditional_execution_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
cb: NemoFlowLlmConditionalCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = wrap_llm_conditional_fn(cb, user_data, free_fn);
match core_registry_api::scope_register_llm_conditional_execution_guardrail(
&uuid, &name, priority, wrapped,
) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_llm_conditional_execution_guardrail(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_llm_conditional_execution_guardrail(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_llm_request_intercept(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
break_chain: bool,
cb: NemoFlowLlmRequestInterceptCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = wrap_llm_request_intercept_fn(cb, user_data, free_fn);
match core_registry_api::scope_register_llm_request_intercept(
&uuid,
&name,
priority,
break_chain,
wrapped,
) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_llm_request_intercept(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_llm_request_intercept(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_llm_execution_intercept(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
exec_cb: NemoFlowLlmExecInterceptCb,
exec_user_data: *mut libc::c_void,
exec_free: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let exec = wrap_llm_exec_intercept_fn(exec_cb, exec_user_data, exec_free);
match core_registry_api::scope_register_llm_execution_intercept(&uuid, &name, priority, exec) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_llm_execution_intercept(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_llm_execution_intercept(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_llm_stream_execution_intercept(
scope_uuid: *const c_char,
name: *const c_char,
priority: i32,
exec_cb: NemoFlowLlmExecInterceptCb,
exec_user_data: *mut libc::c_void,
exec_free: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let exec = wrap_llm_stream_exec_intercept_fn(exec_cb, exec_user_data, exec_free);
match core_registry_api::scope_register_llm_stream_execution_intercept(
&uuid, &name, priority, exec,
) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_llm_stream_execution_intercept(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_registry_api::scope_deregister_llm_stream_execution_intercept(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_register_subscriber(
scope_uuid: *const c_char,
name: *const c_char,
cb: NemoFlowEventSubscriberCb,
user_data: *mut libc::c_void,
free_fn: NemoFlowFreeFn,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
let wrapped = wrap_event_subscriber(cb, user_data, free_fn);
match core_subscriber_api::scope_register_subscriber(&uuid, &name, wrapped) {
Ok(()) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nemo_flow_scope_deregister_subscriber(
scope_uuid: *const c_char,
name: *const c_char,
) -> NemoFlowStatus {
clear_last_error();
let uuid = match parse_scope_uuid(scope_uuid) {
Ok(u) => u,
Err(status) => return status,
};
let name = match c_str_to_string(name) {
Ok(s) => s,
Err(status) => return status,
};
match core_subscriber_api::scope_deregister_subscriber(&uuid, &name) {
Ok(_) => NemoFlowStatus::Ok,
Err(e) => status_from_error(&e),
}
}