CouncilEx.DynamicMember (CouncilEx v0.1.0)

Copy Markdown View Source

Data-only representation of a council member for runtime / DB-driven councils. Module-form members (the static DSL) keep their module() shape; dynamic councils use this struct everywhere a module would appear.

Fields

  • :id — string identifier (UUID or human label). Required.
  • :role — short string describing the member's persona.
  • :system_prompt — string injected as the system message. Required for regular members. May be "" (or nil) for sub-council members whose work is delegated entirely to the inner council.
  • :profile — registered profile name (string) OR nil to inherit the council :default_profile.
  • :profile_overrides — keyword/map of opts that override the resolved profile (e.g., %{temperature: 0.8}).
  • :tools — list of tool refs. Each ref is either a registered tool name (string) or a module (atom — for tools registered without a string name).
  • :output_schema — registered schema name (string).
  • :output_schema_inline — JSON Schema map. Mutually exclusive with :output_schema.
  • :sub_council — turns this member into a sub-council. Accepts:
    • registered sub-council name (string, looked up via CouncilEx.Registry.lookup(:sub_council, name)),
    • a static council module (atom),
    • a nested %CouncilEx.DynamicCouncil{} struct (or its JSON map). When set, profile / tools / output_schema are ignored — the member's output is the wrapped sub-run result.
  • :input_mapper — for sub-council members, projects the parent input before handing it to the inner council. Accepts a registered name (string, CouncilEx.Registry.lookup(:input_mapper, name)) or a remote function capture (e.g. &MyApp.Mappers.to_seo/1). Anonymous closures are not supported (they are not data-serializable). Defaults to identity.
  • :metadata — arbitrary map (UI position, comments, etc).

Summary

Functions

Build a %DynamicMember{} from a plain map OR keyword list. Strings, atom keys, or keyword pairs all accepted (JSON decoders produce string keys; hand-written code often uses keyword lists for ergonomics).

Convert a %DynamicMember{} to a plain map (string keys, JSON-friendly).

Types

input_mapper_ref()

@type input_mapper_ref() :: String.t() | (term() -> term())

sub_council_ref()

@type sub_council_ref() :: String.t() | module() | CouncilEx.DynamicCouncil.t()

t()

@type t() :: %CouncilEx.DynamicMember{
  id: String.t(),
  input_mapper: input_mapper_ref() | nil,
  metadata: map(),
  output_schema: String.t() | nil,
  output_schema_inline: map() | nil,
  profile: String.t() | nil,
  profile_overrides: map(),
  role: String.t() | nil,
  sub_council: sub_council_ref() | nil,
  system_prompt: String.t() | nil,
  tools: [tool_ref()]
}

tool_ref()

@type tool_ref() :: String.t() | module()

Functions

new(attrs)

@spec new(map() | keyword()) :: t()

Build a %DynamicMember{} from a plain map OR keyword list. Strings, atom keys, or keyword pairs all accepted (JSON decoders produce string keys; hand-written code often uses keyword lists for ergonomics).

to_map(m)

@spec to_map(t()) :: map()

Convert a %DynamicMember{} to a plain map (string keys, JSON-friendly).