Class: AgentRequestJob

Inherits:
ApplicationJob show all
Defined in:
app/jobs/agent_request_job.rb

Overview

Executes an LLM agent loop as a background job with retry logic for transient failures (network errors, rate limits, server errors).

Emits events via Events::Bus as it progresses, making results visible to any subscriber (TUI, WebSocket clients). All retry and failure notifications are emitted as Events::SystemMessage to avoid polluting the LLM context window.

Examples:

Inline execution (TUI)

AgentRequestJob.perform_now(session.id)

Background execution (future Brain/TUI separation)

AgentRequestJob.perform_later(session.id)

Instance Method Summary collapse

Instance Method Details

#perform(session_id) ⇒ Object

Parameters:

  • session_id (Integer)

    ID of the session to process



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'app/jobs/agent_request_job.rb', line 43

def perform(session_id)
  session = Session.find(session_id)

  # Atomic: only one job processes a session at a time. If another job
  # is already running, this one exits — the running job will pick up
  # any pending messages after its current loop completes.
  return unless claim_processing(session_id)

  # Run analytical brain BEFORE the main agent on user messages so
  # activated skills are available for the current response.
  run_analytical_brain_blocking(session)

  agent_loop = AgentLoop.new(session: session)
  loop do
    agent_loop.run
    promoted = session.promote_pending_messages!
    break if promoted == 0
  end

  # Non-blocking analytical brain run after agent completes —
  # handles post-response updates (renaming, skill changes).
  session.schedule_analytical_brain!
ensure
  release_processing(session_id)
  clear_interrupt(session_id)
  agent_loop&.finalize
end