Thank you for your interest in contributing. This document gives a short overview of how to get involved.
-
Report bugs or suggest features – Open an issue and describe the problem or idea. Check existing issues first to avoid duplicates.
-
Submit code changes – Create a branch (in your fork or directly in this repo if you have access), make your changes, and open a pull request (PR). You don’t need to fork if you can push branches here. Keep PRs focused; one feature or fix per PR is easier to review. When creating a PR, use the PR template and fill in each section.
-
Improve documentation – Fixes and clarifications in the README, agent docs, or code comments are always welcome. Use the
docs:prefix in your commit (see below). -
Add or fix tests – If you add or change behavior, consider adding or updating tests and use the
test:prefix in commits.
Before submitting, please read our Code of Conduct. By participating, you agree to uphold it.
This repository uses pre-commit hooks to enforce code quality checks before each commit. Set it up once after cloning:
uv tool install pre-commit
pre-commit install --install-hooksAfter this, every git commit will automatically validate your commit message format (see below).
This project uses ruff for Python linting and formatting. CI runs ruff as a blocking check on all pull requests.
Run locally before pushing:
uv tool install ruff==0.15.11
ruff check . # lint
ruff format --check . # format check
ruff format . # auto-formatConfiguration is in ruff.toml at the repo root.
This repository enforces the Conventional Commits specification via a pre-commit hook. Commits that don't follow this format will be blocked locally by the pre-commit hook.
Tip: To bypass the hook in rare cases (e.g., merge commits, emergency hotfixes):
git commit --no-verify
<type>(optional scope): <description>
[optional body]
[optional footer(s)]
| Prefix | Meaning |
|---|---|
| feat: | A new feature |
| fix: | A bug fix |
| docs: | Documentation only |
| chore: | Maintenance (deps, tooling, config) |
| test: | Adding or updating tests |
| perf: | A change that improves performance |
| refactor: | Code change that neither fixes a bug nor adds a feature |
| ci: | CI/CD changes |
| build: | Build system or external dependency changes |
| style: | Code style (formatting, whitespace — no logic changes) |
| revert: | Reverts a previous commit |
You can optionally add a scope (e.g. the agent or module name) in parentheses after the type.
feat: add health check endpoint to autogen mcp_agent
fix: correct env var name in deployment in langgraph_react_agent
docs: update README with OpenShift deploy steps
test: add tests for tool registration
chore: bump python-dotenv in requirements
refactor(langgraph): extract tool registration into helper
ci: add ruff linting workflow
feat!: change /chat response format
For breaking changes, add ! after the type/scope (e.g. feat!:) or include a BREAKING CHANGE: footer:
feat: change /chat response format
BREAKING CHANGE: response field "text" renamed to "content"
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.
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.
Read tracing.md for the full tracing architecture, design principles, and how the existing agents integrate with MLflow. In particular, see the Autolog Coverage Levels section — the amount of work required depends on whether your framework is Level A (full autolog), B (partial), or C (no framework autolog).
These are the files you need to create or update when adding tracing to your agent:
1. Create src/<package>/tracing.py
This module exports enable_tracing() (and wrap_func_with_mlflow_trace() if your framework's autolog doesn't cover everything). It handles health-checking the MLflow server with retry logic, configuring the experiment, enabling the correct autolog for your framework, and gracefully degrading if the server is unreachable. MLflow imports are inside enable_tracing() (not at module top) so the module can be imported without MLflow installed — but if MLFLOW_TRACKING_URI is set and MLflow is missing, the agent will fail at startup with a clear error.
See existing examples:
- Full autolog (no manual wrapping needed):
agents/langgraph/react_agent/src/react_agent/tracing.py - Partial autolog (tools need manual wrapping):
agents/crewai/websearch_agent/src/crewai_web_search/tracing.py - No framework autolog (tools + agent entry point need manual wrapping):
agents/vanilla_python/openai_responses_agent/src/openai_responses_agent/tracing.py
2. Edit main.py
Import enable_tracing and call it as the first line inside your lifespan() function, before any agent initialization. If your framework needs manual wrapping, also import wrap_func_with_mlflow_trace and wrap tool functions (span_type="tool") and the agent entry point (span_type="agent") — in both the streaming and non-streaming code paths.
3. Edit .env.example
Add commented-out MLflow environment variable sections for both local and OpenShift deployment (see any existing agent's .env.example for the format).
4. Edit README.md
Add tracing configuration examples (local and OpenShift) and the uv run --extra tracing mlflow server --port 5000 server start step.
5. Add MLflow as an optional dependency in pyproject.toml
MLflow is listed as an optional dependency under the tracing extra:
[project.optional-dependencies]
tracing = [
"mlflow>=3.10.0",
]This allows make run to auto-install MLflow when MLFLOW_TRACKING_URI is set (via uv run --extra tracing). MLflow is not a core dependency — agents run without it when tracing is disabled.
If you have Claude Code set up, this repo includes a skill that automates the entire process described above.
- Claude Code installed and configured
- Run Claude Code from the repo root so it discovers the skills in
.claude/skills/
/integrate-tracing <framework> <agent_path>
For example:
/integrate-tracing autogen agents/autogen/chat_agent
You can also prompt Claude Code directly (e.g., "integrate tracing into the autogen chat agent using the /integrate-tracing skill") and it will follow the same workflow.
This single command runs the entire pipeline end-to-end. The skill always creates a demo copy of the agent first, implements and verifies tracing on the demo, and only applies the changes to the actual agent template once everything works correctly.
- Researches your framework's MLflow autolog support and classifies it (Level A/B/C)
- Creates a demo copy of the agent with test tools for trace verification
- Reads the agent's code to understand its architecture
- Creates
tracing.pywith the correct pattern for the autolog level - Wires
enable_tracing()into the FastAPI lifespan inmain.py - Adds manual trace wrapping for tools and agent entry points (skipped if autolog covers everything)
- Verifies traces end-to-end — code review + live testing against the MLflow API
- Updates
.env.examplewith MLflow environment variables - Updates
README.mdwith tracing configuration and install steps
Each step of the pipeline is also available as a standalone skill. This is useful if you want to run just one phase, re-run a step after a fix, or integrate tracing manually with some automation:
/check-autolog-support <framework> # Research MLflow autolog support for a framework
/create-tracing-module <agent_path> [framework] # Create tracing.py only
/wire-into-lifespan <agent_path> # Wire tracing into main.py only
/add-manual-tracing <agent_path> # Add manual trace wrapping only
/verify-traces <agent_path> # Run code review + live trace testing
/review-tracing-code <agent_path> # Code review only (no live testing)
/test-tracing <agent_path> # Live trace testing only (no code review)
integrate-tracing is an orchestrator — it doesn't contain all the logic itself. Instead, it coordinates 7 specialized sub-skills in sequence, passing context between them. The most important piece of context is the autolog level (A, B, or C), which is determined in Step 1 by check-autolog-support and drives every decision downstream: what code create-tracing-module generates, what wire-into-lifespan imports, whether add-manual-tracing runs at all, and what spans verify-traces expects to find.
verify-traces is itself a sub-orchestrator — it calls review-tracing-code (static analysis) and test-tracing (live end-to-end testing) and combines their results into a single report. If verification fails, the report points back to which step to revisit.
All skills live as siblings in .claude/skills/ (not nested under integrate-tracing/) because Claude Code discovers skills by scanning .claude/skills/*/SKILL.md. The flat structure also makes each sub-skill independently callable. If you need to maintain or extend a skill, edit the SKILL.md file in its directory. Each skill includes a self-update instruction — if Claude deviates from a skill's steps because they were inaccurate, it updates the skill file automatically so the next run benefits.
Recommended model: These skills were developed and tested with claude-opus-4-6. Use Opus for best results — smaller models may not follow the multi-step orchestration reliably.
See the main README or open an issue. You can also contact wrebisz@redhat.com or tguzik@redhat.com.