Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ If applicable, add screenshots to help explain your problem.

**Libs and packages (please complete the following information):**
`uv pip list`

**Additional context**
Add any other context about the problem here.
60 changes: 60 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Path-based label mappings for actions/labeler@v6
# Uses any-glob-to-any-file: a single file match triggers the label

area/langgraph:
- changed-files:
- any-glob-to-any-file: 'agents/langgraph/**'

area/crewai:
- changed-files:
- any-glob-to-any-file: 'agents/crewai/**'

area/autogen:
- changed-files:
- any-glob-to-any-file: 'agents/autogen/**'

area/llamaindex:
- changed-files:
- any-glob-to-any-file: 'agents/llamaindex/**'

area/langflow:
- changed-files:
- any-glob-to-any-file: 'agents/langflow/**'

area/google-adk:
- changed-files:
- any-glob-to-any-file: 'agents/google/**'

area/a2a:
- changed-files:
- any-glob-to-any-file: 'agents/a2a/**'

area/vanilla-python:
- changed-files:
- any-glob-to-any-file: 'agents/vanilla_python/**'

area/helm:
- changed-files:
- any-glob-to-any-file: 'charts/**'

area/docs:
- changed-files:
- any-glob-to-any-file:
- 'docs/**'
- '*.md'

area/ci:
- changed-files:
- any-glob-to-any-file: '.github/**'

area/tests:
- changed-files:
- any-glob-to-any-file:
- 'tests/**'
- 'eval/**'

area/tracing:
- changed-files:
- any-glob-to-any-file:
- '**/tracing.py'
- 'tracing.md'
164 changes: 164 additions & 0 deletions .github/scripts/pr_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#!/usr/bin/env python3
"""
PR Size Labeler — calculates PR size and applies size/* labels.

Triggered by the pr-labeler workflow. Uses the GitHub API via PyGitHub
to count lines changed (additions + deletions), excluding lock files,
generated files, and images. Posts an advisory comment on XL PRs.

Environment variables (set by the workflow):
GITHUB_TOKEN — GitHub token with pull-requests: write
GITHUB_REPOSITORY — owner/repo
PR_NUMBER — pull request number
"""

import fnmatch
import os
import sys

from github import Github
from github.GithubException import GithubException

# --- Configuration ---

SIZE_THRESHOLDS = [
("size/xs", 0, 10),
("size/s", 11, 100),
("size/m", 101, 500),
("size/l", 501, 1199),
("size/xl", 1200, float("inf")),
]

LABEL_COLORS = {
"size/xs": "0e8a16",
"size/s": "0e8a16",
"size/m": "0e8a16",
"size/l": "fbca04",
"size/xl": "d93f0b",
}

EXCLUDED_PATTERNS = [
"uv.lock",
"*.lock",
"*.generated.*",
]

XL_COMMENT_MARKER = "<!-- pr-size-labeler:xl-warning -->"

XL_COMMENT_TEMPLATE = """{marker}
**Large PR detected ({lines} lines changed)**

This PR exceeds 1200 lines of code changes (excluding lock files, \
generated content, and images). Large PRs are harder to review thoroughly \
and are more likely to introduce bugs.

Consider splitting this PR into smaller, focused changes.
"""


def is_excluded(filename: str) -> bool:
"""Check if a file matches any exclusion pattern or is inside an images/ directory."""
# Check path-component match for images directories at any depth
if "/images/" in f"/{filename}":
return True
for pattern in EXCLUDED_PATTERNS:
if fnmatch.fnmatch(filename, pattern):
return True
return False


def get_size_label(lines: int) -> str:
"""Return the size label for the given line count."""
for label, lower, upper in SIZE_THRESHOLDS:
if lower <= lines <= upper:
return label
return "size/xl"


def ensure_label_exists(repo, label_name: str) -> None:
"""Create the label in the repo if it doesn't exist."""
try:
repo.get_label(label_name)
except GithubException as exc:
if exc.status != 404:
raise
color = LABEL_COLORS.get(label_name, "ededed")
repo.create_label(name=label_name, color=color)
print(f"Created label: {label_name}")


def update_size_label(pr, new_label: str) -> bool:
"""Update the size label on a PR. Returns True if a change was made."""
found = False
stale = []
for label in pr.get_labels():
if label.name == new_label:
found = True
elif label.name.startswith("size/"):
stale.append(label.name)

if found and not stale:
print(f"Label already correct: {new_label}")
return False

for name in stale:
pr.remove_from_labels(name)
print(f"Removed label: {name}")

if not found:
pr.add_to_labels(new_label)
print(f"Applied label: {new_label}")

return True


def calculate_size(pr) -> int:
"""Calculate total lines changed, excluding ignored files."""
total = 0
for f in pr.get_files():
if not is_excluded(f.filename):
total += f.additions + f.deletions
else:
print(f"Excluded: {f.filename}")
return total


def post_xl_comment(pr, lines: int) -> None:
"""Post an XL warning comment if one doesn't already exist."""
for comment in pr.get_issue_comments():
if XL_COMMENT_MARKER in comment.body:
print("XL comment already exists, skipping")
return
body = XL_COMMENT_TEMPLATE.format(marker=XL_COMMENT_MARKER, lines=lines)
pr.create_issue_comment(body)
print("Posted XL warning comment")


