jimfhahn commited on
Commit
c563f2f
Β·
verified Β·
1 Parent(s): e2ca1b0

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +152 -164
app.py CHANGED
@@ -17,27 +17,6 @@ from typing import Any, Dict, List, Optional
17
  import threading
18
  import time
19
 
20
- # CRITICAL: FORCE OVERRIDE ALL ENVIRONMENT VARIABLES THAT COULD INTERFERE
21
- print("πŸ”§ FORCING ENVIRONMENT VARIABLE OVERRIDES...")
22
-
23
- # Remove any HF environment variables that could cause URL concatenation
24
- problematic_env_vars = [
25
- 'HF_API_URL',
26
- 'HF_INFERENCE_URL',
27
- 'HF_ENDPOINT_URL',
28
- 'HF_MODEL',
29
- 'HUGGINGFACE_API_URL',
30
- 'HUGGINGFACE_INFERENCE_URL'
31
- ]
32
-
33
- for var in problematic_env_vars:
34
- if var in os.environ:
35
- old_value = os.environ[var]
36
- del os.environ[var]
37
- print(f"πŸ—‘οΈ Removed environment variable: {var} = {old_value}")
38
-
39
- print("βœ… Environment variables cleaned")
40
-
41
  # Add current directory to path
42
  sys.path.append(os.path.dirname(os.path.abspath(__file__)))
43
 
@@ -68,22 +47,14 @@ except ImportError:
68
  logging.basicConfig(level=logging.INFO)
69
  logger = logging.getLogger(__name__)
70
 
71
- # Configuration - ABSOLUTELY HARDCODED VALUES (NO ENV VARS ALLOWED)
72
- HF_API_KEY = os.getenv('HF_API_KEY', '') # Only this one env var is allowed
73
- # FORCE HARDCODED VALUES - IGNORE ALL OTHER ENVIRONMENT VARIABLES
74
  HF_ENDPOINT_URL = "https://evxgv66ksxjlfrts.us-east-1.aws.endpoints.huggingface.cloud/v1/"
75
  HF_MODEL = "lmstudio-community/Llama-3.3-70B-Instruct-GGUF" # Correct model name for your endpoint
76
 
77
- print(f"πŸ” FORCED hardcoded endpoint: {HF_ENDPOINT_URL}")
78
- print(f"πŸ” FORCED hardcoded model: {HF_MODEL}")
79
- print(f"πŸ”‘ HF_API_KEY configured: {'Yes' if HF_API_KEY else 'No'}")
80
-
81
- # EXTRA PROTECTION: Override any modules that might have cached env vars
82
- import sys
83
- if 'requests' in sys.modules:
84
- print("πŸ”„ Requests module detected - ensuring no cached env vars")
85
- if 'httpx' in sys.modules:
86
- print("πŸ”„ HTTPX module detected - ensuring no cached env vars")
87
 
88
  # OpenAI client configuration for the endpoint
89
  def get_openai_client():
