Automatic Categories (Category Discovery)

How the plugin creates new categories automatically from your data: the category discovery step groups “other” facts by free-form topic labels; any label that appears often enough becomes a real category.


Overview

Besides custom categories in config, the plugin can discover new categories from facts in "other":

  1. Discovery — Before reclassifying “other” into existing categories, an LLM assigns each “other” fact a short topic label (1–2 words). No fixed category list is given; the LLM invents labels from the text (e.g. “food”, “travel”, “technical”).
  2. Threshold — Any label with at least minFactsForNewCategory facts (default 10) becomes a new category. The threshold is not shown to the LLM.
  3. Reclassify — Those facts are updated from "other" to the new category.
  4. Persist — New category names are written to .discovered-categories.json (next to your SQLite DB) and merged with config categories on load.

When it runs

Discovery runs only as part of the auto-classify job (same schedule: ~5 min after startup, then every 24 h if autoClassify.enabled is true). It runs only if:

  • autoClassify.suggestCategories is true (default), and
  • There are at least 15 “other” facts (internal minimum).

Discovery runs before the normal “reclassify other into existing categories” step.


How it works (steps)

  1. Load all facts with category "other".
  2. Send them to the LLM in batches of 25. Prompt: assign a short label per fact; output a JSON array of strings.
  3. Normalize labels (trim, lowercase, length ≤ 40); discard empty or "other".
  4. Group facts by label. For each label with count ≥ minFactsForNewCategory that is not already a category:
    • Add it as a new category.
    • Update those facts from "other" to the new category.
  5. Read .discovered-categories.json, merge in new names, write back.

Built-in and config categories are unchanged; discovered ones are added and used everywhere (memory_store, classify, CLI).


Config

Option Default Description
autoClassify.suggestCategories true Run category discovery before reclassifying “other”. Set false to only use existing categories.
autoClassify.minFactsForNewCategory 10 Min facts per label to create a new category. Not sent to the LLM.

Discovery uses autoClassify.model (e.g. gpt-4o-mini).


File

  • Path~/.openclaw/memory/.discovered-categories.json (or next to sqlitePath). JSON array of strings, e.g. ["research", "travel"].
  • Backup — Include this file in backups if you care about preserving discovered category names (see BACKUP.md).

Reviewing discovered categories (issue #2100)

Discovered categories are already added and in use as soon as the threshold is reached (step 4 above) — there’s no gate before that. categories discovered gives operators a way to review the queue after the fact:

openclaw hybrid-mem categories discovered              # list pending + previously-rejected labels
openclaw hybrid-mem categories discovered approve food  # acknowledge — prints manual promotion steps
openclaw hybrid-mem categories discovered reject food   # remove from the queue; never re-proposed
  • list (the default with no subcommand) prints every pending label plus any labels previously rejected, with the exact approve/reject commands to run next.
  • approve <label> removes the label from the pending queue and prints the manual steps to make it a first-class config category (add it to categories in your plugin config, then openclaw hybrid-mem categories remap --from other --to <label> --apply for any facts that should move). Approving does not auto-apply anything — discovery already reclassified the qualifying facts; this command is a review/acknowledgement step, not a promotion trigger.
  • reject <label> removes the label from the pending queue and records it in a sibling .discovered-categories-rejected.json file so a future discovery run never re-proposes the same label.
  • Add --json to any of the above for machine-readable output.

The bootstrap warning (“N proposed categories pending operator review”) points at this command instead of the raw JSON file.



Back to top

OpenClaw Hybrid Memory — durable agent memory

This site uses Just the Docs, a documentation theme for Jekyll.