///|
/// moon-agent ReAct agent demo with built-in tools.
///
/// This example demonstrates:
/// 1. Loading unified config from `config.json` or env vars
/// 2. Using built-in CalculatorTool for math
/// 3. Using built-in DateTimeTool for time queries
/// 4. Running an AgentExecutor with both tools and memory
///
/// Configuration:
/// Create `config.json` at project root (see `config.example.json`):
/// ```json
/// {
/// "api_key": "sk-...",
/// "base_url": "https://api.deepseek.com",
/// "model": "deepseek-chat"
/// }
/// ```
/// Or set env vars: OPENAI_API_KEY, OPENAI_BASE_URL (optional), OPENAI_MODEL (optional)
///
/// Run with:
/// moon run examples/react_agent --target js
///
/// The agent can answer questions like:
/// "What is 15 * 23 + 100?" (uses CalculatorTool)
/// "What time is it now?" (uses DateTimeTool)
/// "Multiply 7 by 8 and tell me the answer"
///|
fn main {
// Load config from config.json or env vars (unified with cmd/chat)
let config = match @config.load_config() {
Some(c) => c
None => {
println("Please configure API access first.")
println(
"Create `config.json` at project root (see `config.example.json`)",
)
println(
"or set env vars: OPENAI_API_KEY, OPENAI_BASE_URL (optional), OPENAI_MODEL (optional)",
)
return
}
}
// Build provider from config (supports DeepSeek, OpenAI, any OpenAI-compatible endpoint)
let model = @openai.OpenAIProvider::new_compat(
config.base_url,
config.model,
api_key=config.api_key,
max_tokens=config.max_tokens,
system_prompt=config.system_prompt,
)
let provider = @llm.BoxedProvider::new(model)
// Build a tool registry with built-in tools
let registry = @llm_tools.ToolRegistry::new()
@tools.register_into(registry, @tools.CalculatorTool::new())
@tools.register_into(registry, @tools.DateTimeTool::new())
println("Endpoint: " + config.base_url + " | Model: " + config.model)
println("")
// Demo: ask a math question
println("=== Demo 1: Calculator ===")
let executor = @agents.AgentExecutor::new(provider, registry)
|> @agents.AgentExecutor::with_memory(@memory.BufferMemory::new())
|> @agents.AgentExecutor::with_max_steps(5)
let result1 = executor.invoke(
"What is 15 * 23 + 100? Please use the calculator tool.",
)
println("Agent: " + result1)
// Demo: ask about time
println("\n=== Demo 2: DateTime ===")
let executor2 = @agents.AgentExecutor::new(provider, registry)
|> @agents.AgentExecutor::with_max_steps(3)
let result2 = executor2.invoke(
"What is the current date and time? Use the get_current_time tool.",
)
println("Agent: " + result2)
// Demo: multi-tool query
println("\n=== Demo 3: Multi-tool ===")
let executor3 = @agents.AgentExecutor::new(provider, registry)
|> @agents.AgentExecutor::with_max_steps(8)
let result3 = executor3.invoke(
"First get the current time, then calculate 3600 / 60 (seconds per hour divided by minutes per hour). Tell me both results.",
)
println("Agent: " + result3)
}