@@ -106,92 +77,53 @@ def get_openai_client():
106
  SAMPLE_VALID_RDF = '''<?xml version="1.0" encoding="UTF-8"?>
107
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
108
  xmlns:bf="http://id.loc.gov/ontologies/bibframe/"
109
- xmlns:bflc="http://id.loc.gov/ontologies/bflc/"
110
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
111
 
112
  <bf:Work rdf:about="http://example.org/work/1">
113
  <rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Text"/>
114
  <bf:title>
115
  <bf:Title>
116
- <bf:mainTitle>Complete Valid Monograph Title</bf:mainTitle>
117
- <bf:subtitle>A Comprehensive Example for SHACL Validation</bf:subtitle>
118
- </bf:Title>
119
- </bf:title>
120
- <bf:creator>
121
- <bf:Agent>
122
- <rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Person"/>
123
- <rdfs:label>Valid Author Name</rdfs:label>
124
- </bf:Agent>
125
- </bf:creator>
126
- <bf:subject>
127
- <bf:Topic>
128
- <rdfs:label>Library Science</rdfs:label>
129
- </bf:Topic>
130
- </bf:subject>
131
- <bf:language>
132
- <bf:Language rdf:about="http://id.loc.gov/vocabulary/languages/eng"/>
133
- </bf:language>
134
- <bf:hasInstance rdf:resource="http://example.org/instance/1"/>
135
- </bf:Work>
136
-
137
- <bf:Instance rdf:about="http://example.org/instance/1">
138
- <rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Print"/>
139
- <bf:instanceOf rdf:resource="http://example.org/work/1"/>
140
- <bf:title>
141
- <bf:Title>
142
- <bf:mainTitle>Complete Valid Monograph Title</bf:mainTitle>
143
  </bf:Title>
144
  </bf:title>
145
- <bf:provisionActivity>
146
- <bf:Publication>
147
- <bf:date>2024</bf:date>
148
- <bf:place>
149
- <bf:Place>
150
- <rdfs:label>Washington, DC</rdfs:label>
151
- </bf:Place>
152
- </bf:place>
153
  <bf:agent>
154
  <bf:Agent>
155
- <rdfs:label>Sample Publisher</rdfs:label>
156
  </bf:Agent>
157
  </bf:agent>
158
- </bf:Publication>
159
- </bf:provisionActivity>
160
- <bf:extent>
161
- <bf:Extent>
162
- <rdfs:label>256 pages</rdfs:label>
163
- </bf:Extent>
164
- </bf:extent>
165
- </bf:Instance>
 
 
 
 
 
 
 
 
 
 
 
166
 
167
  </rdf:RDF>'''
168
 
169
  SAMPLE_INVALID_RDF = '''<?xml version="1.0" encoding="UTF-8"?>
170
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
171
- xmlns:bf="http://id.loc.gov/ontologies/bibframe/"
172
- xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
173
-
174
  <bf:Work rdf:about="http://example.org/work/1">
175
- <!-- Missing rdf:type - this should cause SHACL validation failure -->
176
- <bf:title>
177
- <!-- Missing bf:Title wrapper - improper title structure -->
178
- <bf:mainTitle>Invalid Monograph Title Structure</bf:mainTitle>
179
- </bf:title>
180
- <!-- Missing required bf:creator property -->
181
- <!-- Missing other required properties like bf:language -->
182
  </bf:Work>
183
-
184
- <bf:Instance rdf:about="http://example.org/instance/1">
185
- <rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Print"/>
186
- <!-- Missing bf:instanceOf property - should link to Work -->
187
- <bf:title>
188
- <bf:Title>
189
- <bf:mainTitle>Invalid Instance Title</bf:mainTitle>
190
- </bf:Title>
191
- </bf:title>
192
- <!-- Missing required bf:provisionActivity -->
193
- </bf:Instance>
194
-
195
  </rdf:RDF>'''
196
 
197
  # MCP Server Tools (can be used independently)
@@ -265,16 +197,13 @@ def get_ai_suggestions(validation_results: str, rdf_content: str) -> str:
265
 
266
  try:
267
  # Use OpenAI client with your Hugging Face Inference Endpoint
268
- print("πŸ” Attempting to get OpenAI client for suggestions...")
269
  client = get_openai_client()
270
  if not client:
271
- print("❌ OpenAI client is None for suggestions.")
272
  return f"""
273
- πŸ”‘ **AI suggestions disabled**: HF_API_KEY not configured or client creation failed.
274
 
275
  {generate_manual_suggestions(validation_results)}
276
  """
277
- print(f"βœ… OpenAI client obtained for suggestions. Client timeout: {client.timeout}")
278
 
279
  prompt = f"""You are an expert in RDF/XML and SHACL validation. Analyze the following validation results and provide clear, actionable suggestions for fixing the RDF issues.
280
 
@@ -293,9 +222,9 @@ Please provide:
293
  Format your response in a helpful, structured way using markdown."""
294
 
295
  # Make API call using OpenAI client
296
- print(f"πŸ”„ Making SUGGESTION API call to: {HF_ENDPOINT_URL} with model: {HF_MODEL}")
 
297
  print(f"πŸ”„ Client base_url: {client.base_url}")
