LemonAgent.Loop (lemon_agent v0.1.0)

View Source

Stateless agent loop functions for conversation management.

This module implements the core agent loop logic that orchestrates:

  • Streaming LLM responses
  • Tool call execution
  • Steering message injection
  • Follow-up message handling

The loop works with LemonAgent.EventStream to emit events for UI clients and returns the final list of new messages created during the run.

Entry Points

Event Flow

The loop emits events in a specific sequence:

{:agent_start}
{:tool_schema_snapshot, snapshot}
{:turn_start}
{:loop_state_transition, nil, :initializing, %{phase: :run_start}}
{:message_start, prompt}
{:message_end, prompt}
{:message_start, assistant_msg}
{:message_update, assistant_msg, event}
...
{:message_end, assistant_msg}
{:tool_execution_start, id, name, args}
{:tool_execution_update, id, name, args, partial}
{:tool_execution_end, id, name, result, is_error}
{:message_start, tool_result}
{:message_end, tool_result}
{:turn_end, assistant_msg, tool_results}
{:loop_budget_exhausted, details}
... (more turns if tool calls or steering)
{:agent_end, new_messages}

Abort Handling

The signal parameter is a reference that can be used for abort handling. Check for abort by monitoring the signal or using Process messages.

Summary

Functions

Start an agent loop with new prompt messages.

Continue an agent loop from an existing context without adding new messages.

Start an agent loop and return an Enumerable of events.

Continue an agent loop and return an Enumerable of events.

Functions

agent_loop(prompts, context, config, signal, stream_fn)

Start an agent loop with new prompt messages.

Creates a new EventStream, emits lifecycle events for the prompts, and starts the main loop in an async task.

Parameters

  • prompts - List of agent messages to add to context as the prompt
  • context - The current agent context (system prompt, messages, tools)
  • config - Agent loop configuration (model, convert_to_llm, etc.)
  • signal - Optional abort signal reference for cancellation
  • stream_fn - Optional custom stream function (defaults to LemonAi.stream/3)

Returns

An EventStream that will emit agent events and complete with {:ok, new_messages} where new_messages contains only the messages created during this run (not the original context messages).

Examples

context = AgentContext.new(system_prompt: "You are helpful")
config = %AgentLoopConfig{model: model, convert_to_llm: &convert/1}
prompt = %LemonAi.Types.UserMessage{content: "Hello", timestamp: now()}

stream = LemonAgent.Loop.agent_loop([prompt], context, config, nil, nil)

for event <- EventStream.events(stream) do
  IO.inspect(event)
end

agent_loop(prompts, context, config, signal, stream_fn, owner)

agent_loop_continue(context, config, signal, stream_fn)

Continue an agent loop from an existing context without adding new messages.

Used for retries or continuing after tool results have been added to context. The context must not be empty and the last message must not be an assistant message.

Parameters

  • context - The agent context to continue from
  • config - Agent loop configuration
  • signal - Optional abort signal reference
  • stream_fn - Optional custom stream function

Raises

Examples

# After adding tool results to context
stream = LemonAgent.Loop.agent_loop_continue(context, config, nil, nil)

agent_loop_continue(context, config, signal, stream_fn, owner)

stream(prompts, context, config, stream_fn \\ nil)

Start an agent loop and return an Enumerable of events.

This is a convenience wrapper around agent_loop/5 that returns the EventStream's events directly as an Enumerable, suitable for use with Enum or Stream functions.

Parameters

  • prompts - List of agent messages to add to context as the prompt
  • context - The current agent context
  • config - Agent loop configuration
  • stream_fn - Optional custom stream function

Returns

An Enumerable of agent events.

stream_continue(context, config, stream_fn \\ nil)

Continue an agent loop and return an Enumerable of events.

This is a convenience wrapper around agent_loop_continue/4 that returns the EventStream's events directly as an Enumerable.

Parameters

  • context - The agent context to continue from
  • config - Agent loop configuration
  • stream_fn - Optional custom stream function

Returns

An Enumerable of agent events.