"""Builds an LLMonitor UserContextManager
    Parameters:
        - `user_id`: The user id.
        - `user_props`: The user properties.
    Returns:
        A context manager that sets the user context.
    """
    return UserContextManager(user_id, user_props)
def _serialize(obj: Any) -> Union[Dict[str, Any], List[Any], Any]:
    if hasattr(obj, "to_json"):
        return obj.to_json()
    if isinstance(obj, dict):
        return {key: _serialize(value) for key, value in obj.items()}
    if isinstance(obj, list):
        return [_serialize(element) for element in obj]
    return obj
def _parse_input(raw_input: Any) -> Any:
    if not raw_input:
        return None
    # if it's an array of 1, just parse the first element
    if isinstance(raw_input, list) and len(raw_input) == 1:
        return _parse_input(raw_input[0])
    if not isinstance(raw_input, dict):
        return _serialize(raw_input)
    input_value = raw_input.get("input")
    inputs_value = raw_input.get("inputs")
    question_value = raw_input.get("question")
    query_value = raw_input.get("query")
    if input_value:
        return input_value
    if inputs_value:
        return inputs_value
    if question_value:
        return question_value
    if query_value:
        return query_value
    return _serialize(raw_input)
def _parse_output(raw_output: dict) -> Any:
    if not raw_output:
        return None
    if not isinstance(raw_output, dict):
        return _serialize(raw_output)
    text_value = raw_output.get("text")