Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b261263
Add all top-level DSM categories to dsm.yaml
hermaplusplus Feb 5, 2026
656c161
Add config and hide navbar
hermaplusplus Feb 5, 2026
43ae775
Set up homepage
hermaplusplus Feb 5, 2026
fec2d65
Add page router config
hermaplusplus Feb 5, 2026
83907d0
Add simple placeholder page
hermaplusplus Feb 5, 2026
76b0f48
Add ADHD page and data
hermaplusplus Feb 5, 2026
8ff5ee2
Add Docker configs
hermaplusplus Feb 5, 2026
c43f08e
Add Docker compose file
hermaplusplus Feb 5, 2026
557d28b
Update routing logic
hermaplusplus Feb 5, 2026
6318d0e
Update Docker container name
hermaplusplus Feb 5, 2026
db1014f
Add util module
hermaplusplus Feb 5, 2026
c2f0597
Update readme
hermaplusplus Feb 5, 2026
088e741
Update homepage
hermaplusplus Feb 5, 2026
8a92c06
Rewrite ADHD text file
hermaplusplus Feb 6, 2026
4bfe706
Add homepage info
hermaplusplus Feb 6, 2026
edf0d61
Add extra toggles and information to ADHD page
hermaplusplus Feb 6, 2026
f2db384
Add return buttons and footer to simple template page
hermaplusplus Feb 6, 2026
2b3d56c
Fix git branch except result
hermaplusplus Feb 6, 2026
aa93e70
Add commit info and styles to footer
hermaplusplus Feb 6, 2026
504d14f
Make go button green
hermaplusplus Feb 6, 2026
8c563c5
Add start script and parameters to Docker files
hermaplusplus Feb 6, 2026
ddf3093
Update text on home and ADHD pages
hermaplusplus Feb 6, 2026
24078cc
Fix git branch and commit display
hermaplusplus Feb 6, 2026
875afdf
Update default state for specifier toggles
hermaplusplus Feb 11, 2026
c5f492f
Add WIP disclaimer
hermaplusplus Feb 11, 2026
4bf5e93
Remove leftover comments on main page
hermaplusplus Feb 11, 2026
e11058e
Split PTSD into o6 and u6 due to different criteria
hermaplusplus Feb 11, 2026
5930477
Add PTSD o6 page and content
hermaplusplus Feb 11, 2026
66e2c8c
Fix ADHD specifier toggles not removing data from output
hermaplusplus Feb 11, 2026
1c101ae
Fix wrong env var get in footer
hermaplusplus Feb 11, 2026
565cb44
Update README
hermaplusplus Feb 11, 2026
bf165d8
Add more information to README
hermaplusplus Feb 11, 2026
3719829
Merge branch 'main' into dev
hermaplusplus Feb 11, 2026
ef2ee6b
Delete dsm.yaml
hermaplusplus Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.venv
.uv
__pycache__
*.pyc
2 changes: 2 additions & 0 deletions .streamlit/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[client]
showSidebarNavigation = false
36 changes: 36 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Use the official uv image for the binary
FROM ghcr.io/astral-sh/uv:latest AS uv_bin

# Use the official Python 3.13 slim image
FROM python:3.13-slim

# Declare build-time arguments
ARG GIT_BRANCH
ARG GIT_COMMIT

# Set them as environment variables so the app can see them
ENV APP_GIT_BRANCH=$GIT_BRANCH
ENV APP_GIT_COMMIT=$GIT_COMMIT

# Copy uv binaries
COPY --from=uv_bin /uv /uvx /bin/

WORKDIR /app

# Enable bytecode compilation for faster startup in Python 3.13
ENV UV_COMPILE_BYTECODE=1

# Copy lockfiles
COPY pyproject.toml uv.lock ./

# Install dependencies
# We use --system because we are inside a dedicated container
RUN uv pip install --system --no-cache -r pyproject.toml

# Copy the rest of your router app
COPY . .

EXPOSE 8501

# Entrypoint remains the same
ENTRYPOINT ["streamlit", "run", "main.py", "--server.port=8501", "--server.address=0.0.0.0"]
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
# Arwen
DSM-5 Diagnostic Criteria aggregator and formatter for EHRs

## About

**Arwen DCA** is designed to help clinicians aggregate diagnostic criteria based on the structure found in the DSM-5-TR.

> [!CAUTION]
> This is **not** a diagnostic tool and should not be used as such. Clinicians should always use their own judgement and verify that criteria and codes are correct.

Clincians can select all diagnostic criteria that apply to their patient/client and the tool will output a list of criteria met formatted in a way that can be easily copied into an EHR or note (including systems which parse criteria to :sparkles: automagically* :sparkles: create a note)

The tool does **not store any data** that is submitted and **does not allow the input of any PHI**. When a user refreshes a page or navigates away, all data is irrevocably lost.

This project is open source and available on [GitHub](https://github.com/hermaplusplus/Arwen). It is provided under the [MIT License](https://github.com/hermaplusplus/Arwen/blob/main/LICENSE). Contributions, issue reports, feedback, and suggestions are welcome.

<sub>Why is the tool called 'Arwen'? I watched Lord of the Rings recently. That's it.</sub>

<sub>* Automagically, meaning using a Large Language Model.</sub>

## Development

Arwen uses [uv](https://docs.astral.sh/uv/) as a package manager and [Docker Compose](https://docs.docker.com/compose/) for containerisation. To run the project, make sure you have these installed, as well as Python 3.11+.

To activate the virtual environment, run the appropriate (for your system) script under `./.venv/Scripts/`.

To run the project during development, run `streamlit run main.py`.

To deploy the project in production, run `./start.sh`.
36 changes: 36 additions & 0 deletions data/adhd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
A: "A persistent pattern of inattention and/or hyperactivityimpulsivity that interferes with functioning or development, as characterized by (1) and/or (2):"
A1: "Inattention: Six (or more) of the following symptoms have persisted for at least 6 months to a degree that is inconsistent with developmental level and that negatively impacts directly on social and academic/occupational activities:"
A1note: "Note: The symptoms are not solely a manifestation of oppositional behavior, defiance, hostility, or failure to understand tasks or instructions. For older adolescents ad adults (age 17 and older), at least five symptoms are required."
A1a: "Fails to give close attention to detail, makes careless mistakes, overlooks or misses details, work is inaccurate."
A1b: "Difficulty focusing."
A1c: "Does not seem to listen when spoken to directly, even in the absence of any obvious distraction."
A1d: "Struggles to follow through on instructions and fails to finish tasks, starts tasks but quickly loses focus and is easily sidetracked."
A1e: "Difficulty organizing tasks and activities, difficulty managing sequential tasks, difficulty keeping materials and belongings in order, messy, disorganized work, has poor time management, fails to meet deadlines."
A1f: "Avoids, dislikes, or is reluctant to engage in tasks that require sustained mental effort."
A1g: "Loses things necessary for tasks or activities."
A1h: "Easily distracted by extraneous stimuli."
A1i: "Forgetful in daily activities."
A2: "Hyperactivity and Impulsivity: Six (or more) of the following symptoms have persisted for at least 6 months to a degree that is inconsistent with developmental level and that negatively impacts directly on social and academic/occupational activities:"
A2note: "Note: The symptoms are not solely a manifestation of oppositional behavior, defiance, hostility, or failure to understand tasks or instructions. For older adolescents ad adults (age 17 and older), at least five symptoms are required."
A2a: "Fidgets with or taps hands or feet or squirms in seat."
A2b: "Leaves seat in situations when remaining seated is expected."
A2c: "Feeling restless."
A2d: "Unable to play or engage in leisure activities quietly."
A2e: "Is often 'on the go,' acting as if 'driven by a motor'."
A2f: "Talks excessively."
A2g: "Blurts out an answer before a question has been completed, completes people's sentences, cannot wait for turn in conversation."
A2h: "Difficulty waiting his or her turn."
A2i: "Interrupts or intrudes on others, butts into conversations, games, or activities, may start using other people's things without asking or receiving permission, may intrude into or take over what others are doing."
B: "Several inattentive or hyperactive-impulsive symptoms were present prior to age 12 years."
C: "Several inattentive or hyperactive-impulsive symptoms are present in two or more settings (e.g., at home, school, or work; with friends or relatives; in other activities)."
D: "There is clear evidence that the symptoms interfere with, or reduce the quality of, social, academic, or occupational functioning."
E: "The symptoms do not occur exclusively during the course of schizophrenia or another psychotic disorder and are not better explained by another mental disorder (e.g., mood disorder, anxiety disorder, dissociative disorder, personality disorder, substance intoxication or withdrawal)."
S1a: "Both inattentive and hyperactive-impulsive presentation: If both Criterion A1 and Criterion A2 are met for the past 6 months."
S1b: "Predominantly inattentive presentation: If Criterion A1 is met but Criterion A2 is not met for the past 6 months."
S1c: "Predominantly hyperactive-impulsive presentation: If Criterion A2 is met but Criterion A1 is not met for the past 6 months."
S2: "In partial remission: Full criteria were previously met, but symptoms currently do not meet full criteria, and the symptoms that are present cause clinically significant impairment in social, academic, or occupational functioning."
S3a: "Mild: Few, if any, symptoms in excess of those required to make the diagnosis are present, and symptoms result in no more than mild impairment in social or occupational functioning."
S3b: "Moderate: Symptoms or functional impairment between 'mild' and 'severe' are present."
S3c: "Severe: Many symptoms in excess of those required to make the diagnosis, or several symptoms that are particularly severe, are present, and symptoms result in marked impairment in social or occupational functioning."
S1: none # key only
S3: none # key only
42 changes: 42 additions & 0 deletions data/ptsd-o6.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Note: "The following criteria apply to adults, adolescents, and children older than 6 years. For children 6 years and younger, return to the homepage and select :green[Post-Traumatic Stress Disorder in Children 6 Years and Younger]."
A: "Exposure to actual or threatened death, serious injury, or sexual violence in one (or more) of the following ways:"
A1: "Directly experiencing the traumatic event(s)."
A2: "Witnessing, in person, the event(s) as it occurred to others."
A3: "Learning that the traumatic event(s) occurred to a close family member or close friend. In cases of actual or threatened death of a family member or friend, the event(s) must have been violent or accidental."
A4: "Experiencing repeated or extreme exposure to aversive details of the traumatic event(s) (e.g., first responders collecting human remains; police officers repeatedlyexposed to details of child abuse)."
A4note: "Note: Criterion A4 does not apply to exposure through electronic media, television, movies, or pictures, unless this exposure is work related."
B: "Presence of one (or more) of the following intrusion symptoms associated with the traumatic event(s), beginning after the traumatic event(s) occurred:"
B1: "Recurrent, involuntary, and intrusive distressing memories of the traumatic event(s)."
B1note: "Note: In children older than 6 years, repetitive play may occur in which themes or aspects of the traumatic event(s) are expressed."
B2: "Recurrent distressing dreams in which the content and/or affect of the dream are related to the traumatic event(s)."
B2note: "Note: In children, there may be frightening dreams without recognizable content."
B3: "Dissociative reactions (e.g., flashbacks) in which the individual feels or acts as if the traumatic event(s) were recurring. (Such reactions may occur on a continuum, with the most extreme expression being a complete loss of awareness of present surroundings.)"
B3note: "Note: In children, trauma-specific reenactment may occur in play."
B4: "Intense or prolonged psychological distress at exposure to internal or external cues that symbolize or resemble an aspect of the traumatic event(s)."
B5: "Marked physiological reactions to internal or external cues that symbolize or resemble an aspect of the traumatic event(s)."
C: "Persistent avoidance of stimuli associated with the traumatic event(s), beginning after the traumatic event(s) occurred, as evidenced by one or both of the following:"
C1: "Avoidance of or efforts to avoid distressing memories, thoughts, or feelings about or closely associated with the traumatic event(s)."
C2: "Avoidance of or efforts to avoid external reminders (people, places, conversations, activities, objects, situations) that arouse distressing memories, thoughts, or feelings about or closely associated with the traumatic event(s)."
D: "Negative alterations in cognitions and mood associated with the traumatic event(s), beginning or worsening after the traumatic event(s) occurred, as evidenced by two (or more) of the following:"
D1: "Inability to remember an important aspect of the traumatic event(s) (typically due to dissociative amnesia and not to other factors such as head injury, alcohol, or drugs)."
D2: "Persistent and exaggerated negative beliefs or expectations about oneself, others, or the world (e.g., 'I am bad,' 'No one can be trusted,' 'The world is completely dangerous', 'My whole nervous system is permanently ruined')."
D3: "Persistent, distorted cognitions about the cause or consequences of the traumatic event(s) that lead the individual to blame himself/herself or others."
D4: "Persistent negative emotional state (e.g., fear, horror, anger, guilt, or shame)."
D5: "Markedly diminished interest or participation in significant activities."
D6: "Feelings of detachment or estrangement from others."
D7: "Persistent inability to experience positive emotions (e.g., inability to experience happiness, satisfaction, or loving feelings)."
E: "Marked alterations in arousal and reactivity associated with the traumatic event(s), beginning or worsening after the traumatic event(s) occurred, as evidenced by two (or more) of the following:"
E1: "Irritable behavior and angry outbursts (with little or no provocation) typically expressed as verbal or physical aggression toward people or objects."
E2: "Reckless or self-destructive behavior."
E3: "Hypervigilance."
E4: "Exaggerated startle response."
E5: "Problems with concentration."
E6: "Sleep disturbance (e.g., difficulty falling or staying asleep or restless sleep)."
F: "Duration of the disturbance (Criteria B, C, D, and E) is more than 1 month."
G: "The disturbance causes clinically significant distress or impairment in social, occupational, or other important areas of functioning."
H: "The disturbance is not attributable to the physiological effects of a substance (e.g., medication, alcohol) or another medical condition."
S1: "With dissociative symptoms: The individual's symptoms meet criteria for post-traumatic stress disorder, and in addition, in response to the stressor, the individual experiences persistent or recurrent symptoms of either of the following:"
S11: "Depersonalization: Persistent or recurrent experiences of feeling detached from, and as if one were an outside observer of, one's mental processes or body (e.g., feeling as though one were in a dream; feeling a sense of unreality of self or body or of time moving slowly)."
S12: "Derealization: Persistent or recurrent experiences of unreality of surroundings (e.g., the world around the individual is experienced as unreal, dreamlike, distant, or distorted)."
S1note: "Note: To use this subtype, the dissociative symptoms must not be attributable to the physiological effects of a substance (e.g., blacking out from alcohol intoxication) or another medical condition (e.g., complex partial seizures)."
S2: "With delayed expression: If the full diagnostic criteria are not met until at least 6 months after the event (although the onset and expression of some symptoms may be immediate)."
14 changes: 14 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
app:
build:
context: .
args:
- GIT_BRANCH=${GIT_BRANCH:-unknown}
- GIT_COMMIT=${GIT_COMMIT:-unknown}
container_name: arwen
ports:
- "8501:8501"
environment:
- PYTHONUNBUFFERED=1
- UV_COMPILE_BYTECODE=1
restart: always
Empty file removed dsm.yaml
Empty file.
43 changes: 40 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
import streamlit as st
import pyyaml
import yaml
from utils import add_clean_footer

st.set_page_config(page_title="Arwen DSM", layout="wide")
# Load data
with open("router.yaml", "r") as f:
data = yaml.safe_load(f)

st.title("Arwen DSM-5 Diagnostic Criteria Aggregator")
st.set_page_config(page_title="Arwen DCA", layout="centered")

st.title("Arwen Diagnostic Criteria Aggregator 📋🧝‍♀️🩺")

st.error("This is **not** a diagnostic tool and should not be used as such. Please read the **About** section below for more information.", icon="🚨")

st.error("This tool is work-in-progress. Some pages may not be fully functional yet or may contain errors.", icon="🚧")

st.markdown("Select a category and disorder, then press the button below to get started:")

cat = st.selectbox("Category", list(data.keys()))
dis = st.selectbox("Disorder", list(data[cat].keys()))

if st.button(":green[Open Diagnostic Criteria ->]"):
st.session_state.current_cat = cat
st.session_state.current_dis = dis
st.session_state.current_dis_page = data[cat][dis]["page_path"]
st.session_state.current_dis_data = data[cat][dis]["data_path"]

logic_type = data[cat][dis].get("logic", "simple")

if logic_type == "complex":
st.switch_page(st.session_state.current_dis_page)
else:
st.switch_page("pages/simple.py")

st.markdown("## About")
st.markdown("**Arwen DCA** is designed to help clinicians aggregate diagnostic criteria based on the structure found in the DSM-5-TR. :red[This is **not** a diagnostic tool and should not be used as such]. Clinicians should always use their own judgement and verify that criteria and codes are correct.")
st.markdown("Clincians can select all diagnostic criteria that apply to their patient/client and the tool will output a list of criteria met formatted in a way that can be easily copied into an EHR or note (including systems which parse criteria to :sparkles: :rainbow[automagically*] :sparkles: create a note)")
st.markdown("This website does :green[**not store any data**] that is submitted and :green[**does not allow the input of any PHI**]. When a user refreshes a page or navigates away, all data is irrevocably lost.")
st.markdown("This project is open source and available on [GitHub](https://github.com/hermaplusplus/Arwen). It is provided under the [MIT License](https://github.com/hermaplusplus/Arwen/blob/main/LICENSE). Contributions, issue reports, feedback, and suggestions are welcome.")
st.markdown(":grey[Why is the tool called 'Arwen'? I watched Lord of the Rings recently. That's it.]")
st.markdown(":grey[:small[* Automagically, meaning using a Large Language Model.]]")

add_clean_footer()
Loading