gemini_rust/interactions/mod.rs
1//! Interactions API — the modern interface for Gemini models and agents.
2//!
3//! The Interactions API is the simplest and best way to use Gemini models and agents.
4//! It provides a unified interface for all use cases, including single-turn text generation,
5//! multimodal understanding, structured output, tool orchestration, and agentic workflows.
6//!
7//! # Key Advantages
8//!
9//! - Unified interface for models and agents
10//! - Server-side state management (`previous_interaction_id`)
11//! - Observable execution steps
12//! - Background execution
13//! - Higher cache hit rates
14//!
15//! # Quick Start
16//!
17//! ```no_run
18//! # use gemini_rust::prelude::*;
19//! # async fn example(gemini: &Gemini) -> Result<(), Box<dyn std::error::Error>> {
20//! let interaction = gemini.create_interaction()
21//! .with_model("gemini-2.5-flash")
22//! .with_text("Hello, world!")
23//! .execute()
24//! .await?;
25//!
26//! println!("{}", interaction.output_text());
27//! # Ok(())
28//! # }
29//! ```
30
31pub mod builder;
32pub mod handle;
33pub mod model;
34pub mod stream;
35
36pub use builder::InteractionBuilder;
37pub use handle::InteractionHandle;
38pub use model::*;
39pub use stream::{InteractionEvent, InteractionStream, StepDeltaData};
40
41/// Convenience methods on [`Interaction`].
42impl Interaction {
43 /// Get the concatenated final text output.
44 ///
45 /// Extracts text from the last `model_output` step's text content items.
46 pub fn output_text(&self) -> String {
47 self.steps
48 .iter()
49 .rev()
50 .find(|s| matches!(s, Step::ModelOutput { .. }))
51 .and_then(|s| {
52 if let Step::ModelOutput { content, .. } = s {
53 Some(
54 content
55 .iter()
56 .filter_map(|c| {
57 if let InteractionContent::Text { text, .. } = c {
58 Some(text.clone())
59 } else {
60 None
61 }
62 })
63 .collect::<Vec<_>>()
64 .join(""),
65 )
66 } else {
67 None
68 }
69 })
70 .unwrap_or_default()
71 }
72
73 /// Get all function_call steps.
74 pub fn function_calls(&self) -> Vec<&Step> {
75 self.steps
76 .iter()
77 .filter(|s| matches!(s, Step::FunctionCall { .. }))
78 .collect()
79 }
80
81 /// Get all model_output steps.
82 pub fn model_outputs(&self) -> Vec<&Step> {
83 self.steps
84 .iter()
85 .filter(|s| matches!(s, Step::ModelOutput { .. }))
86 .collect()
87 }
88
89 /// Get all thought steps.
90 pub fn thoughts(&self) -> Vec<&Step> {
91 self.steps
92 .iter()
93 .filter(|s| matches!(s, Step::Thought { .. }))
94 .collect()
95 }
96
97 /// Whether the interaction requires user action (e.g., function calling).
98 pub fn requires_action(&self) -> bool {
99 self.status == InteractionStatus::RequiresAction
100 }
101
102 /// Whether the interaction is completed.
103 pub fn is_completed(&self) -> bool {
104 self.status == InteractionStatus::Completed
105 }
106
107 /// Get the output image (last model-generated image).
108 pub fn output_image(&self) -> Option<&InteractionContent> {
109 self.steps.iter().rev().find_map(|s| {
110 if let Step::ModelOutput { content, .. } = s {
111 content
112 .iter()
113 .find(|c| matches!(c, InteractionContent::Image { .. }))
114 } else {
115 None
116 }
117 })
118 }
119
120 /// Get the output audio (last model-generated audio).
121 pub fn output_audio(&self) -> Option<&InteractionContent> {
122 self.steps.iter().rev().find_map(|s| {
123 if let Step::ModelOutput { content, .. } = s {
124 content
125 .iter()
126 .find(|c| matches!(c, InteractionContent::Audio { .. }))
127 } else {
128 None
129 }
130 })
131 }
132
133 /// Get the output video (last model-generated video).
134 pub fn output_video(&self) -> Option<&InteractionContent> {
135 self.steps.iter().rev().find_map(|s| {
136 if let Step::ModelOutput { content, .. } = s {
137 content
138 .iter()
139 .find(|c| matches!(c, InteractionContent::Video { .. }))
140 } else {
141 None
142 }
143 })
144 }
145
146 /// Get the output document (last model-generated document).
147 pub fn output_document(&self) -> Option<&InteractionContent> {
148 self.steps.iter().rev().find_map(|s| {
149 if let Step::ModelOutput { content, .. } = s {
150 content
151 .iter()
152 .find(|c| matches!(c, InteractionContent::Document { .. }))
153 } else {
154 None
155 }
156 })
157 }
158
159 /// Get all citation annotations from model outputs.
160 pub fn citations(&self) -> Vec<&Annotation> {
161 self.steps
162 .iter()
163 .filter_map(|s| {
164 if let Step::ModelOutput { content, .. } = s {
165 Some(content.iter().flat_map(|c| {
166 if let InteractionContent::Text { annotations, .. } = c {
167 annotations.iter().collect::<Vec<_>>()
168 } else {
169 vec![]
170 }
171 }))
172 } else {
173 None
174 }
175 })
176 .flatten()
177 .collect()
178 }
179
180 /// Get the total token count.
181 pub fn total_tokens(&self) -> Option<i64> {
182 self.usage.as_ref()?.total_tokens
183 }
184
185 /// Get the interaction ID.
186 pub fn id(&self) -> Option<&str> {
187 self.id.as_deref()
188 }
189}