298
- print("⏳ Attempting client.chat.completions.create() for suggestions...")
299
 
300
  chat_completion = client.chat.completions.create(
301
  model=HF_MODEL,
@@ -310,34 +239,73 @@ Format your response in a helpful, structured way using markdown."""
310
  top_p=0.9
311
  )
312
 
313
- print(f"βœ… client.chat.completions.create() returned for suggestions. Type: {type(chat_completion)}")
314
  generated_text = chat_completion.choices[0].message.content
315
- print("βœ… Suggestion API call successful, content extracted.")
316
  return f"πŸ€– **AI-Powered Suggestions:**\n\n{generated_text}"
317
 
318
  except Exception as e:
319
- logger.error(f"OpenAI/HF Inference Endpoint error (suggestions): {str(e)}", exc_info=True) # Added exc_info for full traceback
320
  return f"""
321
  ❌ **AI suggestions error**: {str(e)}
322
 
323
  {generate_manual_suggestions(validation_results)}
324
  """
325
 
326
- def get_ai_correction(validation_results: str, rdf_content: str) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  """
328
  Generate AI-powered corrected RDF/XML based on validation errors.
329
 
330
  This tool takes invalid RDF/XML and validation results, then generates
331
  a corrected version that addresses all identified validation issues.
 
332
 
333
  Args:
334
  validation_results (str): The validation error messages
335
  rdf_content (str): The original invalid RDF/XML content
 
 
336
 
337
  Returns:
338
  str: Corrected RDF/XML that should pass validation
339
  """
340
 
 
 
 
 
 
 
 
 
341
  if not OPENAI_AVAILABLE:
342
  return generate_manual_correction_hints(validation_results, rdf_content)
343
 
@@ -349,17 +317,15 @@ def get_ai_correction(validation_results: str, rdf_content: str) -> str:
349
  {generate_manual_correction_hints(validation_results, rdf_content)}"""
350
 
351
  try:
352
- # Use OpenAI client with your Hugging Face Inference Endpoint
353
- print("πŸ” Attempting to get OpenAI client for correction...")
354
  client = get_openai_client()
355
  if not client:
356
- print("❌ OpenAI client is None for correction.")
357
- return f"""<!-- AI correction disabled: HF_API_KEY not configured or client creation failed. -->
358
 
359
  {generate_manual_correction_hints(validation_results, rdf_content)}"""
360
- print(f"βœ… OpenAI client obtained for correction. Client timeout: {client.timeout}")
361
 
362
- prompt = f"""You are an expert in RDF/XML. Fix the following RDF/XML based on the validation errors provided.
 
 
363
 
364
  Validation Errors:
365
  {validation_results}
@@ -367,39 +333,69 @@ Validation Errors:
367
  Original RDF/XML:
368
  {rdf_content}
369
 
 
 
370
  Please provide the corrected RDF/XML that addresses all validation issues.
371
  - Return only the corrected XML without additional explanation
372
  - Maintain the original structure as much as possible while fixing errors
373
  - Ensure all namespace declarations are present
374
  - Add any missing required properties
375
  - Fix any syntax or structural issues"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
 
377
- # Make API call using OpenAI client
378
- print(f"πŸ”„ Making CORRECTION API call to: {HF_ENDPOINT_URL} with model: {HF_MODEL}")
379
- print(f"πŸ”„ Client base_url: {client.base_url}")
380
- print("⏳ Attempting client.chat.completions.create() for correction...")
381
-
382
- chat_completion = client.chat.completions.create(
383
- model=HF_MODEL,
384
- messages=[
385
- {
386
- "role": "user",
387
- "content": prompt
388
- }
389
- ],
390
- max_tokens=2000,
391
- temperature=0.3,
392
- top_p=0.9
393
- )
394
-
395
- print(f"βœ… client.chat.completions.create() returned for correction. Type: {type(chat_completion)}")
396
- corrected_text = chat_completion.choices[0].message.content
397
- print("βœ… Correction API call successful, content extracted.")
398
- return corrected_text
399
 
400
  except Exception as e:
401
- logger.error(f"OpenAI/HF Inference Endpoint error (correction): {str(e)}", exc_info=True) # Added exc_info for full traceback
402
- return f"""<!-- AI correction error: {str(e)} -->
403
 
404
  {generate_manual_correction_hints(validation_results, rdf_content)}"""
405
 
@@ -485,7 +481,7 @@ def validate_rdf_interface(rdf_content: str, template: str, use_ai: bool = True)
485
  else:
486
  if use_ai:
487
  suggestions = get_ai_suggestions(results_text, rdf_content)
488
- corrected_rdf = get_ai_correction(results_text, rdf_content)
489
  else:
490
  suggestions = generate_manual_suggestions(results_text)
491
  corrected_rdf = generate_manual_correction_hints(results_text, rdf_content)
@@ -575,7 +571,7 @@ def create_interface():
575
 
576
  gr.HTML(f"""
577
  <div class="header-text">
578
- <h1>πŸ”— RDF Validation Server with AI</h1>
579
  <p>Validate RDF/XML against SHACL schemas with AI-powered suggestions and corrections</p>
580
  <p><strong>Status:</strong> {api_status}</p>
581
  <details><summary>Debug Info</summary><pre>{debug_info}</pre></details>
@@ -609,15 +605,6 @@ def create_interface():
609
  )
