Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions crates/mesh-llm-guardrails/src/content.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// Removes hidden reasoning blocks from model-visible text.
///
/// This is content hygiene only. Tool calls are parsed by the model runtime's
/// native chat parser and are never recovered from assistant text here.
pub fn strip_thinking_blocks(content: &str) -> String {
let stripped_html = strip_tag_pairs(content, "<think>", "</think>");
let stripped_brackets = strip_tag_pairs(&stripped_html, "[THINK]", "[/THINK]");
stripped_brackets.trim().to_owned()
}

fn strip_tag_pairs(content: &str, start_tag: &str, end_tag: &str) -> String {
let mut remainder = content;
let mut result = String::new();
while let Some(start_index) = remainder.find(start_tag) {
result.push_str(&remainder[..start_index]);
let after_start = &remainder[start_index + start_tag.len()..];
if let Some(end_index) = after_start.find(end_tag) {
remainder = &after_start[end_index + end_tag.len()..];
} else {
return result;
}
}
result.push_str(remainder);
result
}
Comment thread
i386 marked this conversation as resolved.

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn strips_supported_thinking_blocks() {
assert_eq!(
strip_thinking_blocks("<think>hidden</think>Visible answer"),
"Visible answer"
);
assert_eq!(
strip_thinking_blocks("[THINK]hidden[/THINK]Visible answer"),
"Visible answer"
);
}

#[test]
fn drops_unterminated_thinking_blocks_without_duplicating_prefix() {
assert_eq!(strip_thinking_blocks("hello <think>truncated"), "hello");
}
}
7 changes: 2 additions & 5 deletions crates/mesh-llm-guardrails/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
pub mod compact;
pub mod content;
pub mod policy;
pub mod request_contract;
pub mod rescue;
pub mod structured;
pub mod tools;

pub use compact::{
CompactionConfig, CompactionDecision, CompactionOverride, CompactionReport, CompactionRequest,
MESH_COMPACT_FIELD, compact_messages, estimate_message_tokens,
};
pub use content::strip_thinking_blocks;
pub use policy::{
GuardrailMode, GuardrailPolicy, GuardrailPolicyHandle, RetryExhaustionMode,
StreamingGuardrailMode,
Expand All @@ -17,10 +18,6 @@ pub use request_contract::{
GuardrailRequestContract, MESH_GUARDRAILS_FIELD, MeshGuardrailsOverride, ParallelToolCalls,
RawResponseFormat, RawToolChoice, RawToolDefinition, RawToolSpec, StructuredResponseFormat,
};
pub use rescue::{
ParsedToolCall, ToolCallParseError, parse_tool_call_value, rescue_tool_call_from_text,
strip_thinking_blocks,
};
pub use structured::{StructuredOutputSpec, UnsupportedStructuredSchema};
pub use tools::{
MESH_EMIT_STRUCTURED_TOOL_NAME, MESH_RESPOND_TOOL_NAME, ToolArgumentSchemaError,
Expand Down
Loading
Loading