AgentCore

Struct AgentCore 

Source
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

Source

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
Source

pub fn set_version(&mut self, version: impl Into<String>)

Set the agent version for display.

Source

pub fn set_conversation_factory<F>(&mut self, factory: F) -> &mut Self
where F: Fn() -> Box<dyn ConversationView> + Send + Sync + 'static,

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))
});
Source

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());
Source

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 });
Source

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);
Source

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 });
Source

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()
);
Source

pub fn set_command_extension<T: Any + Send + 'static>( &mut self, ext: T, ) -> &mut Self

Set extension data available to custom commands.

Commands can access this via ctx.extension::<T>().

§Example
struct MyContext { api_key: String }

agent.set_command_extension(MyContext {
    api_key: "secret".to_string()
});
Source

pub fn register_tools<F>(&mut self, f: F) -> Result<(), AgentError>

Register tools with the agent.

The callback receives references to the tool registry and interaction registries, and should return the tool definitions to register.

§Example
core.register_tools(|registry, user_reg, perm_reg| {
    tools::register_all_tools(registry, user_reg, perm_reg)
})?;
Source

pub fn register_tools_async<F, Fut>(&mut self, f: F) -> Result<(), AgentError>

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(&registry, user_reg, perm_reg).await
})?;
Source

pub fn register_widget<W: Widget>(&mut self, widget: W) -> &mut Self

Register a widget with the agent.

Widgets are registered before calling run() and will be available in the TUI application.

§Example
let mut agent = AgentCore::new(&MyConfig)?;
agent.register_widget(PermissionPanel::new());
agent.register_widget(QuestionPanel::new());
agent.run()
Source

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()
Source

pub fn hide_status_bar(&mut self) -> &mut Self

Hide the default status bar.

This will unregister the default status bar widget. Useful for minimal layouts or when you want to implement your own status display.

§Example
let mut agent = AgentCore::new(&MyConfig)?;
agent.hide_status_bar();
agent.run()
Source

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.

Source

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.

Source

pub fn create_session( &self, config: LLMSessionConfig, ) -> Result<i64, AgentError>

Create a session with the given configuration.

Returns the session ID or an error.

Source

pub fn shutdown(&self)

Signal shutdown to all background tasks and the controller.

Source

pub fn run(&mut self) -> Result<()>

Run the agent with the default TUI.

This is the main entry point for running an agent. It:

  1. Starts background tasks (controller, input router)
  2. Creates an App with the configured settings
  3. Wires up all channels and registries
  4. Creates an initial session if LLM providers are configured
  5. Runs the TUI event loop
  6. Shuts down cleanly when the user quits
§Example
fn main() -> io::Result<()> {
    let mut agent = AgentCore::new(&MyConfig)?;
    agent.run()
}
Source

pub fn to_controller_tx(&self) -> ToControllerTx

Returns a sender for sending messages to the controller.

Source

pub fn take_from_controller_rx(&mut self) -> Option<FromControllerRx>

Takes the receiver for messages from the controller (can only be called once).

Source

pub fn controller(&self) -> &Arc<LLMController>

Returns a reference to the controller.

Source

pub fn runtime(&self) -> &Runtime

Returns a reference to the runtime.

Source

pub fn runtime_handle(&self) -> Handle

Returns a handle to the runtime.

Source

pub fn user_interaction_registry(&self) -> &Arc<UserInteractionRegistry>

Returns a reference to the user interaction registry.

Source

pub fn permission_registry(&self) -> &Arc<PermissionRegistry>

Returns a reference to the permission registry.

Source

pub fn llm_registry(&self) -> Option<&LLMRegistry>

Returns a reference to the LLM registry.

Source

pub fn take_llm_registry(&mut self) -> Option<LLMRegistry>

Takes the LLM registry (can only be called once).

Source

pub fn cancel_token(&self) -> CancellationToken

Returns the cancellation token.

Source

pub fn name(&self) -> &str

Returns the agent name.

Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more