pub mod prompt_injection;
pub mod sensitive_data;
pub mod tool_confirmation;
pub mod unrestricted_tool;
pub use prompt_injection::NoPromptInjectionMarkerRule;
pub use sensitive_data::NoSensitiveDataInInstructionsRule;
pub use tool_confirmation::ToolConfirmationRequiredRule;
pub use unrestricted_tool::NoUnrestrictedToolGrantRule;
use crate::rules::{Rule, RuleId};
pub const AIL200: RuleId = RuleId::new(200, "no-prompt-injection-marker");
pub const AIL201: RuleId = RuleId::new(201, "no-unrestricted-tool-grant");
pub const AIL202: RuleId = RuleId::new(202, "no-sensitive-data-in-instructions");
pub const AIL203: RuleId = RuleId::new(203, "tool-confirmation-required");
pub fn all_rules() -> Vec<Box<dyn Rule>> {
vec![
Box::new(NoPromptInjectionMarkerRule),
Box::new(NoUnrestrictedToolGrantRule),
Box::new(NoSensitiveDataInInstructionsRule),
Box::new(ToolConfirmationRequiredRule),
]
}
pub(crate) fn line_of_offset(raw: &str, offset: usize) -> usize {
let cap = offset.min(raw.len());
raw.as_bytes()[..cap]
.iter()
.filter(|&&b| b == b'\n')
.count()
+ 1
}
pub(crate) fn line_containing(raw: &str, offset: usize) -> String {
let bytes = raw.as_bytes();
let cap = offset.min(bytes.len());
let start = bytes[..cap]
.iter()
.rposition(|&b| b == b'\n')
.map(|i| i + 1)
.unwrap_or(0);
let end = bytes[cap..]
.iter()
.position(|&b| b == b'\n')
.map(|i| cap + i)
.unwrap_or(bytes.len());
raw[start..end].trim().to_string()
}
pub(crate) fn truncate_chars(s: &str, max: usize) -> String {
if s.chars().count() <= max {
return s.to_string();
}
s.chars().take(max).collect()
}