# `Mojentic.Agents.SimpleRecursiveAgent`
[🔗](https://github.com/svetzal/mojentic-ex/blob/v1.5.0/lib/mojentic/agents/simple_recursive_agent.ex#L1)

A simple recursive agent that uses events and async to solve problems.

This agent provides a declarative event-driven approach to problem-solving.
It will continue attempting to solve the problem until it either succeeds,
fails explicitly, or reaches the maximum number of iterations.

## Architecture

The agent uses three main components:

1. **GoalState** - Tracks the problem-solving state through iterations
2. **EventEmitter** - GenServer that manages event subscriptions and async dispatch
3. **SimpleRecursiveAgent** - Orchestrates the problem-solving process

## Events

The agent emits the following events during problem-solving:

- `GoalSubmittedEvent` - When a problem is submitted
- `IterationCompletedEvent` - After each iteration completes
- `GoalAchievedEvent` - When the goal is successfully achieved
- `GoalFailedEvent` - When the goal explicitly fails
- `TimeoutEvent` - When the process times out

## Usage

    alias Mojentic.LLM.{Broker, Gateways.Ollama}
    alias Mojentic.LLM.Tools.DateResolver
    alias Mojentic.Agents.SimpleRecursiveAgent

    broker = Broker.new("qwen3:32b", Ollama)

    agent = SimpleRecursiveAgent.new(
      broker,
      tools: [DateResolver],
      max_iterations: 5
    )

    case SimpleRecursiveAgent.solve(agent, "What's the date next Friday?") do
      {:ok, result} -> IO.puts("Result: #{result}")
      {:error, reason} -> IO.puts("Error: #{inspect(reason)}")
    end

## Options

- `:tools` - List of tool modules available to the LLM (default: [])
- `:max_iterations` - Maximum number of iterations before giving up (default: 5)
- `:system_prompt` - Custom system prompt (default: problem-solving assistant prompt)

## Completion Indicators

The agent treats a response as a completion signal only when the **entire response**
(after trimming leading and trailing whitespace, case-insensitive) equals exactly
`DONE` or `FAIL`.

- `DONE` — Task completed successfully
- `FAIL` — Task cannot be completed

Responses that merely contain "done" or "fail" as substrings (e.g. "The task is done"
or "This was a failing approach") do **not** trigger completion.

# `t`

```elixir
@type t() :: %Mojentic.Agents.SimpleRecursiveAgent{
  broker: Mojentic.LLM.Broker.t(),
  emitter: pid(),
  max_iterations: pos_integer(),
  system_prompt: String.t(),
  tools: [module()]
}
```

# `new`

```elixir
@spec new(
  Mojentic.LLM.Broker.t(),
  keyword()
) :: t()
```

Creates a new SimpleRecursiveAgent.

## Parameters

- `broker` - The LLM broker to use for generating responses
- `opts` - Keyword list of options:
  - `:tools` - List of tool modules (default: [])
  - `:max_iterations` - Maximum iterations (default: 5)
  - `:system_prompt` - Custom system prompt (default: problem-solving prompt)

## Examples

    broker = Broker.new("qwen3:32b", Ollama)

    # With defaults
    agent = SimpleRecursiveAgent.new(broker)

    # With custom options
    agent = SimpleRecursiveAgent.new(broker,
      tools: [MyTool],
      max_iterations: 10,
      system_prompt: "You are a specialized assistant."
    )

# `solve`

```elixir
@spec solve(t(), String.t()) :: {:ok, String.t()} | {:error, term()}
```

Solves a problem asynchronously using the recursive agent.

This method runs the event-driven problem-solving process with a 300-second timeout.
The agent will continue iterating until:
- The task is completed successfully ("DONE")
- The task fails explicitly ("FAIL")
- The maximum number of iterations is reached
- The process times out (300 seconds)

## Parameters

- `agent` - The SimpleRecursiveAgent instance
- `problem` - The problem or request to be solved

## Returns

- `{:ok, solution}` - Success with the solution
- `{:error, reason}` - Error during solving

## Examples

    {:ok, result} = SimpleRecursiveAgent.solve(agent, "Calculate 2+2")
    # => {:ok, "2+2 equals 4."}

    {:ok, result} = SimpleRecursiveAgent.solve(agent, "What's the weather tomorrow?")
    # Uses tools to gather info and answer

---

*Consult [api-reference.md](api-reference.md) for complete listing*
