pub struct MockLlm { /* private fields */ }Expand description
A BaseLlm that replies from a script or a closure and records every
request, for tests that must not reach a provider.
It replies three ways, one per kind of test:
| Constructor | Replies with | Use it to test |
|---|---|---|
MockLlm::text | the same text, every call | wiring, prompts, state flow |
MockLlm::script | each response in turn, then an error | tool rounds, retries, multi-turn |
MockLlm::from_fn | whatever the closure returns | replies that depend on the request |
Every call’s LlmRequest is recorded, so a test can assert on what the
agent actually sent — instructions, history, tool declarations, sampling —
not only on what came back.
MockLlm is a cheap handle: clones share the script and the recording.
Give one clone to the agent and keep one to inspect.
use gemini_adk_rs::llm::{BaseLlm, LlmRequest, LlmResponse, MockLlm};
let llm = MockLlm::script([
LlmResponse::tool_call("get_weather", serde_json::json!({ "city": "Paris" })),
LlmResponse::from_text("It is sunny in Paris."),
]);
let first = llm.generate(LlmRequest::from_text("Weather in Paris?")).await.unwrap();
assert_eq!(first.function_calls()[0].name, "get_weather");
let second = llm.generate(LlmRequest::from_text("…")).await.unwrap();
assert_eq!(second.text(), "It is sunny in Paris.");
// The script is spent: a third call is a test failure, not a silent reply.
assert!(llm.generate(LlmRequest::from_text("again")).await.is_err());
assert_eq!(llm.requests().len(), 3);Implementations§
Source§impl MockLlm
impl MockLlm
Sourcepub fn script(responses: impl IntoIterator<Item = LlmResponse>) -> MockLlm
pub fn script(responses: impl IntoIterator<Item = LlmResponse>) -> MockLlm
Reply with each response in order.
A call after the script is spent returns an error naming the call, so an agent that makes one model call more than the test expected fails instead of receiving a plausible reply.
Sourcepub fn from_fn<F>(reply: F) -> MockLlm
pub fn from_fn<F>(reply: F) -> MockLlm
Reply by calling reply with the request.
This is the programmable mock: branch on the conversation so far, echo the prompt, or return an error for a particular input.
Sourcepub fn with_model_id(self, model_id: impl Into<String>) -> MockLlm
pub fn with_model_id(self, model_id: impl Into<String>) -> MockLlm
Report model_id from BaseLlm::model_id instead of "mock".
Sourcepub fn requests(&self) -> Vec<LlmRequest>
pub fn requests(&self) -> Vec<LlmRequest>
Every request received so far, oldest first.
Sourcepub fn last_request(&self) -> Option<LlmRequest>
pub fn last_request(&self) -> Option<LlmRequest>
The most recent request, if any.
Sourcepub fn call_count(&self) -> usize
pub fn call_count(&self) -> usize
How many times the model has been called.
Trait Implementations§
Source§impl BaseLlm for MockLlm
impl BaseLlm for MockLlm
Source§fn generate_stream<'life0, 'async_trait>(
&'life0 self,
request: LlmRequest,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<LlmResponse, LlmError>> + Send>>, LlmError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MockLlm: 'async_trait,
fn generate_stream<'life0, 'async_trait>(
&'life0 self,
request: LlmRequest,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<LlmResponse, LlmError>> + Send>>, LlmError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MockLlm: 'async_trait,
Streams a text reply one word at a time (usage and the finish reason ride on the last chunk), so tests exercise the multi-chunk path; a reply with tool calls arrives as one chunk.
Source§fn generate<'life0, 'async_trait>(
&'life0 self,
request: LlmRequest,
) -> Pin<Box<dyn Future<Output = Result<LlmResponse, LlmError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MockLlm: 'async_trait,
fn generate<'life0, 'async_trait>(
&'life0 self,
request: LlmRequest,
) -> Pin<Box<dyn Future<Output = Result<LlmResponse, LlmError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MockLlm: 'async_trait,
Source§fn capabilities(&self) -> ModelCapabilities
fn capabilities(&self) -> ModelCapabilities
model_id; back-ends
with authoritative knowledge should override.Auto Trait Implementations§
impl Freeze for MockLlm
impl !RefUnwindSafe for MockLlm
impl Send for MockLlm
impl Sync for MockLlm
impl Unpin for MockLlm
impl !UnwindSafe for MockLlm
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].