Repo restructure: Nemo agent definition + modular tool registry #18

Open
opened 2026-03-29 20:12:02 +00:00 by forgejo_admin · 2 comments

Type

Feature

Lineage

Standalone — restructure for maintainability and tool extensibility. Follows claude-custom agent/skills pattern.

Repo

forgejo_admin/westside-ai-assistant

User Story

As Lucas (platform operator)
I want Nemo's tools organized as modular, auto-discovered definitions
So that adding or removing capabilities is a file operation, not a code change

Context

The assistant is named Nemo. Currently all 14 tool definitions are inline in ai.py as a giant list. Restructure to mirror the claude-custom pattern: agent personality in agents/nemo.md, tools in tools/{category}/TOOL.md + handler.py, system prompt in prompts/system.md. A tool registry auto-discovers tools at startup and generates Anthropic tool definitions. This makes adding/removing tools mechanical — add a directory, restart. Write tools (7 total) stay in the codebase as tool directories but are NOT registered by default — a tools/{category}/TOOL.md frontmatter field enabled: false controls this. The registry only loads enabled tools.

File Targets

Files the agent should create:

  • agents/nemo.md — personality definition (name, role, voice, constraints, read-only V1 policy)
  • tools/__init__.py — empty
  • tools/players/TOOL.md — tool definitions for get_player, list_players (frontmatter: name, description, parameters, enabled: true)
  • tools/players/handler.py — functions that call basketball.py
  • tools/teams/TOOL.md — list_teams, get_roster (enabled: true)
  • tools/teams/handler.py
  • tools/billing/TOOL.md — get_subscriptions_overview, list_subscriptions (enabled: true)
  • tools/billing/handler.py
  • tools/dashboard/TOOL.md — get_dashboard (enabled: true)
  • tools/dashboard/handler.py
  • tools/player_writes/TOOL.md — update_player, toggle_player_visibility (enabled: false — dormant for V1)
  • tools/player_writes/handler.py
  • tools/team_writes/TOOL.md — assign_player_to_team, remove_player_from_team, create_team (enabled: false)
  • tools/team_writes/handler.py
  • tools/tryouts/TOOL.md — checkin_player, bulk_assign_tryout_numbers (enabled: false)
  • tools/tryouts/handler.py
  • app/tool_registry.py — auto-discover tools/ dirs, parse TOOL.md frontmatter, only load enabled tools, import handler.py functions, generate Anthropic tool definitions list
  • prompts/system.md — system prompt template that references nemo.md personality

Files the agent should modify:

  • app/ai.py — replace inline TOOLS list with tool_registry.get_tools(), replace inline dispatch with registry-based dispatch
  • tests/test_ai.py — update imports from inline TOOLS/dispatch to tool_registry. Update any direct references to _TOOL_META, _execute_read_tool, etc.

Files the agent should NOT touch:

  • app/basketball.py — stays as-is (the HTTP client tools call into)
  • app/groupme.py — stays as-is
  • app/confirmation.py — stays dormant (future write support)

Acceptance Criteria

  • agents/nemo.md defines personality, role, voice, constraints (read-only V1)
  • 7 tool categories created (4 read enabled, 3 write disabled) with TOOL.md + handler.py each
  • tool_registry.py auto-discovers tools, respects enabled flag, generates Anthropic-format tool definitions
  • Only enabled tools are returned by get_tools() (7 read tools in V1)
  • ai.py uses registry instead of inline definitions — same behavior, modular structure
  • Adding a new tool = create tools/new_category/TOOL.md + handler.py — no ai.py changes
  • All existing tests pass (updated imports)
  • System prompt built from prompts/system.md + nemo.md personality

Test Expectations

  • Unit test: tool_registry discovers all 7 categories
  • Unit test: tool_registry only returns enabled tools (4 categories, 7 tools)
  • Unit test: disabled tools are NOT in the active set
  • Unit test: handler functions call basketball.py correctly
  • Existing ai.py tests pass with registry-based dispatch (updated imports)
  • Run command: pytest tests/ -v

