E-3 / E-4: PR コメント拡張機能 完了レポート
実装日時
2025-01-XX
概要
GitHub PR コメントに以下を自動付与する機能を実装しました:
- E-3: Run Markdown レポートを PR コメント末尾に添付(折りたたみ形式)
- E-4: Before/After 差分サマリー(AI 要約)を PR コメントに統合
実装ステップ
Step 1: patch_applier.py に差分抽出機能を追加
ファイル: src/nexuscore/agents/patch_applier.py
変更内容:
get_text_diff(before: str, after: str) -> str静的メソッドを追加difflib.unified_diffを使用して unified diff 形式の文字列を返す
コード例:
@staticmethod
def get_text_diff(before: str, after: str) -> str:
"""
Before/After の差分を unified diff 形式の文字列で返す。
"""
before_lines = before.splitlines(keepends=True)
after_lines = after.splitlines(keepends=True)
diff_lines = difflib.unified_diff(
before_lines,
after_lines,
fromfile="before",
tofile="after",
lineterm="",
)
return "".join(diff_lines)
Step 2: guardian_agent.py に差分サマリー生成機能を追加
ファイル: src/nexuscore/agents/guardian_agent.py
変更内容:
generate_diff_summary(before_code: str, after_code: str, model: str = "gpt-4.1") -> strメソッドを追加- LLM を使用してパッチ適用前後のコードを比較し、改善点を5行以内で要約
コード例:
def generate_diff_summary(
self,
before_code: str,
after_code: str,
model: str = "gpt-4.1",
) -> str:
"""
パッチ適用前後のコードを LLM に渡し、改善点を5行で要約する。
"""
# LLM にプロンプトを送信
# 5行以内に制限
return summary.strip()
Step 3: run_report_generator.py にレポートパス取得機能を追加
ファイル: src/nexuscore/integration/run_report_generator.py
変更内容:
get_markdown_report_path(run_id: str, base_dir: Optional[Path] = None) -> Path関数を追加docs/run_reports/RUN_{run_id}.mdのパスを返す
Step 4: github_pr_comment.py にレポート読み込み・フォーマット機能を追加
ファイル: src/nexuscore/integration/github_pr_comment.py
変更内容:
load_run_markdown(run_id: str) -> str: Run レポートの Markdown ファイルを読み込むformat_markdown_report_block(md_text: str) -> str: Markdown レポートを<details>タグで囲むformat_diff_summary_block(summary_text: str) -> str: 差分サマリーを<details>タグで囲むPRCommentContext:diff_summaryとmarkdown_reportフィールドを追加build_pr_comment(): 差分サマリーと Markdown レポートを末尾に追加
コード例:
def load_run_markdown(run_id: str) -> str:
"""docs/run_reports/<run_id>.md を読み込み文字列で返す。"""
from nexuscore.integration.run_report_generator import get_markdown_report_path
report_path = get_markdown_report_path(run_id)
if report_path.exists():
return report_path.read_text(encoding="utf-8")
return ""
def format_markdown_report_block(md_text: str) -> str:
"""Markdown の <details><summary>Run Report</summary>...</details> を生成。"""
if not md_text.strip():
return ""
return f"""<details>
<summary>📄 Run Report (Markdown)</summary>
{md_text}
</details>
"""
Step 5: self_healing_service.py で差分サマリーを生成
ファイル: src/nexuscore/services/self_healing_service.py
変更内容:
- パッチ適用前に、変更されるファイルの before コードを取得
- パッチ適用後に、変更されたファイルの after コードを取得
guardian_agent.generate_diff_summary()を呼び出して差分サマリーを生成- 生成された差分サマリーを
details["diff_summary"]に追加
コード例:
# パッチ適用前に before を取得
before_code_by_file = {}
for file_path in patch_changed_files[:1]: # 最初のファイルのみ
full_path = project_path / file_path
if full_path.exists():
before_code_by_file[file_path] = full_path.read_text(encoding="utf-8")
# パッチ適用
apply_result = self.patch_applier.apply_patch(...)
# パッチ適用後に after を取得し、差分サマリーを生成
if before_code_by_file and self._guardian_agent:
file_path = list(before_code_by_file.keys())[0]
before_code = before_code_by_file[file_path]
after_code = full_path.read_text(encoding="utf-8")
diff_summary = self._guardian_agent.generate_diff_summary(
before_code=before_code,
after_code=after_code,
model="gpt-4.1",
)
details["diff_summary"] = diff_summary
Step 6: github_self_healing_webhook.py で PR コメントに統合
ファイル: src/nexuscore/api/github_self_healing_webhook.py
変更内容:
format_pr_comment()でdetailsからdiff_summaryを取得run_idから Run Markdown レポートを自動読み込みPRCommentContextにdiff_summaryとmarkdown_reportを渡す
コード例:
# E-4: Before/After 差分サマリーを取得
diff_summary = details.get("diff_summary")
# E-3: Run Markdown レポートを取得
markdown_report = details.get("markdown_report")
if not markdown_report and run_id != "N/A":
from nexuscore.integration.github_pr_comment import load_run_markdown
markdown_report = load_run_markdown(run_id)
# PRCommentContext を作成
ctx = PRCommentContext(
...,
diff_summary=diff_summary,
markdown_report=markdown_report,
)
変更ファイル一覧
新規作成ファイル
なし
変更ファイル
src/nexuscore/agents/patch_applier.pyget_text_diff()静的メソッドを追加
src/nexuscore/agents/guardian_agent.pygenerate_diff_summary()メソッドを追加
src/nexuscore/integration/run_report_generator.pyget_markdown_report_path()関数を追加
src/nexuscore/integration/github_pr_comment.pyload_run_markdown()関数を追加format_markdown_report_block()関数を追加format_diff_summary_block()関数を追加PRCommentContextにdiff_summaryとmarkdown_reportフィールドを追加build_pr_comment()を拡張して差分サマリーと Markdown レポートを統合
src/nexuscore/api/github_self_healing_webhook.pyformat_pr_comment()を更新してdiff_summaryとmarkdown_reportを取得・渡す
src/nexuscore/services/self_healing_service.py- パッチ適用前後に before/after コードを取得
guardian_agent.generate_diff_summary()を呼び出して差分サマリーを生成details["diff_summary"]に追加
動作確認結果
静的解析結果
- ✅ リンターエラーなし
- ✅ 型チェックエラーなし
実装確認項目
patch_applier.get_text_diff()が正しく差分を返すかguardian_agent.generate_diff_summary()が 5 行要約を返すかrun_report_generator.get_markdown_report_path()が正しいパスを返すかgithub_pr_comment.load_run_markdown()が Markdown ファイルを読み込めるかgithub_pr_comment.build_pr_comment()がdiff_summary_block/markdown_report_blockを統合するかself_healing_serviceでパッチ適用後に差分サマリーを生成するかformat_pr_comment()がdiff_summaryとmarkdown_reportをPRCommentContextに渡すか
設計上の改善点
アーキテクチャの改善
- PR コメント組み立てロジックを
github_pr_comment.pyに集約 - Run レポート読み込みを
run_report_generator.pyに集約 - 差分サマリー生成を
guardian_agent.pyに集約
将来の拡張性への配慮
PRCommentContextにdiff_summaryとmarkdown_reportを追加することで、将来的に他のソースからも提供可能load_run_markdown()はファイルが存在しない場合に空文字を返すため、エラーが発生しない
コード品質の向上
- 各関数に docstring を追加
- エラーハンドリングを適切に実装
- ログ出力を追加
既知の制約・注意事項
制限事項
- 差分サマリー生成: 現在は最初の変更ファイルのみに対して差分サマリーを生成(複数ファイル対応は将来の拡張)
- Run レポート: Run レポートの Markdown ファイルは
write_run_report_file()で生成される必要がある(webapp の Run モデルが必要)
トレードオフ
- 差分サマリー生成は LLM 呼び出しを伴うため、コストが発生する
- パッチ適用前後のファイル読み込みは、大きなファイルの場合にメモリ使用量が増加する可能性がある
移行時の注意点
- 既存の PR コメント生成フローは後方互換性を維持
diff_summaryとmarkdown_reportが未指定の場合は、従来通り動作
次のステップ
推奨されるフォローアップアクション
- 複数ファイル対応: 複数のファイルが変更された場合、すべてのファイルに対して差分サマリーを生成する機能を追加
- Run レポート自動生成:
_finalize()で Run レポートの Markdown ファイルを自動生成する機能を追加 - 差分サマリーのキャッシュ: 同じパッチに対して差分サマリーを再生成しないようにキャッシュ機能を追加
- テスト追加: 各関数に対するユニットテストを追加
PR コメントの最終構造
実装後の PR コメントは以下の構造になります:
## 🤖 Self-Healing Summary
(メタ情報)
## 🔍 Guardian Review
(Guardian レビュー内容)
## ✨ Change Summary (AI-generated)
(変更要約)
---
## 🤖 AI Diff Summary (Before → After)
<details>
<summary>差分要約(5行)</summary>
- XXX が簡潔化
- 複雑度が低減
...
</details>
---
<details>
<summary>📄 Run Report (Markdown)</summary>
... Markdown全文 ...
</details>
---
## 📊 Observability Links
(リンク)
まとめ
E-3 と E-4 の実装が完了しました。GitHub PR コメントに Run Markdown レポートと Before/After 差分サマリーが自動的に統合されるようになりました。すべての実装は後方互換性を維持しており、既存のフローに影響を与えません。