# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from __future__ import annotations

from typing import Dict, Union, Iterable
from typing_extensions import Literal, Required, TypeAlias, TypedDict

from ..._types import SequenceNotStr

__all__ = [
    "LibraryScreenStartParams",
    "Molecule",
    "Target",
    "TargetEntity",
    "TargetEntityModification",
    "TargetEntityModificationCcdModification",
    "TargetEntityModificationSmilesModification",
    "MoleculeFilters",
    "MoleculeFiltersCustomFilter",
    "MoleculeFiltersCustomFilterLipinskiFilter",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilter",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterFractionCsp3",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterMolLogp",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterMolWt",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterNumAromaticRings",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHAcceptors",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHDonors",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHeteroatoms",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterNumRings",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterNumRotatableBonds",
    "MoleculeFiltersCustomFilterRdkitDescriptorFilterTpsa",
    "MoleculeFiltersCustomFilterSmartsCustomFilter",
    "MoleculeFiltersCustomFilterSmartsCatalogFilter",
    "MoleculeFiltersCustomFilterSmilesRegexFilter",
]


class LibraryScreenStartParams(TypedDict, total=False):
    molecules: Required[Iterable[Molecule]]
    """List of small molecules to screen."""

    target: Required[Target]
    """Target protein with binding pocket for small molecule design or screening"""

    idempotency_key: str
    """Client-provided key to prevent duplicate submissions on retries"""

    molecule_filters: MoleculeFilters
    """Molecule filtering configuration.

    Controls both Boltz built-in SMARTS filtering and custom filters.
    """

    workspace_id: str
    """Target workspace ID (admin keys only; ignored for workspace keys)"""


class Molecule(TypedDict, total=False):
    """A small molecule with SMILES and optional ID"""

    smiles: Required[str]
    """SMILES string of the molecule"""

    id: str
    """Optional identifier for this molecule"""


class TargetEntityModificationCcdModification(TypedDict, total=False):
    residue_index: Required[int]
    """0-based index of the residue to modify"""

    type: Required[Literal["ccd"]]

    value: Required[str]
    """CCD code from RCSB PDB (e.g.

    'MSE' for selenomethionine, 'SEP' for phosphoserine)
    """


class TargetEntityModificationSmilesModification(TypedDict, total=False):
    residue_index: Required[int]
    """0-based index of the residue to modify"""

    type: Required[Literal["smiles"]]

    value: Required[str]
    """SMILES string for the modification"""


TargetEntityModification: TypeAlias = Union[
    TargetEntityModificationCcdModification, TargetEntityModificationSmilesModification
]


class TargetEntity(TypedDict, total=False):
    chain_ids: Required[SequenceNotStr[str]]
    """Chain IDs for this entity"""

    modifications: Required[Iterable[TargetEntityModification]]
    """Post-translational modifications"""

    type: Required[Literal["protein"]]

    value: Required[str]
    """Amino acid sequence (one-letter codes)"""

    cyclic: bool
    """Whether the sequence is cyclic"""


class Target(TypedDict, total=False):
    """Target protein with binding pocket for small molecule design or screening"""

    entities: Required[Iterable[TargetEntity]]
    """Protein entities defining the target structure.

    Each entity represents a protein chain.
    """

    pocket_residues: Dict[str, Iterable[int]]
    """Binding pocket residues, keyed by chain ID.

    Each key is a chain ID (e.g. "A") and the value is an array of 0-indexed residue
    indices that define the binding pocket on that chain. When provided, these
    residues guide pocket extraction. When omitted, the model auto-detects the
    pocket.
    """

    reference_ligands: SequenceNotStr[str]
    """
    Reference ligands as SMILES strings that help the model identify the binding
    pocket. When omitted, a set of drug-like default ligands is used for pocket
    detection.
    """


class MoleculeFiltersCustomFilterLipinskiFilter(TypedDict, total=False):
    """Lipinski's Rule of Five filter.

    Rejects molecules that violate drug-likeness criteria based on molecular weight, LogP, hydrogen bond donors, and hydrogen bond acceptors.
    """

    max_hba: Required[float]
    """Maximum number of hydrogen bond acceptors. Lipinski threshold: 10"""

    max_hbd: Required[float]
    """Maximum number of hydrogen bond donors. Lipinski threshold: 5"""

    max_logp: Required[float]
    """Maximum LogP. Lipinski threshold: 5"""

    max_mw: Required[float]
    """Maximum molecular weight (Da). Lipinski threshold: 500"""

    type: Required[Literal["lipinski_filter"]]

    allow_single_violation: bool
    """If true, one rule violation is allowed (classic Rule of Five).

    Defaults to false (all rules must pass).
    """


