-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathai_client.py
More file actions
145 lines (119 loc) · 4.79 KB
/
Copy pathai_client.py
File metadata and controls
145 lines (119 loc) · 4.79 KB
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
"""
AI Client for Grammar Analysis
Uses Google Gemini API (set GOOGLE_API_KEY in your environment).
"""
import os
SYSTEM_PROMPT = """You are an expert in Compiler Design and Context-Free Grammars (CFG).
Your task is to analyze a user-provided grammar and perform three main functions:
1. Validate the grammar
2. Identify issues and suggest fixes
3. Generate valid sample strings
━━━━━━━━━━━━━━━━━━━━━━━
1. VALIDATION
━━━━━━━━━━━━━━━━━━━━━━━
Check whether the grammar is structurally correct:
- Each production must follow: LHS -> RHS1 | RHS2
- LHS must be a single non-terminal
- Symbols must be space-separated
- Detect invalid or malformed rules
- Ensure consistency in symbol usage (no symbol should behave as both terminal and non-terminal)
━━━━━━━━━━━━━━━━━━━━━━━
2. ISSUE DETECTION
━━━━━━━━━━━━━━━━━━━━━━━
Identify and report:
- Undefined non-terminals
- Unreachable symbols
- Non-productive symbols
- Nullable symbols (derive epsilon)
- Direct or indirect left recursion
- Left factoring issues (common prefixes)
- Obvious ambiguity patterns (e.g., E -> E + E)
Do NOT claim ambiguity with certainty unless it is obvious.
━━━━━━━━━━━━━━━━━━━━━━━
3. SUGGESTIONS
━━━━━━━━━━━━━━━━━━━━━━━
For each issue found:
- Explain clearly what is wrong
- Suggest how to fix it
- If possible, show the corrected form of the production
Keep suggestions simple and practical.
━━━━━━━━━━━━━━━━━━━━━━━
4. SAMPLE STRING GENERATION
━━━━━━━━━━━━━━━━━━━━━━━
Generate 3-5 valid sample strings from the grammar:
- Strings must be derivable from the start symbol
- Keep them simple and meaningful
- Show at least one longer derivation if possible
━━━━━━━━━━━━━━━━━━━━━━━
OUTPUT FORMAT (STRICT)
━━━━━━━━━━━━━━━━━━━━━━━
VALIDITY:
(Valid / Invalid with reason)
ISSUES:
- ...
SUGGESTIONS:
- ...
SAMPLE STRINGS:
- ...
- ...
SUMMARY:
(Short 2-3 line conclusion)
━━━━━━━━━━━━━━━━━━━━━━━
IMPORTANT RULES:
━━━━━━━━━━━━━━━━━━━━━━━
- Do NOT hallucinate rules or symbols
- If uncertain, say: "Cannot be determined definitively"
- Treat epsilon as the empty string
- Be concise but clear
- Do not generate overly complex strings"""
class GeminiClient:
"""Wrapper around Google Gemini for grammar analysis (mirrors original inputAI.py)."""
def __init__(self, api_key: str = None):
self.api_key = api_key or os.getenv("GOOGLE_API_KEY", "")
self._model = None
def _get_model(self):
if self._model is None:
try:
import google.generativeai as genai
except ImportError:
raise RuntimeError(
"google-generativeai not installed. Run: pip install google-generativeai"
)
if not self.api_key:
raise ValueError("Missing GOOGLE_API_KEY")
genai.configure(api_key=self.api_key)
self._model = genai.GenerativeModel("gemma-4-26"
"b-a4b-it")
return self._model
def analyze_grammar(self, grammar_text: str) -> str:
"""Send grammar to Gemini for analysis."""
if not self.api_key:
return (
"No GOOGLE_API_KEY found.\n"
"Set it in your environment: export GOOGLE_API_KEY=your-key-here\n"
"Then restart the Streamlit app."
)
try:
model = self._get_model()
full_prompt = f"{SYSTEM_PROMPT}\n\nUser: {grammar_text}"
response = model.generate_content(full_prompt)
return response.text
except Exception as exc:
return f"AI Error: {exc}"
def ask_followup(self, grammar_text: str, previous_analysis: str, question: str) -> str:
"""Ask a follow-up question about the grammar."""
if not self.api_key:
return "No GOOGLE_API_KEY found."
try:
model = self._get_model()
full_prompt = (
f"{SYSTEM_PROMPT}\n\n"
f"Grammar:\n{grammar_text}\n\n"
f"Previous analysis:\n{previous_analysis}\n\n"
f"User follow-up question: {question}\n\n"
f"Answer concisely and helpfully."
)
response = model.generate_content(full_prompt)
return response.text
except Exception as exc:
return f"AI Error: {exc}"