Skip to main content

agent_works/guard/
config.rs

1/// Reasoning-only handling strategy
2#[derive(Debug, Clone, Default)]
3pub enum ReasoningOnlyAction {
4    /// Default: fail after N nudges
5    #[default]
6    Fail,
7    /// New: disable thinking after N nudges, continue running
8    DisableThinking,
9}
10
11/// Default guard configuration
12pub struct DefaultGuardConfig {
13    // ─── reasoning-only configuration ─────────────────────────
14    /// Maximum retries for reasoning-only responses
15    pub reasoning_only_max_strikes: usize,
16    /// Nudge message for reasoning-only responses
17    pub reasoning_only_nudge: String,
18    /// Reasoning-only handling strategy
19    pub reasoning_only_action: ReasoningOnlyAction,
20
21    // ─── thinking guard configuration (for DisableThinking strategy) ──
22    /// Nudge message when disabling thinking
23    pub disable_thinking_nudge: String,
24
25    // ─── empty-response configuration ─────────────────────────
26    /// Maximum retries for empty responses
27    pub empty_response_max_strikes: usize,
28    /// Nudge message for empty responses
29    pub empty_response_nudge: String,
30
31    // ─── text-only configuration ─────────────────────────────
32    /// Whether to use LLM judge for text-only after tools
33    pub use_llm_judge: bool,
34    /// Timeout in seconds for the LLM judge call
35    pub judge_timeout_secs: u64,
36    /// Skip judge if response is longer than this (likely complete)
37    pub judge_skip_threshold: usize,
38    /// Whether to trust LLM when judge fails or times out.
39    /// - true: fail-open (trust the model, end loop)
40    /// - false: fail-closed (don't trust, force continue)
41    pub judge_fail_open: bool,
42    /// Enable short-response detection (merged from CompletionGateMiddleware).
43    /// When the user input is long but the model response is very short,
44    /// treat it as potentially incomplete and nudge/judge accordingly.
45    pub detect_short_response: bool,
46    /// Minimum user input character count to trigger short-response detection.
47    pub short_response_min_input: usize,
48    /// Maximum LLM output character count to be considered a short response.
49    pub short_response_max_output: usize,
50    /// Nudge message for short responses
51    pub short_response_nudge: String,
52    /// Number of recent user messages to include in the judge prompt.
53    /// Helps the judge understand context like "继续" after a multi-turn discussion.
54    pub recent_user_count: usize,
55}
56
57impl Default for DefaultGuardConfig {
58    fn default() -> Self {
59        Self {
60            // reasoning-only
61            reasoning_only_max_strikes: 3,
62            reasoning_only_nudge: "You produced internal reasoning but no tool call \
63                and no final answer. Make a decision now: call a tool to make progress, \
64                or write your final answer as plain text."
65                .to_string(),
66            reasoning_only_action: ReasoningOnlyAction::Fail,
67
68            // thinking guard
69            disable_thinking_nudge: "Thinking has been disabled due to excessive reasoning. \
70                You MUST now either call a tool or write your final answer. \
71                Do NOT attempt to reason further."
72                .to_string(),
73
74            // empty-response
75            empty_response_max_strikes: 3,
76            empty_response_nudge: "Your response was empty. Please provide a response \
77                with either a tool call or your final answer."
78                .to_string(),
79
80            // text-only
81            use_llm_judge: true,
82            judge_timeout_secs: 10,
83            judge_skip_threshold: 256,
84            judge_fail_open: false, // Default: don't trust LLM on judge failure
85            detect_short_response: true,
86            short_response_min_input: 128,
87            short_response_max_output: 64,
88            short_response_nudge: "Your response may be incomplete — \
89                you may need to continue."
90                .to_string(),
91            recent_user_count: 5,
92        }
93    }
94}