Skip to content

Commit 857183a

Browse files
committed
Merge branch 'main_upstream'
# Conflicts: # api.py # biz/llm/factory.py
2 parents fbe52c5 + e28ee35 commit 857183a

File tree

8 files changed

+566
-136
lines changed

8 files changed

+566
-136
lines changed

api.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from biz.gitlab.webhook_handler import slugify_url
1414
from biz.queue.worker import handle_merge_request_event, handle_push_event, handle_github_pull_request_event, handle_github_push_event
1515
from biz.service.review_service import ReviewService
16+
from biz.utils.config_checker import check_config
1617
from biz.utils.im import notifier
1718
from biz.utils.log import logger
1819
from biz.utils.queue import handle_queue
@@ -22,6 +23,7 @@
2223
api_app = Flask(__name__)
2324

2425
from biz.utils.i18n import get_translator
26+
2527
_ = get_translator()
2628

2729
PUSH_REVIEW_ENABLED = os.environ.get('PUSH_REVIEW_ENABLED', '0') == '1'
@@ -124,6 +126,7 @@ def handle_webhook():
124126
else:
125127
return jsonify({'message': _('Invalid data format')}), 400
126128

129+
127130
def handle_github_webhook(event_type, data):
128131
# 获取GitHub配置
129132
github_token = os.getenv('GITHUB_ACCESS_TOKEN') or request.headers.get('X-GitHub-Token')
@@ -156,6 +159,7 @@ def handle_github_webhook(event_type, data):
156159
logger.error(error_message)
157160
return jsonify(error_message), 400
158161

162+
159163
def handle_gitlab_webhook(data):
160164
object_kind = data.get("object_kind")
161165

@@ -172,7 +176,7 @@ def handle_gitlab_webhook(data):
172176
parsed_url = urlparse(homepage)
173177
gitlab_url = f"{parsed_url.scheme}://{parsed_url.netloc}/"
174178
except Exception as e:
175-
return jsonify({"error": f"Failed to parse homepage URL: {str(e)}"}), 400
179+
return jsonify({"error": _("Failed to parse homepage URL: {}").format(str(e))}), 400
176180

177181
# 优先从环境变量获取,如果没有,则从请求头获取
178182
gitlab_token = os.getenv('GITLAB_ACCESS_TOKEN') or request.headers.get('X-Gitlab-Token')
@@ -207,7 +211,9 @@ def handle_gitlab_webhook(data):
207211
logger.error(error_message)
208212
return jsonify(error_message), 400
209213

214+
210215
if __name__ == '__main__':
216+
check_config()
211217
# 启动定时任务调度器
212218
setup_scheduler()
213219

biz/github/webhook_handler.py

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import json
21
import os
32
import re
43
import time
54

65
import requests
76

7+
from biz.utils.i18n import get_translator
88
from biz.utils.log import logger
99

10+
_ = get_translator()
11+
1012
# 从环境变量中获取支持的文件扩展名
1113
SUPPORTED_EXTENSIONS = os.getenv('SUPPORTED_EXTENSIONS', '.java,.py,.php').split(',')
1214

