-
Notifications
You must be signed in to change notification settings - Fork 12
200 lines (174 loc) · 11.5 KB
/
lore-checker.yml
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
name: Lore Checker
on:
pull_request:
paths:
- '01_Вселенная/**'
- '02_Станция/**'
- '03_Государства/**'
- '04_Корпорации/**'
- '05_Организации/**'
- '06_Расы/**'
- '07_Существа/**'
- '08_Технологии/**'
- '09_Вооружение/**'
- '10_Явления/**'
- '11_Товары/**'
- '12_Другое/**'
- '13_Истории/**'
- '14_Повседневность/**'
jobs:
lore_checker:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install dependencies
run: |
pip install --upgrade pip
pip cache purge
pip install google-generativeai==0.4.0
pip install google-ai-generativelanguage==0.4.0
pip install google-auth>=2.15.0
pip install google-api-core
pip install protobuf
pip install pydantic
pip install tqdm
pip install typing-extensions
pip install "proto-plus>=1.22.3"
pip install "googleapis-common-protos>=1.56.2"
pip install requests>=2.18.0
pip install cachetools>=2.0.0
pip install pyasn1-modules>=0.2.1
pip install rsa>=3.1.4
pip install annotated-types>=0.6.0
pip install pydantic-core
pip install grpcio>=1.33.2
pip install grpcio-status>=1.33.2
pip install pyasn1>=0.4.6
- name: Analyze Markdown Changes
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: |
python <<'EOF'
import os
import subprocess
import google.generativeai as genai
import requests
import json
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-1.5-flash")
def get_changed_files():
changed_files = []
pr_number = os.getenv("GITHUB_REF").split('/')[-2]
api_url = f"https://api.github.com/repos/{os.getenv('GITHUB_REPOSITORY')}/pulls/{pr_number}/files"
headers = {
"Authorization": f"Bearer {os.getenv('GITHUB_TOKEN')}",
"Accept": "application/vnd.github+json",
}
response = requests.get(api_url, headers=headers)
if response.status_code == 200:
files = response.json()
for file in files:
if file["filename"].endswith(".md"):
changed_files.append((file["status"], file["filename"]))
else:
print(f"Failed to get changed files: {response.status_code}, {response.text}")
return changed_files
def get_lore_from_folder(filepath):
lore = []
folder = os.path.dirname(filepath)
for root, _, files in os.walk(folder):
for file in files:
if file.endswith('.md') and file not in ["README.md", "LICENSE.md"]:
with open(os.path.join(root, file), 'r', encoding='utf-8') as f:
lore.append(f.read())
return lore
def create_comment(body):
repo = os.getenv("GITHUB_REPOSITORY")
pr_number = os.getenv("GITHUB_REF").split('/')[-2]
url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments"
headers = {
"Authorization": f"Bearer {os.getenv('GITHUB_TOKEN')}",
"Accept": "application/vnd.github+json",
}
payload = {"body": body}
response = requests.post(url, json=payload, headers=headers)
if response.status_code != 201:
print(f"Failed to post comment: {response.status_code}, {response.text}")
else:
print("Comment posted successfully")
changed_files = get_changed_files()
comments = []
# Initial comment with tags for new files
initial_comments = []
for status, filepath in changed_files:
if status == 'added':
try:
with open(filepath, 'r', encoding='utf-8') as f:
text = f.read()
tags_response = model.generate_content(f"На основе содержания, предложи 3-5 ключевых тега на русском языке в формате '#тег'. Только теги, ничего больше:\n\n{text}")
tags_text = tags_response.candidates[0].content.parts[0].text.strip() if tags_response.candidates and tags_response.candidates[0].content.parts else "Не удалось получить теги."
initial_comments.append(f"### Теги для `{filepath}`\n\n{tags_text}\n")
except Exception as e:
initial_comments.append(f"### Ошибка получения тегов для `{filepath}`: {e}")
if initial_comments:
initial_comment_body = "\n".join(initial_comments)
create_comment(initial_comment_body)
# Process changes
for status, filepath in changed_files:
if status == 'added': # New file
try:
with open(filepath, 'r', encoding='utf-8') as f:
text = f.read()
summary = model.generate_content(f"Кратко опиши содержание следующего текста на русском языке:\n\n{text}")
summary_text = summary.candidates[0].content.parts[0].text.strip() if summary.candidates and summary.candidates[0].content.parts else "Нет доступного описания."
comments.append(f"### Описание для `{filepath}`\n\n{summary_text}\n")
except Exception as e:
comments.append(f"### Ошибка обработки нового файла `{filepath}`: {e}")
elif status == 'modified': # Modified file
try:
result = subprocess.run(["git", "show", f"HEAD~1:{filepath}"], capture_output=True, text=True)
old_text = result.stdout
with open(filepath, 'r', encoding='utf-8') as f:
new_text = f.read()
diff_summary = model.generate_content(f"Кратко опиши изменения в следующем тексте на русском языке:\n\nСтарый текст:\n{old_text}\n\nНовый текст:\n{new_text}")
new_summary = model.generate_content(f"Кратко опиши содержание следующего текста на русском языке:\n\n{new_text}")
diff_summary_text = diff_summary.candidates[0].content.parts[0].text.strip() if diff_summary.candidates and diff_summary.candidates[0].content.parts else "Нет доступного описания изменений"
new_summary_text = new_summary.candidates[0].content.parts[0].text.strip() if new_summary.candidates and new_summary.candidates[0].content.parts else "Нет доступного описания нового текста"
comments.append(
f"### Изменения в `{filepath}`\n\n**Описание изменений:**\n{diff_summary_text}\n\n"
f"**Описание нового текста:**\n{new_summary_text}\n"
)
except Exception as e:
comments.append(f"### Ошибка обработки измененного файла `{filepath}`: {e}")
if status in ['added','modified']:
lore_subset = get_lore_from_folder(filepath)
if lore_subset:
try:
analysis = model.generate_content(f"Кратко проанализируй, насколько изменения в файле {filepath} согласуются со следующим контекстом из той же папки. Сгенерируй анализ на русском языке:\n\n{''.join(lore_subset)}")
analysis_text = analysis.candidates[0].content.parts[0].text.strip() if analysis.candidates and analysis.candidates[0].content.parts else "Анализ соответствия лору недоступен"
comments.append(f"### Анализ соответствия лору для `{filepath}`\n\n{analysis_text}\n")
inconsistencies = model.generate_content(f"Кратко проанализируй текст в файле `{filepath}` на предмет неточностей и противоречий относительно следующего контекста из той же папки. Укажи конкретные места и сформулируй на русском языке:\n\n{''.join(lore_subset)}")
inconsistencies_text = inconsistencies.candidates[0].content.parts[0].text.strip() if inconsistencies.candidates and inconsistencies.candidates[0].content.parts else "Неточностей и противоречий не выявлено."
comments.append(f"### Потенциальные неточности и противоречия в `{filepath}`\n\n{inconsistencies_text}\n")
suggestions = model.generate_content(f"Кратко, на основе анализа текста в файле `{filepath}` и следующего контекста из той же папки, дай советы по улучшению статьи, что стоило бы добавить или исправить, на русском языке:\n\n{''.join(lore_subset)}")
suggestions_text = suggestions.candidates[0].content.parts[0].text.strip() if suggestions.candidates and suggestions.candidates[0].content.parts else "Рекомендации по улучшению отсутствуют."
comments.append(f"### Советы по улучшению для `{filepath}`\n\n{suggestions_text}\n")
clarifications = model.generate_content(f"Кратко укажи на неясные или требующие пояснения моменты в тексте файла `{filepath}` с учетом следующего контекста из той же папки, на русском языке:\n\n{''.join(lore_subset)}")
clarifications_text = clarifications.candidates[0].content.parts[0].text.strip() if clarifications.candidates and clarifications.candidates[0].content.parts else "Неясных моментов не выявлено."
comments.append(f"### Неясные моменты в `{filepath}`\n\n{clarifications_text}\n")
except Exception as e:
comments.append(f"### Ошибка анализа лора для `{filepath}`: {e}")
else:
comments.append(f"### Внимание: Нет файлов лора для сравнения в той же папке, что и `{filepath}`.")
# Post comments to the PR
if comments:
comment_body = "\n".join(comments)
create_comment(comment_body)
EOF