af_agent_runtime/
types.rs1use af_context::{InputId, InteractionId, RunId, SessionId};
2use std::time::Duration;
3use std::time::Instant;
4
5use af_agent_session::{ContentBlock, Event, SessionEvent};
6use af_llm::ChatMessage;
7use async_trait::async_trait;
8
9use crate::{CancellationToken, RuntimeError};
10
11#[derive(Debug, Clone)]
13pub struct RuntimeLimits {
14 pub max_images: usize,
16 pub max_steps: u32,
18 pub max_tool_calls: u32,
20 pub max_tokens: u64,
22 pub max_parallel_tools: usize,
24 pub provider_attempts: u32,
26 pub provider_deadline: Duration,
28}
29
30impl Default for RuntimeLimits {
31 fn default() -> Self {
32 Self {
33 max_images: af_llm::images::MAX_INPUT_IMAGES,
34 max_steps: 8,
35 max_tool_calls: 24,
36 max_tokens: 64_000,
37 max_parallel_tools: 4,
38 provider_attempts: 3,
39 provider_deadline: Duration::from_secs(90),
40 }
41 }
42}
43
44#[derive(Debug, Clone)]
46pub struct TurnRequest {
47 pub compact: bool,
49 pub context: af_context::RequestContext,
51 pub session_id: SessionId,
53 pub run_id: RunId,
55 pub input_id: InputId,
57 pub content: Vec<ContentBlock>,
59 pub history: crate::RunHistory,
61}
62
63#[derive(Debug, Clone, PartialEq)]
65pub struct RuntimeOutcome {
66 pub status: String,
68 pub final_text: Option<String>,
70 pub prompt_tokens: u64,
72 pub completion_tokens: u64,
74 pub waiting_interaction_id: Option<InteractionId>,
76}
77
78#[async_trait]
80pub trait EventWriter: Send + Sync {
81 async fn append_at(
84 &self,
85 expected_seq: u64,
86 events: Vec<Event>,
87 ) -> Result<Vec<SessionEvent>, RuntimeError>;
88 async fn last_seq(&self) -> Result<u64, RuntimeError> {
90 Ok(self
91 .load_after(0)
92 .await?
93 .last()
94 .map_or(0, |event| event.seq))
95 }
96
97 async fn append(&self, events: Vec<Event>) -> Result<Vec<SessionEvent>, RuntimeError>;
99 async fn load_after(&self, seq: u64) -> Result<Vec<SessionEvent>, RuntimeError>;
101}
102
103pub trait TokenMeter: Send + Sync {
105 fn count(&self, model: &str, messages: &[ChatMessage]) -> u64;
107}
108
109pub struct ApproximateTokenMeter;
111
112impl TokenMeter for ApproximateTokenMeter {
113 fn count(&self, _model: &str, messages: &[ChatMessage]) -> u64 {
114 messages
115 .iter()
116 .map(|message| {
117 message
118 .content
119 .as_deref()
120 .map_or(0, |content| content.chars().count().div_ceil(4) as u64)
121 })
122 .sum()
123 }
124}
125
126#[async_trait]
128pub trait Compactor: Send + Sync {
129 fn provider_name(&self) -> Option<&str> {
131 None
132 }
133 fn name(&self) -> &str {
135 "compactor"
136 }
137
138 async fn summarize(
140 &self,
141 request: &af_llm::CompletionRequest,
142 cancellation: CancellationToken,
143 deadline: Instant,
144 ) -> Result<CompactionResult, RuntimeError>;
145}
146
147#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct CompactionResult {
150 pub source: af_agent_session::MeteringSource,
152 pub provider: Option<String>,
154 pub summary: String,
156 pub prompt_tokens: u64,
158 pub completion_tokens: u64,
160}