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}