pub struct BenchmarkChannel { /* private fields */ }Expand description
Headless channel that feeds pre-loaded prompts and captures agent responses.
Used by the bench runner to drive the agent loop without a real terminal or
network connection. recv drains the prompt
queue; send and
flush_chunks accumulate responses
into an internal list. Tool outputs are captured separately via tool_outputs().
§Usage
use zeph_bench::BenchmarkChannel;
let prompts = vec!["What year did WWII end?".into()];
let channel = BenchmarkChannel::new(prompts);
assert_eq!(channel.total(), 1);After the agent loop completes, call into_responses to consume the channel
and retrieve all captured responses:
let channel = BenchmarkChannel::new(vec!["question".into()]);
// ... run agent loop ...
let responses = channel.into_responses();Implementations§
Source§impl BenchmarkChannel
impl BenchmarkChannel
Sourcepub fn new(prompts: Vec<String>) -> Self
pub fn new(prompts: Vec<String>) -> Self
Create a new channel pre-loaded with prompts.
Prompts are fed to the agent one at a time in order via
recv. The channel returns Ok(None) once
all prompts have been drained.
§Examples
use zeph_bench::BenchmarkChannel;
let ch = BenchmarkChannel::new(vec!["hello".into(), "world".into()]);
assert_eq!(ch.total(), 2);Sourcepub fn from_turns(turns: Vec<Turn>) -> Self
pub fn from_turns(turns: Vec<Turn>) -> Self
Create a channel from a multi-turn scenario history.
User turns are fed to the agent in order via recv.
Assistant turns are pre-seeded into responses so that
evaluators and Phase 2 scoring have access to the captured prior context.
§Note
If turns contains no crate::scenario::Role::User turns, total returns
0 and the channel cannot serve as a prompt source. The bench runner rejects this with
BenchError::InvalidFormat — callers must ensure at least one user
turn is present.
§Examples
use zeph_bench::BenchmarkChannel;
use zeph_bench::scenario::{Role, Turn};
let turns = vec![
Turn { role: Role::User, content: "Hello".into() },
Turn { role: Role::Assistant, content: "Hi there".into() },
Turn { role: Role::User, content: "What year?".into() },
];
let ch = BenchmarkChannel::from_turns(turns);
assert_eq!(ch.total(), 2); // two user turns
assert_eq!(ch.responses().len(), 1); // one seeded assistant turnSourcepub fn total(&self) -> usize
pub fn total(&self) -> usize
Total number of prompts this channel was initialised with.
§Examples
use zeph_bench::BenchmarkChannel;
let ch = BenchmarkChannel::new(vec!["a".into(), "b".into(), "c".into()]);
assert_eq!(ch.total(), 3);Sourcepub fn into_responses(self) -> Vec<CapturedResponse>
pub fn into_responses(self) -> Vec<CapturedResponse>
Consume the channel and return all CapturedResponses collected so far.
Call this after the agent loop exits to retrieve every response in prompt order.
§Examples
use zeph_bench::BenchmarkChannel;
let ch = BenchmarkChannel::new(vec!["question".into()]);
// ... run agent ...
let responses = ch.into_responses();Sourcepub fn responses(&self) -> &[CapturedResponse]
pub fn responses(&self) -> &[CapturedResponse]
Borrow the captured responses without consuming the channel.
§Examples
use zeph_bench::BenchmarkChannel;
let ch = BenchmarkChannel::new(vec![]);
assert!(ch.responses().is_empty());Sourcepub fn tool_outputs(&self) -> &[ToolOutputEvent]
pub fn tool_outputs(&self) -> &[ToolOutputEvent]
Borrow the tool output events captured during the agent run.
Events are appended by send_tool_output
and are available for Phase 2 evaluation (#4234) after the agent loop exits.
§Examples
use zeph_bench::BenchmarkChannel;
let ch = BenchmarkChannel::new(vec![]);
assert!(ch.tool_outputs().is_empty());Trait Implementations§
Source§impl Channel for BenchmarkChannel
impl Channel for BenchmarkChannel
Source§async fn recv(&mut self) -> Result<Option<ChannelMessage>, ChannelError>
async fn recv(&mut self) -> Result<Option<ChannelMessage>, ChannelError>
None on EOF or shutdown. Read moreSource§fn supports_exit(&self) -> bool
fn supports_exit(&self) -> bool
Source§async fn send(&mut self, text: &str) -> Result<(), ChannelError>
async fn send(&mut self, text: &str) -> Result<(), ChannelError>
Source§async fn send_chunk(&mut self, chunk: &str) -> Result<(), ChannelError>
async fn send_chunk(&mut self, chunk: &str) -> Result<(), ChannelError>
Source§async fn flush_chunks(&mut self) -> Result<(), ChannelError>
async fn flush_chunks(&mut self) -> Result<(), ChannelError>
Source§async fn send_usage(
&mut self,
input_tokens: u64,
output_tokens: u64,
context_window: u64,
) -> Result<(), ChannelError>
async fn send_usage( &mut self, input_tokens: u64, output_tokens: u64, context_window: u64, ) -> Result<(), ChannelError>
Source§async fn send_tool_output(
&mut self,
event: ToolOutputEvent,
) -> Result<(), ChannelError>
async fn send_tool_output( &mut self, event: ToolOutputEvent, ) -> Result<(), ChannelError>
Source§fn try_recv(&mut self) -> Option<ChannelMessage>
fn try_recv(&mut self) -> Option<ChannelMessage>
None if no message is immediately available.Source§fn send_typing(
&mut self,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_typing( &mut self, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn send_status(
&mut self,
_text: &str,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_status( &mut self, _text: &str, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn send_thinking_chunk(
&mut self,
_chunk: &str,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_thinking_chunk( &mut self, _chunk: &str, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn send_queue_count(
&mut self,
_count: usize,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_queue_count( &mut self, _count: usize, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn send_context_estimate(
&mut self,
_tokens: usize,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_context_estimate( &mut self, _tokens: usize, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn send_diff(
&mut self,
_diff: DiffData,
_tool_call_id: &str,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_diff( &mut self, _diff: DiffData, _tool_call_id: &str, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn send_tool_start(
&mut self,
_event: ToolStartEvent,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_tool_start( &mut self, _event: ToolStartEvent, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Source§fn confirm(
&mut self,
_prompt: &str,
) -> impl Future<Output = Result<bool, ChannelError>> + Send
fn confirm( &mut self, _prompt: &str, ) -> impl Future<Output = Result<bool, ChannelError>> + Send
true if confirmed.
Default: auto-confirm (for headless/test scenarios). Read moreSource§fn elicit(
&mut self,
_request: ElicitationRequest,
) -> impl Future<Output = Result<ElicitationResponse, ChannelError>> + Send
fn elicit( &mut self, _request: ElicitationRequest, ) -> impl Future<Output = Result<ElicitationResponse, ChannelError>> + Send
Source§fn send_stop_hint(
&mut self,
_hint: StopHint,
) -> impl Future<Output = Result<(), ChannelError>> + Send
fn send_stop_hint( &mut self, _hint: StopHint, ) -> impl Future<Output = Result<(), ChannelError>> + Send
Auto Trait Implementations§
impl Freeze for BenchmarkChannel
impl RefUnwindSafe for BenchmarkChannel
impl Send for BenchmarkChannel
impl Sync for BenchmarkChannel
impl Unpin for BenchmarkChannel
impl UnsafeUnpin for BenchmarkChannel
impl UnwindSafe for BenchmarkChannel
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> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request