Constraints

  • TOOL.md uses YAML frontmatter for tool metadata (name, description, parameters schema, enabled flag)
  • handler.py exports an async function matching the tool name
  • Registry returns both the Anthropic tool definition AND a dispatch map (tool_name -> handler function)
  • Follow claude-custom SKILL.md pattern for TOOL.md format
  • Write tool handlers stay in codebase — just disabled via enabled: false

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • project-westside-ai-assistant — parent project
  • story-westside-ai-assistant-read-ops — read operations story
  • arch-domain-westside-ai-assistant — architecture reference
### Type Feature ### Lineage Standalone — restructure for maintainability and tool extensibility. Follows claude-custom agent/skills pattern. ### Repo `forgejo_admin/westside-ai-assistant` ### User Story As Lucas (platform operator) I want Nemo's tools organized as modular, auto-discovered definitions So that adding or removing capabilities is a file operation, not a code change ### Context The assistant is named Nemo. Currently all 14 tool definitions are inline in ai.py as a giant list. Restructure to mirror the claude-custom pattern: agent personality in `agents/nemo.md`, tools in `tools/{category}/TOOL.md` + `handler.py`, system prompt in `prompts/system.md`. A tool registry auto-discovers tools at startup and generates Anthropic tool definitions. This makes adding/removing tools mechanical — add a directory, restart. Write tools (7 total) stay in the codebase as tool directories but are NOT registered by default — a `tools/{category}/TOOL.md` frontmatter field `enabled: false` controls this. The registry only loads enabled tools. ### File Targets Files the agent should create: - `agents/nemo.md` — personality definition (name, role, voice, constraints, read-only V1 policy) - `tools/__init__.py` — empty - `tools/players/TOOL.md` — tool definitions for get_player, list_players (frontmatter: name, description, parameters, enabled: true) - `tools/players/handler.py` — functions that call basketball.py - `tools/teams/TOOL.md` — list_teams, get_roster (enabled: true) - `tools/teams/handler.py` - `tools/billing/TOOL.md` — get_subscriptions_overview, list_subscriptions (enabled: true) - `tools/billing/handler.py` - `tools/dashboard/TOOL.md` — get_dashboard (enabled: true) - `tools/dashboard/handler.py` - `tools/player_writes/TOOL.md` — update_player, toggle_player_visibility (enabled: false — dormant for V1) - `tools/player_writes/handler.py` - `tools/team_writes/TOOL.md` — assign_player_to_team, remove_player_from_team, create_team (enabled: false) - `tools/team_writes/handler.py` - `tools/tryouts/TOOL.md` — checkin_player, bulk_assign_tryout_numbers (enabled: false) - `tools/tryouts/handler.py` - `app/tool_registry.py` — auto-discover tools/ dirs, parse TOOL.md frontmatter, only load enabled tools, import handler.py functions, generate Anthropic tool definitions list - `prompts/system.md` — system prompt template that references nemo.md personality Files the agent should modify: - `app/ai.py` — replace inline TOOLS list with `tool_registry.get_tools()`, replace inline dispatch with registry-based dispatch - `tests/test_ai.py` — update imports from inline TOOLS/dispatch to tool_registry. Update any direct references to _TOOL_META, _execute_read_tool, etc. Files the agent should NOT touch: - `app/basketball.py` — stays as-is (the HTTP client tools call into) - `app/groupme.py` — stays as-is - `app/confirmation.py` — stays dormant (future write support) ### Acceptance Criteria - [ ] `agents/nemo.md` defines personality, role, voice, constraints (read-only V1) - [ ] 7 tool categories created (4 read enabled, 3 write disabled) with TOOL.md + handler.py each - [ ] `tool_registry.py` auto-discovers tools, respects `enabled` flag, generates Anthropic-format tool definitions - [ ] Only enabled tools are returned by `get_tools()` (7 read tools in V1) - [ ] `ai.py` uses registry instead of inline definitions — same behavior, modular structure - [ ] Adding a new tool = create `tools/new_category/TOOL.md` + `handler.py` — no ai.py changes - [ ] All existing tests pass (updated imports) - [ ] System prompt built from prompts/system.md + nemo.md personality ### Test Expectations - [ ] Unit test: tool_registry discovers all 7 categories - [ ] Unit test: tool_registry only returns enabled tools (4 categories, 7 tools) - [ ] Unit test: disabled tools are NOT in the active set - [ ] Unit test: handler functions call basketball.py correctly - [ ] Existing ai.py tests pass with registry-based dispatch (updated imports) - Run command: `pytest tests/ -v` ### Constraints - TOOL.md uses YAML frontmatter for tool metadata (name, description, parameters schema, enabled flag) - handler.py exports an async function matching the tool name - Registry returns both the Anthropic tool definition AND a dispatch map (tool_name -> handler function) - Follow claude-custom SKILL.md pattern for TOOL.md format - Write tool handlers stay in codebase — just disabled via `enabled: false` ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `project-westside-ai-assistant` — parent project - `story-westside-ai-assistant-read-ops` — read operations story - `arch-domain-westside-ai-assistant` — architecture reference
Author
Owner

