Files
optimclaw/src/main.rs
T
Illia PolosukhinandClaude Opus 4.5 d1cb748914 Add CLI subcommands for WASM tool management
Introduces a new CLI module with subcommands for managing WASM tools:
- `tool install`: Build and install tools from source or .wasm files
- `tool list`: List installed tools with optional verbose output
- `tool remove`: Remove installed tools
- `tool info`: Show detailed tool information including capabilities

The install command supports building from Cargo source directories using
cargo-component, or installing pre-compiled .wasm files directly. It
auto-detects capabilities JSON sidecar files and validates them before
installation.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-02-03 00:05:12 -08:00

131 lines
4.2 KiB
Rust

//! NEAR Agent - Main entry point.
use std::sync::Arc;
use clap::Parser;
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
use near_agent::{
agent::Agent,
channels::{ChannelManager, HttpChannel, TuiChannel},
cli::{Cli, Command, run_tool_command},
config::Config,
history::Store,
llm::create_llm_provider,
safety::SafetyLayer,
tools::ToolRegistry,
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
// Handle non-agent commands first (they don't need TUI/full setup)
match &cli.command {
Some(Command::Tool(tool_cmd)) => {
// Simple logging for CLI commands
tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("warn")),
)
.init();
return run_tool_command(tool_cmd.clone()).await;
}
None | Some(Command::Run) => {
// Continue to run agent
}
}
// Create TUI channel early so we can hook up logging
// (channel is created but not started until agent.run())
let tui_channel = TuiChannel::new();
let tui_log_writer = tui_channel.log_writer();
// Initialize tracing with both stderr (for pre-TUI output) and TUI writer
let env_filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("near_agent=info,tower_http=debug"));
tracing_subscriber::registry()
.with(env_filter)
// TUI layer: sends logs to TUI status line (once TUI is running)
.with(
tracing_subscriber::fmt::layer()
.with_writer(tui_log_writer)
.without_time()
.with_target(false)
.with_level(true),
)
.init();
tracing::info!("Starting NEAR Agent...");
// Load configuration
let config = Config::from_env()?;
tracing::info!("Loaded configuration for agent: {}", config.agent.name);
// Initialize database store (optional for testing)
let store = if cli.no_db {
tracing::warn!("Running without database connection");
None
} else {
let store = Store::new(&config.database).await?;
store.run_migrations().await?;
tracing::info!("Database connected and migrations applied");
Some(Arc::new(store))
};
// Initialize LLM provider
let llm = create_llm_provider(&config.llm)?;
tracing::info!("LLM provider initialized: {}", llm.model_name());
// Initialize safety layer
let safety = Arc::new(SafetyLayer::new(&config.safety));
tracing::info!("Safety layer initialized");
// Initialize tool registry
let tools = Arc::new(ToolRegistry::new());
tools.register_builtin_tools();
tracing::info!("Tool registry initialized with {} tools", tools.count());
// Initialize channel manager
let mut channels = ChannelManager::new();
// Add TUI channel (already created for logging hookup)
if config.channels.cli.enabled {
channels.add(Box::new(tui_channel));
tracing::info!("TUI channel enabled");
}
// Add HTTP channel if configured and not CLI-only mode
if !cli.cli_only {
if let Some(ref http_config) = config.channels.http {
channels.add(Box::new(HttpChannel::new(http_config.clone())));
tracing::info!(
"HTTP channel enabled on {}:{}",
http_config.host,
http_config.port
);
}
// TODO: Add Slack and Telegram channels when implemented
if config.channels.slack.is_some() {
tracing::warn!("Slack channel configured but not yet implemented");
}
if config.channels.telegram.is_some() {
tracing::warn!("Telegram channel configured but not yet implemented");
}
}
// Create and run the agent
let agent = Agent::new(config.agent.clone(), store, llm, safety, tools, channels);
tracing::info!("Agent initialized, starting main loop...");
// Run the agent (blocks until shutdown)
agent.run().await?;
tracing::info!("Agent shutdown complete");
Ok(())
}