class MoleculeFiltersCustomFilterRdkitDescriptorFilterFractionCsp3(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterMolLogp(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterMolWt(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterNumAromaticRings(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHAcceptors(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHDonors(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHeteroatoms(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterNumRings(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterNumRotatableBonds(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilterTpsa(TypedDict, total=False):
    """Min/max range constraint for an RDKit molecular descriptor"""

    max: float
    """Maximum allowed value (inclusive)"""

    min: float
    """Minimum allowed value (inclusive)"""


class MoleculeFiltersCustomFilterRdkitDescriptorFilter(TypedDict, total=False):
    """Filter molecules by RDKit molecular descriptors.

    Each descriptor is constrained to a min/max range. Only descriptors you provide are checked — omitted descriptors are unconstrained.
    """

    type: Required[Literal["rdkit_descriptor_filter"]]

    fraction_csp3: MoleculeFiltersCustomFilterRdkitDescriptorFilterFractionCsp3
    """Min/max range constraint for an RDKit molecular descriptor"""

    mol_logp: MoleculeFiltersCustomFilterRdkitDescriptorFilterMolLogp
    """Min/max range constraint for an RDKit molecular descriptor"""

    mol_wt: MoleculeFiltersCustomFilterRdkitDescriptorFilterMolWt
    """Min/max range constraint for an RDKit molecular descriptor"""

    num_aromatic_rings: MoleculeFiltersCustomFilterRdkitDescriptorFilterNumAromaticRings
    """Min/max range constraint for an RDKit molecular descriptor"""

    num_h_acceptors: MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHAcceptors
    """Min/max range constraint for an RDKit molecular descriptor"""

    num_h_donors: MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHDonors
    """Min/max range constraint for an RDKit molecular descriptor"""

    num_heteroatoms: MoleculeFiltersCustomFilterRdkitDescriptorFilterNumHeteroatoms
    """Min/max range constraint for an RDKit molecular descriptor"""

    num_rings: MoleculeFiltersCustomFilterRdkitDescriptorFilterNumRings
    """Min/max range constraint for an RDKit molecular descriptor"""

    num_rotatable_bonds: MoleculeFiltersCustomFilterRdkitDescriptorFilterNumRotatableBonds
    """Min/max range constraint for an RDKit molecular descriptor"""

    tpsa: MoleculeFiltersCustomFilterRdkitDescriptorFilterTpsa
    """Min/max range constraint for an RDKit molecular descriptor"""


class MoleculeFiltersCustomFilterSmartsCustomFilter(TypedDict, total=False):
    """Filter molecules by custom SMARTS patterns.

    Molecules matching any pattern are rejected.
    """

    patterns: Required[SequenceNotStr[str]]
    """SMARTS patterns. Molecules matching any pattern are rejected."""

    type: Required[Literal["smarts_custom_filter"]]


class MoleculeFiltersCustomFilterSmartsCatalogFilter(TypedDict, total=False):
    """Filter molecules using a predefined SMARTS catalog of structural alerts."""

    catalog: Required[
        Literal[
            "PAINS",
            "PAINS_A",
            "PAINS_B",
            "PAINS_C",
            "BRENK",
            "CHEMBL",
            "CHEMBL_BMS",
            "CHEMBL_Dundee",
            "CHEMBL_Glaxo",
            "CHEMBL_Inpharmatica",
            "CHEMBL_LINT",
            "CHEMBL_MLSMR",
            "CHEMBL_SureChEMBL",
            "NIH",
        ]
    ]
    """Predefined SMARTS catalog to apply.

    PAINS, BRENK, ChEMBL, and NIH catalogs reject known problematic substructures.
    """

    type: Required[Literal["smarts_catalog_filter"]]


class MoleculeFiltersCustomFilterSmilesRegexFilter(TypedDict, total=False):
    """Filter molecules by regex patterns on their SMILES representation."""

    patterns: Required[SequenceNotStr[str]]
    """Regex patterns applied to SMILES strings.

    Molecules matching any pattern are rejected.
    """

    type: Required[Literal["smiles_regex_filter"]]


MoleculeFiltersCustomFilter: TypeAlias = Union[
    MoleculeFiltersCustomFilterLipinskiFilter,
    MoleculeFiltersCustomFilterRdkitDescriptorFilter,
    MoleculeFiltersCustomFilterSmartsCustomFilter,
    MoleculeFiltersCustomFilterSmartsCatalogFilter,
    MoleculeFiltersCustomFilterSmilesRegexFilter,
]


class MoleculeFilters(TypedDict, total=False):
    """Molecule filtering configuration.

    Controls both Boltz built-in SMARTS filtering and custom filters.
    """

    boltz_smarts_catalog_filter_level: Literal["recommended", "extra", "aggressive", "disabled"]
    """
    Controls the stringency of Boltz's built-in SMARTS structural alert filtering,
    which removes molecules matching known problematic substructures. 'recommended'
    (default): applies a curated set of alerts balancing safety and hit rate.
    'extra': adds additional alerts beyond the recommended set for stricter
    filtering. 'aggressive': applies the most comprehensive alert set — may reject
    viable molecules. 'disabled': turns off Boltz SMARTS filtering entirely; only
    custom_filters will be applied.
    """

    custom_filters: Iterable[MoleculeFiltersCustomFilter]
    """Custom filters to apply. Molecules must pass all filters (AND logic)."""