def main() -> None:
token = os.environ.get("GITHUB_TOKEN")
repo_name = os.environ.get("GITHUB_REPOSITORY")
pr_number_str = os.environ.get("PR_NUMBER")

if not all([token, repo_name, pr_number_str]):
print("Error: GITHUB_TOKEN, GITHUB_REPOSITORY, and PR_NUMBER must be set")
sys.exit(1)

pr_number = int(pr_number_str)

gh = Github(token, retry=3)
repo = gh.get_repo(repo_name)
pr = repo.get_pull(pr_number)

lines = calculate_size(pr)
label = get_size_label(lines)
print(f"PR #{pr_number}: {lines} lines changed -> {label}")

ensure_label_exists(repo, label)
update_size_label(pr, label)

if label == "size/xl":
post_xl_comment(pr, lines)


if __name__ == "__main__":
main()
57 changes: 57 additions & 0 deletions .github/workflows/pr-labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Automated PR labeling: path-based area/* labels + size-based size/* labels.
# Uses pull_request_target to support fork PRs (write access to base repo).

name: PR Labeler

on:
pull_request_target:
types: [opened, synchronize]

concurrency:
group: pr-labeler-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write

jobs:
label-pr:
runs-on: ubuntu-latest
steps:
# Step 1: Path-based area/* labels
- name: Apply area labels
uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
configuration-path: .github/labeler.yml
sync-labels: true

# Step 2: Size-based size/* labels + XL comment
- name: Checkout scripts
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
sparse-checkout: .github/scripts
sparse-checkout-cone-mode: false

- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"

- name: Install dependencies
run: pip install PyGithub==2.9.1

- name: Apply size labels
id: size_labels
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: python .github/scripts/pr_size.py

- name: Warn if size labeling failed
if: steps.size_labels.outcome == 'failure'
run: |
echo "::warning::Size labeling failed; area labels were applied but size labels may be stale or missing."
38 changes: 38 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Ruff

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

permissions: {}

concurrency:
group: ruff-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"

- name: Install ruff
run: pip install ruff==0.15.11

- name: Ruff lint
run: ruff check . --output-format=github

- name: Ruff format check
run: ruff format --check .
34 changes: 34 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,40 @@ chore: bump python-dotenv in requirements

This is optional but appreciated; maintainers may ask you to reword commits when preparing a release.

## Automated PR labels

Every pull request is automatically labeled when opened or updated:

**Area labels** (`area/*`) — applied based on which directories your PR touches. A PR can have multiple area labels if it spans several directories. These help reviewers quickly identify which parts of the codebase are affected.

| Label | Matches |
|-------|---------|
| `area/langgraph` | `agents/langgraph/**` |
| `area/crewai` | `agents/crewai/**` |
| `area/autogen` | `agents/autogen/**` |
| `area/llamaindex` | `agents/llamaindex/**` |
| `area/langflow` | `agents/langflow/**` |
| `area/google-adk` | `agents/google/**` |
| `area/a2a` | `agents/a2a/**` |
| `area/vanilla-python` | `agents/vanilla_python/**` |
| `area/helm` | `charts/**` |
| `area/docs` | `docs/**`, `*.md` (root) |
| `area/ci` | `.github/**` |
| `area/tests` | `tests/**`, `eval/**` |
| `area/tracing` | `**/tracing.py`, `tracing.md` |

**Size labels** (`size/*`) — applied based on total lines changed (additions + deletions), excluding lock files, generated files, and images.

| Label | Lines Changed |
|-------|--------------|
| `size/xs` | 0–10 |
| `size/s` | 11–100 |
| `size/m` | 101–500 |
| `size/l` | 501–1199 |
| `size/xl` | 1200+ |

PRs labeled `size/xl` will receive an advisory comment encouraging the author to consider splitting the PR. This is informational only — it does not block merges.

## Adding MLflow tracing to your agent template

All agent templates in this repo must include MLflow tracing integration. Tracing lets users optionally capture LLM calls, tool executions, and agent orchestration spans in MLflow — it's opt-in via the `MLFLOW_TRACKING_URI` environment variable. If `MLFLOW_TRACKING_URI` is set but the server is unreachable, the agent logs a warning and continues without tracing. Note: if `MLFLOW_TRACKING_URI` is set but the MLflow package is not installed, the agent will fail at startup with an `ImportError` — MLflow must be installed when the env var is set.
Expand Down
1 change: 0 additions & 1 deletion MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ A repository maintainer is a committer with the additional privilege of managing
|-----------------|---------------------------------------|
| Tomasz Guzik | [MRGuziX](https://github.com/MRGuziX) |
| Wojciech Rębisz | [Wojciech-Rebisz](https://github.com/Wojciech-Rebisz) |

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from uuid import uuid4

import httpx

from a2a.client import A2ACardResolver, A2AClient
from a2a.types import (
JSONRPCErrorResponse,
Expand Down
Loading
Loading