610
 
611
  validate_btn = gr.Button("πŸ” Validate RDF", variant="primary", size="lg")
612
-
613
- # Examples and controls
614
- gr.Markdown("### πŸ“š Examples & Tools")
615
-
616
- with gr.Row():
617
- example1_btn = gr.Button("βœ… Valid RDF Example", variant="secondary")
618
- example2_btn = gr.Button("❌ Invalid RDF Example", variant="secondary")
619
- example3_btn = gr.Button("πŸ“– BibFrame Example", variant="secondary")
620
- clear_btn = gr.Button("πŸ—‘οΈ Clear All", variant="stop")
621
 
622
  # Results section
623
  with gr.Row():
@@ -658,6 +645,16 @@ def create_interface():
658
  placeholder="Corrected RDF will appear here after validation..."
659
  )
660
 
 
 
 
 
 
 
 
 
 
 
661
  # Event handlers
662
  validate_btn.click(
663
  fn=validate_rdf_interface,
@@ -736,16 +733,6 @@ def create_interface():
736
 
737
  # Launch configuration
738
  if __name__ == "__main__":
739
- # Force verify environment is clean
740
- print("πŸ” FINAL CHECK: Verifying problematic environment variables are removed...")
741
- for var in problematic_env_vars:
742
- if var in os.environ:
743
- print(f"⚠️ WARNING: {var} still exists! Value: {os.environ[var]}")
744
- del os.environ[var]
745
- print(f"πŸ—‘οΈ FORCE REMOVED: {var}")
746
- else:
747
- print(f"βœ… {var} confirmed not in environment")
748
-
749
  demo = create_interface()
750
 
751
  # Configuration for different environments
@@ -757,5 +744,6 @@ if __name__ == "__main__":
757
  share=False, # Don't create gradio.live links in production
758
  show_error=True, # Show errors in the interface
759
  show_api=True, # Enable API endpoints
760
- allowed_paths=["."] # Allow serving files from current directory
 
761
  )
 
17
  import threading
18
  import time
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  # Add current directory to path
21
  sys.path.append(os.path.dirname(os.path.abspath(__file__)))
22
 
 
47
  logging.basicConfig(level=logging.INFO)
48
  logger = logging.getLogger(__name__)
49
 
50
+ # Configuration - Your specific Hugging Face Inference Endpoint (hardcoded)
51
+ HF_API_KEY = os.getenv('HF_API_KEY', '') # Hugging Face API key from Secret
 
52
  HF_ENDPOINT_URL = "https://evxgv66ksxjlfrts.us-east-1.aws.endpoints.huggingface.cloud/v1/"
53
  HF_MODEL = "lmstudio-community/Llama-3.3-70B-Instruct-GGUF" # Correct model name for your endpoint
54
 
