File size: 4,215 Bytes
1a17418
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c3b49d6
1a17418
 
 
 
 
 
 
 
 
 
 
 
 
7177af3
 
 
 
 
 
 
 
 
 
 
 
 
 
49f5c84
 
 
 
7177af3
 
 
 
49f5c84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""
Constants for CodeAct agent.
"""

import os

# Available packages with descriptions
LIBRARY_CONTENT_DICT = {
    "numpy": "[Python Package] The fundamental package for scientific computing with Python, providing support for arrays, matrices, and mathematical functions.",
    "scipy": "[Python Package] A Python library for scientific and technical computing, including modules for optimization, linear algebra, integration, and statistics.",
}


def _load_system_prompt() -> str:
    """Load the system prompt template from prompts.yaml at the project root."""
    import yaml

    # core/constants.py lives at <root>/core/ (before move) or <root>/src/core/ (after move).
    # Two or three levels up is the project root in both cases.
    here = os.path.dirname(os.path.abspath(__file__))
    for levels in (1, 2):
        candidate = os.path.normpath(os.path.join(here, *[".."] * levels, "prompts.yaml"))
        if os.path.exists(candidate):
            with open(candidate, encoding="utf-8") as f:
                data = yaml.safe_load(f)
            return data["system_prompt"]
    raise FileNotFoundError("prompts.yaml not found relative to core/constants.py")


SYSTEM_PROMPT_TEMPLATE = _load_system_prompt()


# Standing decoupleR method limitations.
#
# This block is true of EVERY decoupleR run, so it is appended deterministically
# in code to the final solution — it is NOT generated by the model. The model is
# instructed (see prompts.yaml, Example 6 / Reporting Results) to write only
# run-specific caveats (sample sizes, contrast, exclusions). Keeping the standing
# text here guarantees it is byte-for-byte identical on every run and can never be
# softened or dropped.
#
# If the computation changes (PROGENy pathway count, default scoring model, or
# regulon source), update this text to match — it must describe what the pipeline
# actually does.
# The trailing half is identical on every path; only the sentence describing
# *what was scored* differs (see below).
_DISCLAIMER_TAIL = (
    "ULM p-values are liberal and scale "
    "with regulon size, so rank results by effect size rather than by how small "
    "padj is. PROGENy: 14-pathway model. Regulons: CollecTRI. These outputs "
    "require independent validation before any biological or clinical conclusion."
)

_DISCLAIMER_HEAD = "**Method limitations (decoupleR).** All TF and pathway values are *inferred* "

# Path-neutral wording. This is the block the workflow engine appends to every
# <solution>, where the scoring path taken during the run is not known — so it
# must be true of BOTH paths. Do not re-add the "derived from
# differential-expression statistics" clause here: that is false for the
# per-sample path (dataset_score_bulk_samples scores the expression matrix
# directly, without computing DE statistics first).
DECOUPLER_DISCLAIMER = (
    _DISCLAIMER_HEAD + "regulon/gene-set activities — not direct measurements of "
    "protein activity, nuclear localization, or pathway flux. " + _DISCLAIMER_TAIL
)

# DE-based enrichment tools (decoupler_tf_enrichment_collectri,
# decoupler_pathway_enrichment_progeny, decoupler_hallmark_enrichment): the ULM
# fit is over per-contrast DE statistics, so scores are contrast-level.
DECOUPLER_DISCLAIMER_DE = (
    _DISCLAIMER_HEAD + "regulon/gene-set activities derived from "
    "differential-expression statistics via the ULM model — not direct measurements "
    "of protein activity, nuclear localization, or pathway flux. " + _DISCLAIMER_TAIL
)

# Per-sample scoring path (dataset_score_bulk_samples / dataset_score_signature):
# the ULM fit is over the normalised expression matrix itself, so scores are
# per-sample and relative to the rest of the cohort — there is no contrast.
DECOUPLER_DISCLAIMER_PER_SAMPLE = (
    _DISCLAIMER_HEAD + "regulon/gene-set activities scored directly from the "
    "normalised expression matrix (no differential-expression step) — not direct "
    "measurements of protein activity, nuclear localization, or pathway flux. "
    "Per-sample scores are relative to the rest of the scored cohort, so they are "
    "comparable across samples within this run but not across runs or datasets. " + _DISCLAIMER_TAIL
)