WorldSmithAI / README.md
Srishti280992's picture
Update README.md
e9d9620 verified
|
Raw
History Blame Contribute Delete
20 kB
---
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.