55
+ # AI Correction Configuration
56
+ MAX_CORRECTION_ATTEMPTS = 3 # Maximum number of attempts to generate valid RDF
57
+ ENABLE_VALIDATION_LOOP = True # Set to False to disable validation loop for debugging
 
 
 
 
 
 
 
58
 
59
  # OpenAI client configuration for the endpoint
60
  def get_openai_client():
 
77
  SAMPLE_VALID_RDF = '''<?xml version="1.0" encoding="UTF-8"?>
78
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
79
  xmlns:bf="http://id.loc.gov/ontologies/bibframe/"
 
80
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
81
 
82
  <bf:Work rdf:about="http://example.org/work/1">
83
  <rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Text"/>
84
  <bf:title>
85
  <bf:Title>
86
+ <bf:mainTitle>Sample Monograph Title</bf:mainTitle>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  </bf:Title>
88
  </bf:title>
89
+ <bf:contribution>
90
+ <bf:Contribution>
 
 
 
 
 
 
91
  <bf:agent>
92
  <bf:Agent>
93
+ <rdfs:label>Sample Author</rdfs:label>
94
  </bf:Agent>
95
  </bf:agent>
96
+ <bf:role>
97
+ <bf:Role>
98
+ <rdfs:label>Author</rdfs:label>
99
+ </bf:Role>
100
+ </bf:role>
101
+ </bf:Contribution>
102
+ </bf:contribution>
103
+ <bf:language rdf:resource="http://id.loc.gov/vocabulary/languages/eng"/>
104
+ <bf:content rdf:resource="http://id.loc.gov/vocabulary/contentTypes/txt"/>
105
+ <bf:adminMetadata>
106
+ <bf:AdminMetadata>
107
+ <bf:assigner>
108
+ <bf:Organization>
109
+ <rdfs:label>Example Library</rdfs:label>
110
+ </bf:Organization>
111
+ </bf:assigner>
112
+ </bf:AdminMetadata>
113
+ </bf:adminMetadata>
114
+ </bf:Work>
115
 
116
  </rdf:RDF>'''
117
 
118
  SAMPLE_INVALID_RDF = '''<?xml version="1.0" encoding="UTF-8"?>
119
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
120
+ <!-- Missing namespace declarations -->
121
+ <!-- Missing required properties -->
 
122
  <bf:Work rdf:about="http://example.org/work/1">
123
+ <bf:title>Incomplete Title</bf:title>
124
+ <!-- Missing rdf:type -->
125
+ <!-- Missing proper title structure -->
 
 
 
 
126
  </bf:Work>
 
 
 
 
 
 
 
 
 
 
 
 
127
  </rdf:RDF>'''
128
 
129
  # MCP Server Tools (can be used independently)
 
197
 
198
  try:
199
  # Use OpenAI client with your Hugging Face Inference Endpoint
 
200
  client = get_openai_client()
201
  if not client:
 
202
  return f"""
203
+ πŸ”‘ **AI suggestions disabled**: HF_API_KEY not configured.
204
 
205
  {generate_manual_suggestions(validation_results)}
206
  """
 
207
 
208
  prompt = f"""You are an expert in RDF/XML and SHACL validation. Analyze the following validation results and provide clear, actionable suggestions for fixing the RDF issues.
209
 
 
222
  Format your response in a helpful, structured way using markdown."""
223
 
224
  # Make API call using OpenAI client
225
+ print(f"πŸ”„ Making API call to: {HF_ENDPOINT_URL}")
226
+ print(f"πŸ”„ Using model: {HF_MODEL}")
227
  print(f"πŸ”„ Client base_url: {client.base_url}")
 
228
 
229
  chat_completion = client.chat.completions.create(
230
  model=HF_MODEL,
 
239
  top_p=0.9
240
  )
241
 
242
+ print("βœ… API call successful")
243
  generated_text = chat_completion.choices[0].message.content
 
244
  return f"πŸ€– **AI-Powered Suggestions:**\n\n{generated_text}"
245
 
246
  except Exception as e:
247
+ logger.error(f"OpenAI/HF Inference Endpoint error: {str(e)}")
248
  return f"""
249
  ❌ **AI suggestions error**: {str(e)}
250
 
251
  {generate_manual_suggestions(validation_results)}
252
  """