Scope Review: NEEDS_REFINEMENT

Review note: review-683-2026-03-28

Template is complete and well-structured. Three issues found before this ticket is READY:

  • [BODY] Write tools unaddressed — ai.py has 14 tools (7 read + 7 write) but the ticket only structures 4 read categories. The 7 write tools are not mentioned in file targets. Add explicit statement that write tools remain inline (deferred), or expand scope (triggers decomposition).
  • [BODY] test_ai.py not listed as modification target — test file (593 lines) imports TOOLS, _TOOL_META, _execute_read_tool directly from app.ai. After restructure, imports will break unless re-exports are preserved or tests are updated. Add to file targets.
  • [SCOPE] Architecture notes missing — arch:A2 label has no backing note. Project page references arch-domain/dataflow/deployment notes that don't exist yet. Create arch notes before or alongside this work.
## Scope Review: NEEDS_REFINEMENT Review note: `review-683-2026-03-28` Template is complete and well-structured. Three issues found before this ticket is READY: - **[BODY] Write tools unaddressed** — ai.py has 14 tools (7 read + 7 write) but the ticket only structures 4 read categories. The 7 write tools are not mentioned in file targets. Add explicit statement that write tools remain inline (deferred), or expand scope (triggers decomposition). - **[BODY] test_ai.py not listed as modification target** — test file (593 lines) imports TOOLS, _TOOL_META, _execute_read_tool directly from app.ai. After restructure, imports will break unless re-exports are preserved or tests are updated. Add to file targets. - **[SCOPE] Architecture notes missing** — arch:A2 label has no backing note. Project page references arch-domain/dataflow/deployment notes that don't exist yet. Create arch notes before or alongside this work.
Author
Owner

Scope refinement (review-683-2026-03-28):

  1. Write tools now explicitly addressed — 3 write tool categories created with enabled: false in TOOL.md frontmatter. Registry only loads enabled tools.
  2. tests/test_ai.py added to file targets as modification target (imports will change).
  3. Arch notes false positive — arch-domain-westside-ai-assistant and related notes exist in pal-e-docs (created earlier this session).
**Scope refinement (review-683-2026-03-28):** 1. Write tools now explicitly addressed — 3 write tool categories created with `enabled: false` in TOOL.md frontmatter. Registry only loads enabled tools. 2. `tests/test_ai.py` added to file targets as modification target (imports will change). 3. Arch notes false positive — `arch-domain-westside-ai-assistant` and related notes exist in pal-e-docs (created earlier this session).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/westside-ai-assistant#18
No description provided.