pub async fn query(prompt: &str, options: &AgentOptions) -> Result<EventStream>Expand description
Simple query function for single-turn interactions without conversation history.
This is a stateless convenience function for simple queries that don’t require multi-turn conversations. It creates a temporary HTTP client, sends a single prompt, and returns a stream of events.
For multi-turn conversations or more control over the interaction, use Client instead.
§Parameters
prompt: The user’s message to send to the modeloptions: Configuration including model, API key, tools, etc.
§Returns
Returns an EventStream that yields events as they arrive from the model. The stream
must be polled to completion to receive all content and the terminating
StreamEvent::Finish.
§Behavior
- Creates a temporary HTTP client with configured timeout
- Builds message array (system prompt + user prompt)
- Converts tools to the wire format if provided
- Makes an HTTP POST request to the path the configured
ApiProtocolselects - Parses Server-Sent Events (SSE) response stream
- Forwards each text and reasoning fragment as it arrives, and assembles tool calls, whose arguments are not valid JSON until the last fragment lands
- Returns stream that yields events as they arrive, ending with
Finish
§Error Handling
This function can return errors for:
- HTTP client creation failures
- Network errors during the request
- API errors (authentication, invalid model, rate limits, etc.)
- SSE parsing errors
- JSON deserialization errors
§Performance Notes
- Creates a new HTTP client for each call (consider using
Clientfor repeated queries) - Timeout is configurable via
AgentOptions::timeout(default: 120 seconds) - Streaming begins immediately; no buffering of the full response
§Examples
§Basic Usage
use open_agent::{query, AgentOptions, ContentBlock, FinishReason, StreamEvent};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let options = AgentOptions::builder()
.system_prompt("You are a helpful assistant")
.model("gpt-4")
.api_key("sk-...")
.build()?;
let mut stream = query("What's the capital of France?", &options).await?;
while let Some(event) = stream.next().await {
match event? {
StreamEvent::Block(ContentBlock::Text(text)) => print!("{}", text.text),
StreamEvent::Finish(FinishReason::Length) => {
eprintln!("response truncated at the token cap");
}
_ => {}
}
}
Ok(())
}§With Tools
use open_agent::{query, AgentOptions, Tool, ContentBlock, StreamEvent};
use futures::StreamExt;
use serde_json::json;
let calculator = Tool::new(
"calculator",
"Performs calculations",
json!({"type": "object"}),
|input| Box::pin(async move { Ok(json!({"result": 42})) })
);
let options = AgentOptions::builder()
.model("gpt-4")
.api_key("sk-...")
.tools(vec![calculator])
.build()?;
let mut stream = query("Calculate 2+2", &options).await?;
while let Some(event) = stream.next().await {
match event?.into_block() {
Some(ContentBlock::ToolUse(tool_use)) => {
println!("Model wants to use: {}", tool_use.name());
// Note: You'll need to manually execute tools and continue
// the conversation. For automatic execution, use Client.
}
Some(ContentBlock::Text(text)) => print!("{}", text.text),
_ => {}
}
}§Error Handling
use open_agent::{query, AgentOptions};
use futures::StreamExt;
let options = AgentOptions::builder()
.model("gpt-4")
.api_key("invalid-key")
.build()
.unwrap();
match query("Hello", &options).await {
Ok(mut stream) => {
while let Some(result) = stream.next().await {
match result {
Ok(event) => println!("Event: {:?}", event),
Err(e) => {
eprintln!("Stream error: {}", e);
break;
}
}
}
}
Err(e) => eprintln!("Query failed: {}", e),
}