# `Arcana.Maintenance`
[🔗](https://github.com/georgeguimaraes/arcana/blob/main/lib/arcana/maintenance.ex#L1)

Maintenance functions for Arcana.

These functions are designed to be callable from production environments
where mix tasks are not available (e.g., releases).

## Usage in Production

    # Remote IEx
    iex> Arcana.Maintenance.reembed(MyApp.Repo)

    # Release command
    bin/my_app eval "Arcana.Maintenance.reembed(MyApp.Repo)"

# `configured_detector`

The community detector this install would use.

Returns `{module, opts}`, a 3-arity function, or `nil`. Public so callers
can check the dependency the configured detector actually needs, rather
than assuming the built-in one.

# `detect_communities`

Detects communities in the knowledge graph using the Leiden algorithm.

This runs community detection on entities and relationships, producing
hierarchical community clusters. Existing communities for the collection(s)
are cleared before detection.

## Options

  * `:collection` - `:all`, one collection name, or a list of collection
    names (default: `:all`). An empty list does no work.
  * `:resolution` - Community detection resolution (default: 1.0)
  * `:objective` - Quality function (default: `:cpm`)
  * `:iterations` - Optimization iterations (default: 2)
  * `:seed` - Random seed; `0` lets the algorithm randomize (default: 0)
  * `:min_size` - Minimum community size to keep (default: 1)
  * `:max_level` - Maximum hierarchy levels (default: 1, from `:community_levels`)
  * `:progress` - Function to call with progress updates `fn current, total -> :ok end`

## Configuration

Every detection knob can also be set globally, and the detector itself
is pluggable:

    config :arcana, :graph,
      community_detector: :leiden,
      resolution: 1.0,
      objective: :cpm,
      iterations: 2,
      seed: 42,
      min_size: 1,
      community_levels: 3

Knobs resolve in this order, later wins: library defaults, then
`config :arcana, :graph`, then options carried by the configured
`community_detector` tuple, then the per-call options above.

## Examples

    # Basic usage - all collections
    Arcana.Maintenance.detect_communities(MyApp.Repo)

    # Single collection
    Arcana.Maintenance.detect_communities(MyApp.Repo, collection: "my-docs")

    # With custom resolution
    Arcana.Maintenance.detect_communities(MyApp.Repo, resolution: 0.5)

    # Reproducible membership
    Arcana.Maintenance.detect_communities(MyApp.Repo, seed: 42)

# `embed_entities`

Embeds entity descriptions for entities that lack embeddings.

Uses the configured embedder to generate vector embeddings from entity
descriptions, enabling GraphRAG-style entity similarity search.

## Options

  * `:collection` - `:all`, one collection name, or a list of collection
    names (default: `:all`). An empty list does no work.
  * `:batch_size` - Entities per batch (default: 100)
  * `:progress` - Progress callback `fn current, total -> :ok end`
  * `:force` - Re-embed all entities, not just those without embeddings (default: false)

# `embedding_dimensions`

Returns the current embedding dimensions.

Useful for verifying the configured embedder before running migrations.

## Examples

    iex> Arcana.Maintenance.embedding_dimensions()
    {:ok, 1536}

# `embedding_info`

Returns info about the current embedding configuration.

## Examples

    iex> Arcana.Maintenance.embedding_info()
    %{type: :openai, model: "text-embedding-3-small", dimensions: 1536}

# `graph_info`

Returns info about the current graph configuration.

## Examples

    iex> Arcana.Maintenance.graph_info()
    %{enabled: true, extractor: :llm}

# `rebuild_graph`

Rebuilds the knowledge graph for documents.

See module docs for full options.

# `reembed`

Re-embeds all chunks and rechunks documents that have no chunks.

This is useful when switching embedding models or after a migration
that cleared chunks.

## Options

  * `:collection` - `:all`, one collection name, or a list of collection
    names (default: `:all`). An empty list does no work.
  * `:batch_size` - Number of items to process at once (default: 50)
  * `:concurrency` - Number of parallel embedding requests (default: 5)
  * `:skip` - Number of chunks to skip (for resuming interrupted runs)
  * `:progress` - Function to call with progress updates `fn current, total -> :ok end`

## Examples

    # Basic usage
    Arcana.Maintenance.reembed(MyApp.Repo)

    # With progress callback and concurrency
    Arcana.Maintenance.reembed(MyApp.Repo,
      batch_size: 100,
      concurrency: 10,
      progress: fn current, total ->
        IO.puts("Progress: #{current}/#{total}")
      end
    )

    # Resume from chunk 500
    Arcana.Maintenance.reembed(MyApp.Repo, skip: 500)

# `summarize_communities`

Generates summaries for communities that need them.

This function iterates through communities and generates LLM summaries
for those that are dirty, have no summary, or have accumulated changes.

## Options

  - `:collection` - `:all`, one collection name, or a list of collection
    names (default: `:all`). An empty list does no work.
  - `:progress` - Progress callback function
  - `:force` - Regenerate all summaries even if not dirty (default: false)
  - `:concurrency` - Number of parallel summarization tasks (default: 1)
  - `:llm` - LLM function for summarization (uses config if not provided)
  - `:levels` - Hierarchy levels to summarize: an integer, a list, a range
    or `:all`. Defaults to `config :arcana, :graph, community_summary_level`,
    the levels `Arcana.ask/2` actually reads, so detection can generate a
    deeper hierarchy without paying an LLM call per unread level.

## Returns

`{:ok, %{communities: count, summaries: count}}` on success.

## Examples

    # Summarize all dirty communities
    Maintenance.summarize_communities(repo)

    # Force regenerate all summaries
    Maintenance.summarize_communities(repo, force: true)

    # Summarize a specific collection
    Maintenance.summarize_communities(repo, collection: "my-docs")

    # Summarize every hierarchy level, not just the readable ones
    Maintenance.summarize_communities(repo, levels: :all)

---

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