1use std::collections::BTreeMap;
4use std::sync::Arc;
5use std::time::Duration;
6
7use ferrin_message::Message;
8use ferrin_spec::FinishReason;
9use ferrin_spec::JsonValue;
10use ferrin_spec::ModelId;
11use ferrin_spec::ProviderId;
12use ferrin_spec::ResponseMetadata;
13use ferrin_spec::ToolCallId;
14use ferrin_spec::ToolName;
15use ferrin_spec::Usage;
16use ferrin_spec::Warning;
17use ferrin_spec::language_model::CallOptionsRecord;
18use serde::Deserialize;
19use serde::Serialize;
20
21use crate::error::Error;
22use crate::generate_text::StepContent;
23use crate::generate_text::StepPerformance;
24use crate::generate_text::StepResult;
25use crate::generate_text::ToolErrorInfo;
26
27#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29pub struct ModelIdentity {
30 pub provider: ProviderId,
32 pub model_id: ModelId,
34}
35
36impl ModelIdentity {
37 #[must_use]
39 pub fn new(provider: impl Into<ProviderId>, model_id: impl Into<ModelId>) -> Self {
40 Self {
41 provider: provider.into(),
42 model_id: model_id.into(),
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq)]
49pub struct RecordedInputs {
50 pub system: Option<String>,
52 pub messages: Arc<[Message]>,
54}
55
56#[derive(Debug, Clone)]
58pub struct StartEvent {
59 pub call_id: String,
61 pub function_id: Option<String>,
63 pub model: ModelIdentity,
65 pub inputs: Option<RecordedInputs>,
67 pub metadata: BTreeMap<String, JsonValue>,
69}
70
71#[derive(Debug, Clone)]
73pub struct StepStartEvent {
74 pub call_id: String,
76 pub step_number: u32,
78 pub model: ModelIdentity,
80 pub messages: Option<Arc<[Message]>>,
82}
83
84#[derive(Debug, Clone)]
86pub struct ModelCallStartEvent {
87 pub call_id: String,
89 pub step_number: u32,
91 pub model: ModelIdentity,
93 pub call_options: Option<CallOptionsRecord>,
95}
96
97#[derive(Debug, Clone)]
99pub struct ModelCallEndEvent {
100 pub call_id: String,
102 pub step_number: u32,
104 pub model: ModelIdentity,
106 pub content: Option<Vec<StepContent>>,
108 pub finish_reason: FinishReason,
110 pub usage: Usage,
112 pub response: ResponseMetadata,
114 pub performance: StepPerformance,
116 pub warnings: Vec<Warning>,
118}
119
120#[derive(Debug, Clone)]
122pub struct ToolExecutionStartEvent {
123 pub call_id: String,
125 pub tool_call_id: ToolCallId,
127 pub tool_name: ToolName,
129 pub input: Option<JsonValue>,
131}
132
133#[derive(Debug, Clone)]
135pub struct ToolExecutionEndEvent {
136 pub call_id: String,
138 pub tool_call_id: ToolCallId,
140 pub tool_name: ToolName,
142 pub output: Option<ToolOutcome>,
144 pub error: Option<ToolErrorInfo>,
146 pub duration: Duration,
148}
149
150#[derive(Debug, Clone, PartialEq)]
152pub struct ToolOutcome {
153 pub output: JsonValue,
155}
156
157#[derive(Debug, Clone)]
159pub struct StepEndEvent {
160 pub call_id: String,
162 pub step: Arc<StepResult>,
164}
165
166#[derive(Debug, Clone)]
168pub struct EndEvent {
169 pub call_id: String,
171 pub steps: Arc<[StepResult]>,
173 pub total_usage: Usage,
175 pub output_recorded: Option<JsonValue>,
177}
178
179#[derive(Debug, Clone)]
181pub struct AbortEvent {
182 pub call_id: String,
184 pub steps_completed: u32,
186}
187
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
190#[serde(rename_all = "kebab-case")]
191#[non_exhaustive]
192pub enum ErrorPhase {
193 Prompt,
195 ModelCall,
197 ToolExecution,
199 Output,
201 Stream,
203}
204
205#[derive(Debug)]
207pub struct ErrorEvent<'a> {
208 pub call_id: &'a str,
210 pub error: &'a Error,
212 pub phase: ErrorPhase,
214}
215
216#[derive(Debug, Clone)]
218pub struct EmbedStartEvent {
219 pub call_id: String,
221 pub model: ModelIdentity,
223 pub value_count: usize,
225 pub values: Option<Vec<String>>,
227}
228
229#[derive(Debug, Clone)]
231pub struct EmbedEndEvent {
232 pub call_id: String,
234 pub embedding_count: usize,
236 pub tokens: Option<u64>,
238 pub duration: Duration,
240}
241
242#[derive(Debug, Clone)]
244pub struct RerankStartEvent {
245 pub call_id: String,
247 pub model: ModelIdentity,
249 pub document_count: usize,
251 pub query: Option<String>,
253}
254
255#[derive(Debug, Clone)]
257pub struct RerankEndEvent {
258 pub call_id: String,
260 pub ranked_count: usize,
262 pub duration: Duration,
264}