Class: Phronomy::Rails::AgentJob

Inherits:
ActiveJob::Base
  • Object
show all
Defined in:
lib/phronomy/rails/agent_job.rb

Overview

ActiveJob-based job that runs a Phronomy agent in streaming mode and broadcasts each event to an ActionCable stream.

Enqueue with +perform_later+ to run the agent asynchronously in a background worker. Every streaming event is forwarded to ActionCable subscribers in real time.

Events broadcast to the ActionCable stream: { type: "token", content: "..." } — each content delta from the LLM { type: "done", output: "..." } — final complete output { type: "error", message: "..." } — when the agent or job raises

Examples:

Enqueueing a streaming agent job

Phronomy::Rails::AgentJob.perform_later(
  "MyAgent",
  "What is the weather today?",
  channel: "AgentChannel",
  stream: "agent_#{current_user.id}"
)

Instance Method Summary collapse

Instance Method Details

#perform(agent_class_name, input, channel:, stream:, config: {}) ⇒ Object

Parameters:

  • agent_class_name (String)

    The constantize-able class name of the agent to run (e.g. "MyAgent"). Security: only classes that are subclasses of +Phronomy::Agent::Base+ are accepted. Never pass a value derived from user-controlled input.

  • input (String, Hash)

    User input forwarded unchanged to the agent's +#stream+ method.

  • channel (String)

    ActionCable channel name. Retained for documentation / future routing.

  • stream (String)

    ActionCable stream identifier passed to +ActionCable.server.broadcast+.

  • config (Hash) (defaults to: {})

    Configuration forwarded to the agent's +#stream+ call. Both symbol and string keys are accepted; all keys are converted to symbols before use.



39
40
41
42
43
44
45
46
47
48
# File 'lib/phronomy/rails/agent_job.rb', line 39

def perform(agent_class_name, input, channel:, stream:, config: {})
  klass = resolve_agent_class!(agent_class_name)
  agent = klass.new
  agent.stream(input, config: config.transform_keys(&:to_sym)) do |event|
    ActionCable.server.broadcast(stream, build_payload(event))
  end
rescue => e
  ::Rails.logger.error("[Phronomy::Rails::AgentJob] agent error (#{e.class}): #{e.message}")
  ActionCable.server.broadcast(stream, {type: "error", message: "An error occurred while processing your request."})
end