Codumentor logo Codumentor

Configuration Assistant Plugin

The configuration_assistant plugin gives administrators a chat that edits this Codumentor instance's own configuration in plain language — "add this repo", "switch the main model to the fast slot", "enable the redmine plugin and tell me what secret it needs", "why are webhooks failing?" — instead of hand-editing YAML against the configuration reference.

It runs against the running instance itself (target = self) using curated, in-process tools that read and write the real config file directly. The full design rationale is in doc/core-dev/design/configuration-assistant.md.

How it works

The plugin does not add a new agent surface. Instead, an admin-only launcher on the Admin page creates a normal conversation stamped with metadata.agent_profile = "config_assistant" and opens it in the standard chat UI (so streaming, approvals, and the rest are reused). A run-last onPromptAssemble hook then, only for those conversations:

  1. swaps in a focused system prompt, and
  2. replaces the visible tool list with a curated allowlist of seven config tools (the inverse of the goal-worker denylist) — a narrow blast radius.

Ordinary conversations are untouched.

Tools

ToolApprovalPurpose
config_schemanone (read)Introspect the live pydantic Config (keys, types, defaults) joined with each section's hot-reload class (🟢 live / 🟡 rebuild / 🔴 restart). Generated from the code, so it cannot go stale.
config_readnone (read)The current resolved config (env-substituted; secret values redacted).
config_docsnone (read)The prose docs (doc/admin/configuration.md) on demand — list topics, then fetch a section.
read_logsnone (read)Tail / grep the configured log file (logging.file) to diagnose problems.
config_proposenone (read)Build a candidate change, dry-run validate it, and return the exact YAML diff + each changed section's reload class. Writes nothing.
config_applywrite_system_configRe-validate, back up, write the leaf config atomically, then hot-reload.
config_rollbackwrite_system_configRestore the most recent timestamped backup and reload.

Write tools declare a PermissionRequest, so they flow through the runtime's PermissionProvider exactly like any other side-effectful tool — the admin approves the diff before anything is written. Every tool also refuses to run outside a config-assistant conversation (defense-in-depth).

The safety flow

config_apply never reimplements reload. One turn looks like:

  1. Groundconfig_read + config_schema + config_docs.
  2. Proposeconfig_propose runs the real loader pipeline (without sys.exit) to validate, then returns a unified YAML diff and the reload class. An invalid change is reported with the precise error and never offered for apply.
  3. Approveconfig_apply is gated; the admin approves the diff.
  4. Apply — backup → atomic write → ConfigReloadManager.reload(). The resulting ReloadReport (applied / rebuilt / restart_required / errors) is surfaced verbatim.
  5. Rollbackconfig_rollback restores the last backup and reloads.

Configuration

plugins:
  - module: codumentor.plugins.configuration_assistant
    class: ConfigurationAssistantPlugin
    args:
      enabled: true

No other settings. The plugin edits the leaf instance config (the last file in CODUMENTOR_CONFIG_FILES).

Access control

Access is gated at the conversation-creation route (POST /ui/plugins/configuration_assistant/conversations) by require_permission("admin:*") — only an admin can create a config-assistant conversation. Because the activation hook keys off that metadata, activation implies admin; the curated tools are never registered on an ordinary user's conversation.

Reload classes

What a change costs is taken from config/reload/semantics.py and shown up front:

Notes & limitations