Skip to content

Add species architecture β€” composable creature inheritance#88

Open
woltspace wants to merge 4 commits intorefactor-speciesfrom
nw/species-architecture
Open

Add species architecture β€” composable creature inheritance#88
woltspace wants to merge 4 commits intorefactor-speciesfrom
nw/species-architecture

Conversation

@woltspace
Copy link
Copy Markdown
Collaborator

Summary

The creatures section has been held together by hardcoded strings and constants scattered across 4 files. This PR introduces a species/ directory that makes creature types declarative and file-driven.

What changes:

  • species/ directory with species.json + instructions.md for each creature type (rodent, wolf, dog, spider, bear, panda)
  • container/lib/species.py β€” loading, resolution, and inheritance library
  • container/lib/wolts.py β€” reads valid types and singleton constraints from species definitions instead of hardcoded VALID_TYPES / SINGLETON_TYPES
  • container/bot/core.py β€” creature model resolution reads from species.json, creature descriptions in system prompt built dynamically from species definitions (with full hardcoded fallback)
  • container/entrypoint.sh β€” 3-layer skill loading: platform β†’ species β†’ wolt

What stays the same:

  • Everything is backwards-compatible. If species/ is missing, all code falls back to previous hardcoded behavior.
  • No changes to wolts/ directory, wolt.json format, or woltspace.json
  • The type field in wolt.json becomes the inheritance pointer β€” type: wolf means "inherit from species/wolf/"

Design doc: neowolt/wolt/site/species-architecture.html has the full visual spec

The inheritance model

Layer 3 β€” Wolt (user-owned, wins)     wolts/howlie/.claude/skills/
Layer 2 β€” Species (platform, inherited) woltspace/species/wolf/skills/
Layer 1 β€” Platform (universal)          woltspace/container/skills/

Adding a new species = drop a folder in species/. No touching bot core, entrypoint, or wolts.py.

Test plan

  • Verify species.py loads all 6 species correctly
  • Verify wolts.py reads types/singletons from species (not hardcoded)
  • Verify bot core creature model resolution returns correct models for all tiers
  • Verify entrypoint.sh layers skills correctly (platform β†’ species β†’ wolt)
  • Verify fallback behavior works when species/ dir is missing
  • Test bot system prompt generation with species-driven creature descriptions

🐿️ Generated with Claude Code

Introduces a species/ directory that defines creature types declaratively:
each species has a species.json (runtime mode, singleton, model, tiers),
instructions.md, and optional skills/. This replaces hardcoded constants
with file-driven discovery.

Three-layer inheritance: platform skills β†’ species skills β†’ wolt overrides.
entrypoint.sh now reads the wolt's type from wolt.json and layers species
skills between platform and wolt-specific skills.

species.py provides the loading/resolution library. wolts.py now reads
valid types and singleton constraints from species definitions instead of
hardcoded sets. bot core.py reads creature models from species.json with
fallback to previous hardcoded values.

All changes are backwards-compatible β€” if species/ is missing, everything
falls back to previous behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
woltspace Ready Ready Preview, Comment Mar 16, 2026 1:08am

All hardcoded prompt sections in build_system_prompt() are now loaded
from species/dog/prompts/*.md files:
- intro.md / intro-fallback.md β€” dog identity intro
- creatures.md β€” creature roster with {creature_list} and {species_list} vars
- voice.md β€” how the dog talks
- tools.md β€” available tools
- projects.md β€” project routing rules
- communication.md β€” session message protocol
- memory.md β€” memory usage instructions

build_system_prompt() is now a pure file loader: load, substitute
variables, concatenate. Zero prompt text in Python.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@woltspace woltspace changed the base branch from staging to refactor-species March 16, 2026 00:42
}


def build_system_prompt() -> str:
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels hacky, why dont we have a build system prompt per species?

except ImportError:
pass
# Fallback: hardcoded mapping (removed once species/ is stable)
return {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is all this fluff still needed?

Addresses PR review: prompt composition and creature resolution no longer
live in core.py at all.

- build_system_prompt() is now ~10 lines: gather variables, call
  species.build_prompt("dog", variables), append memory. Done.
- species.build_prompt() owns all composition: loads prompts/ in order
  defined by order.txt, substitutes variables, concatenates.
- _resolve_creature_model() drops the hardcoded fallback dict β€” just
  calls species.get_creature_model() directly.
- CREATURE_EMOJIS hardcoded dict removed β€” build_ack_text() calls
  species.get_creature_emoji() instead.
- _load_prompt(), _build_creatures_list() removed β€” their logic now
  lives in species.py where it belongs.
- intro-fallback.md removed β€” intro.md handles both cases via
  {dog_identity} variable (empty string when no dog-wolt exists).
- species/dog/prompts/order.txt added β€” loading order declared in the
  species definition, not in Python.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers what's done (PR #88), what's left (phases 3-5), and key design
decisions so the next session can pick up without re-litigating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants