Skip to main content

Running Simulations

PatientHub provides multiple ways to run therapy session simulations.

CLI Simulation

The simplest approach uses the command-line interface:

patienthub simulate client=user therapist=eliza

Customize Components

# Specify client and therapist
patienthub simulate client=patientPsi therapist=basic

# Attach an evaluator (TherapySession runs it at the end of the session; see Evaluation guide)
patienthub simulate client=patientPsi therapist=basic evaluator=conv_judge

# Adjust session parameters
patienthub simulate event.max_turns=25 event.reminder_turn_num=5

patienthub simulate verbose=true

By default only warnings and errors are shown. Setting verbose=true enables DEBUG-level logging on the console and saves all logs to logs/simulate_<timestamp>.log.

Batch and Resuming

Set client.data_idx=-1 to run one session per character in the client's data file, and num_sessions=N to repeat each character N times. Each session writes its own output file, so resume=true skips sessions whose output already exists — re-run the same command to finish a batch that was interrupted:

patienthub simulate client=deprofile client.data_idx=-1 num_sessions=3 num_workers=4 resume=true

Python API

For programmatic control:

from patienthub.clients import get_client
from patienthub.events.therapySession import TherapySession
from patienthub.therapists import get_therapist
from omegaconf import OmegaConf

# Configure client
client_config = OmegaConf.create({
'agent_name': 'patientPsi',
'patient_type': 'upset',
'model_type': 'OPENAI',
'model_name': 'gpt-4o',
'temperature': 0.7,
'max_tokens': 1024,
'max_retries': 3,
'prompt_path': 'data/prompts/client/patientPsi.yaml',
'data_path': 'data/characters/patientPsi.json',
'data_idx': 0,
})

# Configure therapist
therapist_config = OmegaConf.create({
'agent_name': 'basic',
'model_type': 'OPENAI',
'model_name': 'gpt-4o',
'prompt_path': 'data/prompts/therapist/CBT.yaml',
'temperature': 0.7,
'max_tokens': 1024,
'max_retries': 3,
})

# Configure session
event_config = OmegaConf.create({
'max_turns': 20,
'reminder_turn_num': 5,
'output_dir': 'outputs/my_session.json',
})

# Load components
client = get_client(agent_name='patientPsi', configs=client_config, lang='en')
therapist = get_therapist(agent_name='basic', configs=therapist_config, lang='en')
event = TherapySession(configs=event_config)

# Set up session
event.set_characters({
'client': client,
'therapist': therapist,
'evaluator': None,
})

# Run simulation
event.start()

Manual Turn-by-Turn

For fine-grained control over each turn:

from patienthub.clients import get_client
from omegaconf import OmegaConf

config = OmegaConf.create({
'agent_name': 'patientPsi',
'patient_type': 'upset',
'model_type': 'OPENAI',
'model_name': 'gpt-4o',
'temperature': 0.7,
'max_tokens': 1024,
'max_retries': 3,
'data_path': 'data/characters/patientPsi.json',
'data_idx': 0,
})

client = get_client(agent_name='patientPsi', configs=config, lang='en')
client.set_therapist({'name': 'Therapist'})

# Simulate conversation
conversation = []
therapist_messages = [
"Hi, thanks for coming in today. What brings you here?",
"I see. Can you tell me more about that?",
"How does that make you feel?",
"What would you like to change about this situation?",
]

for msg in therapist_messages:
print(f"Therapist: {msg}")
conversation.append({'role': 'therapist', 'content': msg})
response = client.generate_response(msg)
print(f"Client: {response.content}\n")
conversation.append({'role': 'client', 'content': response.content})

# Save conversation
from patienthub.utils import save_json
save_json({'messages': conversation}, 'outputs/manual_session.json', overwrite=True)

Human-in-the-Loop

Use the user therapist for manual input:

patienthub simulate client=patientPsi therapist=user

Or in Python:

from omegaconf import OmegaConf
from patienthub.clients import get_client

config = OmegaConf.create({
'agent_name': 'eeyore',
'model_type': 'LOCAL',
'model_name': 'hosted_vllm//<MODEL_PATH>/Eeyore_llama3.1_8B',
'temperature': 0.7,
'max_tokens': 1024,
'max_retries': 3,
'data_path': 'data/characters/eeyore.json',
'data_idx': 0,
})

client = get_client(agent_name='eeyore', configs=config, lang='en')
client.set_therapist({'name': 'You'})

print("Type 'quit' to exit\n")
while True:
user_input = input("You: ")
if user_input.lower() == 'quit':
break

response = client.generate_response(user_input)
print(f"Client: {response.content}\n")

Session Events

The TherapySession event manages the simulation flow using a Burr state machine:

  1. init_session: Set up client and therapist
  2. generate_therapist_response: Get therapist's message
  3. generate_client_response: Get client's response
  4. check_and_remind: Notify about remaining turns
  5. end_session: Save session data

Session State

from typing import TypedDict, List, Dict, Any, Optional

class TherapySessionState(TypedDict):
messages: List[Dict[str, Any]] # Conversation history
msg: Optional[str] # Current message
num_turns: int
session_ended: bool
initialized: bool
needs_reminder: bool

Output Format

Sessions are saved as JSON:

{
"profile": {
"name": "Alex",
"id": "1-1"
},
"messages": [
{ "role": "therapist", "content": "Hello, how are you?" },
{ "role": "client", "content": "I've been feeling..." }
],
"num_turns": 15
}

Next Steps