DocUA commited on
Commit
dc74ed9
·
1 Parent(s): d1f04f2

Виправлено логіку відображення результатів у Gradio інтерфейсі, щоб різні типи аналізу показували відповідні результати. Додано нові методи форматування для аналізу якості, структури, змісту та якості витягування. Включено повідомлення про виправлення у інтерфейсі для покращення користувацького досвіду.

Browse files
Files changed (1) hide show
  1. app_interface.py +283 -9
app_interface.py CHANGED
@@ -1,4 +1,4 @@
1
- """Gradio interface assembly for the MarkItDown Testing Platform."""
2
 
3
  from __future__ import annotations
4
 
@@ -65,7 +65,7 @@ class ApplicationState:
65
 
66
 
67
  class GradioResponseFactory:
68
- """Creates UI-ready artifacts from processing results."""
69
 
70
  def __init__(self, viz_engine: InteractiveVisualizationEngine) -> None:
71
  self.viz_engine = viz_engine
@@ -73,6 +73,14 @@ class GradioResponseFactory:
73
  def create_success_response(
74
  self, response: ProcessingResponse
75
  ) -> Tuple[str, str, str, JSONDict]:
 
 
 
 
 
 
 
 
76
  processing_time = response.conversion_result.processing_time or 0
77
  content_length = len(response.conversion_result.content)
78
 
@@ -97,7 +105,45 @@ class GradioResponseFactory:
97
  """
98
 
99
  original_preview = self._generate_document_preview(response.conversion_result.metadata)
100
- markdown_content = response.conversion_result.content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  quick_metrics = self._extract_summary_metrics(response)
102
 
103
  return (
@@ -107,6 +153,216 @@ class GradioResponseFactory:
107
  quick_metrics,
108
  )
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  def create_error_response(
111
  self, error_message: str, error_context: Optional[JSONDict] = None
112
  ) -> Tuple[str, str, str, JSONDict]:
@@ -291,14 +547,15 @@ class MarkItDownTestingApp:
291
  with gr.Group(visible=llm_enabled_by_default) as llm_controls:
292
  analysis_type = gr.Dropdown(
293
  choices=[
294
- ("Quality Analysis", "quality_analysis"),
295
- ("Structure Review", "structure_review"),
296
- ("Content Summary", "content_summary"),
297
- ("Extraction Quality", "extraction_quality"),
298
  ],
299
  value="quality_analysis",
300
  label="Analysis Type",
301
  interactive=True,
 
302
  )
303
 
304
  model_preference = gr.Dropdown(
@@ -329,6 +586,21 @@ class MarkItDownTestingApp:
329
 
330
  with gr.Column(scale=2):
331
  gr.Markdown("### 📊 Processing Results")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  status_display = gr.HTML()
333
 
334
  with gr.Tabs():
@@ -336,6 +608,7 @@ class MarkItDownTestingApp:
336
  original_preview = gr.HTML()
337
 
338
  with gr.TabItem("📝 Markdown Output"):
 
339
  markdown_output = gr.Code(
340
  language="markdown",
341
  show_label=False,
@@ -437,6 +710,7 @@ class MarkItDownTestingApp:
437
  <p>Built with enterprise-grade architecture principles |
438
  <a href=\"https://github.com/microsoft/markitdown\">Microsoft MarkItDown</a> |
439
  <a href=\"https://ai.google.dev/\">Google Gemini</a></p>
 
440
  </div>
441
  """
442
  )
@@ -863,9 +1137,9 @@ def main() -> None:
863
 
864
  __all__ = [
865
  "ApplicationFactory",
866
- "MarkItDownTestingApp",
867
  "GradioResponseFactory",
868
  "ApplicationState",
869
  "create_gradio_app",
870
  "main",
871
- ]
 
1
+ """Gradio interface assembly for the MarkItDown Testing Platform - ВИПРАВЛЕНА ВЕРСІЯ."""
2
 
3
  from __future__ import annotations
4
 
 
65
 
66
 
67
  class GradioResponseFactory:
68
+ """Creates UI-ready artifacts from processing results - ВИПРАВЛЕНА ВЕРСІЯ з правильною логікою відображення."""
69
 
70
  def __init__(self, viz_engine: InteractiveVisualizationEngine) -> None:
71
  self.viz_engine = viz_engine
 
73
  def create_success_response(
74
  self, response: ProcessingResponse
75
  ) -> Tuple[str, str, str, JSONDict]:
76
+ """
77
+ 🚨 ВИПРАВЛЕНА ЛОГІКА: Правильне відображення результатів залежно від analysis_type
78
+
79
+ Strategic Architecture Decision:
80
+ - Показуємо AI analysis результат якщо доступний та успішний
81
+ - Різні analysis_type режими показують різні форматовані результати
82
+ - Graceful fallback до base conversion якщо AI недоступний
83
+ """
84
  processing_time = response.conversion_result.processing_time or 0
