Skip to main content

Client Agents API

Client agents simulate patients in therapy conversations.

Available Clients

ClientKeyDescription
SAPSsapsState-aware medical patient
ConsistentMIconsistentMIMI client with stage transitions (ACL 2025)
EeyoreeeyoreDepression simulation (ACL 2025)
AnnaAgentannaAgentMulti-session with memory (ACL 2025)
AdaptiveVPadaptiveVPNurse training simulation (ACL 2025)
SimPatientsimPatientCognitive model updates (CHI 2025)
TalkDeptalkDepDepression screening (CIKM 2025)
ClientCastclientCastPsychotherapy assessment
PsychepsychePsychiatric assessment
PatientPsipatientPsiCBT-focused patient (EMNLP 2024)
RoleplayDohroleplayDohPrinciple-based simulation (EMNLP 2024)
UseruserHuman input client

Loading a Client

from omegaconf import OmegaConf
from patienthub.clients import get_client

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

client = get_client(configs=config, lang='en')

Client Interface

All clients implement the ChatAgent abstract base class:

from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Type
from pydantic import BaseModel

class ChatAgent(ABC):
chat_model: Any
data: Dict[str, Any]
messages: List[str] | List[Dict[str, Any]]
lang: str

@abstractmethod
def generate(
self,
messages: List[str] | List[Dict[str, Any]],
response_format: Optional[Type[BaseModel]] = None,
) -> BaseModel | str:
"""Generate a response based on the input messages."""
pass

@abstractmethod
def generate_response(self, msg: str) -> BaseModel:
"""Generate response to a single therapist message."""
pass

@abstractmethod
def set_therapist(
self,
therapist: Dict[str, Any],
prev_sessions: List[Dict[str, str]] | None = None
):
"""Set the therapist for the session."""
pass

@abstractmethod
def reset(self) -> None:
"""Reset the client to its initial state."""
pass

Configuration Options

Common Options

OptionTypeDefaultDescription
agent_typestrrequiredClient type identifier
model_typestr"OPENAI"Model provider key (used to read ${MODEL_TYPE}_API_KEY / ${MODEL_TYPE}_BASE_URL)
model_namestr"gpt-4o"Model identifier
temperaturefloat0.7Sampling temperature (0-1)
max_tokensint8192Max response tokens
max_retriesint3API retry attempts
data_pathstrvariesPath to character JSON file
data_idxint0Index of character in file
langstr"en"Language code

Response Format

Most clients return a structured response:

from pydantic import BaseModel, Field

class Response(BaseModel):
content: str = Field(
description="The content of the patient's response"
)

Some clients include additional fields:

# PatientPsi response
class Response(BaseModel):
content: str
# Internal reasoning (not shown to therapist)

# ConsistentMI response
class Response(BaseModel):
content: str
action: str # Selected action type

Example: Comparing Clients

from patienthub.clients import get_client, CLIENT_REGISTRY
from omegaconf import OmegaConf

base_config = {
'model_type': 'OPENAI',
'model_name': 'gpt-4o',
'temperature': 0.7,
'max_tokens': 8192,
'max_retries': 3,
}

test_message = "How have you been feeling lately?"

data_paths = {
'saps': 'data/characters/SAPS.json',
'talkDep': 'data/characters/talkDep.json',
'psyche': 'data/characters/Psyche.json',
}

for agent_type in ['saps', 'talkDep', 'psyche']:
config = OmegaConf.create({
**base_config,
'agent_type': agent_type,
'data_path': data_paths[agent_type],
'data_idx': 0,
})
try:
client = get_client(configs=config, lang='en')
client.set_therapist({'name': 'Therapist'})
response = client.generate_response(test_message)
print(f"\n=== {agent_type} ===")
print(response.content[:200] + "..." if len(response.content) > 200 else response.content)
except Exception as e:
print(f"\n=== {agent_type} === Error: {e}")

Listing Available Clients

from patienthub.clients import CLIENT_REGISTRY, CLIENT_CONFIG_REGISTRY

# List all client types
print("Available clients:", list(CLIENT_REGISTRY.keys()))

# Get config class for a client
config_class = CLIENT_CONFIG_REGISTRY['patientPsi']
print(config_class)

Data Format

  • Prompt Data is stored in data/prompts.
  • Character data is stored in files under data/characters
  • Each file is a JSON list; data_idx selects the entry to be simulated

By Focus Area

Depression & Mood Disorders

  • Eeyore: Realistic depression simulation with expert validation
  • TalkDep: Clinically grounded personas for depression screening

Motivational Interviewing

  • ConsistentMI: Stage-of-change model with consistent behavior
  • SimPatient: Cognitive model with internal state tracking

General Psychotherapy

  • PatientPsi: CBT-focused with cognitive distortions
  • RoleplayDoh: Domain-expert created principles
  • ClientCast: Assessment-focused simulation

Specialized Training

  • AdaptiveVP: Nurse communication training
  • SAPS: Medical diagnosis training
  • Psyche: Psychiatric assessment training