Skip to main content

tirea_contract/event/
termination.rs

1use serde::{Deserialize, Serialize};
2
3/// Why stop-condition evaluation requested loop termination.
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(tag = "type", content = "value", rename_all = "snake_case")]
6pub enum StopReason {
7    /// Maximum tool-call rounds reached.
8    MaxRoundsReached,
9    /// Total elapsed time exceeded the configured limit.
10    TimeoutReached,
11    /// Cumulative token usage exceeded the configured budget.
12    TokenBudgetExceeded,
13    /// A specific tool was called that triggers termination.
14    ToolCalled(String),
15    /// LLM output matched a stop pattern.
16    ContentMatched(String),
17    /// Too many consecutive tool execution failures.
18    ConsecutiveErrorsExceeded,
19    /// Identical tool call patterns detected across rounds.
20    LoopDetected,
21    /// Custom stop reason from a user-defined condition.
22    Custom(String),
23}
24
25/// Why a run terminated.
26///
27/// This is the top-level lifecycle exit reason for a run. A stop-condition hit is
28/// represented by `Stopped(...)`.
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30#[serde(tag = "type", content = "value", rename_all = "snake_case")]
31pub enum TerminationReason {
32    /// LLM returned a response with no tool calls.
33    NaturalEnd,
34    /// A plugin requested inference skip.
35    PluginRequested,
36    /// A configured stop condition fired.
37    Stopped(StopReason),
38    /// External run cancellation signal was received.
39    Cancelled,
40    /// Run paused waiting for external interaction input.
41    PendingInteraction,
42    /// Run ended due to an error path.
43    Error,
44}
45
46/// Declarative stop-condition configuration used by loop runtimes.
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
48#[serde(tag = "type", rename_all = "snake_case")]
49pub enum StopConditionSpec {
50    /// Stop after a fixed number of tool-call rounds.
51    MaxRounds { rounds: usize },
52    /// Stop after a wall-clock duration (in seconds) elapses.
53    Timeout { seconds: u64 },
54    /// Stop when cumulative token usage exceeds a budget. 0 = unlimited.
55    TokenBudget { max_total: usize },
56    /// Stop after N consecutive rounds where all tool executions failed. 0 = disabled.
57    ConsecutiveErrors { max: usize },
58    /// Stop when a specific tool is called by the LLM.
59    StopOnTool { tool_name: String },
60    /// Stop when LLM output text contains a literal pattern.
61    ContentMatch { pattern: String },
62    /// Stop when identical tool call patterns repeat within a sliding window.
63    LoopDetection { window: usize },
64}