@@ -21,9 +23,9 @@ def filter_changes(changes: list):
2123
for change in changes:
2224
# 优先检查status字段是否为"removed"
2325
if change.get('status') == 'removed':
24-
logger.info(f"Detected file deletion via status field: {change.get('new_path')}")
26+
logger.info(_("Detected file deletion via status field: {}").format(change.get('new_path')))
2527
continue
26-
28+
2729
# 如果没有status字段或status不为"removed",继续检查diff模式
2830
diff = change.get('diff', '')
2931
if diff:
@@ -34,12 +36,12 @@ def filter_changes(changes: list):
3436
if all(line.startswith('-') or not line for line in diff_lines):
3537
logger.info(f"Detected file deletion via diff pattern: {change.get('new_path')}")
3638
continue
37-
39+
3840
not_deleted_changes.append(change)
39-
40-
logger.info(f"SUPPORTED_EXTENSIONS: {SUPPORTED_EXTENSIONS}")
41-
logger.info(f"After filtering deleted files: {not_deleted_changes}")
42-
41+
42+
logger.info(_("SUPPORTED_EXTENSIONS: {}").format(SUPPORTED_EXTENSIONS))
43+
logger.info(_("After filtering deleted files: {}").format(not_deleted_changes))
44+
4345
# 过滤 `new_path` 以支持的扩展名结尾的元素, 仅保留diff和new_path字段
4446
filtered_changes = [
4547
{
@@ -49,7 +51,7 @@ def filter_changes(changes: list):
4951
for item in not_deleted_changes
5052
if any(item.get('new_path', '').endswith(ext) for ext in SUPPORTED_EXTENSIONS)
5153
]
52-
logger.info(f"After filtering by extension: {filtered_changes}")
54+
logger.info(_("After filtering by extension: {}").format(filtered_changes))
5355
return filtered_changes
5456

5557

@@ -78,7 +80,8 @@ def parse_pull_request_event(self):
7880
def get_pull_request_changes(self) -> list:
7981
# 检查是否为 Pull Request Hook 事件
8082
if self.event_type != 'pull_request':
81-
logger.warn(f"Invalid event type: {self.event_type}. Only 'pull_request' event is supported now.")
83+
logger.warn(
84+
_("Invalid event type: {}. Only 'pull_request' event is supported now.").format(self.event_type))
8285
return []
8386

8487
# GitHub pull request changes API可能存在延迟,多次尝试
@@ -93,7 +96,9 @@ def get_pull_request_changes(self) -> list:
9396
}
9497
response = requests.get(url, headers=headers)
9598
logger.debug(
96-
f"Get changes response from GitHub (attempt {attempt + 1}): {response.status_code}, {response.text}, URL: {url}")
99+
_("Get changes response from GitHub (attempt {attempt}): {response_status_code}, {response_text}, URL: {url}").format(
100+
attempt={attempt + 1}, response_status_code=response.status_code, response_text=response.text,
101+
url=url))
97102

98103
# 检查请求是否成功
99104
if response.status_code == 200:
@@ -111,13 +116,14 @@ def get_pull_request_changes(self) -> list:
111116
return changes
112117
else:
113118
logger.info(
114-
f"Changes is empty, retrying in {retry_delay} seconds... (attempt {attempt + 1}/{max_retries}), URL: {url}")
119+
_("Changes is empty, retrying in {retry_delay} seconds... (attempt {attempt}/{max_retries}), URL: {url}").format(retry_delay=retry_delay,
120+
attempt={attempt + 1}, max_retries=max_retries, url=url))
115121
time.sleep(retry_delay)
116122
else:
117-
logger.warn(f"Failed to get changes from GitHub (URL: {url}): {response.status_code}, {response.text}")
123+
logger.warn(_("Failed to get changes from GitHub (URL: {url}): {response.status_code}, {response.text}").format(url, response.status_code, response.text))
118124
return []
119125

120-
logger.warning(f"Max retries ({max_retries}) reached. Changes is still empty.")
126+
logger.warning(_("Max retries ({}) reached. Changes is still empty.").format(max_retries))
121127
return [] # 达到最大重试次数后返回空列表
122128

123129
def get_pull_request_commits(self) -> list:
@@ -132,8 +138,8 @@ def get_pull_request_commits(self) -> list:
132138
'Accept': 'application/vnd.github.v3+json'
133139
}
134140
response = requests.get(url, headers=headers)
135-
logger.debug(f"Get commits response from GitHub: {response.status_code}, {response.text}")
136-
141+
logger.debug(_("Get commits response from GitHub: {}, {}").format(response.status_code, response.text))
142+
137143
# 检查请求是否成功
138144
if response.status_code == 200:
139145
# 将GitHub的commits转换为GitLab格式的commits
@@ -152,7 +158,7 @@ def get_pull_request_commits(self) -> list:
152158
gitlab_format_commits.append(gitlab_commit)
153159
return gitlab_format_commits
154160
else:
155-
logger.warn(f"Failed to get commits: {response.status_code}, {response.text}")
161+
logger.warn(_("Failed to get commits: {}, {}").format(response.status_code, response.text))
156162
return []
157163

