6.5 KiB
6.5 KiB
🔧 Исправление: Экранирование HTML тегов в комментариях
🐛 Проблема
AI комментарии содержали упоминания JSX/HTML тегов, которые исчезали при отображении в Gitea/GitHub:
До исправления:
Неправильное использование key: key должен быть на элементе , а не на
↑ ↑
<CharacterItem> исчез <img> исчез
Причина: Markdown интерпретирует <CharacterItem> как HTML тег и пытается его отрендерить, но т.к. такого тега не существует, он просто исчезает.
✅ Решение
Добавлена функция _escape_html_in_text(), которая оборачивает HTML-подобные теги в backticks:
def _escape_html_in_text(self, text: str) -> str:
"""Escape HTML tags in text to prevent Markdown from hiding them"""
import re
def replace_tag(match):
tag = match.group(0)
return f"`{tag}`" # Оборачиваем в backticks
# Находим все <...> паттерны
text = re.sub(r'<[^>]+>', replace_tag, text)
return text
🎯 Как работает
Шаг 1: AI генерирует комментарий
"key должен быть на элементе <CharacterItem>, а не на <img>"
Шаг 2: Функция экранирования
text = _escape_html_in_text(text)
# Результат:
"key должен быть на элементе `<CharacterItem>`, а не на `<img>`"
Шаг 3: В Gitea/GitHub отображается
key должен быть на элементе `<CharacterItem>`, а не на `<img>`
↑ ↑ ↑ ↑
backticks делают теги видимыми
📊 Примеры
Пример 1: JSX элементы
Входной текст:
Неправильное использование key: key должен быть на <CharacterItem>, а не на <img>
После обработки:
Неправильное использование key: key должен быть на `<CharacterItem>`, а не на `<img>`
В Gitea видно:
Неправильное использование key: key должен быть на `<CharacterItem>`, а не на `<img>`
Пример 2: HTML теги
Входной текст:
Используйте <div> вместо <span> для обертки
После обработки:
Используйте `<div>` вместо `<span>` для обертки
В Gitea видно:
Используйте `<div>` вместо `<span>` для обертки
Пример 3: Без HTML тегов
Входной текст:
Опечатка в строке: 'shmapplication/json' должно быть 'application/json'
После обработки:
Опечатка в строке: 'shmapplication/json' должно быть 'application/json'
В Gitea видно:
Опечатка в строке: 'shmapplication/json' должно быть 'application/json'
Без изменений - теги не найдены
🔄 Где применяется
Функция вызывается дважды для каждого ревью:
1. Для каждого комментария
for comment_data in state["comments"]:
message = comment_data.get("message", "")
message = self._remove_think_blocks(message)
message = self._escape_html_in_text(message) # ← Экранируем
comment = Comment(content=message, ...)
2. Для общего summary
summary = await self.analyzer.generate_summary(...)
summary = self._remove_think_blocks(summary)
summary = self._escape_html_in_text(summary) # ← Экранируем
await git_service.create_review(body=summary, ...)
🧪 Тестирование
Создан тест для проверки:
test_texts = [
"key должен быть на элементе <CharacterItem>, а не на <img>",
"Используйте <div> вместо <span> здесь"
]
for text in test_texts:
escaped = escape_html_in_text(text)
print(f"Original: {text}")
print(f"Escaped: {escaped}")
Результат:
Original: key должен быть на элементе <CharacterItem>, а не на <img>
Escaped: key должен быть на элементе `<CharacterItem>`, а не на `<img>`
Original: Используйте <div> вместо <span> здесь
Escaped: Используйте `<div>` вместо `<span>` здесь
✅ Работает как ожидалось!
🎨 Визуальное сравнение
❌ До исправления (в Gitea):
❌ src/pages/search-character.tsx:105
ERROR: Неправильное использование key: key должен быть на элементе , а не на
↑ теги исчезли, непонятно о чем речь
✅ После исправления (в Gitea):
❌ src/pages/search-character.tsx:105
ERROR: Неправильное использование key: key должен быть на элементе `<CharacterItem>`, а не на `<img>`
↑ теги видны и кликабельны, все понятно
📝 Измененные файлы
backend/app/agents/reviewer.py:- Добавлена функция
_escape_html_in_text() - Вызов функции для комментариев
- Вызов функции для summary
- Добавлена функция
🚀 Как попробовать
- Backend уже подхватил изменения (
--reload) - Нажмите 🔄 Повторить ревью
- Откройте PR в Gitea
- Проверьте что теги теперь видны:
<CharacterItem>,<img>, и т.д.
✅ Готово!
Теперь все HTML/JSX теги в комментариях отображаются корректно и код понятен! 🎉
Попробуйте прямо сейчас! 🧪