API Reference

Top-Level Functions

agent_loop()

#![allow(unused)]
fn main() {
pub async fn agent_loop(
    prompts: Vec<AgentMessage>,
    context: &mut AgentContext,
    config: &AgentLoopConfig,
    tx: mpsc::UnboundedSender<AgentEvent>,
    cancel: CancellationToken,
) -> Vec<AgentMessage>
}

Start an agent loop with new prompt messages. Returns all messages generated during the run.

agent_loop_continue()

#![allow(unused)]
fn main() {
pub async fn agent_loop_continue(
    context: &mut AgentContext,
    config: &AgentLoopConfig,
    tx: mpsc::UnboundedSender<AgentEvent>,
    cancel: CancellationToken,
) -> Vec<AgentMessage>
}

Resume from existing context. The last message must not be an assistant message.

default_tools()

#![allow(unused)]
fn main() {
pub fn default_tools() -> Vec<Arc<dyn AgentTool>>
}

Returns: BashTool, ReadFileTool, WriteFileTool, EditFileTool, ListFilesTool, SearchTool.

Agent Trait

The runtime interface for all agent implementations. Programs against this trait to remain independent of the specific implementation.

#![allow(unused)]
fn main() {
use phi_core::Agent;  // trait must be in scope to call trait methods
}

Trait methods cover: prompting (prompt, prompt_messages, prompt_with_sender, prompt_messages_with_sender, continue_loop, continue_loop_with_sender), state access (messages, is_streaming, agent_id, session_id, last_loop_id), message mutation (clear_messages, append_message, replace_messages, save_messages, restore_messages, set_tools), control (abort, reset), and steering/follow-up queues (steer, follow_up, clear_steering_queue, clear_follow_up_queue, clear_all_queues, set_steering_mode, set_follow_up_mode).

The trait is object-safe: Box<dyn Agent> and &mut dyn Agent work for runtime polymorphism.

phi_core::* re-exports Agent, so use phi_core::* brings it into scope automatically.

BasicAgent Struct

The default in-memory Agent implementation. Owns a single linear message history, tool registry, and model configuration.

Construction

#![allow(unused)]
fn main() {
let api_key = std::env::var("ANTHROPIC_API_KEY").unwrap();
let agent = BasicAgent::new(ModelConfig::anthropic(
    "claude-sonnet-4-20250514",
    "Claude Sonnet 4",
    &api_key,
));
}
SignatureDescription
BasicAgent::new(model_config: ModelConfig) -> SelfCreate a new agent with the given model configuration

Builder Methods

All return Self for chaining (unless noted as Result).

Core

MethodDescription
with_system_prompt(prompt) -> SelfSet the system prompt
with_thinking(level: ThinkingLevel) -> SelfSet thinking level (Off, Minimal, Low, Medium, High)
with_max_tokens(max: u32) -> SelfSet max output tokens
with_model_config(config: ModelConfig) -> SelfReplace the entire ModelConfig (id, api_key, base_url, compat, cost, etc.)
with_provider_override(provider: Arc<dyn StreamProvider>) -> SelfBypass ProviderRegistry dispatch and use this provider directly (primarily for testing with MockProvider)

Tools & Integrations

MethodDescription
with_tools(tools: Vec<Arc<dyn AgentTool>>) -> SelfSet tools (replaces existing)
with_sub_agent(sub: SubAgentTool) -> SelfAdd a sub-agent tool
with_skills(skills: SkillSet) -> SelfLoad skills and append their index to the system prompt
async with_mcp_server_stdio(command, args, env) -> Result<Self, McpError>Connect to MCP server via stdio and add its tools
async with_mcp_server_http(url) -> Result<Self, McpError>Connect to MCP server via HTTP and add its tools
async with_openapi_file(path, config, filter) -> Result<Self, OpenApiError>Load tools from an OpenAPI spec file (requires openapi feature)
async with_openapi_url(url, config, filter) -> Result<Self, OpenApiError>Fetch spec from URL and add tools (requires openapi feature)
with_openapi_spec(spec_str, config, filter) -> Result<Self, OpenApiError>Parse spec string and add tools (requires openapi feature)

Workspace & System Prompt

MethodDescription
with_workspace(path: impl Into<PathBuf>) -> SelfSet the agent's workspace directory

