CouncilEx.Councils.Consensus (CouncilEx v0.1.0)

Copy Markdown View Source

Topology #9 — independent_analysis → iterate(critique, until: ...) → chair.

Members analyse independently, then critique each other's outputs iteratively until a convergence callback returns true or max_iterations is reached. The chair synthesizes the final iteration's outputs.

Options

  • :members — list of {id, module, opts} tuples (required)
  • :chair{module, opts} tuple (required)
  • :until(prev_round_result | nil, current_round_result -> boolean) (default: always false)

  • :max_iterations — positive integer, default 3
  • :as — module name for the created council module (optional)

Usage (module-form)

council =
  CouncilEx.Councils.Consensus.new(
    as: MyApp.ConsensusCouncil,
    members: [
      {:m1, MyApp.Members.Analyst, [provider: :openai, model: "gpt-4o-mini"]},
      {:m2, MyApp.Members.Analyst, [provider: :openai, model: "gpt-4o-mini"]}
    ],
    chair: {MyApp.Members.Synth, [provider: :openai, model: "gpt-4o"]},
    max_iterations: 3
  )

Usage (dynamic / data-only form)

new_dynamic/1 returns a %CouncilEx.DynamicCouncil{} with the same topology. The :until callback (when provided) MUST be a remote function capture — &MyMod.converged?/2 — not an inline fn, because dynamic councils are designed to be JSON-serializable. Inline fn works at runtime but won't survive to_json/from_json. Omit :until to rely solely on :max_iterations.

Summary

Functions

Look up the until/2 function registered for a council module.

Build the Consensus topology as a generated council module.

Build the same Consensus topology as new/1 but as a data-only %CouncilEx.DynamicCouncil{}.

Functions

__get_until__(council_module)

Look up the until/2 function registered for a council module.

new(opts)

@spec new(keyword()) :: module()

Build the Consensus topology as a generated council module.

Options

  • :as — module name for the generated council (default: anonymous unique).
  • :members (required) — [{id, module, opts}] member tuples.
  • :chair (required) — {module, opts} chair tuple.
  • :until — 2-arity (prev_round_result | nil, current_round_result -> boolean) convergence callback. Defaults to "always false" (run until :max_iterations).

  • :max_iterations — positive integer, default 3.

See the moduledoc for a complete example. Use new_dynamic/1 for the data-only %CouncilEx.DynamicCouncil{} form.

new_dynamic(opts)

@spec new_dynamic(keyword()) :: CouncilEx.DynamicCouncil.t()

Build the same Consensus topology as new/1 but as a data-only %CouncilEx.DynamicCouncil{}.

Members and chair accept the same shapes as Specialist.new_dynamic/1.

The optional :until MUST be a remote function capture (&MyMod.converged?/2); inline fn literals will work at runtime but break JSON round-trips.