253
 
254
+ def extract_rdf_from_response(response: str) -> str:
255
+ """
256
+ Extract RDF/XML content from AI response, handling code blocks.
257
+
258
+ Args:
259
+ response (str): AI response that may contain RDF wrapped in code blocks
260
+
261
+ Returns:
262
+ str: Extracted RDF/XML content
263
+ """
264
+ response = response.strip()
265
+
266
+ # Handle ```xml code blocks
267
+ if "```xml" in response:
268
+ try:
269
+ return response.split("```xml")[1].split("```")[0].strip()
270
+ except IndexError:
271
+ pass
272
+
273
+ # Handle generic ``` code blocks
274
+ if "```" in response and response.count("```") >= 2:
275
+ try:
276
+ return response.split("```")[1].split("```")[0].strip()
277
+ except IndexError:
278
+ pass
279
+
280
+ # If no code blocks found, return the response as-is
281
+ return response
282
+
283
+ def get_ai_correction(validation_results: str, rdf_content: str, template: str = 'monograph', max_attempts: int = None) -> str:
284
  """
285
  Generate AI-powered corrected RDF/XML based on validation errors.
286
 
287
  This tool takes invalid RDF/XML and validation results, then generates
288
  a corrected version that addresses all identified validation issues.
289
+ The generated correction is validated before being returned to the user.
290
 
291
  Args:
292
  validation_results (str): The validation error messages
293
  rdf_content (str): The original invalid RDF/XML content
294
+ template (str): The validation template to use
295
+ max_attempts (int): Maximum number of attempts to generate valid RDF (uses MAX_CORRECTION_ATTEMPTS if None)
296
 
297
  Returns:
298
  str: Corrected RDF/XML that should pass validation
299
  """
300
 
301
+ # Use configuration default if not specified
302
+ if max_attempts is None:
303
+ max_attempts = MAX_CORRECTION_ATTEMPTS
304
+
305
+ # Check if validation loop is enabled
306
+ if not ENABLE_VALIDATION_LOOP:
307
+ max_attempts = 1 # Fall back to single attempt if validation loop disabled
308
+
309
  if not OPENAI_AVAILABLE:
310
  return generate_manual_correction_hints(validation_results, rdf_content)
311
 
 
317
  {generate_manual_correction_hints(validation_results, rdf_content)}"""
318
 
319
  try:
 
 
320
  client = get_openai_client()
321
  if not client:
322
+ return f"""<!-- AI correction disabled: HF_API_KEY not configured -->
 
323
 
324
  {generate_manual_correction_hints(validation_results, rdf_content)}"""
 
325
 
326
+ # Try multiple attempts to generate valid RDF
327
+ for attempt in range(max_attempts):
328
+ prompt = f"""You are an expert in RDF/XML. Fix the following RDF/XML based on the validation errors provided.
329
 
330
  Validation Errors:
331
  {validation_results}
 
333
  Original RDF/XML:
334
  {rdf_content}
335
 
336
+ {f"Previous attempt {attempt} still had validation errors. Please fix ALL issues this time." if attempt > 0 else ""}
337
+
338
  Please provide the corrected RDF/XML that addresses all validation issues.
339
  - Return only the corrected XML without additional explanation
340
  - Maintain the original structure as much as possible while fixing errors
341
  - Ensure all namespace declarations are present
342
  - Add any missing required properties
