Beamlens.Operator (beamlens v0.3.1)

View Source

Operator for LLM-driven BEAM monitoring.

Static Supervision

Operators are started as static, always-running supervised processes. They wait in :idle status until invoked, then run their LLM loop.

Running Analysis with run/2

For scheduled or triggered analysis (e.g., Oban workers):

{:ok, notifications} = Beamlens.Operator.run(Beamlens.Skill.Beam, %{reason: "high memory detected"})

# With custom LLM provider
{:ok, notifications} = Beamlens.Operator.run(Beamlens.Skill.Beam, %{reason: "high memory"},
  client_registry: custom_registry
)

The LLM investigates and calls done() when finished, returning the notifications generated during analysis.

State Model

Operators maintain one of four health states:

  • :healthy - Everything is normal
  • :observing - Something looks off, gathering more data
  • :warning - Elevated concern, but not critical
  • :critical - Active issue requiring immediate attention

Status

Operators have a run status:

  • :idle - Waiting for invocation
  • :running - LLM loop is active

Summary

Functions

Awaits completion for an operator.

Returns a specification to start this module under a supervisor.

Sends a message to the operator and receives an LLM-generated response.

Runs analysis using the static operator for the given skill.

Invokes an existing operator process directly.

Runs an operator asynchronously with notification callbacks.

Starts an operator process.

Returns the current operator status.

Stops the operator process.

Functions

await(server, timeout \\ :infinity)

Awaits completion for an operator.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

message(server, prompt, timeout \\ 30000)

Sends a message to the operator and receives an LLM-generated response.

The coordinator's LLM generates a custom prompt, and the operator's LLM responds using its full conversation context. Useful for LLM-to-LLM communication where the coordinator needs to understand what the operator is observing.

Returns {:ok, response} with:

  • :skill - The operator's skill ID
  • :state - Current operator state
  • :iteration - Current iteration count
  • :response - The LLM-generated response content

run(skill, opts)

Runs analysis using the static operator for the given skill.

The operator must be configured in your Beamlens supervision tree. Raises ArgumentError if the operator is not started.

The LLM investigates and calls done() when finished, returning the notifications generated during analysis.

Arguments

  • skill - Module implementing Beamlens.Skill, or atom for built-in skill
  • context - Map with context for the investigation (e.g., %{reason: "high memory"})
  • opts - Options

Options

  • :context - Map with context (alternative to second argument)
  • :client_registry - LLM provider configuration map (default: %{})
  • :puck_client - Optional Puck.Client to use instead of BAML
  • :max_iterations - Maximum LLM iterations before returning (default: 25)
  • :timeout - Timeout for awaiting completion (default: :infinity)

Returns

  • {:ok, notifications} - List of notifications sent during this run
  • {:error, reason} - If the skill couldn't be resolved or LLM failed

Examples

# Context as second argument
{:ok, notifications} = Beamlens.Operator.run(:beam, %{reason: "high memory"})

# Context in opts
{:ok, notifications} = Beamlens.Operator.run(:beam, context: %{reason: "high memory"})

# With custom LLM provider
{:ok, notifications} = Beamlens.Operator.run(:beam, %{reason: "investigating"},
  client_registry: %{primary: "Ollama", clients: [...]}
)

run(pid, context, opts)

Invokes an existing operator process directly.

Use this when you have a reference to a static operator and want to run analysis on it. The operator queues the request if already running.

run_async(pid, context, opts \\ [])

Runs an operator asynchronously with notification callbacks.

The caller will receive messages:

  • {:operator_notification, pid, notification} for each notification
  • {:operator_complete, pid, skill, completion_result} when done

Returns :ok immediately after queuing the invocation.

start_link(opts)

Starts an operator process.

Options

  • :name - Optional process name for registration
  • :skill - Required module implementing Beamlens.Skill
  • :client_registry - Optional LLM provider configuration map
  • :puck_client - Optional Puck.Client to use instead of BAML
  • :start_loop - Whether to start the LLM loop on init (default: false)
  • :context - Map with context to pass to the LLM
  • :max_iterations - Maximum LLM iterations before returning (default: 25)
  • :compaction_max_tokens - Token threshold for compaction (default: 50_000)
  • :compaction_keep_last - Messages to keep verbatim after compaction (default: 5)
  • :notify_pid - PID to receive real-time notifications and completion messages

status(server)

Returns the current operator status.

Returns a map with:

  • :operator - Domain atom (e.g., :beam)
  • :state - Current state (:healthy, :observing, :warning, :critical)
  • :iteration - Current iteration count
  • :running - Boolean indicating if the loop is active

stop(server)

Stops the operator process.