rune-chain-agent 0.1.0

ReAct agent loop for rune-chain: LLM + tools + scratchpad reasoning
Documentation

rune-chain-agent

ReAct agent loop for rune-chain: LLM reasoning + tool invocation + scratchpad.

crates.io docs.rs license CI

What it does

rune-chain-agent implements the ReAct (Reasoning + Acting) pattern for the rune-chain ecosystem. The agent iterates between an LLM and a set of registered tools: the LLM reasons about which tool to call, the tool runs and returns an observation, and the loop continues until the LLM produces a final answer or the iteration cap is hit.

It is provider-agnostic — wire in any rune-chain-core::Llm implementation (OpenAI, Anthropic, Ollama, or your own) and implement Tool for each capability you want the agent to use.

Installation

[dependencies]
rune-chain-agent = "0.1"
rune-chain-core  = "0.1"

Usage

use std::sync::Arc;
use rune_chain_core::{Llm, Tool};
use rune_chain_agent::AgentExecutor;

// 1. Implement a tool.
struct Echo;
impl Tool for Echo {
    fn name(&self) -> &str { "echo" }
    fn description(&self) -> &str { "Returns the input unchanged." }
    fn run(&self, input: &str) -> String { input.to_string() }
}

# async fn run() -> Result<(), rune_chain_core::ChainError> {
# let llm: Arc<dyn Llm> = unimplemented!();
// 2. Build the agent.
let agent = AgentExecutor::new(llm)
    .tool(Echo)
    .max_iterations(10);

// 3. Run it.
let result = agent.run("Echo 'hello world' back to me.").await?;
println!("Answer: {}", result.output);
println!("Steps taken: {}", result.iterations);
# Ok(())
# }

As a Chain

AgentExecutor implements rune_chain_core::Chain, so it composes with sequential and conversational chains:

use std::sync::Arc;
use rune_chain_core::{Chain, Llm, prompt_args};
use rune_chain_agent::AgentExecutor;

# async fn run() -> Result<(), rune_chain_core::ChainError> {
# let llm: Arc<dyn Llm> = unimplemented!();
let agent = AgentExecutor::new(llm);
let answer = agent.invoke(prompt_args! { "input" => "What is 6 * 7?" }).await?;
println!("{answer}");
# Ok(())
# }

ReAct Scratchpad Format

The agent instructs the LLM to follow this format during reasoning:

Thought: <reason about what to do>
Action: <tool_name>
Action Input: <input to the tool>
Observation: <result of the action>
... (repeat Thought/Action/Action Input/Observation as needed)
Thought: I now have enough information.
Final Answer: <your final answer>

Builder API

Method Description
AgentExecutor::new(llm) Create agent with an Arc<dyn Llm>
.tool(t) Register a Tool implementation
.max_iterations(n) Cap the reasoning loop (default: 10)
.system_prompt(s) Override the auto-generated system prompt
.run(input) Execute and return AgentResult
.call(prompt_args) Chain interface — reads the "input" key

Output

Answer: The result is HELLO WORLD.
Steps taken: 2

The full AgentResult also exposes scratchpad: Vec<String> with every thought, action, and observation from the run.

License

MIT