import requests
import json
import re
from typing import Optional, Dict, Any, List
class BoardProcessor:
def __init__(self, api_url: str = "https://corvo-ai-claude-4-6-opus.hf.space/chat"):
self.api_url = api_url
self.system_prompt = self._load_system_prompt()
def _load_system_prompt(self) -> str:
"""Load system prompt from system.txt file"""
try:
with open('system.txt', 'r', encoding='utf-8') as f:
return f.read()
except FileNotFoundError:
# Provide a default system prompt if file not found
return """You are a converter that transforms XML board data into JSON format.
Convert the given XML to JSON following these rules:
1. Extract all elements from the XML
2. Convert them to proper JSON structure
3. Wrap your JSON output in tags
Example:
Input: Hello
Output: {"board": {"notes": [{"color": "yellow", "x": 100, "y": 200, "text": "Hello"}]}}
Always wrap your final JSON output in tags."""
def _call_ai_api(
self,
user_input: Optional[str] = None,
chat_history: Optional[List[Dict[str, Any]]] = None,
temperature: float = 0.9,
top_p: float = 0.95,
max_tokens: Optional[int] = None
) -> str:
"""Call the AI API and return the assistant's response"""
payload = {
"user_input": user_input,
"chat_history": chat_history or [],
"temperature": temperature,
"top_p": top_p,
"max_tokens": max_tokens
}
try:
response = requests.post(self.api_url, json=payload, timeout=120)
response.raise_for_status()
result = response.json()
return result.get("assistant_response", "")
except requests.exceptions.RequestException as e:
raise Exception(f"API request failed: {str(e)}")
def _extract_json_from_response(self, response: str) -> str:
"""Extract JSON from tags in the AI response and return as text"""
# Print the raw response for debugging
print("\n🔍 DEBUG - Raw AI Response:")
print("=" * 80)
print(response)
print("=" * 80)
# Try multiple patterns to find JSON
patterns = [
r'(.*?)', # Standard tags
r'```json\s*(.*?)\s*```', # Markdown code blocks
r'```\s*(.*?)\s*```', # Generic code blocks
]
for pattern in patterns:
json_match = re.search(pattern, response, re.DOTALL)
if json_match:
json_str = json_match.group(1).strip()
try:
json.loads(json_str) # Validate
return json_str
except json.JSONDecodeError:
continue
# If no tags found, try to find JSON directly in the response
try:
# Look for JSON object pattern
json_match = re.search(r'\{.*\}', response, re.DOTALL)
if json_match:
json_str = json_match.group(0).strip()
json.loads(json_str) # Validate
return json_str
except json.JSONDecodeError:
pass
raise ValueError("No valid JSON found in AI response. Check the debug output above.")
def convert_xml_to_json(
self,
xml_text: str,
temperature: float = 0.9,
top_p: float = 0.95,
max_tokens: Optional[int] = None
) -> str:
"""
Convert XML text to Board JSON text
Args:
xml_text: The XML string to convert
temperature: AI temperature parameter (default: 0.9)
top_p: AI top_p parameter (default: 0.95)
max_tokens: Maximum tokens for AI response (default: None)
Returns:
JSON string (as text)
"""
# Prepare chat history with system prompt
chat_history = [
{"role": "system", "content": self.system_prompt}
]
# Call AI API with XML input
ai_response = self._call_ai_api(
user_input=xml_text,
chat_history=chat_history,
temperature=temperature,
top_p=top_p,
max_tokens=max_tokens
)
print(xml_text)
# Extract and return JSON as text
json_text = self._extract_json_from_response(ai_response)
return json_text
# Example usage
if __name__ == "__main__":
processor = BoardProcessor()
xml_input = """
قانون نيوتن الثاني:
القوة = الكتلة × التسارع
F = m × a
"""
try:
json_output = processor.convert_xml_to_json(xml_input)
print("\n✅ Conversion successful!")
print("\nJSON Output (as text):")
print(json_output)
# Optionally pretty print
print("\n📋 Pretty printed:")
print(json.dumps(json.loads(json_output), indent=2, ensure_ascii=False))
except Exception as e:
print(f"\n❌ Error: {str(e)}")