This guide is for teams embedding Pi as a Rust library. The Rust SDK provides idiomatic Rust APIs that deliver equivalent functionality to the TypeScript SDK, using Rust-native patterns like Result types, structured concurrency, and zero-copy operations.
Note: This SDK is an idiomatic Rust companion to the pi-mono TypeScript SDK, not a drop-in equivalent. The APIs provide functional equivalence while following Rust ecosystem conventions.
[dependencies]
pi = { path = "." }
futures = "0.3"The supported library surface is the crate root aliases pi::Error,
pi::PiResult, and the pi::sdk module. Other root modules are implementation
details for the CLI, examples, and in-repository tests; they are hidden from the
published API documentation and may change without SemVer guarantees.
The semver GitHub Actions workflow runs cargo-semver-checks on PRs and
main pushes that touch the SDK/API surface. It compares the current public
API to the PR target branch or previous push baseline. Removing or changing a
stable item below requires a major version bump; additive changes remain
minor-version compatible.
| Item | Stability | Notes |
|---|---|---|
pi::Error |
Stable | Crate-root error type alias target. |
pi::PiResult |
Stable | Crate-root result alias for pi::Error. |
pi::sdk::{Error, Result} |
Stable | SDK error/result exports. |
pi::sdk::{AbortHandle, AbortSignal} |
Stable | Prompt cancellation handles. |
pi::sdk::{Agent, AgentConfig, AgentEvent, AgentSession, QueueMode} |
Stable | In-process agent/session integration exports. |
pi::sdk::{AssistantMessage, ContentBlock, Cost, CustomMessage, ImageContent, Message, StopReason, StreamEvent, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserContent, UserMessage} |
Stable | Message, content, streaming, and accounting model types. |
pi::sdk::{Config, ExtensionManager, ExtensionPolicy, ExtensionRegion, Session, ThinkingLevel} |
Stable | Configuration, extension, session, and thinking-control exports. |
pi::sdk::{InputType, Model, ModelCost, Provider, ProviderContext, ProviderThinkingBudgets, StreamOptions, ToolDef} |
Stable | Provider integration exports. |
pi::sdk::{ModelEntry, ModelRegistry} |
Stable | Model registry exports. |
pi::sdk::{Tool, ToolDefinition, ToolOutput, ToolRegistry, ToolUpdate} |
Stable | Tool integration exports. |
pi::sdk::BUILTIN_TOOL_NAMES |
Stable | Canonical built-in tool-name inventory. |
pi::sdk::{create_read_tool, create_bash_tool, create_edit_tool, create_write_tool, create_grep_tool, create_find_tool, create_ls_tool, create_hashline_edit_tool, create_all_tools} |
Stable | Built-in tool constructors. |
pi::sdk::{tool_to_definition, all_tool_definitions} |
Stable | Tool schema helpers. |
pi::sdk::{SubscriptionId, EventListeners, EventSubscriber, OnStreamEvent, OnToolEnd, OnToolStart} |
Stable | Event subscription and hook types. |
pi::sdk::{SessionOptions, ToolFactory, default_tool_registry} |
Stable | In-process session construction and custom tool registry extension points. |
pi::sdk::{AgentSessionHandle, AgentSessionState, create_agent_session} |
Stable | Primary in-process SDK entry point and state handle. |
pi::sdk::{SessionPromptResult, SessionTransport, SessionTransportEvent, SessionTransportState} |
Stable | Unified in-process/RPC transport adapter. |
pi::sdk::{RpcTransportClient, RpcTransportOptions} |
Stable | Subprocess RPC transport client. |
pi::sdk::{RpcBashResult, RpcCancelledResult, RpcCommandInfo, RpcCompactionResult, RpcCycleModelResult, RpcExportHtmlResult, RpcExtensionUiResponse, RpcForkMessage, RpcForkResult, RpcLastAssistantText, RpcModelInfo, RpcSessionState, RpcSessionStats, RpcThinkingLevelResult, RpcTokenStats} |
Stable | RPC request/response payloads. |
| TypeScript surface | Rust SDK surface |
|---|---|
createAgentSession(options) |
pi::sdk::create_agent_session(SessionOptions) |
session.prompt(text, onEvent) |
AgentSessionHandle::prompt(text, on_event) |
session.subscribe(listener) |
AgentSessionHandle::subscribe(listener) |
unsubscribe() |
AgentSessionHandle::unsubscribe(subscription_id) |
session.setModel(provider, model) |
AgentSessionHandle::set_model(provider, model) |
session.setThinkingLevel(level) |
AgentSessionHandle::set_thinking_level(level) |
session.compact() |
AgentSessionHandle::compact(on_event) |
session.abort() |
AgentSessionHandle::new_abort_handle() + prompt_with_abort(...) |
session.steer(...), session.followUp(...) |
RpcTransportClient::steer(...), RpcTransportClient::follow_up(...) |
| RPC bridge client | RpcTransportClient / SessionTransport::RpcSubprocess |
use futures::executor::block_on;
use pi::sdk::{AgentEvent, SessionOptions, create_agent_session};
fn main() -> pi::sdk::Result<()> {
let mut session = block_on(create_agent_session(SessionOptions {
provider: Some("openai".to_string()),
model: Some("gpt-4o".to_string()),
api_key: Some(std::env::var("OPENAI_API_KEY").unwrap_or_default()),
no_session: true,
..SessionOptions::default()
}))?;
let message = block_on(session.prompt("Summarize src/sdk.rs", |event: AgentEvent| {
eprintln!("{event:?}");
}))?;
println!("{message:#?}");
Ok(())
}use futures::executor::block_on;
use pi::sdk::{SessionOptions, create_agent_session};
use std::sync::Arc;
fn main() -> pi::sdk::Result<()> {
let options = SessionOptions {
on_tool_start: Some(Arc::new(|tool, args| eprintln!("tool start: {tool} {args}"))),
on_tool_end: Some(Arc::new(|tool, output, is_error| {
eprintln!("tool end: {tool}, error={is_error}, output={output:?}");
})),
on_stream_event: Some(Arc::new(|ev| eprintln!("stream: {ev:?}"))),
..SessionOptions::default()
};
let mut session = block_on(create_agent_session(options))?;
let sub_id = session.subscribe(|event| eprintln!("session event: {event:?}"));
let _ = block_on(session.prompt("read Cargo.toml", |_| {}))?;
let _removed = session.unsubscribe(sub_id);
Ok(())
}use futures::executor::block_on;
use pi::sdk::{AgentSessionHandle, SessionOptions, create_agent_session};
fn main() -> pi::sdk::Result<()> {
let mut session = block_on(create_agent_session(SessionOptions::default()))?;
let (abort_handle, abort_signal) = AgentSessionHandle::new_abort_handle();
let fut = session.prompt_with_abort("long running prompt", abort_signal, |_| {});
abort_handle.abort();
let _ = block_on(fut);
Ok(())
}use futures::executor::block_on;
use pi::sdk::{SessionOptions, ThinkingLevel, create_agent_session};
fn main() -> pi::sdk::Result<()> {
let mut session = block_on(create_agent_session(SessionOptions::default()))?;
block_on(session.set_model("openai", "gpt-4o"))?;
block_on(session.set_thinking_level(ThinkingLevel::Low))?;
let state = block_on(session.state())?;
println!("provider={} model={}", state.provider, state.model_id);
Ok(())
}use futures::executor::block_on;
use pi::sdk::{SessionOptions, create_agent_session};
use std::path::PathBuf;
fn main() -> pi::sdk::Result<()> {
let session = block_on(create_agent_session(SessionOptions {
extension_paths: vec![PathBuf::from("extensions/my_extension.js")],
extension_policy: Some("safe".to_string()),
repair_policy: Some("ask".to_string()),
..SessionOptions::default()
}))?;
if session.has_extensions() {
eprintln!("extensions loaded");
}
Ok(())
}use futures::executor::block_on;
use pi::sdk::{RpcTransportClient, RpcTransportOptions};
fn main() -> pi::sdk::Result<()> {
let mut rpc = RpcTransportClient::connect(RpcTransportOptions::default())?;
let state = block_on(rpc.get_state())?;
println!("rpc session id: {}", state.session_id);
let events = block_on(rpc.prompt("Hello from RPC"))?;
println!("received {} rpc events", events.len());
rpc.shutdown()?;
Ok(())
}use futures::executor::block_on;
use pi::sdk::{SessionOptions, SessionTransport};
fn main() -> pi::sdk::Result<()> {
let mut transport = block_on(SessionTransport::in_process(SessionOptions::default()))?;
let _result = block_on(transport.prompt("Status?", |_event| {}))?;
let _state = block_on(transport.state())?;
transport.shutdown()?;
Ok(())
}SessionOptions::default().no_sessionistrue(ephemeral by default).- In-process
AgentSessionHandlecurrently exposes prompt/state/model/thinking/compaction flows; queue controls likesteer/follow_upare onRpcTransportClient. SessionTransport::promptreturnsSessionPromptResult, which isInProcess(AssistantMessage)orRpcEvents(Vec<Value>)depending on backend.- Extension loading is opt-in via
extension_paths, withextension_policy/repair_policycontrols.
src/sdk.rstests/sdk_api.rstests/sdk_unit.rstests/sdk_integration.rs