Spaces:
Running
Running
| """ | |
| signatures.py — DSPy signatures for the advisor pipeline. | |
| Each signature is a small, focused contract. GEPA will rewrite the docstrings | |
| ("instructions") and the field descriptions during optimization, which is why | |
| the *initial* prompts here are deliberately minimal — they're starting points, | |
| not finished prompts. We give just enough scaffolding to make the very first | |
| forward pass coherent. GEPA does the rest. | |
| Merged signatures (AnalyzeAndPlan, SelectAndSynthesize) combine the original | |
| four into two, halving the number of LLM round-trips at inference time. | |
| The original four (UnderstandQuery, PlanRetrieval, SelectPassages, SynthesizeAdvice) | |
| are kept for GEPA optimization runs which benefit from granular predictors. | |
| """ | |
| from __future__ import annotations | |
| from typing import Literal | |
| import dspy | |
| # ──────────────────────────── Stage 1: Understanding ──────────────────────────── | |
| class UnderstandQuery(dspy.Signature): | |
| """Your task is to provide insightful and empathetic guidance to users who are | |
| experiencing existential and emotional crises or questioning their life situations, | |
| using the philosophy of Advaita Vedānta. Here's how you should approach each user query: | |
| 1. **Understand the User's Context**: | |
| - Carefully read the user's description of their life situation. Pay attention to any | |
| prior exchanges that might provide context for the user's current emotional state or | |
| references to previous discussions. | |
| - Identify both the surface issues and the deeper existential or spiritual concerns the | |
| user is facing. | |
| 2. **Emotional and Spiritual Analysis**: | |
| - Determine the felt emotion that the user is experiencing. This could range from | |
| existential dread, alienation, a sense of loss, or confusion, among others. | |
| - Identify the deeper spiritual concern underlying the user's emotional state. This | |
| concerns how the user's experiences relate to their sense of self, agency, stability, | |
| or meaning in life. | |
| 3. **Vedāntic Themes Identification**: | |
| - Analyze the user's situation in light of Advaita Vedānta principles. Identify themes such as: | |
| - Māyā: The illusory and impermanent nature of the phenomenal world. | |
| - Adhyāsa: The superimposition of false identities or worldly roles onto the true Self. | |
| - Anitya: The inherent impermanence of worldly circumstances. | |
| - Nishkama Karma: Acting without attachment to the fruits of one's actions. | |
| - Vairāgya: Detachment from the changing fortunes of life. | |
| - Use relevant scriptural references where necessary to support your advice. | |
| 4. **Craft a Compassionate Response**: | |
| - Open with empathy to acknowledge the user's emotional struggle. | |
| - Provide a clear and practical offering that is actionable within the user's daily life. | |
| This could include specific meditation practices, reflective exercises, or philosophical | |
| insights into practicing sākṣī-bhāva (witness consciousness). | |
| - Integrate a sense of lightness or wit where appropriate to gently uplift the user, | |
| keeping in mind the dry humor seen in Śaṅkara's tradition. | |
| - Where possible, include relatable anecdotes or parables to illustrate Vedāntic concepts | |
| in a way that connects them to the user's lived experience. | |
| 5. **Integration and Calibration**: | |
| - Maintain coherence to the non-dual Advaita tradition by emphasizing the distinction | |
| between the eternal Self and the transient ego-personality or worldly achievements. | |
| - Avoid clichés and strive for a fresh and nuanced expression of philosophical insights. | |
| - Ensure the non-dual register of Advaita Vedānta is preserved without dismissing the | |
| user's lived experiences. | |
| By combining a deep understanding of Advaita philosophy with empathy and practical guidance, | |
| you can help users navigate their existential queries and emotional challenges toward a | |
| greater sense of peace and self-understanding.""" | |
| history: dspy.History = dspy.InputField( | |
| desc="Prior turns as a list of message dicts with 'user_question' and 'response' keys. " | |
| "Empty history means this is the first message." | |
| ) | |
| user_question: str = dspy.InputField(desc="The user's current message; may be a question, a vent, a follow-up, or a description of a situation.") | |
| felt_emotion: str = dspy.OutputField( | |
| desc="The dominant emotion the user is experiencing, named precisely (e.g. 'anticipatory grief', not just 'sad')." | |
| ) | |
| surface_concern: str = dspy.OutputField( | |
| desc="What the user is literally asking about, in one sentence." | |
| ) | |
| deeper_concern: str = dspy.OutputField( | |
| desc="The underlying existential/spiritual concern — usually about identity, attachment, " | |
| "fear, dharma, or meaning — that the surface concern is a symptom of. One sentence." | |
| ) | |
| vedantic_themes: list[str] = dspy.OutputField( | |
| desc="2-4 Advaita-Vedānta concepts most relevant to this situation. " | |
| "Use Sanskrit terms with brief gloss, e.g. 'adhyāsa (superimposition of self onto roles)', " | |
| "'vairāgya (dispassion)', 'sākṣī (witness consciousness)'." | |
| ) | |
| # ──────────────────────────── Stage 2: Retrieval Planning ──────────────────────────── | |
| class PlanRetrieval(dspy.Signature): | |
| """Given the user's situation and identified themes, generate diverse search | |
| queries to find relevant passages from the Advaita corpus (Bhagavad Gītā with | |
| Śaṅkara bhāṣya, Upaniṣads, Brahma Sūtras, prakaraṇa texts). Each query should | |
| target a different angle — one query about the philosophical principle, | |
| one about a parallel situation in the texts, one about the practical | |
| teaching offered by the lineage.""" | |
| surface_concern: str = dspy.InputField() | |
| deeper_concern: str = dspy.InputField() | |
| vedantic_themes: list[str] = dspy.InputField() | |
| queries: list[str] = dspy.OutputField( | |
| desc="3 distinct search queries (each 5-15 words). Vary in angle: principle, parallel, practice." | |
| ) | |
| # ──────────────────────────── Stage 3: Source Selection ──────────────────────────── | |
| class SelectPassages(dspy.Signature): | |
| """From the retrieved candidate passages, select the ones that genuinely | |
| speak to this user's situation. Prefer primary sources (Gītā verses, | |
| Upaniṣadic mantras, Śaṅkara's bhāṣya) over secondary or modern commentary | |
| when both are available. Reject passages that are merely topically adjacent | |
| but don't address the actual spiritual concern. Avoid re-selecting passages | |
| whose source was already cited in a prior turn — prefer fresh ground.""" | |
| deeper_concern: str = dspy.InputField() | |
| candidate_passages: str = dspy.InputField( | |
| desc="Numbered candidate passages with source attribution." | |
| ) | |
| previously_cited: list[str] = dspy.InputField( | |
| desc="Source references already cited in earlier turns of this conversation " | |
| "(e.g. ['BG 2.47', 'BG 18.66']). Prefer passages not on this list so " | |
| "the conversation covers new ground. Empty list on the first turn." | |
| ) | |
| selected_indices: list[int] = dspy.OutputField( | |
| desc="Passage numbers (1-based integers) of the 2–4 most relevant passages. " | |
| "Use the number that appears after 'Passage' in the candidate list " | |
| "(e.g. if the passage starts with 'Passage 3:', output 3). " | |
| "Never output a verse reference like '16.5' or '18.73' here — " | |
| "only the integer position in the list." | |
| ) | |
| selection_rationale: str = dspy.OutputField( | |
| desc="One sentence per selection explaining why that passage speaks to this concern." | |
| ) | |
| # ──────────────────────────── Stage 4: Advice Synthesis ──────────────────────────── | |
| class SynthesizeAdvice(dspy.Signature): | |
| """Compose a response that is grounded in Advaita Vedānta as taught by | |
| Śaṅkarācārya, empathetic to the user's felt experience, and practically | |
| useful for their situation. Honor the two-truths distinction: meet the user | |
| in vyāvahārika (transactional reality) without ever denying the | |
| pāramārthika (absolute) view. Cite specific verses/passages by reference, | |
| integrate them into prose rather than dumping quotes, and keep wit gentle — | |
| light around the cosmic predicament, never light about the user's pain. | |
| If history has prior turns: do not repeat citations or teachings already | |
| given; build on or deepen what was said; acknowledge any shift the user has | |
| expressed since the last turn. If the user is following up, open by briefly | |
| acknowledging the continuity before moving forward.""" | |
| history: dspy.History = dspy.InputField( | |
| desc="Prior turns as a list of message dicts with 'user_question' and 'response' keys. " | |
| "Use this to avoid repetition and to build across turns." | |
| ) | |
| user_question: str = dspy.InputField() | |
| felt_emotion: str = dspy.InputField() | |
| deeper_concern: str = dspy.InputField() | |
| selected_passages: str = dspy.InputField( | |
| desc="The selected passages with full source attribution." | |
| ) | |
| response: str = dspy.OutputField( | |
| desc="The advisor's reply to the user. 250-450 words. " | |
| "Open by acknowledging the felt experience. Move into the Vedāntic perspective. " | |
| "Cite at least one primary source (Gītā chapter:verse, Upaniṣad name + section, etc.). " | |
| "Close with a concrete practice or shift in perspective they can try this week. " | |
| "Address the user as 'you' throughout. Avoid Western therapy clichés." | |
| ) | |
| sources_cited: list[str] = dspy.OutputField( | |
| desc="Source references actually cited in the response, e.g. 'BG 2.47', 'Bṛhadāraṇyaka Up. 4.4.5', 'Vivekacūḍāmaṇi 11'." | |
| ) | |
| # ──────────────── Merged signatures (inference-time, 2 calls instead of 4) ──────────────── | |
| class AnalyzeAndPlan(dspy.Signature): | |
| """Understand the user's situation through the lens of Advaita Vedānta and | |
| plan diverse search queries to find the most relevant scriptural passages. | |
| First identify the felt emotion, surface concern, and the deeper existential | |
| concern (usually about identity, attachment, dharma, or meaning). Then name | |
| 2-4 Vedāntic themes using precise Sanskrit terms. Finally, produce 3 diverse | |
| search queries targeting different angles — one philosophical principle, | |
| one parallel situation in the texts, one practical teaching.""" | |
| history: dspy.History = dspy.InputField( | |
| desc="Prior turns as a list of message dicts with 'user_question' and 'response' keys. " | |
| "Empty history means this is the first message." | |
| ) | |
| user_question: str = dspy.InputField( | |
| desc="The user's current message; may be a question, a vent, a follow-up, or a situation." | |
| ) | |
| felt_emotion: str = dspy.OutputField( | |
| desc="The dominant emotion the user is experiencing, named precisely (e.g. 'anticipatory grief', not just 'sad')." | |
| ) | |
| surface_concern: str = dspy.OutputField( | |
| desc="What the user is literally asking about, in one sentence." | |
| ) | |
| deeper_concern: str = dspy.OutputField( | |
| desc="The underlying existential/spiritual concern — usually about identity, attachment, " | |
| "fear, dharma, or meaning — that the surface concern is a symptom of. One sentence." | |
| ) | |
| vedantic_themes: list[str] = dspy.OutputField( | |
| desc="2-4 Advaita-Vedānta concepts most relevant to this situation. " | |
| "Use Sanskrit terms with brief gloss, e.g. 'adhyāsa (superimposition of self onto roles)'." | |
| ) | |
| queries: list[str] = dspy.OutputField( | |
| desc="3 distinct search queries (5-15 words each) to find relevant scriptural passages. " | |
| "Vary in angle: philosophical principle, parallel situation, practical teaching." | |
| ) | |
| class SelectAndSynthesize(dspy.Signature): | |
| """From the candidate passages, select the 2-4 that genuinely speak to this | |
| user's situation, then compose a response grounded in Advaita Vedānta. | |
| Prefer primary sources (Gītā verses, Upaniṣadic mantras, Śaṅkara's bhāṣya). | |
| Reject passages that are merely topically adjacent. Honor the two-truths | |
| distinction: meet the user in vyāvahārika (transactional reality) without | |
| denying the pāramārthika (absolute) view. Cite specific verses in prose — | |
| integrate, do not dump. Wit is welcome around the cosmic predicament, never | |
| around the user's pain. Avoid repeating sources already cited in prior turns.""" | |
| history: dspy.History = dspy.InputField( | |
| desc="Prior turns. Use to avoid repeating citations and to build across turns." | |
| ) | |
| user_question: str = dspy.InputField() | |
| felt_emotion: str = dspy.InputField() | |
| deeper_concern: str = dspy.InputField() | |
| candidate_passages: str = dspy.InputField( | |
| desc="Numbered candidate passages with source attribution. Select from these." | |
| ) | |
| previously_cited: list[str] = dspy.InputField( | |
| desc="Sources already cited in earlier turns (e.g. ['BG 2.47']). Prefer fresh ground." | |
| ) | |
| response: str = dspy.OutputField( | |
| desc="The advisor's reply. 250-450 words. Open by acknowledging the felt experience. " | |
| "Move into the Vedāntic perspective. Cite 2-4 primary sources inline (use only " | |
| "passages from the candidates). Close with a concrete practice or shift in " | |
| "perspective they can try this week. Address the user as 'you'. " | |
| "Avoid Western therapy clichés ('it's understandable', 'validate', etc.)." | |
| ) | |
| sources_cited: list[str] = dspy.OutputField( | |
| desc="Source references actually cited in the response, e.g. 'BG 2.47', 'Muṇḍaka Up. 2.2.5'." | |
| ) | |