Skip to main content

agent_types/
guard.rs

1//! Guard-related pure types: GuardDecision, GuardCtx.
2
3use serde::{Deserialize, Serialize};
4
5use crate::execution::FinishReason;
6use crate::session::SessionId;
7
8/// Guard decision — returned by guard, executed by base loop.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub enum GuardDecision {
11    /// Continue loop, optionally inject nudge message
12    Continue { nudge: Option<String> },
13    /// Normal completion (fire_turn_end + RunOutcome::Completed)
14    Complete,
15    /// Abnormal termination (fire_guard_fail + RunOutcome::Failed)
16    Fail { error: String },
17
18    // ─── Thinking control ─────────────────────────────────────
19    /// Temporarily disable thinking functionality
20    ///
21    /// Used for reasoning-only loop scenarios: model keeps thinking but produces no output.
22    /// After calling, runtime will:
23    /// 1. Set thinking_disabled_for_rest_of_run = true
24    /// 2. Inject nudge message
25    /// 3. Continue loop
26    DisableThinking { nudge: String },
27
28    /// Restore thinking functionality to previous state
29    ///
30    /// Used for thinking recovery scenarios: model starts working normally (has text or tool call).
31    /// After calling, runtime will:
32    /// 1. Restore thinking_disabled_for_rest_of_run to original state
33    /// 2. Reset related counters
34    RestoreThinking,
35}
36
37/// Guard context information — built by runtime, passed to guard.
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct GuardCtx {
40    pub session_id: SessionId,
41    pub turn_count: u32,
42    pub user_input: String,
43    pub model_response: String,
44    pub finish_reason: FinishReason,
45    pub available_tools: Vec<String>,
46    // RunState information
47    pub reasoning_only_strikes: usize,
48    pub empty_response_strikes: usize,
49    pub run_has_tool_calls: bool,
50    /// All user messages in the current session, ordered oldest-first.
51    /// Guards can use this to reconstruct full conversation context
52    /// (e.g. "继续" after a multi-turn discussion).
53    pub all_user_inputs: Vec<String>,
54    // Scene hints (runtime detected, guard can trust or ignore)
55    pub is_reasoning_only: bool,
56    pub is_empty_response: bool,
57    pub is_text_only: bool,
58    // Environment state
59    pub thinking_disabled: bool,
60    /// Original thinking configuration (for restoration)
61    ///
62    /// From RunState.original_thinking_enabled
63    pub original_thinking_enabled: bool,
64    /// Remaining turns before hitting max_turns limit
65    ///
66    /// Guards can use this to nudge the model to wrap up when running low on turns.
67    /// When remaining_turns == 0, the run will be terminated with MaxTurnsExceeded.
68    pub remaining_turns: u32,
69}