From 92f1354fa4faeaf80a2b74bd64818717d27f6a43 Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 21:48:21 -0700 Subject: [PATCH 1/7] Add GitHub Actions CI/CD pipeline (closes #8) - Add ci.yml: runs backend+analysis tests and Django frontend tests on every PR and push to main using python:3.9.12 with pip cache - Add docker.yml: builds and pushes backend+frontend images to GHCR on merge to main using GITHUB_TOKEN (no extra secrets required) - Add release.yml: creates a GitHub Release with auto-generated notes on push of a v* tag - Update CLAUDE.md with CI badge and CI/CD reference table Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 53 +++++++++++++++++++++++++++++++++ .github/workflows/docker.yml | 56 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 20 +++++++++++++ CLAUDE.md | 17 +++++++++++ 4 files changed, 146 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f9d985a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test-backend: + name: Backend & Analysis Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.9.12" + cache: pip + cache-dependency-path: requirements.txt + + - name: Install dependencies + run: pip install -r requirements.txt + + - name: Run tests + run: python -m pytest tests/backend/ tests/analysis/ -v -p no:django + + test-frontend: + name: Frontend (Django) Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.9.12" + cache: pip + cache-dependency-path: | + requirements.txt + environment/frontend_server/requirements.txt + + - name: Install dependencies + run: | + pip install -r requirements.txt + pip install -r environment/frontend_server/requirements.txt + + - name: Run tests + run: python -m pytest tests/frontend/ -v + env: + DJANGO_SETTINGS_MODULE: frontend_server.settings.base + PYTHONPATH: reverie/backend_server:environment/frontend_server:analysis diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..dbfbb8a --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,56 @@ +name: Docker + +on: + push: + branches: [main] + +jobs: + build-backend: + name: Build & Push Backend Image + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.backend + push: true + tags: | + ghcr.io/${{ github.repository_owner }}/edsim-backend:latest + ghcr.io/${{ github.repository_owner }}/edsim-backend:${{ github.sha }} + + build-frontend: + name: Build & Push Frontend Image + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.frontend + push: true + tags: | + ghcr.io/${{ github.repository_owner }}/edsim-frontend:latest + ghcr.io/${{ github.repository_owner }}/edsim-frontend:${{ github.sha }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a8fb0a5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,20 @@ +name: Release + +on: + push: + tags: + - "v*" + +jobs: + release: + name: Create GitHub Release + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + + - uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true diff --git a/CLAUDE.md b/CLAUDE.md index a59697b..ef0ee3e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,7 @@ # CLAUDE.md +![CI](https://github.com/denoslab/EDSim/actions/workflows/ci.yml/badge.svg) + This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview @@ -46,6 +48,21 @@ To run tests inside the container: docker compose run --rm backend python -m pytest /app/tests/backend/ /app/tests/analysis/ -v -p no:django ``` +## CI/CD + +GitHub Actions runs automatically on every PR and push to `main`: + +| Workflow | Trigger | What it does | +|---|---|---| +| **CI** (`ci.yml`) | PR / push to `main` | Runs all unit tests — backend, analysis, and frontend | +| **Docker** (`docker.yml`) | Push to `main` | Builds and pushes images to GHCR | +| **Release** (`release.yml`) | Push a `v*` tag | Creates a GitHub Release with auto-generated notes | + +To cut a release: +```bash +git tag v1.0.0 && git push origin v1.0.0 +``` + ## Running the Simulation ### Interactive mode (frontend + backend) From d29a0ef27a3c2a74947c9a7497ebe4eeb2a45864 Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 21:56:28 -0700 Subject: [PATCH 2/7] Fix frontend CI: install only frontend requirements to avoid anyio/typing-extensions conflict The root requirements.txt pulls in openai which depends on anyio>=3.5, which in turn requires typing_extensions>=4.4. The frontend requirements.txt pins typing-extensions==4.0.0, causing an ImportError at pytest startup. Frontend tests only use django.test so they only need the frontend requirements plus pytest/pytest-django. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9d985a..0785a80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,14 +37,12 @@ jobs: with: python-version: "3.9.12" cache: pip - cache-dependency-path: | - requirements.txt - environment/frontend_server/requirements.txt + cache-dependency-path: environment/frontend_server/requirements.txt - name: Install dependencies run: | - pip install -r requirements.txt pip install -r environment/frontend_server/requirements.txt + pip install pytest==8.1.1 pytest-django==4.8.0 - name: Run tests run: python -m pytest tests/frontend/ -v From 835205e019a70aaf20dc992ca6e3220b1f8a20f8 Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 21:59:01 -0700 Subject: [PATCH 3/7] Add missing psutil dependency to frontend requirements views.py imports psutil but it was only in the root requirements.txt, not in environment/frontend_server/requirements.txt. This caused the frontend CI job to fail with ModuleNotFoundError. Co-Authored-By: Claude Sonnet 4.6 --- environment/frontend_server/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/environment/frontend_server/requirements.txt b/environment/frontend_server/requirements.txt index c7679c5..90f81bc 100644 --- a/environment/frontend_server/requirements.txt +++ b/environment/frontend_server/requirements.txt @@ -34,6 +34,7 @@ packaging==23.0 pandas==1.1.5 patsy==0.5.3 Pillow==8.4.0 +psutil==7.0.0 psycopg2-binary==2.9.5 pycparser==2.21 pyparsing==3.0.6 From 3cb40d4839caa5117b5088ab9aa1680bdd27bcf8 Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 22:01:53 -0700 Subject: [PATCH 4/7] Move test deps into frontend requirements.txt; remove hardcoded versions from CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pytest and pytest-django belong in environment/frontend_server/requirements.txt as proper project dependencies, not hardcoded in the workflow YAML. The CI workflow now just installs the requirements file — version updates only need to happen in one place. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 4 +--- environment/frontend_server/requirements.txt | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0785a80..cdb3c75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,9 +40,7 @@ jobs: cache-dependency-path: environment/frontend_server/requirements.txt - name: Install dependencies - run: | - pip install -r environment/frontend_server/requirements.txt - pip install pytest==8.1.1 pytest-django==4.8.0 + run: pip install -r environment/frontend_server/requirements.txt - name: Run tests run: python -m pytest tests/frontend/ -v diff --git a/environment/frontend_server/requirements.txt b/environment/frontend_server/requirements.txt index 90f81bc..fc9375d 100644 --- a/environment/frontend_server/requirements.txt +++ b/environment/frontend_server/requirements.txt @@ -36,6 +36,8 @@ patsy==0.5.3 Pillow==8.4.0 psutil==7.0.0 psycopg2-binary==2.9.5 +pytest==8.1.1 +pytest-django==4.8.0 pycparser==2.21 pyparsing==3.0.6 PySocks==1.7.1 From f04532c10440d9a4a3d261140b28266c82ad4be1 Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 22:04:04 -0700 Subject: [PATCH 5/7] Pin Python version via .python-version file; remove hardcoded version from CI Replace hardcoded python-version: "3.9.12" in both CI jobs with python-version-file: .python-version. The .python-version file is the single source of truth for the Python version, recognised by pyenv, actions/setup-python, and other tooling. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 4 ++-- .python-version | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .python-version diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdb3c75..5c7c04e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.9.12" + python-version-file: .python-version cache: pip cache-dependency-path: requirements.txt @@ -35,7 +35,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.9.12" + python-version-file: .python-version cache: pip cache-dependency-path: environment/frontend_server/requirements.txt diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..78c9a28 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.9.12 From afa766557b7e8df0158bf8a247abc5e2a194a579 Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 22:08:10 -0700 Subject: [PATCH 6/7] Add CI badge to README Co-Authored-By: Claude Sonnet 4.6 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 432e07d..49fe802 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # EDsim: An LLM-Powered Emergency Department Simulation Using Generative Agents +[![CI](https://github.com/denoslab/EDSim/actions/workflows/ci.yml/badge.svg)](https://github.com/denoslab/EDSim/actions/workflows/ci.yml) + EDsim is a multi-agent simulation of emergency department (ED) workflows driven by large language model (LLM)-powered autonomous agents. Each agent (doctors, nurses, patients) perceives its environment, makes decisions through cognitive modules, and interacts with other agents in real time, producing realistic ED dynamics suitable for operational analysis and research. ## Table of Contents From 953f1d1e024ec962f2561961b254591c299d1b5c Mon Sep 17 00:00:00 2001 From: Steve Drew Date: Tue, 3 Mar 2026 22:10:18 -0700 Subject: [PATCH 7/7] Standardise capitalisation: EDsim -> EDSim throughout Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 2 +- README.md | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ef0ee3e..2fb2484 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -EDsim is an LLM-powered multi-agent simulation of emergency department (ED) workflows. It builds on the [Generative Agents](https://arxiv.org/abs/2304.03442) framework (Park et al., 2023). Four agent types — Doctor, Bedside Nurse, Triage Nurse, and Patient — perceive their environment, plan actions, converse with each other, and execute behaviors driven by LLM calls. +EDSim is an LLM-powered multi-agent simulation of emergency department (ED) workflows. It builds on the [Generative Agents](https://arxiv.org/abs/2304.03442) framework (Park et al., 2023). Four agent types — Doctor, Bedside Nurse, Triage Nurse, and Patient — perceive their environment, plan actions, converse with each other, and execute behaviors driven by LLM calls. ## Environment Setup diff --git a/README.md b/README.md index 49fe802..dad10c0 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# EDsim: An LLM-Powered Emergency Department Simulation Using Generative Agents +# EDSim: An LLM-Powered Emergency Department Simulation Using Generative Agents [![CI](https://github.com/denoslab/EDSim/actions/workflows/ci.yml/badge.svg)](https://github.com/denoslab/EDSim/actions/workflows/ci.yml) -EDsim is a multi-agent simulation of emergency department (ED) workflows driven by large language model (LLM)-powered autonomous agents. Each agent (doctors, nurses, patients) perceives its environment, makes decisions through cognitive modules, and interacts with other agents in real time, producing realistic ED dynamics suitable for operational analysis and research. +EDSim is a multi-agent simulation of emergency department (ED) workflows driven by large language model (LLM)-powered autonomous agents. Each agent (doctors, nurses, patients) perceives its environment, makes decisions through cognitive modules, and interacts with other agents in real time, producing realistic ED dynamics suitable for operational analysis and research. ## Table of Contents @@ -18,7 +18,7 @@ EDsim is a multi-agent simulation of emergency department (ED) workflows driven ## Architecture Overview -EDsim consists of three main components: +EDSim consists of three main components: ### Backend Simulation Engine (`reverie/`) @@ -54,8 +54,8 @@ Post-simulation scripts that compute operational metrics from the simulation out 2. Clone this repository: ```bash - git clone EDsim - cd EDsim + git clone EDSim + cd EDSim ``` 3. Create and activate the Conda environment: @@ -107,7 +107,7 @@ Post-simulation scripts that compute operational metrics from the simulation out ## Running the Simulation -There are two ways to run EDsim: **interactive mode** (with the frontend visualization) and **batch mode** (headless, using `run_simulation.py`). +There are two ways to run EDSim: **interactive mode** (with the frontend visualization) and **batch mode** (headless, using `run_simulation.py`). --- @@ -280,14 +280,14 @@ Patient times in both area and state are also exported as separate CSV files alo ## Acknowledgments -EDsim builds on the **Generative Agents** framework by Park et al. (Stanford/Google): +EDSim builds on the **Generative Agents** framework by Park et al. (Stanford/Google): > Joon Sung Park, Joseph C. O'Brien, Carrie J. Cai, Meredith Ringel Morris, Percy Liang, and Michael S. Bernstein. 2023. *Generative Agents: Interactive Simulacra of Human Behavior.* In Proceedings of the 36th Annual ACM Symposium on User Interface Software and Technology (UIST '23). ACM. > ## Citation -If you use EDsim in your research, please cite: +If you use EDSim in your research, please cite: ```bibtex @misc{wu2026edsim,