diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index f9a6fe0..9ac9ec7 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -3,33 +3,18 @@
### Summary
Describe the purpose and key changes of this PR.
-### Change Type
-- [ ] Bug fix
-- [ ] New feature
-- [ ] Breaking change
-- [ ] Documentation
-- [ ] Refactor
-- [ ] Performance
-- [ ] Other:
-
-### Related Issues
-- Fixes: #
-- Related: #
-
### What Was Changed
-
-### Testing
+### Quality Control
- [ ] Added/updated tests
- [ ] All tests pass locally
- [ ] Linter and type checks pass
-### Checklist
-- [ ] Follows style guidelines
-- [ ] Self-reviewed
-- [ ] Code is commented where needed
-- [ ] Documentation updated
-- [ ] No new warnings
+### Related Issues
+- Fixes: #
+- Related: #
+
### Screenshots / Notes
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 31af69b..ac73f15 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,6 +21,9 @@ jobs:
- name: Install dependencies
run: uv sync
+ - name: Run linting
+ run: uv run ruff check .
+
- name: Run type checking
run: uv run mypy src/
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 0c33965..b720e6e 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -3,11 +3,12 @@
"version": "0.2.0",
"configurations": [
{
- "name": "Curr File",
+ "name": "cartpole",
"type": "debugpy",
"request": "launch",
- "program": "${workspaceFolder}/src/cumind/__main__.py",
- "console": "integratedTerminal"
+ "program": "${workspaceFolder}/src/cartpole.py",
+ "console": "integratedTerminal",
+ "stopOnEntry": true
},
{
"name": "CuMind",
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e9ccd6f..ae8e013 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -240,7 +240,7 @@ def test_select_action_training_mode(self):
agent = Agent(config)
action = agent.select_action(observation, training=True)
assert isinstance(action, int)
- assert 0 <= action < config.action_space_size
+ assert 0 <= action < config.env_action_space_size
```
## Project Structure
diff --git a/Release_Notes.txt b/Release_Notes.txt
index c5cb835..68995bb 100644
--- a/Release_Notes.txt
+++ b/Release_Notes.txt
@@ -2,6 +2,15 @@ CuMind Release Notes
-------------------------------------------------------------------
Document all technical changes introduced in this release as concise bullet points below.
+v0.1.8 (2025-07-18)
+----------------------
+Tarek Ibrahim (68)
+- Major configuration refactor: unified and simplified config, key, logger management
+- Refactored agent, core, and data modules for consistency with new config structure
+- Replaced explicit relative imports for absolute imports
+- Added standard output coloring for logs
+- Enhanced code quality: 126 passing tests, 86% code coverage
+- Decoupled neural network code in core/
v0.1.7 (2025-07-15)
----------------------
diff --git a/checkpoints/CartPole-v1/20250713-141205/episode_01200.pkl b/checkpoints/CartPole-v1/20250713-141205/episode_01200.pkl
deleted file mode 100644
index c7d2f52..0000000
Binary files a/checkpoints/CartPole-v1/20250713-141205/episode_01200.pkl and /dev/null differ
diff --git a/configuration.json b/configuration.json
index 79383e2..b2b573e 100644
--- a/configuration.json
+++ b/configuration.json
@@ -1,54 +1,72 @@
{
- "Network architecture": {
- "hidden_dim": 128,
- "num_blocks": 2,
- "conv_channels": 32
- },
- "Training": {
- "batch_size": 64,
- "learning_rate": 0.01,
- "weight_decay": 0.0001,
- "target_update_frequency": 250,
- "checkpoint_interval": 50,
- "num_episodes": 1220,
- "train_frequency": 2,
- "checkpoint_root_dir": "checkpoints"
- },
- "MCTS": {
- "num_simulations": 25,
- "c_puct": 1.25,
- "dirichlet_alpha": 0.25,
- "exploration_fraction": 0.25
- },
- "Environment": {
- "env_name": "CartPole-v1",
- "action_space_size": 2,
- "observation_shape": [
- 4
- ]
- },
- "Self-Play": {
- "num_unroll_steps": 5,
- "td_steps": 10,
- "discount": 0.997
- },
- "Memory": {
- "memory_capacity": 2000,
- "min_memory_size": 100,
- "min_memory_pct": 0.1,
- "per_alpha": 0.6,
- "per_epsilon": 1e-06,
- "per_beta": 0.4
- },
- "Data Types": {
- "model_dtype": "float32",
- "action_dtype": "int32",
- "target_dtype": "float32"
- },
- "Device": {
- "device_type": "cpu"
- },
- "Other": {
+ "CuMind": {
+ "networks": {
+ "hidden_dim": 128
+ },
+ "representation": {
+ "type": "cumind.core.resnet.ResNet",
+ "num_blocks": 2,
+ "conv_channels": 32,
+ "seed": 42
+ },
+ "dynamics": {
+ "type": "cumind.core.mlp.MLPWithEmbedding",
+ "num_blocks": 2,
+ "seed": 42
+ },
+ "prediction": {
+ "type": "cumind.core.mlp.MLPDual",
+ "seed": 42
+ },
+ "memory": {
+ "type": "cumind.data.memory.MemoryBuffer",
+ "capacity": 2000,
+ "min_size": 100,
+ "min_pct": 0.1,
+ "per_alpha": 0.6,
+ "per_epsilon": 1e-06,
+ "per_beta": 0.4
+ },
+ "training": {
+ "optimizer": "optax.adamw",
+ "batch_size": 64,
+ "learning_rate": 0.01,
+ "weight_decay": 0.0001,
+ "target_update_frequency": 250,
+ "checkpoint_interval": 50,
+ "num_episodes": 1220,
+ "train_frequency": 2,
+ "checkpoint_root_dir": "checkpoints"
+ },
+ "mcts": {
+ "num_simulations": 25,
+ "c_puct": 1.25,
+ "dirichlet_alpha": 0.25,
+ "exploration_fraction": 0.25
+ },
+ "env": {
+ "name": "CartPole-v1",
+ "action_space_size": 2,
+ "observation_shape": [4]
+ },
+ "selfplay": {
+ "num_unroll_steps": 5,
+ "td_steps": 10,
+ "discount": 0.997
+ },
+ "dtypes": {
+ "model": "float32",
+ "action": "int32",
+ "target": "float32"
+ },
+ "logging": {
+ "dir": "logs",
+ "level": "INFO",
+ "console": true,
+ "timestamps": false,
+ "tqdm": false
+ },
+ "device": "cpu",
"seed": 42
}
-}
\ No newline at end of file
+}
diff --git a/cumind.svg b/cumind.svg
new file mode 100644
index 0000000..a8ce2ee
--- /dev/null
+++ b/cumind.svg
@@ -0,0 +1,529 @@
+
+
+
+
+
diff --git a/docs/GPU_PERFORMANCE_TIPS.md b/docs/GPU_PERFORMANCE_TIPS.md
index 3e7bb41..400d7d7 100644
--- a/docs/GPU_PERFORMANCE_TIPS.md
+++ b/docs/GPU_PERFORMANCE_TIPS.md
@@ -223,7 +223,7 @@ from cumind import Agent, Config
def benchmark_inference(config: Config, num_runs: int = 1000):
"""Benchmark inference speed on GPU."""
agent = Agent(config)
- observation = jnp.ones(config.observation_shape)
+ observation = jnp.ones(config.env_observation_shape)
# Warm-up
for _ in range(10):
@@ -248,7 +248,7 @@ if __name__ == "__main__":
]
for config in configs:
- print(f"\nTesting with dtype: {config.model_dtype}")
+ print(f"\nTesting with dtype: {config.dtypes_model}")
benchmark_inference(config)
```
diff --git a/docs/ONBOARDING.md b/docs/ONBOARDING.md
new file mode 100644
index 0000000..1527bf6
--- /dev/null
+++ b/docs/ONBOARDING.md
@@ -0,0 +1,156 @@
+# CuMind Development Environment Setup Guide
+
+This guide walks you through setting up the CuMind development environment on **macOS** and **Windows (WSL)** using GitHub, VSCode or Cursor, and `uv` for Python dependency management.
+
+## 1. Platform Prerequisites
+
+CuMind requires a Linux-based development environment.
+
+To achieve this on your machine:
+
+### On Windows:
+
+- Install WSL and Ubuntu by following the [official Microsoft guide](https://learn.microsoft.com/en-us/windows/wsl/install)
+- Recommended: WSL 2 and Ubuntu 22.04
+- After installation, open "Ubuntu" from the Start Menu to launch your WSL terminal
+- Use a code editor such as [VSCode](https://code.visualstudio.com/) or [Cursor](https://cursor.so) that supports WSL.
+ If you're using VSCode, install the **Remote - WSL** extension — you'll use it to open and work with the project from inside your WSL environment after cloning the repository.
+ - Additional resource: [VSCode: Developing in WSL](https://code.visualstudio.com/docs/remote/wsl)
+
+### On macOS:
+
+- No WSL needed — the built-in Terminal provides a compatible Unix-based environment
+- Use any local code editor such as [VSCode](https://code.visualstudio.com/) or [Cursor](https://cursor.so)
+
+## 2. Setup Python & `uv`
+
+### 1. **Install Python**
+
+Ensure Python 3.12 or higher is installed:
+
+```bash
+python3 --version
+```
+
+If not installed or the version is too old, install:
+
+- #### On WSL:
+
+ Install Python and pip:
+
+ ```bash
+ sudo apt update
+ sudo apt install python3 python3-pip
+ ```
+
+- #### On macOS:
+
+ ```bash
+ brew install python
+ ```
+
+### 2. **Install `uv`**
+
+Install the Python dependency manager `uv` using one of two ways:
+
+- Using pip/pipx:
+
+ ```bash
+ pip install uv
+ # or
+ pipx install uv
+ ```
+
+- Using the standalone installer:
+
+ ```bash
+ curl -LsSf https://astral.sh/uv/install.sh | sh
+ ```
+
+ To update, run:
+
+ ```bash
+ uv self update
+ ```
+
+More details: [uv documentation](https://astral.sh/uv/)
+
+## 4. Clone Repo and Setup Git Authentication
+
+You can clone the repo using either **SSH** or **HTTPS**.
+
+### Option 1: SSH (Recommended)
+
+1. Generate a new SSH key (if you don't have one already):
+
+```bash
+ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "your_email@example.com"
+```
+
+2. Copy your public key:
+
+```bash
+cat ~/.ssh/id_ed25519.pub
+```
+
+3. Add it to GitHub:
+ [https://github.com/settings/ssh/new](https://github.com/settings/ssh/new)
+
+4. Test your connection:
+
+```bash
+ssh -T git@github.com
+```
+
+5. Clone the repo:
+
+```bash
+git clone git@github.com:carletonai/CuMind.git
+```
+
+> If you already have an SSH key and have it registered with GitHub, skip steps 1–3.
+
+### Option 2: HTTPS
+
+Clone the repo using:
+
+```bash
+git clone https://github.com/carletonai/CuMind.git
+```
+
+You’ll be prompted to enter your GitHub **username** and a **personal access token** (PAT) instead of a password.
+Generate a PAT here: [https://github.com/settings/tokens](https://github.com/settings/tokens)
+
+## 5. Set Up and Run the Project
+
+Once the repo is cloned, navigate to it and install dependencies:
+
+```bash
+cd CuMind
+uv sync
+```
+
+Test out running a specific file to make sure your setup is working:
+
+`uv run python src/cartpole.py`
+
+To run the full application:
+
+`uv run python -m cumind --config configuration.json`
+
+## 6. Test Your Git Setup
+
+Make sure you can push a new branch:
+
+```bash
+git checkout -b test-branch
+git push origin test-branch
+```
+
+Once confirmed, please delete the test branch:
+
+`git push origin --delete test-branch`
+
+## You’re Ready!
+
+You should now be able to develop and contribute to CuMind locally. If you run into issues, feel free to reach out on Discord.
diff --git a/plots/episode_loss.png b/plots/episode_loss.png
new file mode 100644
index 0000000..dee2107
Binary files /dev/null and b/plots/episode_loss.png differ
diff --git a/plots/policy_loss.png b/plots/policy_loss.png
new file mode 100644
index 0000000..7601168
Binary files /dev/null and b/plots/policy_loss.png differ
diff --git a/plots/reward.png b/plots/reward.png
new file mode 100644
index 0000000..d634f1b
Binary files /dev/null and b/plots/reward.png differ
diff --git a/plots/reward_loss.png b/plots/reward_loss.png
new file mode 100644
index 0000000..fad0de1
Binary files /dev/null and b/plots/reward_loss.png differ
diff --git a/plots/total_loss.png b/plots/total_loss.png
new file mode 100644
index 0000000..cb2b791
Binary files /dev/null and b/plots/total_loss.png differ
diff --git a/plots/value_loss.png b/plots/value_loss.png
new file mode 100644
index 0000000..d51a08e
Binary files /dev/null and b/plots/value_loss.png differ
diff --git a/pyproject.toml b/pyproject.toml
index 679bf54..0cfab56 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,8 +3,8 @@
# =========================
[project]
name = "cumind"
-version = "0.1.7"
-description = "CUAIS CuMind implementation"
+version = "0.1.8"
+description = "A JAX-based CuMind is a JAX-based RL framework inspired by Google DeepMind. Achieve's superhuman performance in complex domains without pretraining nor prior knowledge of their rules."
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
@@ -60,7 +60,7 @@ target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W"] # Errors, pyFlakes, Import, Naming, Warnings
-ignore = ["E203", "E501", "F401"]
+ignore = ["E203", "E501"]
# Mypy configuration
[tool.mypy]
diff --git a/scripts/exportconfig.py b/scripts/exportconfig.py
old mode 100644
new mode 100755
index c037f1c..6f81f87
--- a/scripts/exportconfig.py
+++ b/scripts/exportconfig.py
@@ -1,10 +1,5 @@
-from cumind.config import Config
-
-
-def main() -> None:
- config = Config()
- config.to_json("configuration.json")
-
+#!./.venv/bin/python3.12
+from cumind.utils.config import cfg
if __name__ == "__main__":
- main()
+ cfg.save("configuration.json")
diff --git a/scripts/plot.py b/scripts/plot.py
new file mode 100755
index 0000000..d99b557
--- /dev/null
+++ b/scripts/plot.py
@@ -0,0 +1,128 @@
+#!./.venv/bin/python3.12
+import datetime
+import os
+import re
+
+import matplotlib.pyplot as plt
+
+
+def parse_log_file(filepath):
+ episode_re = re.compile(r"(?P