tirea_contract/runtime/
executor.rs1use crate::event::interaction::{FrontendToolInvocation, Interaction};
2use crate::plugin::contract::AgentPlugin;
3use crate::runtime::activity::ActivityManager;
4use crate::thread::{Message, ToolCall};
5use crate::tool::contract::{Tool, ToolDescriptor, ToolResult};
6use crate::RunConfig;
7use async_trait::async_trait;
8use futures::Stream;
9use genai::chat::{ChatOptions, ChatRequest, ChatResponse, ChatStreamEvent};
10use serde_json::Value;
11use std::collections::HashMap;
12use std::pin::Pin;
13use std::sync::Arc;
14use thiserror::Error;
15use tirea_state::TrackedPatch;
16use tokio_util::sync::CancellationToken;
17
18pub type LlmEventStream = Pin<Box<dyn Stream<Item = genai::Result<ChatStreamEvent>> + Send>>;
20
21#[async_trait]
23pub trait LlmExecutor: Send + Sync {
24 async fn exec_chat_response(
26 &self,
27 model: &str,
28 chat_req: ChatRequest,
29 options: Option<&ChatOptions>,
30 ) -> genai::Result<ChatResponse>;
31
32 async fn exec_chat_stream_events(
34 &self,
35 model: &str,
36 chat_req: ChatRequest,
37 options: Option<&ChatOptions>,
38 ) -> genai::Result<LlmEventStream>;
39
40 fn name(&self) -> &'static str {
42 "llm_executor"
43 }
44}
45
46#[derive(Debug, Clone)]
48pub struct ToolExecution {
49 pub call: ToolCall,
50 pub result: ToolResult,
51 pub patch: Option<TrackedPatch>,
52}
53
54pub struct ToolExecutionRequest<'a> {
56 pub tools: &'a HashMap<String, Arc<dyn Tool>>,
57 pub calls: &'a [ToolCall],
58 pub state: &'a Value,
59 pub tool_descriptors: &'a [ToolDescriptor],
60 pub plugins: &'a [Arc<dyn AgentPlugin>],
61 pub activity_manager: Option<Arc<dyn ActivityManager>>,
62 pub run_config: &'a RunConfig,
63 pub thread_id: &'a str,
64 pub thread_messages: &'a [Arc<Message>],
65 pub state_version: u64,
66 pub cancellation_token: Option<&'a CancellationToken>,
67}
68
69#[derive(Debug, Clone)]
71pub struct ToolExecutionResult {
72 pub execution: ToolExecution,
73 pub reminders: Vec<String>,
74 pub pending_interaction: Option<Interaction>,
75 pub pending_frontend_invocation: Option<FrontendToolInvocation>,
76 pub pending_patches: Vec<TrackedPatch>,
77}
78
79#[derive(Debug, Clone, Error)]
81pub enum ToolExecutorError {
82 #[error("tool execution cancelled")]
83 Cancelled { thread_id: String },
84 #[error("tool execution failed: {message}")]
85 Failed { message: String },
86}
87
88#[async_trait]
90pub trait ToolExecutor: Send + Sync {
91 async fn execute(
92 &self,
93 request: ToolExecutionRequest<'_>,
94 ) -> Result<Vec<ToolExecutionResult>, ToolExecutorError>;
95
96 fn name(&self) -> &'static str;
98
99 fn requires_parallel_patch_conflict_check(&self) -> bool {
101 false
102 }
103}