CouncilEx.Events (CouncilEx v0.1.0)

Copy Markdown View Source

Public catalog of PubSub events emitted on the run-scoped topic "council_ex:run:#{run_id}". Stable extension surface as of v0.7.

Subscribing

:ok = CouncilEx.PubSub.subscribe("council_ex:run:#{run_id}")

receive do
  {:run_started, ^run_id, council_module, input} -> ...
  {:round_started, ^run_id, round_name, idx} -> ...
  {:member_started, ^run_id, round_name, member_id} -> ...
  {:member_token, ^run_id, round_name, member_id, %CouncilEx.StreamChunk{}} -> ...
  {:tool_call_request, ^run_id, round_name, member_id, %CouncilEx.ToolCall{}} -> ...
  {:tool_call_result, ^run_id, round_name, member_id, %CouncilEx.ToolCallResult{}} -> ...
  {:member_completed, ^run_id, round_name, member_id, %CouncilEx.MemberResult{}} -> ...
  {:round_completed, ^run_id, round_name, %CouncilEx.RoundResult{}} -> ...
  {:run_completed, ^run_id, %CouncilEx.Result{}} -> ...
  {:run_failed, ^run_id, [%CouncilEx.Error{}, ...], %CouncilEx.Result{}} -> ...
end

Order

:run_started
 :round_started (round 1)
    :member_started × N
    :member_token × M       (during streaming members)
    :tool_call_request × K  (during tool-calling members)
    :tool_call_result × K
    :member_completed × N
    :round_completed
 :round_started (round 2)
    ...
 :run_completed

Ordering is guaranteed within a single run because broadcasts originate from a single RunServer process serially. Across rounds: strictly ordered. Within a round: members may interleave (per-member event groups can overlap with other members'), but each member's own events are ordered.

Stability

This surface is frozen as of v0.7. Future versions may add new events but will not remove or rename existing events without a major version bump. The :member_completed payload was changed in v0.7 (see CHANGELOG).

Payloads

  • :run_started — emitted once per run, before any round begins.

    • council_module — atom, the council module being run.
    • input — map, the input passed to CouncilEx.run/2 or start/2.
  • :round_started — emitted at the start of each round.

    • round_name — atom, the round's symbolic name (e.g., :independent_analysis).
    • idx — non-negative integer, the round's 0-based index in the council's round list.
  • :member_started — emitted before each member begins executing in a round. Per-member, fires once per (round × member_id) pair.

  • :member_token — emitted for each streaming chunk from a member with stream true. May fire many times per member.

    • 5th element: %CouncilEx.StreamChunk{content, index, finish_reason}.
  • :tool_call_request — emitted just before each tool execution during a tool-calling member's turn. Synthetic Anthropic _respond tool excluded.

    • 5th element: %CouncilEx.ToolCall{id, name, args_raw, args_parsed}.
  • :tool_call_result — emitted after each tool execution completes (success or error). _respond excluded.

    • 5th element: %CouncilEx.ToolCallResult{id, name, result, error}.
  • :member_completed — emitted after each member's turn finishes. Always carries %MemberResult{} (status :ok | :error | :timeout | :skipped | :invalid_output | :eliminated). Replaces the v0.6 split between :member_completed (ok-only) and :member_failed (error-only).

    • 5th element: %CouncilEx.MemberResult{member_id, status, response, error, duration_ms, attempts, metadata}.
  • :round_completed — emitted after a round finishes (all members done).

    • 4th element: %CouncilEx.RoundResult{name, member_results, metadata, ...}.
  • :run_completed — emitted once per run, after the final round, on the success path. Mutually exclusive with :run_failed.

    • 3rd element: %CouncilEx.Result{} carrying the final synthesized output and per-round results.
  • :run_failed — emitted once per run on any non-success terminal path: round task crash, member-level errors with failure_mode: :halt, or cancellation via CouncilEx.cancel/2. Mutually exclusive with :run_completed.

    • 3rd element: list of %CouncilEx.Error{}. Cancellation surfaces as %CouncilEx.Error{kind: :cancelled, reason: :cancelled_by_user} so subscribers can distinguish cancel from crash.
    • 4th element: %CouncilEx.Result{status: :error} with whatever partial round results were collected before termination.

Topic

Single per-run topic: "council_ex:run:#{run_id}". Run IDs are generated by RunState.new/1 and returned from CouncilEx.start/2. Subscribe before calling start/2 to avoid missing :run_started.