Context & Limits

MethodDescription
with_context_config(config: ContextConfig) -> SelfSet context compaction config
with_execution_limits(limits: ExecutionLimits) -> SelfSet execution limits (max turns, tokens, duration)
with_compaction_strategy(strategy: impl CompactionStrategy) -> SelfSet a custom compaction strategy
without_context_management() -> SelfDisable automatic context compaction and execution limits

Behavior

MethodDescription
with_messages(msgs: Vec<AgentMessage>) -> SelfPre-load message history
with_cache_config(config: CacheConfig) -> SelfSet prompt caching configuration
with_tool_execution(strategy: ToolExecutionStrategy) -> SelfSet tool execution strategy (Parallel, Sequential, Batched)
with_retry_config(config: RetryConfig) -> SelfSet retry configuration
with_input_filter(filter: impl InputFilter) -> SelfAdd an input filter (runs on user messages before LLM call)

Callbacks

MethodDescription
on_before_loop(f: Fn(&[AgentMessage], u64) -> bool) -> SelfCalled once before AgentStart; return false to abort the entire run
on_after_loop(f: Fn(&[AgentMessage], &Usage)) -> SelfCalled once after AgentEnd with all new messages and accumulated usage
on_before_turn(f: Fn(&[AgentMessage], usize) -> bool) -> SelfCalled before each LLM call; return false to abort
on_after_turn(f: Fn(&[AgentMessage], &Usage)) -> SelfCalled after each LLM response and tool execution
on_error(f: Fn(&str)) -> SelfCalled when the LLM returns StopReason::Error
on_before_tool_execution(f: Fn(&str, &str, &Value) -> bool) -> SelfCalled before each tool call (name, call_id, args); return false to skip
on_after_tool_execution(f: Fn(&str, &str, bool)) -> SelfCalled after each tool call (name, call_id, is_error)
on_before_tool_execution_update(f: Fn(&str, &str, &str) -> bool) -> SelfCalled before each streaming tool update (name, call_id, text); return false to suppress the event
on_after_tool_execution_update(f: Fn(&str, &str, &str)) -> SelfCalled after each streaming tool update (name, call_id, text)
on_before_compaction_start(f: Fn(usize, usize) -> bool) -> SelfCalled before compaction begins (estimated_tokens, message_count); return false to skip compaction
on_after_compaction_end(f: Fn(usize, usize, usize, usize)) -> SelfCalled after compaction completes (messages_before, messages_after, tokens_before, tokens_after)

Prompting

MethodDescription
async prompt(text) -> UnboundedReceiver<AgentEvent>Send a text prompt, returns event stream
async prompt_messages(messages) -> UnboundedReceiver<AgentEvent>Send messages as prompt
async prompt_with_sender(text, tx: UnboundedSender<AgentEvent>)Send a text prompt, streaming events to a caller-provided sender for real-time consumption
async prompt_messages_with_sender(messages, tx)Send messages, streaming events to a caller-provided sender
async continue_loop() -> UnboundedReceiver<AgentEvent>Resume from current context with ContinuationKind::Default. continuation_kind on AgentStart is ContinuationKind (not Option).
async continue_loop_with_sender(tx: UnboundedSender<AgentEvent>, kind: ContinuationKind)Resume from current context with an explicit continuation kind, streaming events to a caller-provided sender

State Access

MethodDescription
messages() -> &[AgentMessage]Get the full message history
is_streaming() -> boolWhether the agent is currently running
agent_id() -> &strStable UUID assigned at construction; included in every AgentStart event
session_id() -> &strStable UUID assigned at construction; groups all loops from this Agent instance
last_loop_id() -> Option<&str>The loop_id of the most recently started loop; None before first run
workspace() -> Option<&Path>The agent's workspace directory, if set (Agent trait method)

State Mutation

MethodDescription
set_tools(tools: Vec<Arc<dyn AgentTool>>)Replace the tool set
clear_messages()Clear all messages
append_message(msg: AgentMessage)Add a message to history
replace_messages(msgs: Vec<AgentMessage>)Replace all messages
save_messages() -> Result<String, serde_json::Error>Serialize message history to JSON
restore_messages(json: &str) -> Result<(), serde_json::Error>Restore message history from JSON

Steering & Follow-Up Queues

