pub struct AgentCore { /* private fields */ }Expand description
AgentCore - Core runtime infrastructure for LLM-powered agents.
AgentCore provides all the infrastructure needed for an LLM-powered agent:
- Logging with tracing
- LLM configuration loading
- Tokio async runtime
- LLMController for session management
- Communication channels
- User interaction and permission registries
This is the runtime-only version. For TUI support, use the agent-core crate
with the tui feature enabled, which provides the run() method.
§Basic Usage (Headless)
use agent_core_runtime::agent::{AgentConfig, AgentCore};
struct MyConfig;
impl AgentConfig for MyConfig {
fn config_path(&self) -> &str { ".myagent/config.yaml" }
fn default_system_prompt(&self) -> &str { "You are helpful." }
fn log_prefix(&self) -> &str { "myagent" }
fn name(&self) -> &str { "MyAgent" }
}
fn main() -> std::io::Result<()> {
let mut core = AgentCore::new(&MyConfig)?;
core.start_background_tasks();
// Get channels for custom frontend integration
let tx = core.to_controller_tx();
let rx = core.take_from_controller_rx();
// Create a session and interact programmatically
let (session_id, model, _) = core.create_initial_session()?;
// ... send messages and receive responses via channels
core.shutdown();
Ok(())
}Implementations§
Source§impl AgentCore
impl AgentCore
Sourcepub fn new<C>(config: &C) -> Result<AgentCore, Error>where
C: AgentConfig,
pub fn new<C>(config: &C) -> Result<AgentCore, Error>where
C: AgentConfig,
Create a new AgentCore with the given configuration.
This initializes:
- Logging infrastructure
- LLM configuration from config file or environment
- Tokio runtime
- Communication channels
- LLMController
- User interaction and permission registries
Sourcepub fn with_config(
name: impl Into<String>,
config_path: impl Into<String>,
system_prompt: impl Into<String>,
) -> Result<AgentCore, Error>
pub fn with_config( name: impl Into<String>, config_path: impl Into<String>, system_prompt: impl Into<String>, ) -> Result<AgentCore, Error>
Create a new AgentCore with simple configuration parameters.
This is a convenience constructor for quick agent setup without defining a custom config struct.
§Arguments
name- Agent name for display (e.g., “my-agent”)config_path- Path to config file (e.g., “~/.config/my-agent/config.yaml”)system_prompt- Default system prompt for the agent
§Example
use agent_core::agent::AgentCore;
use agent_core::tui::AgentCoreExt;
AgentCore::with_config("my-agent", "~/.config/my-agent/config.yaml", "You are helpful.")?
.into_tui()
.run()Sourcepub fn set_error_no_session(
&mut self,
message: impl Into<String>,
) -> &mut AgentCore
pub fn set_error_no_session( &mut self, message: impl Into<String>, ) -> &mut AgentCore
Sourcepub fn error_no_session(&self) -> Option<&str>
pub fn error_no_session(&self) -> Option<&str>
Get the error message for no session, if set.
Sourcepub fn set_version(&mut self, version: impl Into<String>)
pub fn set_version(&mut self, version: impl Into<String>)
Set the agent version for display.
Sourcepub fn load_environment_context(&mut self) -> &mut AgentCore
pub fn load_environment_context(&mut self) -> &mut AgentCore
Load environment context into the system prompt.
This adds information about the current execution environment to all LLM session prompts:
- Current working directory
- Platform (darwin, linux, windows)
- OS version
- Today’s date
The context is wrapped in <env> tags and appended to the system prompt.
§Example
let mut core = AgentCore::new(&config)?;
core.load_environment_context();Sourcepub fn register_tools<F>(&mut self, f: F) -> Result<(), AgentError>where
F: FnOnce(&Arc<ToolRegistry>, &Arc<UserInteractionRegistry>, &Arc<PermissionRegistry>) -> Result<Vec<Tool>, String>,
pub fn register_tools<F>(&mut self, f: F) -> Result<(), AgentError>where
F: FnOnce(&Arc<ToolRegistry>, &Arc<UserInteractionRegistry>, &Arc<PermissionRegistry>) -> Result<Vec<Tool>, String>,
Sourcepub fn register_tools_async<F, Fut>(&mut self, f: F) -> Result<(), AgentError>where
F: FnOnce(Arc<ToolRegistry>, Arc<UserInteractionRegistry>, Arc<PermissionRegistry>) -> Fut,
Fut: Future<Output = Result<Vec<Tool>, String>>,
pub fn register_tools_async<F, Fut>(&mut self, f: F) -> Result<(), AgentError>where
F: FnOnce(Arc<ToolRegistry>, Arc<UserInteractionRegistry>, Arc<PermissionRegistry>) -> Fut,
Fut: Future<Output = Result<Vec<Tool>, String>>,
Register tools with the agent using an async function.
Similar to register_tools, but accepts an async closure. The closure
is executed using the agent’s tokio runtime via block_on.
§Example
core.register_tools_async(|registry, user_reg, perm_reg| async move {
tools::register_all_tools(®istry, user_reg, perm_reg).await
})?;Sourcepub fn start_background_tasks(&mut self)
pub fn start_background_tasks(&mut self)
Start the controller and input router as background tasks.
This must be called before sending messages or creating sessions. After calling this, the controller is running and ready to accept input.
Sourcepub fn create_initial_session(
&mut self,
) -> Result<(i64, String, i32), AgentError>
pub fn create_initial_session( &mut self, ) -> Result<(i64, String, i32), AgentError>
Create an initial session using the default LLM provider.
Returns the session ID, model name, and context limit.
Sourcepub fn create_session(
&self,
config: LLMSessionConfig,
) -> Result<i64, AgentError>
pub fn create_session( &self, config: LLMSessionConfig, ) -> Result<i64, AgentError>
Create a session with the given configuration.
Returns the session ID or an error.
Sourcepub fn run_with_frontend<E, I, P>(
&mut self,
event_sink: E,
input_source: I,
permission_policy: P,
) -> Result<(), Error>
pub fn run_with_frontend<E, I, P>( &mut self, event_sink: E, input_source: I, permission_policy: P, ) -> Result<(), Error>
Run the agent with a custom frontend.
This is the primary entry point for custom frontends. It:
- Starts background tasks (controller, input router)
- Wires the event sink to receive engine events
- Wires the input source to provide user input
- Applies the permission policy
- Runs until the input source closes
§Arguments
event_sink- Receives events from the engineinput_source- Provides input to the enginepermission_policy- Handles permission requests
§Example: Headless with Auto-Approve
use agent_core_runtime::agent::{
AgentCore, AutoApprovePolicy, StdoutEventSink, ChannelInputSource
};
let mut agent = AgentCore::with_config(
"my-agent",
"~/.config/my-agent/config.yaml",
"You are helpful."
)?;
// Create input channel
let (input_tx, input_source) = ChannelInputSource::channel(100);
// Run with custom frontend (blocks until input_tx is dropped)
agent.run_with_frontend(
StdoutEventSink::new(),
input_source,
AutoApprovePolicy::new(),
)?;Sourcepub fn to_controller_tx(&self) -> Sender<ControllerInputPayload>
pub fn to_controller_tx(&self) -> Sender<ControllerInputPayload>
Returns a sender for sending messages to the controller.
Sourcepub fn take_from_controller_rx(&mut self) -> Option<Receiver<UiMessage>>
pub fn take_from_controller_rx(&mut self) -> Option<Receiver<UiMessage>>
Takes the receiver for messages from the controller (can only be called once).
Sourcepub fn controller(&self) -> &Arc<LLMController>
pub fn controller(&self) -> &Arc<LLMController>
Returns a reference to the controller.
Sourcepub fn runtime_handle(&self) -> Handle
pub fn runtime_handle(&self) -> Handle
Returns a handle to the runtime.
Sourcepub fn user_interaction_registry(&self) -> &Arc<UserInteractionRegistry>
pub fn user_interaction_registry(&self) -> &Arc<UserInteractionRegistry>
Returns a reference to the user interaction registry.
Sourcepub fn permission_registry(&self) -> &Arc<PermissionRegistry>
pub fn permission_registry(&self) -> &Arc<PermissionRegistry>
Returns a reference to the permission registry.
Sourcepub async fn remove_session(&self, session_id: i64) -> bool
pub async fn remove_session(&self, session_id: i64) -> bool
Removes a session and cleans up all associated resources.
This is the recommended way to remove a session as it orchestrates cleanup across:
- The LLM session manager (terminates the session)
- The permission registry (cancels pending permission requests)
- The user interaction registry (cancels pending user questions)
- The tool registry (cleans up per-session state in tools)
§Arguments
session_id- The ID of the session to remove
§Returns
true if the session was found and removed, false if session didn’t exist
Sourcepub fn llm_registry(&self) -> Option<&LLMRegistry>
pub fn llm_registry(&self) -> Option<&LLMRegistry>
Returns a reference to the LLM registry.
Sourcepub fn take_llm_registry(&mut self) -> Option<LLMRegistry>
pub fn take_llm_registry(&mut self) -> Option<LLMRegistry>
Takes the LLM registry (can only be called once).
Sourcepub fn cancel_token(&self) -> CancellationToken
pub fn cancel_token(&self) -> CancellationToken
Returns the cancellation token.
Sourcepub fn from_controller_tx(&self) -> Sender<UiMessage>
pub fn from_controller_tx(&self) -> Sender<UiMessage>
Returns a clone of the UI message sender.
This can be used to send messages to the frontend’s event loop.
Sourcepub fn tool_definitions(&self) -> &[Tool]
pub fn tool_definitions(&self) -> &[Tool]
Returns a reference to the tool definitions.
Sourcepub fn skill_registry(&self) -> &Arc<SkillRegistry>
pub fn skill_registry(&self) -> &Arc<SkillRegistry>
Returns a reference to the skill registry.
Sourcepub fn register_list_skills_tool(&mut self) -> Result<Tool, AgentError>
pub fn register_list_skills_tool(&mut self) -> Result<Tool, AgentError>
Register the ListSkillsTool, allowing the LLM to discover available skills.
This registers the list_skills tool with the tool registry and adds its
definition to the tool list. Call this after register_tools() if you want
the LLM to be able to query available skills.
Returns the LLM tool definition that was added.
Sourcepub fn add_skill_path(&mut self, path: PathBuf) -> &mut AgentCore
pub fn add_skill_path(&mut self, path: PathBuf) -> &mut AgentCore
Add a custom skill search path.
Skills are discovered from directories containing SKILL.md files.
By default, $PWD/.skills/ and ~/.agent-core/skills/ are searched.
Sourcepub fn load_skills(&mut self) -> (usize, Vec<SkillDiscoveryError>)
pub fn load_skills(&mut self) -> (usize, Vec<SkillDiscoveryError>)
Load skills from configured directories.
This scans all configured skill paths and registers discovered skills in the skill registry. Call this after configuring skill paths.
Returns the number of skills loaded and any errors encountered.
Sourcepub fn load_skills_from(
&self,
paths: Vec<PathBuf>,
) -> (usize, Vec<SkillDiscoveryError>)
pub fn load_skills_from( &self, paths: Vec<PathBuf>, ) -> (usize, Vec<SkillDiscoveryError>)
Load skills from specific paths (one-shot, doesn’t modify default discovery).
This creates a temporary discovery instance with only the provided paths,
loads skills from them, and registers them in the skill registry.
Unlike add_skill_path() + load_skills(), this doesn’t affect the
default discovery paths used by reload_skills().
Returns the number of skills loaded and any errors encountered.
Sourcepub fn reload_skills(&mut self) -> SkillReloadResult
pub fn reload_skills(&mut self) -> SkillReloadResult
Reload skills from configured directories.
This re-scans all configured skill paths and updates the registry:
- New skills are added
- Removed skills are unregistered
- Existing skills are re-registered (silently updated)
Returns information about what changed (added/removed only).
Sourcepub fn skills_prompt_xml(&self) -> String
pub fn skills_prompt_xml(&self) -> String
Get skills XML for injection into system prompts.
Returns an XML string listing all available skills that can be included in the system prompt to inform the LLM about available capabilities.
Sourcepub async fn refresh_session_skills(
&self,
session_id: i64,
) -> Result<(), AgentError>
pub async fn refresh_session_skills( &self, session_id: i64, ) -> Result<(), AgentError>
Refresh a session’s system prompt with current skills.
This updates the session’s system prompt to include the current
<available_skills> XML from the skill registry.
Note: This appends the skills XML to the existing system prompt. If skills were previously loaded, this may result in duplicate entries.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for AgentCore
impl !RefUnwindSafe for AgentCore
impl Send for AgentCore
impl Sync for AgentCore
impl Unpin for AgentCore
impl !UnwindSafe for AgentCore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more