Topology #6 — specialist members → peer_review → chair.
Each member independently analyses the input, then all members cross-review each other's outputs in a peer-review pass. The chair synthesizes.
Usage (module-form)
council =
CouncilEx.Councils.Specialist.new(
as: MyApp.SpecialistCouncil,
members: [
{:legal, MyApp.Members.Legal, [provider: :openai, model: "gpt-4o-mini"]},
{:tech, MyApp.Members.Tech, [provider: :openai, model: "gpt-4o-mini"]},
{:biz, MyApp.Members.Biz, [provider: :openai, model: "gpt-4o-mini"]}
],
chair: {MyApp.Members.Synth, [provider: :openai, model: "gpt-4o"]}
)Usage (dynamic / data-only form)
Returns a %CouncilEx.DynamicCouncil{} with the same topology — useful
for runtime-built / DB-driven councils. Members and chair are described
as plain maps (or %DynamicMember{} structs):
council =
CouncilEx.Councils.Specialist.new_dynamic(
id: "specialist-1",
default_profile: "openai_mini",
members: [
%{id: "legal", role: "Legal", system_prompt: "..."},
%{id: "tech", role: "Tech", system_prompt: "..."},
%{id: "biz", role: "Biz", system_prompt: "..."}
],
chair: %{id: "synth", role: "Synthesizer",
system_prompt: "...", profile: "openai_balanced"}
)
Summary
Functions
Build the Specialist 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.
See the moduledoc for a complete example. Use new_dynamic/1 for the
data-only %CouncilEx.DynamicCouncil{} form.
@spec new_dynamic(keyword()) :: CouncilEx.DynamicCouncil.t()
Build the same Specialist topology as new/1 but as a data-only
%CouncilEx.DynamicCouncil{}.
Each member entry is a %DynamicMember{}, a map, or a keyword list.
The chair is the same shape (single member, not a tuple).