Class: Protege::InferenceJob

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

Overview

Runs one inbound email through the full Protege inference pipeline (the "I" of LOGI).

Enqueued by AgentMailbox once persona routing succeeds. The job re-hydrates the raw email and persona from their IDs, ingests a Message, runs the Orchestrator's Harness, and records the outcome on the message. IDs (not objects) are passed across the async boundary so the queue adapter can serialize and safely retry the job across process restarts.

The correlation_id argument carries the trace token set in AgentMailbox; restoring it into Protege::Current at the top of perform keeps events consistent from HTTP ingress through inference. Failures are captured on the message before re-raising so the retry machinery and the UI both have full context.

Instance Method Summary collapse

Instance Method Details

#perform(inbound_email_id:, persona_id:, correlation_id:) ⇒ void

This method returns an undefined value.

Process one inbound email end to end: ingest, run inference, record the result.

Parameters:

  • inbound_email_id (Integer)

    id of the ActionMailbox::InboundEmail to process

  • persona_id (Integer)

    primary key of the Protege::Persona; STI loads the subclass

  • correlation_id (String)

    the RFC 2822 Message-ID set by AgentMailbox for tracing

Raises:

  • (StandardError)

    re-raised after being recorded on the message, to trigger retries



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/jobs/protege/inference_job.rb', line 25

def perform(inbound_email_id:, persona_id:, correlation_id:)
  restore_correlation_id(correlation_id)

  # Re-hydrate the raw email and the target persona from their IDs.
  # IDs are passed rather than objects so Solid Queue can serialize
  # the job and retry it safely across process restarts.
  inbound_email = ActionMailbox::InboundEmail.find(inbound_email_id)
  persona       = Persona.find(persona_id)

  # Parse the raw email, find-or-create the EmailThread, and persist
  # a Protege::Message record with processing_status: :processing.
  # Returns the saved message so we can update its lifecycle below.
  message = Message.ingest!(inbound_email:, persona:)

  process(message:, persona:)
rescue StandardError => e
  # Capture the error on the message record before re-raising so the
  # job can be inspected and manually re-queued without losing context.
  message&.mark_failed!(e)
  raise
end