pub struct AgentCore { /* private fields */ }Expand description
AgentCore - A complete, working agent infrastructure.
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
§Basic Usage
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() -> io::Result<()> {
let mut core = AgentCore::new(&MyConfig)?;
// Access channels and controller to wire up your TUI
// then run your TUI loop
Ok(())
}Implementations§
Source§impl AgentCore
impl AgentCore
Sourcepub fn new<C: AgentConfig>(config: &C) -> Result<Self>
pub fn new<C: AgentConfig>(config: &C) -> Result<Self>
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 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 set_conversation_factory<F>(&mut self, factory: F) -> &mut Self
pub fn set_conversation_factory<F>(&mut self, factory: F) -> &mut Self
Set the conversation view factory.
The factory is called to create conversation views when sessions are created or cleared. This allows customizing the chat view with custom welcome screens, title renderers, etc.
§Example
agent.set_conversation_factory(|| {
Box::new(ChatView::new()
.with_title("My Agent")
.with_initial_content(welcome_renderer))
});Sourcepub fn set_layout(&mut self, template: LayoutTemplate) -> &mut Self
pub fn set_layout(&mut self, template: LayoutTemplate) -> &mut Self
Set the layout template for the TUI.
This allows customizing how widgets are arranged in the terminal. If not set, the default Standard layout with panels is used.
§Example
// Use standard layout (default)
agent.set_layout(LayoutTemplate::standard());
// Add a sidebar
agent.set_layout(LayoutTemplate::with_sidebar("file_browser", 30));
// Minimal layout (no status bar)
agent.set_layout(LayoutTemplate::minimal());Sourcepub fn set_key_handler<H: KeyHandler>(&mut self, handler: H) -> &mut Self
pub fn set_key_handler<H: KeyHandler>(&mut self, handler: H) -> &mut Self
Set a custom key handler for the TUI.
This allows full control over key handling behavior. For simpler
customization where you just want to change which keys trigger
which actions, use Self::set_key_bindings instead.
§Example
struct VimKeyHandler { mode: VimMode }
impl KeyHandler for VimKeyHandler {
fn handle_key(&mut self, key: KeyEvent, ctx: &KeyContext) -> AppKeyResult {
// Implement vim-style modal editing
}
}
let mut agent = AgentCore::new(&config)?;
agent.set_key_handler(VimKeyHandler { mode: VimMode::Normal });Sourcepub fn set_key_bindings(&mut self, bindings: KeyBindings) -> &mut Self
pub fn set_key_bindings(&mut self, bindings: KeyBindings) -> &mut Self
Set custom key bindings using the default handler.
This is a simpler alternative to Self::set_key_handler when you
only need to change which keys trigger which actions.
§Example
// Use minimal bindings (Esc to quit, arrow keys only)
let mut agent = AgentCore::new(&config)?;
agent.set_key_bindings(KeyBindings::minimal());
// Or customize specific bindings
let mut bindings = KeyBindings::emacs();
bindings.quit = vec![KeyCombo::key(KeyCode::Esc)];
agent.set_key_bindings(bindings);Sourcepub fn set_exit_handler<H: ExitHandler>(&mut self, handler: H) -> &mut Self
pub fn set_exit_handler<H: ExitHandler>(&mut self, handler: H) -> &mut Self
Set an exit handler for cleanup before quitting.
The exit handler’s on_exit() method is called when the user
confirms exit. If it returns false, the exit is cancelled.
§Example
struct SaveOnExitHandler { session_file: PathBuf }
impl ExitHandler for SaveOnExitHandler {
fn on_exit(&mut self) -> bool {
self.save_session();
true // proceed with exit
}
}
let mut agent = AgentCore::new(&config)?;
agent.set_exit_handler(SaveOnExitHandler { session_file: path });Sourcepub fn set_commands(
&mut self,
commands: Vec<Box<dyn SlashCommand>>,
) -> &mut Self
pub fn set_commands( &mut self, commands: Vec<Box<dyn SlashCommand>>, ) -> &mut Self
Set the slash commands for this agent.
If not called, uses the default command set.
§Example
use agent_core::tui::commands::{CommandRegistry, CustomCommand, CommandResult};
agent.set_commands(
CommandRegistry::with_defaults()
.add(CustomCommand::new("deploy", "Deploy app", |args, ctx| {
CommandResult::Message(format!("Deployed to {}", args))
}))
.remove("quit")
.build()
);Sourcepub fn set_command_extension<T: Any + Send + 'static>(
&mut self,
ext: T,
) -> &mut Self
pub fn set_command_extension<T: Any + Send + 'static>( &mut self, ext: T, ) -> &mut Self
Sourcepub fn register_tools<F>(&mut self, f: F) -> Result<(), AgentError>where
F: FnOnce(&Arc<ToolRegistry>, &Arc<UserInteractionRegistry>, &Arc<PermissionRegistry>) -> Result<Vec<LLMTool>, String>,
pub fn register_tools<F>(&mut self, f: F) -> Result<(), AgentError>where
F: FnOnce(&Arc<ToolRegistry>, &Arc<UserInteractionRegistry>, &Arc<PermissionRegistry>) -> Result<Vec<LLMTool>, 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<LLMTool>, 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<LLMTool>, 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 register_widget<W: Widget>(&mut self, widget: W) -> &mut Self
pub fn register_widget<W: Widget>(&mut self, widget: W) -> &mut Self
Sourcepub fn set_status_bar<W: Widget>(&mut self, status_bar: W) -> &mut Self
pub fn set_status_bar<W: Widget>(&mut self, status_bar: W) -> &mut Self
Set a custom status bar widget to replace the default.
This will unregister the default status bar and register the custom one.
§Example
use agent_core::tui::{StatusBar, StatusBarConfig};
let mut agent = AgentCore::new(&MyConfig)?;
let custom_status_bar = StatusBar::new()
.with_renderer(|data, theme| {
vec![Line::from(format!(" {} | {}", data.model_name, data.session_id))]
});
agent.set_status_bar(custom_status_bar);
agent.run()Sourcepub fn hide_status_bar(&mut self) -> &mut Self
pub fn hide_status_bar(&mut self) -> &mut Self
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(&mut self) -> Result<()>
pub fn run(&mut self) -> Result<()>
Run the agent with the default TUI.
This is the main entry point for running an agent. It:
- Starts background tasks (controller, input router)
- Creates an App with the configured settings
- Wires up all channels and registries
- Creates an initial session if LLM providers are configured
- Runs the TUI event loop
- Shuts down cleanly when the user quits
§Example
fn main() -> io::Result<()> {
let mut agent = AgentCore::new(&MyConfig)?;
agent.run()
}Sourcepub fn to_controller_tx(&self) -> ToControllerTx
pub fn to_controller_tx(&self) -> ToControllerTx
Returns a sender for sending messages to the controller.
Sourcepub fn take_from_controller_rx(&mut self) -> Option<FromControllerRx>
pub fn take_from_controller_rx(&mut self) -> Option<FromControllerRx>
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 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) -> FromControllerTx
pub fn from_controller_tx(&self) -> FromControllerTx
Returns a clone of the UI message sender.
This can be used to send messages to the App’s UI event loop.
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