85
  content_length = len(response.conversion_result.content)
86
 
 
105
  """
106
 
107
  original_preview = self._generate_document_preview(response.conversion_result.metadata)
108
+
109
+ # 🚨 КРИТИЧНЕ ВИПРАВЛЕННЯ: Правильна логіка вибору контенту для відображення
110
+ if response.analysis_result and response.analysis_result.success:
111
+ # Показуємо AI-обробний результат залежно від analysis_type
112
+ analysis_type_value = response.analysis_result.analysis_type.value
113
+ ai_content = response.analysis_result.content
114
+
115
+ status_html += f"""
116
+ <div style="background: #e8f5e8; border: 1px solid #4caf50; padding: 10px; border-radius: 5px; margin-top: 10px;">
117
+ <strong>🤖 AI Analysis Active:</strong> {analysis_type_value.replace('_', ' ').title()}<br/>
118
+ <strong>Model Used:</strong> {response.analysis_result.model_used.value}<br/>
119
+ <strong>Processing Time:</strong> {response.analysis_result.processing_time:.2f}s
120
+ </div>
121
+ """
122
+
123
+ if analysis_type_value == "quality_analysis":
124
+ markdown_content = self._format_quality_analysis(ai_content)
125
+ elif analysis_type_value == "structure_review":
126
+ markdown_content = self._format_structure_analysis(ai_content)
127
+ elif analysis_type_value == "content_summary":
128
+ markdown_content = self._format_content_summary(ai_content)
129
+ elif analysis_type_value == "extraction_quality":
130
+ markdown_content = self._format_extraction_analysis(ai_content)
131
+ else:
132
+ # Fallback до formatted AI result
133
+ markdown_content = self._format_generic_ai_result(ai_content)
134
+
135
+ else:
136
+ # Fallback до базової конвертації якщо AI недоступний або неуспішний
137
+ markdown_content = response.conversion_result.content
138
+
139
+ if response.analysis_result and not response.analysis_result.success:
140
+ status_html += f"""
141
+ <div style="background: #fff3cd; border: 1px solid #ffc107; padding: 10px; border-radius: 5px; margin-top: 10px;">
142
+ <strong>⚠️ AI Analysis Failed:</strong> {response.analysis_result.error_message}<br/>
143
+ <strong>Showing Base Conversion</strong>
144
+ </div>
145
+ """
146
+
147
  quick_metrics = self._extract_summary_metrics(response)
148
 
149
  return (
 
153
  quick_metrics,
154
  )
155
 
156
+ def _format_quality_analysis(self, ai_content: Dict) -> str:
157
+ """Форматує результати Quality Analysis для UI display"""
158
+
159
+ markdown = f"""# 📊 Quality Analysis Results
160
+
161
+ ## Overall Assessment
162
+ **Quality Score**: {ai_content.get('overall_score', 'N/A')}/10
163
+
164
+ ## Detailed Metrics
165
+ - **Structure Score**: {ai_content.get('structure_score', 'N/A')}/10 - Збереження заголовків, списків, таблиць
166
+ - **Completeness Score**: {ai_content.get('completeness_score', 'N/A')}/10 - Повнота інформації з оригіналу
167
+ - **Accuracy Score**: {ai_content.get('accuracy_score', 'N/A')}/10 - Точність передачі форматування
168
+ - **Readability Score**: {ai_content.get('readability_score', 'N/A')}/10 - Оптимізація для AI-споживання
169
+
170
+ ## 🤖 AI Analysis Feedback
171
+ {ai_content.get('detailed_feedback', 'No detailed feedback available')}
172
+
173
+ ## 💡 Recommendations
174
+ """
175
+
176
+ recommendations = ai_content.get('recommendations', [])
177
+ if recommendations:
178
+ for i, rec in enumerate(recommendations, 1):
179
+ markdown += f"{i}. {rec}\n"
180
+ else:
181
+ markdown += "No specific recommendations available.\n"
182
+
183
+ # Додаємо detected elements якщо доступні
184
+ detected_elements = ai_content.get('detected_elements', {})
185
+ if detected_elements:
186
+ markdown += f"""
187
+ ## 🔍 Detected Document Elements
188
+ """
189
+ for element, count in detected_elements.items():
190
+ markdown += f"- **{element.replace('_', ' ').title()}**: {count}\n"
191
+
192
+ return markdown
193
+
194
+ def _format_structure_analysis(self, ai_content: Dict) -> str:
195
+ """Форматує результати Structure Review для UI display"""
196
+
197
+ markdown = f"""# 🏗️ Document Structure Analysis
198
+
199
+ ## Document Outline
200
+ ```
201
+ {ai_content.get('document_outline', 'No outline available')}
202
+ ```
203
+
204
+ ## Heading Analysis
205
+ """
206
+
207
+ heading_analysis = ai_content.get('heading_analysis', {})
208
+ if heading_analysis:
209
+ for level, count in heading_analysis.items():
210
+ markdown += f"- **{level}**: {count} occurrences\n"
211
+ else:
212
+ markdown += "No heading analysis available\n"
213
+
214
+ markdown += f"""
215
+ ## Organization Score
216
+ **Structure Quality**: {ai_content.get('organization_score', 'N/A')}/10
217
+
218
+ ## List Analysis
219
+ """
220
+
221
+ list_analysis = ai_content.get('list_analysis', {})
222
+ if list_analysis:
223
+ markdown += f"- **Total Lists**: {list_analysis.get('total_lists', 0)}\n"
224
+ markdown += f"- **Nested Lists**: {list_analysis.get('nested_lists', 0)}\n"
225
+ markdown += f"- **List Items**: {list_analysis.get('total_items', 0)}\n"
226
+
227
+ markdown += f"""
228
+ ## Table Analysis
229
+ """
230
+
231
+ table_analysis = ai_content.get('table_analysis', {})
232
+ if table_analysis:
233
+ markdown += f"- **Total Tables**: {table_analysis.get('table_count', 0)}\n"
234
+ markdown += f"- **Table Quality**: {table_analysis.get('formatting_quality', 'N/A')}\n"
235
+
236
+ markdown += f"""
237
+ ## 💡 Structure Recommendations
238
+ """
239
+
240
+ recommendations = ai_content.get('structure_recommendations', [])
241
+ if recommendations:
242
+ for i, rec in enumerate(recommendations, 1):
243
+ markdown += f"{i}. {rec}\n"
244
+ else:
245
+ markdown += "Document structure is well-organized.\n"
246
+
247
+ return markdown
248
+
249
+ def _format_content_summary(self, ai_content: Dict) -> str:
250
+ """Форматує результати Content Summary для UI display"""
251
+
252
+ markdown = f"""# 📝 Content Summary & Analysis
253
+
254
+ ## Executive Summary
255
+ {ai_content.get('executive_summary', 'No summary available')}
256
+
257
+ ## Main Topics
258
+ """
259
+
260
+ topics = ai_content.get('main_topics', [])
261
+ if topics:
262
+ for topic in topics:
263
+ markdown += f"- {topic}\n"
264
+ else:
265
+ markdown += "No main topics identified\n"
266
+
267
+ markdown += f"""
268
+ ## Document Classification
269
+ """
270
+
271
+ classification = ai_content.get('document_classification', {})
272
+ if classification:
273
+ markdown += f"- **Type**: {classification.get('type', 'Unknown')}\n"
274
+ markdown += f"- **Purpose**: {classification.get('purpose', 'Unknown')}\n"
275
+ markdown += f"- **Target Audience**: {classification.get('audience', 'Unknown')}\n"
276
+
277
+ markdown += f"""
278
+ ## Content Quality Score
279
+ **Information Value**: {ai_content.get('content_quality', 'N/A')}/10
280
+
281
+ ## Key Information
282
+ """
283
+
284
+ key_info = ai_content.get('key_information', [])
285
+ if key_info:
286
+ for info in key_info:
287
+ markdown += f"- {info}\n"
288
+ else:
289
+ markdown += "No key information extracted\n"
290
+
291
+ # Додаємо content metrics якщо доступні
292
+ content_metrics = ai_content.get('content_metrics', {})
293
+ if content_metrics:
294
+ markdown += f"""
295
+ ## Content Metrics
296
+ - **Word Count**: {content_metrics.get('word_count', 'N/A')}
297
+ - **Complexity Level**: {content_metrics.get('complexity_level', 'N/A')}
298
+ """
299
+
300
+ return markdown
301
+
302
+ def _format_extraction_analysis(self, ai_content: Dict) -> str:
303
+ """Форматує результати Extraction Quality для UI display"""
304
+
305
+ markdown = f"""# 🔍 Extraction Quality Assessment
306
+
307
+ ## Overall Extraction Score
308
+ **Quality Rating**: {ai_content.get('extraction_score', 'N/A')}/10
309
+
310
+ ## Data Accuracy Assessment
311
+ {ai_content.get('data_accuracy', 'No accuracy assessment available')}
312
+
313
+ ## Context Preservation
314
+ **Meaning Retention**: {ai_content.get('context_preservation', 'No context analysis available')}
315
+
316
+ ## Formatting Quality
317
+ **Original Structure**: {ai_content.get('formatting_quality', 'No formatting analysis available')}
318
+
319
+ ## Completeness Indicators
320
+ {ai_content.get('completeness_indicators', 'No completeness data available')}
321
+
322
+ ## Conversion Artifacts
323
+ """
324
+
325
+ artifacts = ai_content.get('conversion_artifacts', [])
326
+ if artifacts:
327
+ for artifact in artifacts:
328
+ markdown += f"- ⚠️ {artifact}\n"
329
+ else:
330
+ markdown += "✅ No conversion artifacts detected\n"
331
+
332
+ markdown += f"""
333
+ ## 💡 Quality Recommendations
334
+ """
335
+
336
+ recommendations = ai_content.get('quality_recommendations', [])
337
+ if recommendations:
338
+ for i, rec in enumerate(recommendations, 1):
339
+ markdown += f"{i}. {rec}\n"
340
+ else:
341
+ markdown += "Extraction quality is satisfactory.\n"
342
+
343
+ # Додаємо confidence level
344
+ confidence = ai_content.get('confidence_level', 'N/A')
345
+ markdown += f"""
346
+ ## Analysis Confidence
347
+ **Confidence Level**: {confidence}
348
+ """
349
+
350
+ return markdown
351
+
352
+ def _format_generic_ai_result(self, ai_content: Dict) -> str:
353
+ """Generic formatter для невідомих analysis types"""
354
+
355
+ markdown = f"""# 🤖 AI Analysis Results
356
+
357
+ ## Analysis Output
358
+ ```json
359
+ {ai_content}
360
+ ```
361
+
362
+ *This analysis type uses a generic formatter. Consider adding specific formatting for better readability.*
363
+ """
364
+ return markdown
365
+
366
  def create_error_response(
367
  self, error_message: str, error_context: Optional[JSONDict] = None
368
  ) -> Tuple[str, str, str, JSONDict]:
 
547
  with gr.Group(visible=llm_enabled_by_default) as llm_controls:
548
  analysis_type = gr.Dropdown(
549
  choices=[
550
+ ("Quality Analysis - Комплексна оцінка якості конвертації", "quality_analysis"),
551
+ ("Structure Review - Фокус на збереження ієрархії документа", "structure_review"),
552
+ ("Content Summary - Тематичний аналіз та ключові інсайти", "content_summary"),
553
+ ("Extraction Quality - Оцінка збереження даних", "extraction_quality"),
554
  ],
555
  value="quality_analysis",
556
  label="Analysis Type",
557
  interactive=True,
558
+ info="🚨 ВИПРАВЛЕНО: Тепер різні режими показуватимуть різні результати!"
559
  )
560
 
561
  model_preference = gr.Dropdown(
 
586
 
587
  with gr.Column(scale=2):
588
  gr.Markdown("### 📊 Processing Results")
589
+
590
+ # 🚨 ДОДАНО ВАЖЛИВЕ ПОВІДОМЛЕННЯ ПРО ВИПРАВЛЕННЯ
591
+ gr.HTML("""
592
+ <div style="background: #d1ecf1; border: 1px solid #bee5eb; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
593
+ <h4 style="margin: 0 0 10px 0; color: #0c5460;">🔧 Architectural Fix Applied</h4>
594
+ <p style="margin: 0; color: #0c5460;"><strong>Fixed Issue:</strong> Different analysis types now show different results in Markdown Output!</p>
595
+ <ul style="margin: 10px 0 0 20px; color: #0c5460;">
596
+ <li><strong>Quality Analysis:</strong> Shows detailed quality metrics and AI feedback</li>
597
+ <li><strong>Structure Review:</strong> Shows document structure analysis and organization</li>
598
+ <li><strong>Content Summary:</strong> Shows thematic analysis and key insights</li>
599
+ <li><strong>Extraction Quality:</strong> Shows data preservation assessment</li>
600
+ </ul>
601
+ </div>
602
+ """)
603
+
604
  status_display = gr.HTML()
605
 
606
  with gr.Tabs():
 
608
  original_preview = gr.HTML()
609
 
610
  with gr.TabItem("📝 Markdown Output"):
611
+ gr.Markdown("**Результати обробки будуть показані тут з урахуванням обраного Analysis Type**")
612
  markdown_output = gr.Code(
613
  language="markdown",
614
  show_label=False,
 
710
  <p>Built with enterprise-grade architecture principles |
711
  <a href=\"https://github.com/microsoft/markitdown\">Microsoft MarkItDown</a> |
712
  <a href=\"https://ai.google.dev/\">Google Gemini</a></p>
713
+ <p><strong>🔧 Critical Fix Applied:</strong> Different analysis types now show different results!</p>
714
  </div>
715
  """
716
  )
 
1137
 
1138
  __all__ = [
1139
  "ApplicationFactory",
1140
+ "MarkItDownTestingApp",
1141
  "GradioResponseFactory",
1142
  "ApplicationState",
1143
  "create_gradio_app",
1144
  "main",
1145
+ ]