gemini_adk_fluent_rs/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![warn(unreachable_pub)]
3#![forbid(unsafe_code)]
4#![warn(missing_docs)]
5//! # gemini-adk-fluent-rs
6//!
7//! Fluent developer experience layer for the Gemini Live agent stack.
8//! This is the highest-level crate in the workspace, providing a builder API,
9//! operator algebra, and composition modules that sit on top of
10//! [`gemini_adk_rs`] (agent runtime) and [`gemini_genai_rs`] (wire protocol).
11//!
12//! ## Module Organization
13//!
14//! | Module | Purpose |
15//! |--------|---------|
16//! | [`builder`] | Copy-on-write immutable `AgentBuilder` for declarative agent configuration |
17//! | [`compose`] | The eight-namespace operator algebra — `S` state, `C` context, `T` tools, `P` prompts, `M` middleware, `A` artifacts, `E` evaluation, `G` guards |
18//! | [`live`] | `Live` session builder — callback-driven full-duplex event handling |
19//! | [`live_builders`] | Phase and watcher sub-builders for `Live` |
20//! | [`operators`] | `>> | * /` combinators for composing agents |
21//! | [`patterns`] | Pre-built composition patterns for common use cases |
22//! | [`voice`] | Microphone/speaker plumbing; `talk()` needs the `voice-io` feature |
23//! | [`testing`] | Contract checks, data-flow inference, mock harnesses |
24//!
25//! ## Quick Start
26//!
27//! Text generation is on by default (feature `gemini-llm`); set
28//! `GEMINI_API_KEY` and ask a question:
29//!
30//! ```no_run
31//! use gemini_adk_fluent_rs::prelude::*;
32//! use std::sync::Arc;
33//!
34//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
35//! let llm = Arc::new(GeminiLlm::new(GeminiLlmParams::default()));
36//! let agent = AgentBuilder::new("assistant")
37//!     .instruction("You are a concise assistant.")
38//!     .build(llm)?;
39//! let state = State::new();
40//! state.set("input", "Say hello in one sentence.")?;
41//! println!("{}", agent.run(&state).await?);
42//!
43//! // Voice: microphone in, speakers out, barge-in handled — `.talk()` exists
44//! // only with the `voice-io` feature (Linux: libasound2-dev).
45//! let handle = Live::builder()
46//!     .instruction("You are a helpful concierge.")
47//!     .greeting("Greet the caller.")
48//!     .connect_from_env()
49//!     .await?;
50//! # let _ = handle;
51//! # Ok(())
52//! # }
53//! ```
54//!
55//! ## Relationship to Other Crates
56//!
57//! - **`gemini-genai-rs`** (L0): wire protocol, transport, types — re-exported as [`gemini_genai_rs`]
58//! - **`gemini-adk-rs`** (L1): agent runtime, tools, sessions — re-exported as [`gemini_adk_rs`]
59//! - **`gemini-adk-fluent-rs`** (L2): this crate — the builder API and composition algebra
60
61pub mod a2a;
62pub mod builder;
63pub mod compose;
64pub mod conversation;
65pub mod flow_macros;
66pub mod handoff;
67pub mod live;
68pub mod live_builders;
69pub mod motifs;
70pub mod operators;
71pub mod patterns;
72pub mod policy;
73pub mod primitives;
74pub mod simulation;
75pub mod spec;
76pub mod telephony;
77pub mod testing;
78pub mod voice;
79
80pub use gemini_adk_rs;
81pub use gemini_genai_rs;
82
83// ---------------------------------------------------------------------------
84// Curated submodule homes (the prelude is a kernel, not an everything-glob).
85//
86// The kernel `prelude` (below) re-exports only the ~30 types a typical app
87// touches. Everything else lives in these focused, discoverable modules so
88// `use gemini_adk_fluent_rs::prelude::*` stays small and the rest is one
89// `use gemini_adk_fluent_rs::{live, text, tools, …}` away. Import from the
90// highest-level crate you need.
91// ---------------------------------------------------------------------------
92
93/// Text-agent runtime and combinators (carved out of the kernel `prelude`).
94///
95/// `LlmTextAgent`, the sequential/parallel/loop/fallback/route/race/timeout/map
96/// combinators, and the `TextAgent` trait.
97pub mod text {
98    pub use gemini_adk_rs::text::*;
99}
100
101/// Tool definitions, dispatch, toolsets, the confirmation flow, and frames.
102pub mod tools {
103    pub use gemini_adk_rs::confirmation::*;
104    pub use gemini_adk_rs::extract::{Recognizer, RecordExtractor};
105    pub use gemini_adk_rs::frame::{
106        ConfirmPolicy, FrameSpec, SlotRecognizer, SlotSpec, SlotValidator,
107    };
108    pub use gemini_adk_rs::tool::*;
109    pub use gemini_adk_rs::toolset::*;
110}
111
112/// LLM abstraction: params, requests/responses, and the registry.
113pub mod llm {
114    pub use gemini_adk_rs::llm::*;
115}
116
117/// Concurrent typed state: `State`, `PrefixedState`, `StateKey`, prefix scopes.
118pub mod state {
119    pub use gemini_adk_rs::state::*;
120}
121
122/// Governed-conversation flow primitives: `Flow`, `Step`, `Guard`, `FlowMonitor`.
123pub mod flow {
124    pub use gemini_adk_rs::flow::*;
125}
126
127/// Agent builders, the L1 [`Agent`](gemini_adk_rs::agent::Agent) trait, and
128/// the operator/pattern combinators.
129pub mod agents {
130    pub use crate::builder::*;
131    pub use crate::operators::*;
132    pub use crate::patterns::*;
133    #[doc(inline)]
134    pub use gemini_adk_rs::agent::Agent;
135    pub use gemini_adk_rs::agent_session::*;
136    pub use gemini_adk_rs::orchestration::{self, AgentMode, Resolver, call_agent, provenance};
137}
138
139/// L0 wire-protocol types for raw WebSocket access.
140pub mod wire {
141    pub use gemini_genai_rs::prelude::*;
142}
143
144/// Clone multiple bindings for use in `move` closures, reducing Arc/clone boilerplate.
145///
146/// # Example
147///
148/// ```
149/// use gemini_adk_fluent_rs::let_clone;
150/// use std::sync::Arc;
151///
152/// let state = Arc::new(42);
153/// let writer = Arc::new("hello");
154///
155/// let_clone!(state, writer);
156/// let task = move || format!("{state} {writer}");
157/// assert_eq!(task(), "42 hello");
158/// ```
159#[macro_export]
160macro_rules! let_clone {
161    ($($name:ident),+ $(,)?) => {
162        $(let $name = $name.clone();)+
163    };
164}
165
166/// The kernel prelude — the ~40 types a typical application touches.
167///
168/// Deliberately a kernel, not an everything-glob. Anything not here lives in
169/// a focused submodule and is one import away:
170///
171/// | Need | Import |
172/// |------|--------|
173/// | Full Live control plane (persistence, repair, steering, transcripts, contracts) | `use gemini_adk_fluent_rs::live::*;` |
174/// | Text-agent runtime details | `use gemini_adk_fluent_rs::text::*;` |
175/// | Toolsets, confirmation, frames | `use gemini_adk_fluent_rs::tools::*;` |
176/// | State prefixes / `SlotEvidence` | `use gemini_adk_fluent_rs::state::*;` |
177/// | Full flow vocabulary (`CompiledFlow`, `StepAction`, `Violation`, …) | `use gemini_adk_fluent_rs::flow::*;` |
178/// | `Agent` trait + operator/pattern internals | `use gemini_adk_fluent_rs::agents::*;` |
179/// | Conversation compiler (`Conversation`, `ConversationSpec`, …) | `use gemini_adk_fluent_rs::conversation::*;` |
180/// | A2A, motifs, policy, simulation, testing, orchestration, credentials, run_config | the same-named module, e.g. `use gemini_adk_fluent_rs::simulation::*;` |
181/// | Raw L0 wire types | `use gemini_adk_fluent_rs::wire::*;` |
182pub mod prelude {
183    // ── Voice I/O: `.talk()` on a connected handle (feature `voice-io`) ──
184    #[cfg(feature = "voice-io")]
185    pub use crate::voice::Talk;
186
187    // ── Builders, composition algebra, operators, patterns (headline DX) ──
188    pub use crate::builder::*;
189    pub use crate::compose::{A, C, Ctx, E, G, M, P, S, T};
190    pub use crate::live::Live;
191    // Dynamic instructions (ADK instruction-provider pattern) + tool media.
192    pub use crate::operators::*;
193    pub use crate::patterns::*;
194    pub use gemini_adk_rs::instruction::InstructionProvider;
195    #[cfg(feature = "templates")]
196    pub use gemini_adk_rs::instruction::TemplateInstruction;
197    pub use gemini_adk_rs::tool::media as tool_media;
198    // Build-time validation DX (contract checking, data-flow inference, harness).
199    pub use crate::testing::{
200        AgentHarness, ContractViolation, DataFlowEdge, LiveViolation, check_contracts, check_live,
201        diagnose, infer_data_flow,
202    };
203
204    // The L1 `Agent` trait (`name()` + `run_live()`); the L2 builder is
205    // `AgentBuilder`, so the two names never collide.
206    #[doc(inline)]
207    pub use gemini_adk_rs::agent::Agent;
208
209    // ── Errors ──
210    pub use gemini_adk_rs::error::{AgentError, AgentResult, ConfigError, ToolError};
211
212    // ── Governed flow (core vocabulary; full set in `crate::flow`) ──
213    pub use gemini_adk_rs::flow::{Enforcement, Flow, FlowMonitor, Guard, Verdict};
214
215    // ── State (prefix scopes + `SlotEvidence` in `crate::state`) ──
216    pub use gemini_adk_rs::state::{State, StateKey};
217
218    // ── LLM (core; request/response/registry in `crate::text`) ──
219    pub use gemini_adk_rs::llm::{BaseLlm, GeminiLlm, GeminiLlmParams};
220
221    // ── Tools ──
222    pub use gemini_adk_rs::tool::{
223        SimpleTool, ToolDispatcher, ToolFunction, ToolPolicy, TypedTool,
224    };
225    // The `#[tool]` attribute macro — turns an `async fn` into a registrable tool.
226    pub use gemini_adk_rs::tool;
227    // Brings in both the `Extract` struct and the `#[derive(Extract)]` macro.
228    pub use gemini_adk_rs::Extract;
229    // The `#[derive(Frame)]` macro.
230    pub use gemini_adk_rs::Frame;
231
232    // ── Callback contexts (used in `M::` hooks) ──
233    pub use gemini_adk_rs::context::{CallbackContext, ToolContext};
234
235    // ── Common Live session types (full control plane in `crate::live`) ──
236    pub use gemini_adk_rs::live::{
237        ContextDelivery, EventCallbacks, ExtractionTrigger, FsPersistence, LiveHandle,
238        LlmExtractor, MemoryPersistence, PersistenceError, RepairConfig, SessionPersistence,
239        SoftTurnDetector, SteeringMode, TranscriptBuffer, TranscriptTurn, TurnExtractor,
240    };
241
242    // ── Text-agent combinators (runtime details in `crate::text`) ──
243    pub use gemini_adk_rs::text::{
244        DispatchTextAgent, FallbackTextAgent, FnTextAgent, JoinTextAgent, LlmTextAgent,
245        LoopTextAgent, MapOverTextAgent, ParallelTextAgent, RaceTextAgent, RouteRule,
246        RouteTextAgent, SequentialTextAgent, TapTextAgent, TaskRegistry, TextAgent,
247        TimeoutTextAgent,
248    };
249
250    // ── L0 wire protocol (ModelId, Voice, Content, Part, Role, …) ──
251    pub use gemini_genai_rs::prelude::*;
252}