tirea_contract/runtime/tool_call/
executor.rs1use crate::runtime::activity::ActivityManager;
2use crate::runtime::behavior::AgentBehavior;
3use crate::runtime::tool_call::lifecycle::SuspendedCall;
4use crate::runtime::tool_call::{Tool, ToolDescriptor, ToolResult};
5use crate::thread::{Message, ToolCall};
6use crate::RunConfig;
7use async_trait::async_trait;
8use serde_json::Value;
9use std::collections::HashMap;
10use std::sync::Arc;
11use thiserror::Error;
12use tirea_state::TrackedPatch;
13use tokio_util::sync::CancellationToken;
14
15#[derive(Debug, Clone)]
17pub struct ToolExecution {
18 pub call: ToolCall,
19 pub result: ToolResult,
20 pub patch: Option<TrackedPatch>,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
25#[serde(rename_all = "snake_case")]
26pub enum ToolCallOutcome {
27 Suspended,
29 Succeeded,
31 Failed,
33}
34
35impl ToolCallOutcome {
36 pub fn from_tool_result(result: &ToolResult) -> Self {
38 match result.status {
39 crate::runtime::tool_call::ToolStatus::Pending => Self::Suspended,
40 crate::runtime::tool_call::ToolStatus::Error => Self::Failed,
41 crate::runtime::tool_call::ToolStatus::Success
42 | crate::runtime::tool_call::ToolStatus::Warning => Self::Succeeded,
43 }
44 }
45}
46
47pub struct ToolExecutionRequest<'a> {
49 pub tools: &'a HashMap<String, Arc<dyn Tool>>,
50 pub calls: &'a [ToolCall],
51 pub state: &'a Value,
52 pub tool_descriptors: &'a [ToolDescriptor],
53 pub agent_behavior: Option<&'a dyn AgentBehavior>,
55 pub activity_manager: Arc<dyn ActivityManager>,
56 pub run_config: &'a RunConfig,
57 pub thread_id: &'a str,
58 pub thread_messages: &'a [Arc<Message>],
59 pub state_version: u64,
60 pub cancellation_token: Option<&'a CancellationToken>,
61}
62
63#[derive(Debug, Clone)]
65pub struct ToolExecutionResult {
66 pub execution: ToolExecution,
67 pub outcome: ToolCallOutcome,
68 pub suspended_call: Option<SuspendedCall>,
70 pub reminders: Vec<String>,
71 pub user_messages: Vec<String>,
73 pub pending_patches: Vec<TrackedPatch>,
74 pub serialized_actions: Vec<crate::runtime::state::SerializedAction>,
76}
77
78#[derive(Debug, Clone, Error)]
80pub enum ToolExecutorError {
81 #[error("tool execution cancelled")]
82 Cancelled { thread_id: String },
83 #[error("tool execution failed: {message}")]
84 Failed { message: String },
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum DecisionReplayPolicy {
90 Immediate,
92 BatchAllSuspended,
94}
95
96#[async_trait]
98pub trait ToolExecutor: Send + Sync {
99 async fn execute(
100 &self,
101 request: ToolExecutionRequest<'_>,
102 ) -> Result<Vec<ToolExecutionResult>, ToolExecutorError>;
103
104 fn name(&self) -> &'static str;
106
107 fn requires_parallel_patch_conflict_check(&self) -> bool {
109 false
110 }
111
112 fn decision_replay_policy(&self) -> DecisionReplayPolicy {
114 DecisionReplayPolicy::Immediate
115 }
116}