File size: 6,684 Bytes
f794e31
 
 
 
 
 
 
 
fe17125
f794e31
 
 
 
 
 
9197fac
fe17125
 
9197fac
fe17125
 
 
9197fac
fe17125
9197fac
f794e31
fe17125
 
9197fac
 
 
 
 
 
fe17125
9197fac
 
 
 
 
 
f794e31
 
9197fac
 
f794e31
 
fe17125
f794e31
 
fe17125
f794e31
fe17125
 
 
 
 
 
 
9197fac
fe17125
 
 
 
9197fac
f794e31
fe17125
 
 
 
 
 
f794e31
fe17125
 
 
 
 
f794e31
 
 
fe17125
 
 
 
 
 
 
 
 
 
 
 
 
 
9197fac
 
 
fe17125
 
 
 
 
 
 
f794e31
 
 
fe17125
f794e31
fe17125
 
 
 
 
 
 
 
 
 
9197fac
fe17125
 
f794e31
fe17125
 
 
 
 
 
 
 
 
 
 
 
 
 
9197fac
 
 
f794e31
 
fe17125
 
f794e31
 
fe17125
 
 
 
 
f794e31
 
fe17125
f794e31
fe17125
f794e31
fe17125
 
f794e31
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# ai_interpreter.py
"""
AI interpretation module using Claude API.
Handles astrological interpretations and user interactions.
"""

from typing import Dict, Any
import streamlit as st
import os
from anthropic import Anthropic

class AstroAI:
    """Handles AI-powered astrological interpretations"""
    
    def __init__(self):
        # Try multiple methods to get the API key
        api_key = None
        
        # Method 1: Try Streamlit secrets
        try:
            api_key = st.secrets["CLAUDE_API_KEY"]
        except Exception:
            pass
        
        # Method 2: Try environment variable
        if not api_key:
            api_key = os.getenv("CLAUDE_API_KEY")
        
        # Method 3: Try direct input if in development
        if not api_key and not os.getenv('PRODUCTION'):
            api_key = st.text_input("Enter your Claude API key:", type="password")
            if api_key:
                os.environ["CLAUDE_API_KEY"] = api_key
        
        if not api_key:
            raise ValueError("""
                CLAUDE_API_KEY not found. Please set it using one of these methods:
                1. Add to .streamlit/secrets.toml: CLAUDE_API_KEY = "your-key-here"
                2. Set environment variable: export CLAUDE_API_KEY="your-key-here"
                3. Enter it directly in the app (development mode only)
            """)
        
        self.client = Anthropic(api_key=api_key)
        st.session_state['api_initialized'] = True
    
    def _format_chart_data(self, chart_data: Dict[str, Any]) -> str:
        """Convert chart data to a readable format for the AI"""
        formatted = "Birth Chart Analysis:\n\n"
        
        # Format planetary positions
        formatted += "Planetary Positions:\n"
        for planet, data in chart_data['planets'].items():
            if 'error' not in data:
                retrograde = data.get('retrograde', False)
                house = data.get('house', 'Unknown')
                formatted += (f"{planet}: {data['degrees']:.1f}° {data['sign']} "
                            f"in House {house}"
                            f"{' (Retrograde)' if retrograde else ''}\n")
        
        # Format aspects
        if 'aspects' in chart_data and chart_data['aspects']:
            formatted += "\nMajor Aspects:\n"
            for aspect in chart_data['aspects']:
                formatted += (f"{aspect['planet1']} {aspect['aspect']} {aspect['planet2']} "
                            f"(Orb: {aspect['orb']}°)\n")
        
        # Format element and modality balances
        if 'patterns' in chart_data:
            if 'elements' in chart_data['patterns']:
                formatted += "\nElement Balance:\n"
                for element, count in chart_data['patterns']['elements'].items():
                    formatted += f"{element}: {count} planets\n"
            
            if 'modalities' in chart_data['patterns']:
                formatted += "\nModality Balance:\n"
                for modality, count in chart_data['patterns']['modalities'].items():
                    formatted += f"{modality}: {count} planets\n"
        
        return formatted

    def get_interpretation(self, chart_data: Dict[str, Any], question: str) -> str:
        """Generate an astrological interpretation based on the chart and user's question"""
        try:
            formatted_chart = self._format_chart_data(chart_data)
            
            system_prompt = """You are an expert astrologer with deep knowledge of both modern and traditional astrology. 
            When interpreting charts:
            - Focus on the specific question asked while considering the whole chart context
            - Provide practical, actionable insights
            - Balance technical astrological terms with clear explanations
            - Consider aspect patterns, dignities, and dispositors
            - Include both challenging and supportive elements
            - Be honest but constructive in your interpretations
            """
            
            # Print debug information
            st.write("Sending request to Claude API...")
            
            response = self.client.messages.create(
                model="claude-3-sonnet-20240229",
                max_tokens=1000,
                system=system_prompt,
                messages=[{
                    "role": "user",
                    "content": f"""Based on the following birth chart data:

{formatted_chart}

Question: {question}

Please provide an insightful astrological interpretation focusing specifically on the question asked."""
                }]
            )
            
            return response.content[0].text
            
        except Exception as e:
            error_message = f"Error generating interpretation: {str(e)}"
            st.error(error_message)
            return f"I apologize, but I encountered an error: {error_message}"
    
    def get_initial_analysis(self, chart_data: Dict[str, Any]) -> str:
        """Generate an initial overview analysis of the birth chart"""
        try:
            formatted_chart = self._format_chart_data(chart_data)
            
            system_prompt = """You are a skilled astrologer providing initial birth chart readings. 
            In your analysis:
            - Start with the most prominent features of the chart
            - Highlight significant patterns and configurations
            - Discuss the balance of elements and modalities
            - Note any particularly strong or challenged planets
            - Keep the tone informative and encouraging
            - Use clear language while preserving astrological accuracy
            
            Structure your response with clear sections and insights.
            """
            
            # Print debug information
            st.write("Generating initial analysis...")
            
            response = self.client.messages.create(
                model="claude-3-sonnet-20240229",
                max_tokens=1500,
                system=system_prompt,
                messages=[{
                    "role": "user",
                    "content": f"""Please provide an initial overview analysis of this birth chart:

{formatted_chart}

Focus on the most significant patterns and features that form the core themes of this chart."""
                }]
            )
            
            return response.content[0].text
            
        except Exception as e:
            error_message = f"Error generating initial analysis: {str(e)}"
            st.error(error_message)
            return f"I apologize, but I encountered an error: {error_message}"