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.py — AgentLoader
- 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.md → lessing.md (frontmatter currently starts with ___ instead of ---, which breaks parsing)
02-author-Schiller.md → schiller.md
03-audit-Humboldt.md → humboldt.md
04-review-Nietzsche.md → nietzsche.md
Tests
tests/test_all.py — TestAgentLoader:
- 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.
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 currentAgentLoaderonly scans the top level and resolves names via the filename stem, so:FileNotFoundErrorat runtime.docs/agent-definitions.md: "name: Agent identifier used in workflow slots") already says the frontmatternameis the identifier, but the implementation actually uses the filename. This change aligns code with the documented semantics.Decisions
<name>.md, frontmatternameequals 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.nameonly. The filename is irrelevant for resolution.rglob) belowagents_dir..mdfiles (e.g.README.md) are skipped with a warning.--validatecommand).Behavior / API changes
core/agent.py—AgentLoader.mdfiles underagents_dir(recursive) on every call (no caching — preserves the current behavior of re-reading files, so mid-run edits are still picked up).namefield are skipped and reported via a newloader.warnings: list[str].name.ValueErrorwith all paths, e.g.:Duplicate agent name 'humboldt': agents/DocsAgents/humboldt.md, agents/other/humboldt.mdlist_agents()→ sorted canonical names (recursive).get_agent(name)→ resolves via the index; raisesFileNotFoundErrorwith a helpful message if unknown.load_all()→ all valid agents.AgentDefinitiongains asource_path: Optional[Path] = Nonefield, populated by_load_file, so callers (GUI preview) never build paths themselves.core/engine.pyexecute_workflow_data(): resolve every agent referenced inpreparation_agents+loop_agents+finalization_agentsviaget_agent(). Missing agents → clear error listing the missing names; duplicates surface via the index-build error.loader.warnings(skipped non-agent files) once at start._execute_agent()(line 1134) and_build_correction_prompt()(line 1333) continue to useget_agent(); they now benefit from recursion automatically.ui/app.py_refresh_agent_list()(717): unchanged call, now recursive. Catch duplicateValueError→ show messagebox._show_preview()(744): resolve the file vialoader.get_agent(name).source_pathinstead ofPath(agents_dir) / f"{name}.md". This also fixes the three zone listboxes (prep/loop/final) which share the function.ImportErroris caught).Housekeeping
agents/DocsAgents/files to simple names and fix a frontmatter bug:01-prep-Lessing.md→lessing.md(frontmatter currently starts with___instead of---, which breaks parsing)02-author-Schiller.md→schiller.md03-audit-Humboldt.md→humboldt.md04-review-Nietzsche.md→nietzsche.mdTests
tests/test_all.py—TestAgentLoader:get_agentresolves by frontmatternameeven when the filename stem differsnameacross files → raises with both paths.md(no valid frontmatter/name) → skipped, reported inwarningssource_pathis populatedtests/test_integration.py(tier3): existingtest_amala_agent_parses/test_vera_agent_parsesshould 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-nameidentity, recursive resolution, uniqueness requirement, non-agent.mdhandling.docs/gui.md: Agent Pool description → "all agents found recursively inagents_dir".docs/configuration.md:agents_dirdescription → recursive scan.docs/workflows.md: note that agent names must be unique across all subdirectories.AGENTS.md: replace "Agent filenames inagents/match the name used in workflows (stem of.md)" with the new contract.Out of scope
--validateCLI command or GUI validation button (validation is automatic at run start).