use anyhow::Result;
use futures::StreamExt;
use rig_agent::{
agent::{CompletionResponseEvent, ObservationAction, StreamResponseFinish},
prelude::*,
};
use rig_core::providers::openai;
use serde::Deserialize;
struct PrintOpenAiFields;
impl AgentHook for PrintOpenAiFields {
async fn on_completion_response(
&self,
_ctx: &HookContext,
event: CompletionResponseEvent<'_>,
) -> ObservationAction {
match openai::CompletionResponse::deserialize(event.raw) {
Ok(response) => println!(
" id {} · system_fingerprint {:?} · service_tier {:?}",
response.id, response.system_fingerprint, response.service_tier
),
Err(err) => println!(" raw is not an OpenAI response: {err}"),
}
ObservationAction::continue_run()
}
async fn on_stream_response_finish(
&self,
_ctx: &HookContext,
event: StreamResponseFinish<'_>,
) -> ObservationAction {
match openai::StreamingCompletionResponse::<openai::Usage>::deserialize(event.raw) {
Ok(terminal) => {
let extra = |key: &str| {
terminal
.additional_params
.as_ref()
.and_then(|params| params.get(key))
.cloned()
};
println!(
" id {:?} · system_fingerprint {:?} · service_tier {:?}",
terminal.response_id,
extra("system_fingerprint"),
extra("service_tier"),
);
}
Err(err) => println!(" raw is not an OpenAI terminal: {err}"),
}
ObservationAction::continue_run()
}
}
#[tokio::main]
async fn main() -> Result<()> {
let client = openai::Client::from_env()?.completions_api();
let agent = client
.agent(openai::GPT_5_2)
.preamble("Answer in one short sentence.")
.add_hook(PrintOpenAiFields)
.build();
println!("blocking:");
let response = agent
.prompt("What does a system fingerprint identify?")
.extended_details()
.await?;
println!(" => {}", response.output);
for call in &response.completion_calls {
println!(" call {} recorded raw: {}", call.call_index, call.raw);
}
println!("\nstreaming:");
let mut stream = agent
.stream_prompt("What does a system fingerprint identify?")
.await;
while let Some(item) = stream.next().await {
if let MultiTurnStreamItem::FinalResponse(final_response) = item? {
println!(" => {}", final_response.output);
}
}
Ok(())
}