Spaces:
Runtime error
Runtime error
| title: WorldSmithAI | |
| emoji: 📈 | |
| colorFrom: pink | |
| colorTo: gray | |
| sdk: gradio | |
| sdk_version: 6.18.0 | |
| python_version: '3.13' | |
| app_file: app.py | |
| pinned: false | |
| short_description: Forge ecosystems from small models | |
| Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference | |
| # WorldSmithAI | |
| ## Demo Link | |
| Video Link: | |
| https://youtu.be/-iwRIDpiOII | |
| ## LinkedIn Post | |
| https://www.linkedin.com/feed/update/urn:li:share:7472437512364318720/ | |
| **Production-Level Agent-Based World Simulation Framework** | |
| WorldSmithAI is a modular Python framework that converts natural language descriptions into generic agent-based worlds and simulates emergent behavior. | |
| The core idea is simple: | |
| ```text | |
| Natural language prompt | |
| → WorldSpec JSON DSL | |
| → Pydantic validation | |
| → WorldFactory | |
| → World | |
| → Scheduler | |
| → Agents | |
| → Policies | |
| → Behaviors | |
| → Metrics | |
| → Visualization | |
| → Narration | |
| → Gradio UI | |
| ``` | |
| WorldSmithAI is intentionally **not hardcoded for any single domain**. | |
| There are no runtime classes like: | |
| ```python | |
| class Sheep | |
| class Wolf | |
| class Scientist | |
| class Merchant | |
| class Dragon | |
| ``` | |
| Instead, every world is composed from generic runtime concepts: | |
| ```python | |
| Agent | |
| Behavior | |
| Resource | |
| Event | |
| World | |
| Policy | |
| ``` | |
| That means the same engine can simulate: | |
| - farm ecosystems | |
| - medieval civilizations | |
| - research ecosystems | |
| - startup economies | |
| - social networks | |
| - fantasy worlds | |
| - transport networks | |
| - power grids | |
| - space colonies | |
| - any DSL-generated ecosystem | |
| --- | |
| ## Project Status | |
| WorldSmithAI is designed as a hackathon-grade prototype with production-oriented architecture. | |
| Current capabilities include: | |
| - generic agent representation | |
| - behavior abstraction | |
| - concrete behavior modules | |
| - rule-based policies | |
| - contextual bandit policy scaffold | |
| - Pydantic DSL schema | |
| - JSON parser and semantic validator | |
| - WorldFactory for DSL → runtime conversion | |
| - metrics for diversity, entropy, stability, and interestingness | |
| - Matplotlib renderer | |
| - GIF/MP4 animation support | |
| - chart generation | |
| - deterministic narration | |
| - root-level Gradio app | |
| - CLI runner | |
| - example DSL worlds | |
| The system works without an external LLM by using a deterministic fallback world generator. If a model is configured, the model is only responsible for generating JSON DSL, never Python code. | |
| --- | |
| ## Repository Layout | |
| ```text | |
| WorldSmithAI/ | |
| ├── app.py | |
| ├── callbacks.py | |
| ├── main.py | |
| ├── README.md | |
| ├── requirements.txt | |
| │ | |
| ├── core/ | |
| │ ├── agent.py | |
| │ ├── behavior.py | |
| │ ├── resource.py | |
| │ ├── event.py | |
| │ ├── world.py | |
| │ └── scheduler.py | |
| │ | |
| ├── behaviors/ | |
| │ ├── movement.py | |
| │ ├── consume.py | |
| │ ├── trade.py | |
| │ ├── attack.py | |
| │ ├── research.py | |
| │ ├── collaboration.py | |
| │ ├── transport.py | |
| │ ├── construction.py | |
| │ ├── governance.py | |
| │ ├── market.py | |
| │ ├── adoption.py | |
| │ ├── planning.py | |
| │ └── memory.py | |
| │ | |
| ├── policies/ | |
| │ ├── base_policy.py | |
| │ ├── rule_policy.py | |
| │ └── contextual_bandit.py | |
| │ | |
| ├── dsl/ | |
| │ ├── schema.py | |
| │ ├── parser.py | |
| │ └── validator.py | |
| │ | |
| ├── factory/ | |
| │ └── world_factory.py | |
| │ | |
| ├── metrics/ | |
| │ ├── diversity.py | |
| │ ├── entropy.py | |
| │ ├── stability.py | |
| │ └── interestingness.py | |
| │ | |
| ├── visualization/ | |
| │ ├── renderer.py | |
| │ ├── animation.py | |
| │ └── charts.py | |
| │ | |
| ├── llm/ | |
| │ ├── world_generator.py | |
| │ ├── narrator.py | |
| │ └── prompts.py | |
| │ | |
| └── examples/ | |
| ├── farm.json | |
| ├── civilization.json | |
| └── research.json | |
| ``` | |
| `app.py` is intentionally at the repository root because Hugging Face Gradio Spaces expect the app entry point there. | |
| --- | |
| ## Core Design Principles | |
| WorldSmithAI follows these principles: | |
| 1. **No hardcoded species or domains** | |
| A wolf, scientist, startup founder, train, dragon, or power node is just an `Agent` with a different `type`, `state`, `memory`, `goals`, `behaviors`, and `policy`. | |
| 2. **DSL-first world definition** | |
| Worlds are described as JSON using the `WorldSpec` schema. | |
| 3. **LLM generates JSON only** | |
| The model never generates Python code. The Python engine remains deterministic. | |
| 4. **Composition over inheritance** | |
| Agent behavior comes from behavior objects and policies, not subclass-specific logic. | |
| 5. **Strong module boundaries** | |
| Parsing, validation, factory construction, simulation, visualization, metrics, narration, and UI are separate layers. | |
| 6. **Gradio app is thin** | |
| `app.py` defines the UI. `callbacks.py` runs the engine pipeline. | |
| --- | |
| ## Installation | |
| ### 1. Clone the repository | |
| ```bash | |
| git clone <your-repo-url> | |
| cd WorldSmithAI | |
| ``` | |
| ### 2. Create a virtual environment | |
| Python 3.11 or newer is recommended. | |
| ```bash | |
| python -m venv .venv | |
| ``` | |
| Activate it: | |
| ```bash | |
| source .venv/bin/activate | |
| ``` | |
| On Windows PowerShell: | |
| ```powershell | |
| .venv\Scripts\Activate.ps1 | |
| ``` | |
| ### 3. Install dependencies | |
| If your project already has a `requirements.txt`, run: | |
| ```bash | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements.txt | |
| ``` | |
| If you have not created `requirements.txt` yet, use this minimal set: | |
| ```bash | |
| python -m pip install --upgrade pip | |
| python -m pip install gradio pydantic numpy matplotlib pillow huggingface_hub | |
| ``` | |
| Optional development tools: | |
| ```bash | |
| python -m pip install pytest ruff mypy | |
| ``` | |
| Optional MP4 support requires `ffmpeg` installed on the system. GIF output works through Pillow and is the safer default. | |
| --- | |
| ## Suggested `requirements.txt` | |
| Create this file at the repository root: | |
| ```text | |
| gradio | |
| pydantic>=2 | |
| numpy | |
| matplotlib | |
| pillow | |
| huggingface_hub | |
| ``` | |
| Optional dev dependencies can be placed in `requirements-dev.txt`: | |
| ```text | |
| pytest | |
| ruff | |
| mypy | |
| ``` | |
| --- | |
| ## Can This Be Tested Locally? | |
| Yes. WorldSmithAI can be tested locally without Hugging Face Spaces and without an external LLM. | |
| The deterministic fallback generator allows this command to work even if no model is configured: | |
| ```bash | |
| python main.py --prompt "A research ecosystem with scientists, reviewers, funding agents, and knowledge resources" --steps 10 --no-animation | |
| ``` | |
| For a faster smoke test, disable all visual outputs: | |
| ```bash | |
| python main.py \ | |
| --prompt "A tiny farm ecosystem with farmers, water, crops, and soil health" \ | |
| --steps 5 \ | |
| --no-animation \ | |
| --no-charts \ | |
| --no-final-image \ | |
| --no-narrative | |
| ``` | |
| If that completes, your parser, schema, world generation fallback, validation, factory, scheduler, policies, behaviors, and metrics are at least importable and executable. | |
| --- | |
| ## Local Smoke Test Checklist | |
| Run these from the repository root. | |
| ### 1. Check Python syntax | |
| ```bash | |
| python -m compileall . | |
| ``` | |
| This catches syntax errors across all modules. | |
| ### 2. List example worlds | |
| ```bash | |
| python main.py --list-examples | |
| ``` | |
| Expected output should include some or all of: | |
| ```text | |
| farm | |
| civilization | |
| research | |
| ``` | |
| ### 3. Validate an example DSL file | |
| ```bash | |
| python main.py --example research --validate-only | |
| ``` | |
| Or directly: | |
| ```bash | |
| python main.py --dsl examples/research.json --validate-only | |
| ``` | |
| This checks: | |
| - JSON parsing | |
| - Pydantic schema validation | |
| - semantic DSL validation | |
| ### 4. Run a short simulation without animation | |
| ```bash | |
| python main.py --example research --steps 5 --no-animation | |
| ``` | |
| This checks: | |
| - WorldFactory | |
| - runtime object construction | |
| - policies | |
| - behaviors | |
| - scheduler/world stepping | |
| - metrics | |
| - charts/final image unless disabled | |
| ### 5. Run the fastest full-pipeline smoke test | |
| ```bash | |
| python main.py \ | |
| --example farm \ | |
| --steps 5 \ | |
| --no-animation \ | |
| --no-charts \ | |
| --no-final-image \ | |
| --no-narrative | |
| ``` | |
| This is useful when debugging core engine issues. | |
| ### 6. Run a full local artifact test | |
| ```bash | |
| python main.py --example research --steps 20 --output-dir outputs/research_test | |
| ``` | |
| Expected outputs: | |
| ```text | |
| outputs/research_test/ | |
| ├── world_spec.json | |
| ├── validation_report.json | |
| ├── metrics.json | |
| ├── narrative.md | |
| ├── run_summary.json | |
| ├── simulation.gif | |
| ├── population chart image | |
| ├── resource chart image | |
| └── final world image | |
| ``` | |
| Exact image filenames may depend on the callback artifact writer. | |
| ### 7. Run the Gradio app locally | |
| ```bash | |
| python app.py | |
| ``` | |
| Then open the local URL printed in the terminal, usually something like: | |
| ```text | |
| http://127.0.0.1:7860 | |
| ``` | |
| Try the default prompt first. Then try one of: | |
| ```text | |
| A medieval civilization with rulers, merchants, artisans, guards, public trust, taxes, and trade. | |
| A startup economy with founders, customers, investors, market adoption, and shifting goals. | |
| A fantasy world with dragons, mages, healers, mana, alliances, and negotiation. | |
| ``` | |
| --- | |
| ## CLI Usage | |
| `main.py` is the local command-line entry point. | |
| ### Run an example world | |
| ```bash | |
| python main.py --example research --steps 60 | |
| ``` | |
| ### Run a DSL file | |
| ```bash | |
| python main.py --dsl examples/farm.json --steps 80 | |
| ``` | |
| ### Generate a world from a prompt | |
| ```bash | |
| python main.py \ | |
| --prompt "A fantasy kingdom with dragons, mages, merchants, mana, trade, and alliances" \ | |
| --steps 70 | |
| ``` | |
| ### Validate only | |
| ```bash | |
| python main.py --dsl examples/civilization.json --validate-only | |
| ``` | |
| ### Generate DSL only | |
| ```bash | |
| python main.py \ | |
| --prompt "A transport network with hubs, carriers, queues, chargers, and route planning" \ | |
| --generate-only | |
| ``` | |
| ### Disable expensive outputs | |
| ```bash | |
| python main.py --example research --steps 20 --no-animation --no-charts | |
| ``` | |
| ### Use MP4 animation | |
| ```bash | |
| python main.py --example research --steps 30 --animation-format mp4 | |
| ``` | |
| If MP4 fails, install `ffmpeg` or use GIF: | |
| ```bash | |
| python main.py --example research --steps 30 --animation-format gif | |
| ``` | |
| --- | |
| ## Gradio App Usage | |
| Start the app: | |
| ```bash | |
| python app.py | |
| ``` | |
| The UI includes: | |
| 1. **Generate + Simulate** | |
| Enter a natural-language world prompt. The app generates DSL, builds a world, runs simulation, and returns: | |
| - generated JSON DSL | |
| - validation report | |
| - animation | |
| - population chart | |
| - resource chart | |
| - final world image | |
| - narrative summary | |
| - metrics JSON | |
| 2. **Generate DSL only** | |
| Use this to inspect the generated `WorldSpec` before simulation. | |
| 3. **Simulate existing DSL** | |
| Paste JSON or load an example from `examples/`. | |
| 4. **Validate DSL** | |
| Validate a JSON world spec without running it. | |
| --- | |
| ## Optional Model Setup | |
| WorldSmithAI works without an LLM by using a deterministic fallback generator. | |
| To enable a Hugging Face model for DSL generation, set: | |
| ```bash | |
| export WORLDSMITHAI_MODEL_ID="your-model-id" | |
| ``` | |
| Optional token: | |
| ```bash | |
| export HF_TOKEN="your-hugging-face-token" | |
| ``` | |
| Then run: | |
| ```bash | |
| python app.py | |
| ``` | |
| The model is only asked to generate WorldSpec JSON. It is not allowed to generate Python code. | |
| If the model fails or returns invalid JSON, WorldSmithAI can fall back to deterministic generation. | |
| --- | |
| ## Environment Variables | |
| | Variable | Purpose | | |
| |---|---| | |
| | `WORLDSMITHAI_MODEL_ID` | Optional Hugging Face model id for JSON DSL generation | | |
| | `HF_TOKEN` | Optional Hugging Face token | | |
| | `WORLDSMITHAI_OUTPUT_DIR` | Directory for generated artifacts | | |
| | `WORLDSMITHAI_DEFAULT_STEPS` | Default simulation steps in the app | | |
| | `WORLDSMITHAI_MAX_FRAMES` | Maximum animation frames | | |
| | `WORLDSMITHAI_LOG_LEVEL` | Logging level, for example `INFO` or `DEBUG` | | |
| Example: | |
| ```bash | |
| export WORLDSMITHAI_DEFAULT_STEPS=60 | |
| export WORLDSMITHAI_MAX_FRAMES=80 | |
| export WORLDSMITHAI_LOG_LEVEL=INFO | |
| python app.py | |
| ``` | |
| --- | |
| ## DSL Example | |
| A minimal world looks like this: | |
| ```json | |
| { | |
| "schema_version": "1.0", | |
| "id": "tiny_world", | |
| "name": "Tiny World", | |
| "description": "A minimal generic world.", | |
| "simulation": { | |
| "steps": 10, | |
| "seed": 0, | |
| "scheduler": "sequential", | |
| "activation": "sequential", | |
| "collect_history": true | |
| }, | |
| "space": { | |
| "dimensions": 2, | |
| "bounds": [[0, 10], [0, 10]], | |
| "toroidal": false, | |
| "enforce_bounds": true | |
| }, | |
| "agents": [ | |
| { | |
| "id": "agent_1", | |
| "type": "explorer", | |
| "position": [1, 1], | |
| "state": { | |
| "energy": 10, | |
| "credits": 5 | |
| }, | |
| "memory": { | |
| "goals": [ | |
| { | |
| "id": "learn", | |
| "importance": 1, | |
| "score": 1 | |
| } | |
| ] | |
| }, | |
| "goals": [ | |
| { | |
| "id": "learn", | |
| "importance": 1, | |
| "score": 1 | |
| } | |
| ], | |
| "behaviors": [ | |
| { | |
| "name": "prioritize", | |
| "params": { | |
| "source_path": "memory.goals" | |
| } | |
| }, | |
| { | |
| "name": "choose_goal", | |
| "params": {} | |
| }, | |
| { | |
| "name": "remember", | |
| "params": { | |
| "category": "initial", | |
| "content": { | |
| "note": "hello world" | |
| } | |
| } | |
| } | |
| ], | |
| "policy": { | |
| "type": "rule_policy", | |
| "params": { | |
| "rules": [ | |
| { | |
| "behavior_name": "choose_goal", | |
| "score_delta": 3 | |
| }, | |
| { | |
| "behavior_name": "prioritize", | |
| "score_delta": 2 | |
| }, | |
| { | |
| "behavior_name": "remember", | |
| "score_delta": 1 | |
| } | |
| ] | |
| } | |
| }, | |
| "alive": true, | |
| "metadata": {} | |
| } | |
| ], | |
| "resources": [], | |
| "events": [], | |
| "metrics": [ | |
| { | |
| "name": "diversity", | |
| "params": { | |
| "collection": "agents", | |
| "group_by_path": "type" | |
| } | |
| } | |
| ], | |
| "metadata": {} | |
| } | |
| ``` | |
| --- | |
| ## Architecture Notes | |
| ### World generation | |
| `llm/world_generator.py` converts prompts into `WorldSpec`. | |
| If no model client is configured, it uses a deterministic fallback builder. | |
| ### Parsing and validation | |
| `dsl/parser.py` accepts: | |
| - JSON strings | |
| - dictionaries | |
| - JSON files | |
| - Markdown-fenced JSON | |
| - model responses containing JSON | |
| `dsl/schema.py` performs structural validation. | |
| `dsl/validator.py` performs semantic validation, such as checking behavior names, policy names, constructor parameters, and references. | |
| ### Runtime construction | |
| `factory/world_factory.py` turns `WorldSpec` into runtime objects: | |
| ```text | |
| WorldSpec | |
| → Agent | |
| → Resource | |
| → Event | |
| → Behavior | |
| → Policy | |
| → World | |
| ``` | |
| ### Simulation | |
| The world and scheduler advance agents. Agents delegate decision-making to policies, and behaviors mutate generic state/memory. | |
| ### Visualization | |
| `visualization/renderer.py` renders a single world state. | |
| `visualization/animation.py` renders GIF or MP4 animations. | |
| `visualization/charts.py` renders population and resource curves. | |
| ### Metrics | |
| `metrics/` includes: | |
| - diversity | |
| - entropy | |
| - stability | |
| - interestingness | |
| ### Narration | |
| `llm/narrator.py` produces deterministic narrative summaries and can optionally use a model client for polished narration. | |
| --- | |
| ## Testing Strategy | |
| A practical local testing ladder: | |
| ### Level 1: Syntax | |
| ```bash | |
| python -m compileall . | |
| ``` | |
| ### Level 2: DSL parsing | |
| ```bash | |
| python main.py --dsl examples/farm.json --validate-only | |
| python main.py --dsl examples/civilization.json --validate-only | |
| python main.py --dsl examples/research.json --validate-only | |
| ``` | |
| ### Level 3: Fast simulation | |
| ```bash | |
| python main.py --example farm --steps 5 --no-animation --no-charts --no-final-image --no-narrative | |
| ``` | |
| ### Level 4: Metrics and narration | |
| ```bash | |
| python main.py --example research --steps 10 --no-animation --no-charts --no-final-image | |
| ``` | |
| ### Level 5: Full artifact generation | |
| ```bash | |
| python main.py --example civilization --steps 20 --output-dir outputs/civilization_test | |
| ``` | |
| ### Level 6: Gradio UI | |
| ```bash | |
| python app.py | |
| ``` | |
| --- | |
| ## Troubleshooting | |
| ### `ModuleNotFoundError` | |
| Make sure you are running commands from the repository root: | |
| ```bash | |
| pwd | |
| ``` | |
| The current directory should contain: | |
| ```text | |
| app.py | |
| callbacks.py | |
| main.py | |
| core/ | |
| behaviors/ | |
| dsl/ | |
| factory/ | |
| metrics/ | |
| visualization/ | |
| llm/ | |
| ``` | |
| Then run: | |
| ```bash | |
| python -m compileall . | |
| ``` | |
| ### `ImportError` for a behavior module | |
| Check that the behavior file exists and that the behavior registry includes the expected names. | |
| For example: | |
| ```bash | |
| python - <<'PY' | |
| from dsl.validator import load_default_behavior_registry | |
| result = load_default_behavior_registry() | |
| print("Behavior count:", len(result.registry)) | |
| print("Import errors:", result.import_errors) | |
| print("Names:", sorted(result.registry.keys())[:50]) | |
| PY | |
| ``` | |
| ### Unknown behavior warnings | |
| If semantic validation reports unknown behavior names, check: | |
| 1. the behavior file exists | |
| 2. it defines a `BEHAVIOR_REGISTRY` | |
| 3. the behavior name in JSON matches the registry key | |
| 4. `factory/world_factory.py` includes the behavior module in `DEFAULT_BEHAVIOR_MODULES` | |
| ### Constructor parameter warnings | |
| If the validator reports unknown constructor parameters, either: | |
| - fix the JSON behavior params, or | |
| - update the behavior dataclass to accept the parameter, or | |
| - run in permissive mode through `callbacks.py`, which is friendlier for hackathon demos. | |
| ### MP4 animation fails | |
| Use GIF instead: | |
| ```bash | |
| python main.py --example research --steps 30 --animation-format gif | |
| ``` | |
| MP4 requires `ffmpeg` installed on the host. | |
| ### Gradio app starts but generation is slow | |
| Use fewer steps: | |
| ```bash | |
| export WORLDSMITHAI_DEFAULT_STEPS=20 | |
| export WORLDSMITHAI_MAX_FRAMES=30 | |
| python app.py | |
| ``` | |
| Or disable model usage in the UI and use deterministic fallback generation. | |
| ### Model returns invalid JSON | |
| The parser can extract JSON from common model response formats, but small models may still produce invalid JSON. | |
| Use: | |
| - the deterministic fallback generator | |
| - “Generate DSL only” tab | |
| - “Validate DSL” tab | |
| - simpler prompts | |
| - fewer agents | |
| --- | |
| ## Hugging Face Space Notes | |
| For a Gradio Space, keep these files at the repository root: | |
| ```text | |
| app.py | |
| callbacks.py | |
| requirements.txt | |
| ``` | |
| The Space should install dependencies from `requirements.txt`. | |
| Recommended Space hardware for the deterministic version is CPU basic. If you use a larger model locally inside the Space, choose hardware appropriate for that model. | |
| --- | |
| ## Development Tips | |
| Run formatting and lint checks if you install dev tools: | |
| ```bash | |
| ruff check . | |
| ``` | |
| Run type checks if your environment is ready: | |
| ```bash | |
| mypy . | |
| ``` | |
| Run a quick no-UI smoke test before pushing: | |
| ```bash | |
| python main.py --example research --steps 5 --no-animation --no-charts --no-final-image --no-narrative | |
| ``` | |
| Then run the app: | |
| ```bash | |
| python app.py | |
| ``` | |
| --- | |
| ## Hackathon Demo Script | |
| A good demo flow: | |
| 1. Open the app. | |
| 2. Enter a world prompt, for example: | |
| ```text | |
| A startup economy where founders, investors, customers, and competitors bid for attention, | |
| adopt strategies, collaborate, forecast demand, and rebalance resources. | |
| ``` | |
| 3. Run simulation for 40 to 60 steps. | |
| 4. Show the generated DSL. | |
| 5. Show the animation. | |
| 6. Show population and resource charts. | |
| 7. Show metrics JSON. | |
| 8. Read the narrative summary. | |
| 9. Explain that the model generated only JSON, while the deterministic Python engine executed the simulation. | |
| --- | |
| ## Current Limitations | |
| WorldSmithAI is designed as a hackathon-grade but production-oriented framework. Some areas are intentionally extensible: | |
| - event execution is generic and can be expanded | |
| - richer scheduler activation modes can be added | |
| - metric registry integration can be expanded | |
| - behavior parameter schemas can be tightened | |
| - model-specific generation adapters can be added | |
| - graph/network visualization can be added | |
| - multi-run comparison can be added | |
| - unit tests should be expanded as the codebase stabilizes | |
| --- | |
| ## Acknowledgments | |
| Built for the Hugging Face Build Small Hackathon. | |
| WorldSmithAI explores how small language models can generate compact, validated world DSLs while deterministic Python systems execute and visualize the resulting simulations. | |