158164
def add_pull_request_notes(self, review_result):
@@ -165,11 +171,11 @@ def add_pull_request_notes(self, review_result):
165171
'body': review_result
166172
}
167173
response = requests.post(url, headers=headers, json=data)
168-
logger.debug(f"Add comment to GitHub PR {url}: {response.status_code}, {response.text}")
174+
logger.debug(_("Add comment to GitHub PR {url}: {response_status_code}, {response_text}").format(url=url, response_status_code=response.status_code, response_text=response.text))
169175
if response.status_code == 201:
170-
logger.info("Comment successfully added to pull request.")
176+
logger.info(_("Comment successfully added to pull request."))
171177
else:
172-
logger.error(f"Failed to add comment: {response.status_code}")
178+
logger.error(_("Failed to add comment: {}").format(response.status_code))
173179
logger.error(response.text)
174180

175181

@@ -198,7 +204,7 @@ def parse_push_event(self):
198204
def get_push_commits(self) -> list:
199205
# 检查是否为 Push 事件
200206
if self.event_type != 'push':
201-
logger.warn(f"Invalid event type: {self.event_type}. Only 'push' event is supported now.")
207+
logger.warn(_("Invalid event type: {}. Only 'push' event is supported now.").format(self.event_type))
202208
return []
203209

204210
# 提取提交信息
@@ -212,19 +218,19 @@ def get_push_commits(self) -> list:
212218
}
213219
commit_details.append(commit_info)
214220

215-
logger.info(f"Collected {len(commit_details)} commits from push event.")
221+
logger.info(_("Collected {} commits from push event.").format(len(commit_details)))
216222
return commit_details
217223

218224
def add_push_notes(self, message: str):
219225
# 添加评论到 GitHub Push 请求的提交中(此处假设是在最后一次提交上添加注释)
220226
if not self.commit_list:
221-
logger.warn("No commits found to add notes to.")
227+
logger.warn(_("No commits found to add notes to."))
222228
return
223229

224230
# 获取最后一个提交的ID
225231
last_commit_id = self.commit_list[-1].get('id')
226232
if not last_commit_id:
227-
logger.error("Last commit ID not found.")
233+
logger.error(_("Last commit ID not found."))
228234
return
229235

230236
url = f"https://api.github.com/repos/{self.repo_full_name}/commits/{last_commit_id}/comments"
@@ -236,11 +242,11 @@ def add_push_notes(self, message: str):
236242
'body': message
237243
}
238244
response = requests.post(url, headers=headers, json=data)
239-
logger.debug(f"Add comment to commit {last_commit_id}: {response.status_code}, {response.text}")
245+
logger.debug(_("Add comment to commit {last_commit_id}: {response_status_code}, {response_text}").format(last_commit_id, response.status_code, response.text))
240246
if response.status_code == 201:
241-
logger.info("Comment successfully added to push commit.")
247+
logger.info(_("Comment successfully added to push commit."))
242248
else:
243-
logger.error(f"Failed to add comment: {response.status_code}")
249+
logger.error(_("Failed to add comment: {}").format(response.status_code))
244250
logger.error(response.text)
245251

246252
def __repository_commits(self, sha: str = "", per_page: int = 100, page: int = 1):
@@ -252,13 +258,14 @@ def __repository_commits(self, sha: str = "", per_page: int = 100, page: int = 1
252258
}
253259
response = requests.get(url, headers=headers)
254260
logger.debug(
255-
f"Get commits response from GitHub for repository_commits: {response.status_code}, {response.text}, URL: {url}")
261+
_("Get commits response from GitHub for repository_commits: {response_status_code}, {response_text}, URL: {url}").format(
262+
response_status_code=response.status_code, response_text=response.text, url=url))
256263

257264
if response.status_code == 200:
258265
return response.json()
259266
else:
260267
logger.warn(
261-
f"Failed to get commits for sha {sha}: {response.status_code}, {response.text}")
268+
_("Failed to get commits for sha {sha}: {response_status_code}, {response_text}").format(sha=sha, response_status_code=response.status_code, response_text=response.text))
262269
return []
263270

