Spaces:
Running
Running
| import gradio as gr | |
| import os | |
| from datetime import datetime | |
| import json | |
| # Initialize with sponsor APIs (will be configured with environment variables) | |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "") | |
| ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY", "") | |
| ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY", "") | |
| # Essential Dignities Tables | |
| DOMICILE_RULERS = { | |
| "Aries": "Mars", "Taurus": "Venus", "Gemini": "Mercury", | |
| "Cancer": "Moon", "Leo": "Sun", "Virgo": "Mercury", | |
| "Libra": "Venus", "Scorpio": "Mars", "Sagittarius": "Jupiter", | |
| "Capricorn": "Saturn", "Aquarius": "Saturn", "Pisces": "Jupiter" | |
| } | |
| EXALTATIONS = { | |
| "Aries": "Sun", "Taurus": "Moon", "Gemini": None, | |
| "Cancer": "Jupiter", "Leo": None, "Virgo": "Mercury", | |
| "Libra": "Saturn", "Scorpio": None, "Sagittarius": None, | |
| "Capricorn": "Mars", "Aquarius": None, "Pisces": "Venus" | |
| } | |
| TRIPLICITIES = { | |
| "Fire": {"day": "Sun", "night": "Jupiter", "participating": "Saturn"}, | |
| "Earth": {"day": "Venus", "night": "Moon", "participating": "Mars"}, | |
| "Air": {"day": "Saturn", "night": "Mercury", "participating": "Jupiter"}, | |
| "Water": {"day": "Venus", "night": "Mars", "participating": "Moon"} | |
| } | |
| SIGN_TRIPLICITIES = { | |
| "Aries": "Fire", "Leo": "Fire", "Sagittarius": "Fire", | |
| "Taurus": "Earth", "Virgo": "Earth", "Capricorn": "Earth", | |
| "Gemini": "Air", "Libra": "Air", "Aquarius": "Air", | |
| "Cancer": "Water", "Scorpio": "Water", "Pisces": "Water" | |
| } | |
| def calculate_profections(birth_year: int, target_year: int) -> dict: | |
| """Calculate annual profections from Ascendant""" | |
| age = target_year - birth_year | |
| profected_house = (age % 12) + 1 | |
| return { | |
| "age": age, | |
| "profected_house": profected_house, | |
| "description": f"At age {age}, the profection is to the {profected_house}th house." | |
| } | |
| def assess_planetary_dignity(planet: str, sign: str, is_day_chart: bool) -> dict: | |
| """Assess a planet's essential dignity in a given sign""" | |
| dignity_score = 0 | |
| dignities = [] | |
| # Check domicile (+5) | |
| if DOMICILE_RULERS.get(sign) == planet: | |
| dignity_score += 5 | |
| dignities.append("Domicile (+5)") | |
| # Check exaltation (+4) | |
| if EXALTATIONS.get(sign) == planet: | |
| dignity_score += 4 | |
| dignities.append("Exaltation (+4)") | |
| # Check triplicity (+3) | |
| triplicity = SIGN_TRIPLICITIES.get(sign) | |
| if triplicity: | |
| triplicity_rulers = TRIPLICITIES[triplicity] | |
| if is_day_chart and triplicity_rulers["day"] == planet: | |
| dignity_score += 3 | |
| dignities.append("Triplicity Ruler - Day (+3)") | |
| elif not is_day_chart and triplicity_rulers["night"] == planet: | |
| dignity_score += 3 | |
| dignities.append("Triplicity Ruler - Night (+3)") | |
| elif triplicity_rulers["participating"] == planet: | |
| dignity_score += 3 | |
| dignities.append("Triplicity Ruler - Participating (+3)") | |
| condition = "Strong" if dignity_score >= 4 else "Moderate" if dignity_score > 0 else "Peregrine" | |
| return { | |
| "planet": planet, | |
| "sign": sign, | |
| "dignity_score": dignity_score, | |
| "dignities": dignities if dignities else ["None (Peregrine)"], | |
| "condition": condition, | |
| "sect_considered": "Day Chart" if is_day_chart else "Night Chart" | |
| } | |
| def calculate_lots(asc_degree: float, sun_degree: float, moon_degree: float, is_day_chart: bool) -> dict: | |
| """Calculate traditional Hellenistic lots (Fortuna and Spirit)""" | |
| if is_day_chart: | |
| # Lot of Fortune (day): Asc + Moon - Sun | |
| fortune = (asc_degree + moon_degree - sun_degree) % 360 | |
| else: | |
| # Lot of Fortune (night): Asc + Sun - Moon | |
| fortune = (asc_degree + sun_degree - moon_degree) % 360 | |
| if is_day_chart: | |
| # Lot of Spirit (day): Asc + Sun - Moon | |
| spirit = (asc_degree + sun_degree - moon_degree) % 360 | |
| else: | |
| # Lot of Spirit (night): Asc + Moon - Sun | |
| spirit = (asc_degree + moon_degree - sun_degree) % 360 | |
| return { | |
| "Lot of Fortune": round(fortune, 2), | |
| "Lot of Spirit": round(spirit, 2), | |
| "chart_type": "Day Chart" if is_day_chart else "Night Chart" | |
| } | |
| def research_hellenistic_topic(query: str) -> str: | |
| """Research assistant for Hellenistic astrology topics""" | |
| # This will integrate with OpenAI/Anthropic APIs | |
| # For now, return educational placeholder | |
| topics = { | |
| "sect": """Sect Theory (Hairesis) | |
| According to Vettius Valens (Anthology, Book III), sect distinguishes between day and night charts: | |
| **Day Chart (Diurnal)**: Sun above horizon at birth | |
| - Benefics: Jupiter, Saturn (traditionally) | |
| - Malefics: Mars more difficult than Saturn | |
| - Solar sect planets: Sun, Jupiter, Saturn | |
| **Night Chart (Nocturnal)**: Sun below horizon at birth | |
| - Benefics: Venus, Moon | |
| - Malefics: Saturn more difficult than Mars | |
| - Lunar sect planets: Moon, Venus, Mars | |
| **Practical Application**: | |
| Ptolemy (Tetrabiblos, Book III) emphasizes that planets in their proper sect are strengthened, while planets contrary to sect are weakened. A day chart with Jupiter angular is far more favorable than Saturn in the same position. | |
| **Source Differences**: | |
| - Valens: More emphasis on sect in time-lord systems | |
| - Ptolemy: More theoretical, applies to natal interpretation | |
| - Dorotheus: Less explicit about sect distinctions | |
| """, | |
| "profections": """Annual Profections (Epembasis) | |
| The technique advances one house per year of life from the Ascendant. | |
| **Method** (from Valens, Anthology Book IV): | |
| 1. Count age in complete years | |
| 2. Each year = one house from Ascendant | |
| 3. The profected house's ruler becomes the "Lord of the Year" | |
| **Example**: | |
| - Age 0-11 months: 1st house | |
| - Age 1: 2nd house | |
| - Age 12: Returns to 1st house (first return) | |
| - Age 25: 2nd house (third time) | |
| **Application**: | |
| The Lord of the Year is activated. Transits to that planet are significant. The house profected to shows the area of life emphasis. | |
| **Paulus Alexandrinus** adds that planets in the profected house are also activated that year. | |
| """, | |
| "bounds": """Egyptian Bounds (Terms) | |
| Each sign is divided into five unequal sections, each ruled by a planet. | |
| **Ptolemy vs Egyptian System**: | |
| Ptolemy (Tetrabiblos I.21) presents his own system, but most practitioners use the older Egyptian bounds found in Valens. | |
| **Significance** (per Valens): | |
| - Bounds = +2 dignity points | |
| - Show more refined planet influence within a sign | |
| - Used in time-lord distributions | |
| **Example - Aries** (Egyptian): | |
| - 0-6°: Jupiter | |
| - 6-12°: Venus | |
| - 12-20°: Mercury | |
| - 20-25°: Mars | |
| - 25-30°: Saturn | |
| """ | |
| } | |
| # Simple keyword matching | |
| query_lower = query.lower() | |
| for keyword, content in topics.items(): | |
| if keyword in query_lower: | |
| return content | |
| return f"""Research Query: "{query}" | |
| This would integrate with OpenAI/Anthropic to search through: | |
| - Vettius Valens (Anthology) | |
| - Ptolemy (Tetrabiblos) | |
| - Dorotheus (Carmen Astrologicum) | |
| - Modern synthesizers: Chris Brennan, Demetra George | |
| Please implement API keys to enable full research capabilities. | |
| """ | |
| # Gradio Interface | |
| def create_demo(): | |
| with gr.Blocks( | |
| theme=gr.themes.Soft(primary_hue="purple", secondary_hue="blue"), | |
| title="HERMES - Hellenistic Astrology Research Assistant" | |
| ) as demo: | |
| gr.Markdown(""" | |
| # 🏛️ HERMES - Hellenistic Ephemeris Research & MCP Educational System | |
| **Ancient Wisdom Meets Modern AI** | |
| Research assistant for traditional Hellenistic astrology combining classical texts | |
| (Valens, Ptolemy, Dorotheus) with modern AI agents and MCP architecture. | |
| Built for the MCP 1st Birthday Hackathon using OpenAI, Anthropic, ElevenLabs, and Modal. | |
| """) | |
| with gr.Tab("📊 Chart Analysis"): | |
| gr.Markdown("### Essential Dignity Calculator") | |
| with gr.Row(): | |
| planet_input = gr.Dropdown( | |
| choices=["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn"], | |
| label="Planet", | |
| value="Sun" | |
| ) | |
| sign_input = gr.Dropdown( | |
| choices=list(DOMICILE_RULERS.keys()), | |
| label="Sign", | |
| value="Aries" | |
| ) | |
| sect_input = gr.Checkbox(label="Day Chart (uncheck for Night Chart)", value=True) | |
| dignity_btn = gr.Button("Assess Planetary Condition", variant="primary") | |
| dignity_output = gr.JSON(label="Dignity Analysis") | |
| dignity_btn.click( | |
| fn=assess_planetary_dignity, | |
| inputs=[planet_input, sign_input, sect_input], | |
| outputs=dignity_output | |
| ) | |
| gr.Markdown("### Lot Calculator") | |
| with gr.Row(): | |
| asc_deg = gr.Number(label="Ascendant (degrees 0-360)", value=0) | |
| sun_deg = gr.Number(label="Sun (degrees 0-360)", value=45) | |
| moon_deg = gr.Number(label="Moon (degrees 0-360)", value=180) | |
| lot_sect = gr.Checkbox(label="Day Chart", value=True) | |
| lot_btn = gr.Button("Calculate Lots", variant="primary") | |
| lot_output = gr.JSON(label="Traditional Lots") | |
| lot_btn.click( | |
| fn=calculate_lots, | |
| inputs=[asc_deg, sun_deg, moon_deg, lot_sect], | |
| outputs=lot_output | |
| ) | |
| with gr.Tab("📚 Source Research"): | |
| gr.Markdown(""" | |
| ### Hellenistic Astrology Knowledge Base | |
| Ask about traditional techniques and get answers citing ancient sources. | |
| """) | |
| research_query = gr.Textbox( | |
| label="Research Question", | |
| placeholder="e.g., 'Explain sect theory' or 'What are profections?' or 'Describe Egyptian bounds'", | |
| lines=2 | |
| ) | |
| research_btn = gr.Button("Search Ancient Sources", variant="primary") | |
| research_output = gr.Textbox(label="Research Results", lines=20) | |
| research_btn.click( | |
| fn=research_hellenistic_topic, | |
| inputs=research_query, | |
| outputs=research_output | |
| ) | |
| gr.Markdown(""" | |
| **Sources Referenced:** | |
| - Vettius Valens (*Anthology*) | |
| - Ptolemy (*Tetrabiblos*) | |
| - Dorotheus of Sidon (*Carmen Astrologicum*) | |
| - Paulus Alexandrinus | |
| - Modern: Chris Brennan, Demetra George, Robert Schmidt | |
| """) | |
| with gr.Tab("⏱️ Time-Lord Systems"): | |
| gr.Markdown("### Annual Profections Calculator") | |
| with gr.Row(): | |
| birth_year_input = gr.Number(label="Birth Year", value=1990) | |
| target_year_input = gr.Number(label="Target Year", value=2025) | |
| profection_btn = gr.Button("Calculate Profections", variant="primary") | |
| profection_output = gr.JSON(label="Profection Results") | |
| profection_btn.click( | |
| fn=calculate_profections, | |
| inputs=[birth_year_input, target_year_input], | |
| outputs=profection_output | |
| ) | |
| gr.Markdown(""" | |
| **About Annual Profections:** | |
| An ancient time-lord technique from Hellenistic astrology where each year of life | |
| corresponds to a house counted from the Ascendant. The ruler of the profected house | |
| becomes the "Lord of the Year." | |
| Used by Valens, Paulus Alexandrinus, and modern practitioners for annual forecasting. | |
| """) | |
| with gr.Tab("ℹ️ About"): | |
| gr.Markdown(""" | |
| ## About HERMES | |
| **Hellenistic Ephemeris Research & MCP Educational System** | |
| ### Purpose | |
| HERMES is a research and teaching tool for traditional Hellenistic astrology, bridging | |
| 2000-year-old wisdom with modern AI technology. | |
| ### Technical Stack | |
| - **Agent Framework**: OpenAI GPT-4 + Anthropic Claude | |
| - **Voice**: ElevenLabs Conversational AI | |
| - **MCP Server**: Python + Modal (serverless) | |
| - **UI**: Gradio 6 on HuggingFace Spaces | |
| - **Compute**: Modal GPU credits | |
| ### Features | |
| - Essential dignity calculations (domicile, exaltation, triplicity, bounds) | |
| - Time-lord systems (profections, zodiacal releasing) | |
| - Traditional lot calculations (Fortune, Spirit) | |
| - Source research with citations to ancient texts | |
| - Voice-enabled teaching mode (coming soon) | |
| ### Educational Use Cases | |
| 1. **Students**: Interactive learning of complex traditional techniques | |
| 2. **Researchers**: Rapid comparison across source texts and translations | |
| 3. **Practitioners**: Chart analysis using authentic Hellenistic methods | |
| ### Built For | |
| MCP 1st Birthday Hackathon (Nov 14-30, 2025) | |
| ### Author | |
| Created by an astrology author and strategy consultant | |
| ### Credits | |
| - Hackathon Sponsors: Anthropic, OpenAI, ElevenLabs, Modal, HuggingFace | |
| - Ancient Sources: Valens, Ptolemy, Dorotheus, Firmicus, Paulus | |
| - Modern Teachers: Chris Brennan, Demetra George, Robert Schmidt | |
| --- | |
| *Note: This is Phase 1 of development. Full MCP integration, voice agents, | |
| and advanced chart calculations coming in subsequent phases.* | |
| """) | |
| return demo | |
| # Launch the app | |
| if __name__ == "__main__": | |
| demo = create_demo() | |
| demo.launch() | |