Skip to content

Recursive agent discovery + frontmatter-name identity + duplicate detection #52

Description

@maddes8cht

Context

Agents were previously required to live directly in agents_dir (default ./agents), one file per agent, named <name>.md. Users want to organize agents into subdirectories by theme (e.g. agents/TestAgents/, agents/DocsAgents/). The current AgentLoader only scans the top level and resolves names via the filename stem, so:

  • Agents in subdirectories are invisible in the GUI Agent Pool and cause FileNotFoundError at runtime.
  • The documented contract (docs/agent-definitions.md: "name: Agent identifier used in workflow slots") already says the frontmatter name is the identifier, but the implementation actually uses the filename. This change aligns code with the documented semantics.

Decisions

  • Naming convention: simple names, no numeric prefixes. File = <name>.md, frontmatter name equals the stem. Execution order lives only in the workflow arrays (preparation_agents/loop_agents/finalization_agents), which are already ordered and reorderable in the GUI.
  • Canonical identity: the frontmatter name only. The filename is irrelevant for resolution.
  • Search: unlimited recursion (rglob) below agents_dir.
  • Non-agent .md files (e.g. README.md) are skipped with a warning.
  • Duplicate names: hard error (fail-fast) listing all conflicting file paths.
  • Validation: automatic, at run start only (no separate --validate command).

Behavior / API changes

core/agent.pyAgentLoader

  • Build an index of all .md files under agents_dir (recursive) on every call (no caching — preserves the current behavior of re-reading files, so mid-run edits are still picked up).
  • For each file, parse frontmatter. Files with missing/malformed frontmatter or no name field are skipped and reported via a new loader.warnings: list[str].
  • Canonical name = stripped frontmatter name.
  • Two (or more) files resolving to the same name → raise ValueError with all paths, e.g.:
    Duplicate agent name 'humboldt': agents/DocsAgents/humboldt.md, agents/other/humboldt.md
  • list_agents() → sorted canonical names (recursive).
  • get_agent(name) → resolves via the index; raises FileNotFoundError with a helpful message if unknown.
  • load_all() → all valid agents.
  • AgentDefinition gains a source_path: Optional[Path] = None field, populated by _load_file, so callers (GUI preview) never build paths themselves.

core/engine.py

  • New pre-flight check at the start of execute_workflow_data(): resolve every agent referenced in preparation_agents + loop_agents + finalization_agents via get_agent(). Missing agents → clear error listing the missing names; duplicates surface via the index-build error.
  • Log loader.warnings (skipped non-agent files) once at start.
  • _execute_agent() (line 1134) and _build_correction_prompt() (line 1333) continue to use get_agent(); they now benefit from recursion automatically.

ui/app.py

  • _refresh_agent_list() (717): unchanged call, now recursive. Catch duplicate ValueError → show messagebox.
  • _show_preview() (744): resolve the file via loader.get_agent(name).source_path instead of Path(agents_dir) / f"{name}.md". This also fixes the three zone listboxes (prep/loop/final) which share the function.
  • Surface pre-flight validation errors as messageboxes when starting a run (currently only ImportError is caught).

Housekeeping

  • Rename agents/DocsAgents/ files to simple names and fix a frontmatter bug:
    • 01-prep-Lessing.mdlessing.md (frontmatter currently starts with ___ instead of ---, which breaks parsing)
    • 02-author-Schiller.mdschiller.md
    • 03-audit-Humboldt.mdhumboldt.md
    • 04-review-Nietzsche.mdnietzsche.md

Tests

  • tests/test_all.pyTestAgentLoader:
    • recursive listing finds agents in nested subdirectories
    • get_agent resolves by frontmatter name even when the filename stem differs
    • duplicate name across files → raises with both paths
    • non-agent .md (no valid frontmatter/name) → skipped, reported in warnings
    • source_path is populated
    • existing flat-dir tests stay valid
  • tests/test_integration.py (tier3): existing test_amala_agent_parses / test_vera_agent_parses should pass again once the loader recurses; add a tier3 test resolving a DocsAgents agent (e.g. humboldt).

Docs

  • docs/agent-definitions.md: document subdirectory organization, frontmatter-name identity, recursive resolution, uniqueness requirement, non-agent .md handling.
  • docs/gui.md: Agent Pool description → "all agents found recursively in agents_dir".
  • docs/configuration.md: agents_dir description → recursive scan.
  • docs/workflows.md: note that agent names must be unique across all subdirectories.
  • AGENTS.md: replace "Agent filenames in agents/ match the name used in workflows (stem of .md)" with the new contract.

Out of scope

  • No separate --validate CLI command or GUI validation button (validation is automatic at run start).
  • No agent-grouping feature beyond directories.
  • No aliases/fallback to filename stems.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions