# `Arcana.Graph.CommunitySummarizer`
[🔗](https://github.com/georgeguimaraes/arcana/blob/main/lib/arcana/graph/community_summarizer.ex#L1)

Behaviour for community summarization in GraphRAG.

Community summarizers generate natural language descriptions of
entity communities. These summaries provide high-level context
for global queries that need broad understanding rather than
specific document chunks.

## Built-in Implementations

- `Arcana.Graph.CommunitySummarizer.LLM` - LLM-based summarization (default)

## Configuration

Configure your community summarizer in `config.exs`:

    # Default: LLM-based summarization
    config :arcana, :graph,
      community_summarizer: {Arcana.Graph.CommunitySummarizer.LLM, llm: &MyApp.llm/3}

    # Disable summarization (communities won't have summaries)
    config :arcana, :graph,
      community_summarizer: nil

    # Custom module implementing this behaviour
    config :arcana, :graph,
      community_summarizer: {MyApp.ExtractiveSum, max_sentences: 3}

    # Inline function
    config :arcana, :graph,
      community_summarizer: fn entities, relationships, _opts ->
        {:ok, "Community with #{length(entities)} entities"}
      end

## Implementing a Custom Summarizer

Create a module that implements this behaviour:

    defmodule MyApp.ExtractiveSum do
      @behaviour Arcana.Graph.CommunitySummarizer

      @impl true
      def summarize(entities, relationships, opts) do
        max_sentences = Keyword.get(opts, :max_sentences, 3)
        # Extract key sentences from entity descriptions...
        {:ok, summary}
      end
    end

## Summary Format

Summarizers should return a concise string (2-5 sentences) that:
- Identifies the community's central theme or domain
- Names the most important entities
- Describes key relationships between entities

# `summarize`

```elixir
@callback summarize(
  entities :: [map()],
  relationships :: [map()],
  opts :: keyword()
) :: {:ok, String.t()} | {:error, term()}
```

Generates a summary for a community.

## Parameters

- `entities` - List of entity maps with `:name`, `:type`, and optional `:description`
- `relationships` - List of relationship maps connecting entities
- `opts` - Options passed from the summarizer configuration

## Returns

- `{:ok, summary}` - The generated summary string
- `{:error, reason}` - On failure

# `needs_regeneration?`

Checks if a community needs its summary regenerated.

## Regeneration Triggers

  - `dirty: true` - Community was modified since last summary
  - `change_count >= threshold` - Many changes accumulated
  - `summary: nil` - No summary exists yet

## Options

  - `:threshold` - Number of changes before regeneration (default: 10)

# `reset_change_tracking`

Returns a map of fields to reset after regenerating a summary.

Use with `Ecto.Changeset.change/2` to mark a community as clean:

    community
    |> Community.changeset(CommunitySummarizer.reset_change_tracking())
    |> Repo.update()

# `summarize`

Generates a summary using the configured summarizer.

The summarizer can be:
- A `{module, opts}` tuple where module implements this behaviour
- A function `(entities, relationships, opts) -> {:ok, summary} | {:error, reason}`
- `nil` to skip summarization (returns empty string)

Falls back to LLM summarizer if not configured but `:llm` option is provided.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
