pub mod callbacks;
pub mod client;
pub mod error;
pub mod parser;
pub mod query;
pub mod transport;
pub mod types;
pub use callbacks::{HookCallback, PermissionCallback};
pub use client::ClaudeSDKClient;
pub use error::{ClaudeSDKError, Result};
pub use types::{
AgentDefinition, AssistantMessage, ClaudeAgentOptions, ContentBlock, Effort, HookContext,
HookEvent, HookInput, HookOutput, Message, MessageContent, PermissionMode, PermissionResult,
ResultMessage, SandboxSettings, SdkPluginConfig, SettingSource, SystemPrompt,
SystemPromptPreset, TextBlock, ThinkingConfig, ToolPermissionContext, ToolUseBlock,
ToolsOption, UserMessage,
};
use futures::Stream;
use query::Query;
use transport::{check_claude_version, find_claude_cli, subprocess::SubprocessTransport};
pub async fn query(
prompt: impl Into<String>,
options: Option<ClaudeAgentOptions>,
) -> Result<impl Stream<Item = Result<Message>>> {
let prompt_str = prompt.into();
let options = options.unwrap_or_default();
let cli_path = find_claude_cli(options.cli_path.as_ref())?;
if std::env::var("CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK").is_err() {
let _ = check_claude_version(&cli_path).await;
}
let mut transport = SubprocessTransport::new_streaming(cli_path, &options);
transport.spawn(&options, "").await?;
let query_obj = Query::new(transport);
let query_handle = query_obj.start();
query_handle.initialize(None).await?;
query_handle.send_user_message(&prompt_str).await?;
query_handle.close_stdin().await;
let message_stream = async_stream::stream! {
use futures::stream::StreamExt as _;
let mut stream = Box::pin(query_handle.read_messages());
while let Some(result) = stream.next().await {
match result {
Ok(value) => {
match parser::parse_message(value) {
Ok(message) => yield Ok(message),
Err(ClaudeSDKError::UnknownMessageType(_)) => {
continue;
}
Err(e) => yield Err(e),
}
}
Err(e) => yield Err(e),
}
}
};
Ok(message_stream)
}