Skip to main content

af_agent_runtime/
types.rs

1use 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/// Hard limits for one Run.
12#[derive(Debug, Clone)]
13pub struct RuntimeLimits {
14    /// Upper bound on model steps per Run.
15    pub max_steps: u32,
16    /// Maximum tool calls per Run.
17    pub max_tool_calls: u32,
18    /// Upper bound on prompt plus completion tokens.
19    pub max_tokens: u64,
20    /// Maximum tools executed concurrently within a step.
21    pub max_parallel_tools: usize,
22    /// Model attempts before a step fails.
23    pub provider_attempts: u32,
24    /// Deadline for one model attempt or extension call.
25    pub provider_deadline: Duration,
26}
27
28impl Default for RuntimeLimits {
29    fn default() -> Self {
30        Self {
31            max_steps: 8,
32            max_tool_calls: 24,
33            max_tokens: 64_000,
34            max_parallel_tools: 4,
35            provider_attempts: 3,
36            provider_deadline: Duration::from_secs(90),
37        }
38    }
39}
40
41/// Everything the loop needs to run one Turn.
42#[derive(Debug, Clone)]
43pub struct TurnRequest {
44    /// Caller identity and entitlements for this operation.
45    pub context: af_context::RequestContext,
46    /// Session this record belongs to.
47    pub session_id: SessionId,
48    /// Run this record belongs to.
49    pub run_id: RunId,
50    /// Queued input this record refers to.
51    pub input_id: InputId,
52    /// Content blocks carried by this record.
53    pub content: Vec<ContentBlock>,
54    /// Committed Session events the Turn resumes from.
55    pub history: Vec<SessionEvent>,
56}
57
58/// Terminal result of a Turn.
59#[derive(Debug, Clone, PartialEq)]
60pub struct RuntimeOutcome {
61    /// Current lifecycle status.
62    pub status: String,
63    /// Final assistant text, when the Run completed with prose.
64    pub final_text: Option<String>,
65    /// Prompt tokens consumed.
66    pub prompt_tokens: u64,
67    /// Completion tokens produced.
68    pub completion_tokens: u64,
69    /// Interaction the Run is parked on, when it stopped to wait for input.
70    pub waiting_interaction_id: Option<InteractionId>,
71}
72
73/// Fenced append/read access to the Session log for one Run.
74#[async_trait]
75pub trait EventWriter: Send + Sync {
76    /// Append events atomically and return them with assigned sequences.
77    async fn append(&self, events: Vec<Event>) -> Result<Vec<SessionEvent>, RuntimeError>;
78    /// Events committed after `seq`.
79    async fn load_after(&self, seq: u64) -> Result<Vec<SessionEvent>, RuntimeError>;
80}
81
82/// Token estimator used for limits and compaction decisions.
83pub trait TokenMeter: Send + Sync {
84    /// Estimated prompt tokens for `messages` under `model`.
85    fn count(&self, model: &str, messages: &[ChatMessage]) -> u64;
86}
87
88/// Character-based estimate (about four characters per token).
89pub struct ApproximateTokenMeter;
90
91impl TokenMeter for ApproximateTokenMeter {
92    fn count(&self, _model: &str, messages: &[ChatMessage]) -> u64 {
93        messages
94            .iter()
95            .map(|message| {
96                message
97                    .content
98                    .as_deref()
99                    .map_or(0, |content| content.chars().count().div_ceil(4) as u64)
100            })
101            .sum()
102    }
103}
104
105/// Produces the summary that replaces old transcript when the context overflows.
106#[async_trait]
107pub trait Compactor: Send + Sync {
108    /// Stable name recorded in compaction events.
109    fn name(&self) -> &str {
110        "compactor"
111    }
112
113    /// Summarize `transcript`, returning the summary and the usage it cost.
114    async fn summarize(
115        &self,
116        model: &str,
117        messages: &[ChatMessage],
118        operation_id: &str,
119        cancellation: CancellationToken,
120        deadline: Instant,
121    ) -> Result<CompactionResult, RuntimeError>;
122}
123
124/// Summary text and its token usage.
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub struct CompactionResult {
127    /// Short human-readable summary.
128    pub summary: String,
129    /// Prompt tokens consumed.
130    pub prompt_tokens: u64,
131    /// Completion tokens produced.
132    pub completion_tokens: u64,
133}