MethodDescription
steer(msg: AgentMessage)Queue a steering message (interrupts mid-tool-execution)
follow_up(msg: AgentMessage)Queue a follow-up message (processed after agent finishes)
clear_steering_queue()Clear pending steering messages
clear_follow_up_queue()Clear pending follow-up messages
clear_all_queues()Clear both queues
set_steering_mode(mode: QueueMode)Set delivery mode: OneAtATime or All
set_follow_up_mode(mode: QueueMode)Set delivery mode: OneAtATime or All

Control

MethodDescription
abort()Cancel the current run via CancellationToken
reset()Clear all state (messages, queues, streaming flag)

Session Callback Types

TypeSignatureDescription
BeforeTaskFnArc<dyn Fn(&Session) -> bool + Send + Sync>Called on first AgentStart with a new session_id. Parameter is the Session. Return false to reject.
AfterTaskFnArc<dyn Fn(&Session) + Send + Sync>Called in flush() when the session is finalized. Parameter is the completed Session.

These are set on SessionRecorderConfig and fire at the session level (not per-loop). See Sessions for usage.

Re-exports

The crate re-exports key types from lib.rs:

#![allow(unused)]
fn main() {
// Agent system
pub use agents::{Agent, AgentProfile, BasicAgent, QueueMode};
pub use agents::SubAgentTool;

// Agent loop
pub use agent_loop::{agent_loop, agent_loop_continue, agent_loop_parallel};
pub use agent_loop::evaluation::{
    ElaborateEvaluation, LlmJudgeEvaluation, PickFirstEvaluation,
    TokenEfficientEvaluation, TransparentEvaluation,
};

// Config-driven construction
pub use config::{
    agent_from_config, agent_from_config_with_registry, agents_from_config,
    parse_config, parse_config_file, AgentConfig, ConfigError, ConfigFormat,
};

// Context management
pub use context::{
    CompactionStrategy, CompactionConfig, CompactionScope, ContextConfig,
    DefaultCompaction, DefaultBlockCompaction, BlockCompactionStrategy,
    ContextTracker, CompactionBlock, CompactedSection, TurnMap, TurnRange,
    build_context_from_session, compact_session_loops,
};
pub use context::skills::SkillSet;

// Session persistence
pub use session::{
    Session, SessionRecorder, SessionRecorderConfig, SessionScope, SessionError,
    LoopRecord, LoopEvent, LoopStatus, Turn, LoopConfigSnapshot,
    ParallelGroupRecord, ChildLoopRef, SpawnRef, SessionFormation,
    save_session, load_session, list_session_ids, delete_session, load_sessions_for_agent,
};

// Provider
pub use provider::retry::RetryConfig;

// Types (glob re-export)
pub use types::*;  // Message, Content, AgentMessage, AgentEvent, Usage, LlmMessage,
                    // StopReason, StreamDelta, TurnTrigger, ThinkingLevel, CacheConfig, etc.
}

0.7.0 additions (reachable via module paths)

These symbols were added in 0.7.0 but are not (yet) part of the top-level glob. Import them via their module path:

#![allow(unused)]
fn main() {
// Session: trait-based pluggable store + atomic-write filesystem impl with
// advisory locks (fs2 exclusive lock; returns SessionError::Locked on contention).
use phi_core::session::{SessionStore, FileSystemSessionStore};

// Provider: credential refresh hook for long-running agents whose token expires
// mid-run. On ProviderError::Auth, the loop invalidates the cached credential
// and retries once before propagating.
use phi_core::provider::{CredentialProvider, StaticCredentialProvider};

// Provider: structured-output contract. JsonObject = free-form JSON;
// JsonSchema = strict schema (native where supported, tool-call emulation on
// Anthropic and Anthropic-on-Bedrock, SchemaMismatch on others).
use phi_core::provider::ResponseFormat;

// Agent: fallible build_config(). Default impl returns Err(MissingModelConfig)
// instead of panicking when model_config() is None.
use phi_core::agents::AgentBuildError;

// MCP: configurable per-request timeout (default 30s) on both stdio + HTTP
// transports. Use McpClientConfig with connect_stdio_with_config /
// connect_http_with_config.
use phi_core::mcp::{McpClientConfig, DEFAULT_REQUEST_TIMEOUT};
}