264271
def get_parent_commit_id(self, commit_id: str) -> str:
@@ -269,7 +276,8 @@ def get_parent_commit_id(self, commit_id: str) -> str:
269276
}
270277
response = requests.get(url, headers=headers)
271278
logger.debug(
272-
f"Get commit response from GitHub: {response.status_code}, {response.text}, URL: {url}")
279+
_("Get commit response from GitHub: {response_status_code}, {response_text}, URL: {url}").format(
280+
response_status_code=response.status_code, response_text=response.text, url=url))
273281

274282
if response.status_code == 200 and response.json().get('parents'):
275283
return response.json().get('parents')[0].get('sha', '')
@@ -284,7 +292,8 @@ def repository_compare(self, base: str, head: str):
284292
}
285293
response = requests.get(url, headers=headers)
286294
logger.debug(
287-
f"Get changes response from GitHub for repository_compare: {response.status_code}, {response.text}, URL: {url}")
295+
_("Get changes response from GitHub for repository_compare: {response_status_code}, {response_text}, URL: {url}").format(
296+
response_status_code=response.status_code, response_text=response.text, url=url))
288297

289298
if response.status_code == 200:
290299
# 转换为GitLab格式的diffs
@@ -301,18 +310,18 @@ def repository_compare(self, base: str, head: str):
301310
return diffs
302311
else:
303312
logger.warn(
304-
f"Failed to get changes for repository_compare: {response.status_code}, {response.text}")
313+
_("Failed to get changes for repository_compare: {response.status_code}, {response.text}").format(response_status_code=response.status_code, response_text=response.text))
305314
return []
306315

307316
def get_push_changes(self) -> list:
308317
# 检查是否为 Push 事件
309318
if self.event_type != 'push':
310-
logger.warn(f"Invalid event type: {self.event_type}. Only 'push' event is supported now.")
319+
logger.warn(_("Invalid event type: {}. Only 'push' event is supported now.").format(self.event_type))
311320
return []
312321

313322
# 如果没有提交,返回空列表
314323
if not self.commit_list:
315-
logger.info("No commits found in push event.")
324+
logger.info(_("No commits found in push event."))
316325
return []
317326

318327
# 优先尝试compare API获取变更
@@ -330,12 +339,12 @@ def get_push_changes(self) -> list:
330339
elif self.webhook_data.get('deleted', False):
331340
# 删除分支处理
332341
return []
333-
342+
334343
return self.repository_compare(before, after)
335344
else:
336345
# 如果before和after不存在,尝试通过commits获取
337-
logger.info("before or after not found in webhook data, trying to get changes from commits.")
338-
346+
logger.info(_("before or after not found in webhook data, trying to get changes from commits."))
347+
339348
changes = []
340349
for commit in self.commit_list:
341350
commit_id = commit.get('id')
@@ -344,5 +353,5 @@ def get_push_changes(self) -> list:
344353
if parent_id:
345354
commit_changes = self.repository_compare(parent_id, commit_id)
346355
changes.extend(commit_changes)
347-
348-
return changes
356+
357+
return changes

biz/llm/client/base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@
22
from typing import List, Dict, Optional
33

44
from biz.llm.types import NotGiven, NOT_GIVEN
5+
from biz.utils.log import logger
56

67

78
class BaseClient:
89
""" Base class for chat models client. """
910

11+
def ping(self) -> bool:
12+
"""Ping the model to check connectivity."""
13+
try:
14+
result = self.completions(messages=[{"role": "user", "content": '请仅返回 "ok"。'}])
15+
return result and result == 'ok'
16+
except Exception:
17+
logger.error("尝试连接LLM失败, {e}")
18+
return False
19+
1020
@abstractmethod
1121
def completions(self,
1222
messages: List[Dict[str, str]],

biz/llm/factory.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ def getClient(provider: str = None) -> BaseClient:
2424

2525
provider_func = chat_model_providers.get(provider)
2626
if provider_func:
27-
logger.info(_("Successfully loaded LLM provider: {provider}").format(provider=provider))
2827
return provider_func()
2928
else:
3029
raise Exception(_('Unknown chat model provider: {provider}'.format(provider=provider)))

0 commit comments

Comments
 (0)