343
  - Fix any syntax or structural issues"""
344
+
345
+ print(f"πŸ”„ Correction attempt {attempt + 1}/{max_attempts}")
346
+ print(f"πŸ”„ Using endpoint: {HF_ENDPOINT_URL}")
347
+ print(f"πŸ”„ Using model: {HF_MODEL}")
348
+
349
+ chat_completion = client.chat.completions.create(
350
+ model=HF_MODEL,
351
+ messages=[
352
+ {
353
+ "role": "user",
354
+ "content": prompt
355
+ }
356
+ ],
357
+ max_tokens=2000,
358
+ temperature=0.3 # Lower temperature for more consistent output
359
+ )
360
+
361
+ corrected_rdf = chat_completion.choices[0].message.content.strip()
362
+
363
+ # Extract RDF content if it's wrapped in code blocks
364
+ corrected_rdf = extract_rdf_from_response(corrected_rdf)
365
+
366
+ # Validate the corrected RDF
367
+ if VALIDATOR_AVAILABLE:
368
+ try:
369
+ # Validate the corrected RDF using the same template
370
+ conforms, new_results = validate_rdf(corrected_rdf.encode('utf-8'), template)
371
+
372
+ if conforms:
373
+ print(f"βœ… Correction validated successfully on attempt {attempt + 1}")
374
+ return f"""<!-- AI-generated correction validated successfully -->
375
+ {corrected_rdf}"""
376
+ else:
377
+ print(f"❌ Correction attempt {attempt + 1} still has validation errors")
378
+ # Update validation_results for next attempt
379
+ validation_results = new_results
380
+
381
+ except Exception as e:
382
+ print(f"⚠️ Error validating correction attempt {attempt + 1}: {str(e)}")
383
+ # Continue to next attempt
384
+ else:
385
+ # If validator not available, return the first attempt
386
+ print("⚠️ Validator not available, returning unvalidated correction")
387
+ return corrected_rdf
388
 
389
+ # All attempts failed
390
+ return f"""<!-- AI correction failed after {max_attempts} attempts to generate valid RDF -->
391
+ <!-- The AI-generated corrections still contained validation errors -->
392
+ <!-- Please correct manually using the validation results as a guide -->
393
+
394
+ {generate_manual_correction_hints(validation_results, rdf_content)}"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
 
396
  except Exception as e:
397
+ logger.error(f"LLM API error: {str(e)}")
398
+ return f"""<!-- Error generating AI correction: {str(e)} -->
399
 
400
  {generate_manual_correction_hints(validation_results, rdf_content)}"""
401
 
 
481
  else:
482
  if use_ai:
483
  suggestions = get_ai_suggestions(results_text, rdf_content)
484
+ corrected_rdf = get_ai_correction(results_text, rdf_content, template)
485
  else:
486
  suggestions = generate_manual_suggestions(results_text)
487
  corrected_rdf = generate_manual_correction_hints(results_text, rdf_content)
 
571
 
572
  gr.HTML(f"""
573
  <div class="header-text">
574
+ <h1>πŸ” RDF Validation Server with AI</h1>
575
  <p>Validate RDF/XML against SHACL schemas with AI-powered suggestions and corrections</p>
576
  <p><strong>Status:</strong> {api_status}</p>
577
  <details><summary>Debug Info</summary><pre>{debug_info}</pre></details>
 
605
  )
606
 
607
  validate_btn = gr.Button("πŸ” Validate RDF", variant="primary", size="lg")
 
 
 
 
 
 
 
 
 
608
 
609
  # Results section
610
  with gr.Row():
 
645
  placeholder="Corrected RDF will appear here after validation..."
646
  )
647
 
648
+ # Examples and controls
649
+ with gr.Row():
650
+ gr.Markdown("### πŸ“š Examples & Tools")
651
+
652
+ with gr.Row():
653
+ example1_btn = gr.Button("βœ… Valid RDF Example", variant="secondary")
654
+ example2_btn = gr.Button("❌ Invalid RDF Example", variant="secondary")
655
+ example3_btn = gr.Button("πŸ“– BibFrame Example", variant="secondary")
656
+ clear_btn = gr.Button("πŸ—‘οΈ Clear All", variant="stop")
657
+
658
  # Event handlers
659
  validate_btn.click(
660
  fn=validate_rdf_interface,
 
733
 
734
  # Launch configuration
735
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
736
  demo = create_interface()
737
 
738
  # Configuration for different environments
 
744
  share=False, # Don't create gradio.live links in production
745
  show_error=True, # Show errors in the interface
746
  show_api=True, # Enable API endpoints
747
+ allowed_paths=["."], # Allow serving files from current directory
748
+ mcp_server=True # Enable MCP server functionality (Gradio 5.28+)
749
  )