Skip to content

Refactored BugZooka inference with py-commons#115

Merged
vishnuchalla merged 5 commits into
redhat-performance:mainfrom
qu4rkn3t:inference
Jun 16, 2026
Merged

Refactored BugZooka inference with py-commons#115
vishnuchalla merged 5 commits into
redhat-performance:mainfrom
qu4rkn3t:inference

Conversation

@qu4rkn3t

Copy link
Copy Markdown
Contributor

Description

Updated BugZooka to use py-commons inference module

  • Significant updates in inference_client.py (removed old client and exposed py-commons APIs)
  • Note: renamed INFERENCE_API_TIMEOUT_SECONDS to INFERENCE_API_TIMEOUT to match other time variables. Unit is explicitly stated in py-commons and the variable is updated where needed in BugZooka.
  • Warning: py-commons update with inference module has not made its way to PyPi, so BugZooka faces an issue when running make install. To circumvent, clone py-commons and use pip to manually install the local package.

Example

Below is an analyze_pr call, which works exactly like the dev BugZooka client.

Screenshot 2026-06-11 at 12 11 42 PM Screenshot 2026-06-11 at 12 11 57 PM Screenshot 2026-06-11 at 12 12 08 PM Screenshot 2026-06-11 at 12 12 25 PM Screenshot 2026-06-11 at 12 12 32 PM Screenshot 2026-06-11 at 12 12 39 PM

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@qu4rkn3t, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 28 minutes and 46 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: be116ebc-e593-413b-8d40-4b9a65cfadbf

📥 Commits

Reviewing files that changed from the base of the PR and between 6c3f776 and 2d574a0.

📒 Files selected for processing (1)
  • requirements.txt
📝 Walkthrough

Walkthrough

This PR migrates the inference client implementation and configuration management from BugZooka into a shared py-commons library. The core inference client, exception types, and base configuration are now re-exported from commons.inference, while BugZooka retains only its custom retry policy layer. Async execution switches from asyncio to anyio, and environment variable naming changes from INFERENCE_API_TIMEOUT_SECONDS to INFERENCE_API_TIMEOUT.

Changes

Inference commons migration and async execution

Layer / File(s) Summary
Dependency foundation and shared config refactor
requirements.txt, bugzooka/core/config.py, bugzooka/core/constants.py
rh-py-commons>=0.3.0 and cryptography>=44.0.0 are added as dependencies. get_inference_config() is refactored to call the shared get_base_inference_config() from commons.inference for base settings (timeout, verify_ssl, api_key), then overlays BugZooka-specific retry parameters from INFERENCE_API_RETRY_* environment variables. Inference configuration constants (INFERENCE_TEMPERATURE, INFERENCE_MAX_TOKENS, INFERENCE_MAX_TOOL_ITERATIONS, INFERENCE_API_TIMEOUT_SECONDS) are removed from constants.py as they now belong to commons.
Inference client re-export layer
bugzooka/integrations/inference_client.py
The inference_client.py implementation is replaced with re-exports of InferenceClient, get_inference_client, and analyze_with_agentic from commons.inference. Error classes are aliased for backward compatibility (InferenceAPIUnavailableErrorInferenceAPIError, AgentAnalysisLimitExceededErrorInferenceIterationLimitError). The exported constant INFERENCE_API_TIMEOUT is now imported from commons.inference.
Update config consumer for new retry structure
bugzooka/analysis/log_analyzer.py
The _with_retry decorator is updated to retrieve retry settings from get_inference_config()["retry"] instead of from the client object's retry_config attribute.
Async execution model migration to anyio
bugzooka/analysis/log_analyzer.py, bugzooka/integrations/slack_socket_listener.py
Async execution switches from asyncio.run() and asyncio.new_event_loop() to anyio.run() in run_agent_analysis and in Slack Socket listener handlers for analyze_pr_with_gemini, analyze_nightly_regression, and analyze_performance calls. Module-level anyio imports are added to both files.
Documentation and environment variable naming
CONTRIBUTING.md, README.md
The environment variable example is updated from INFERENCE_API_TIMEOUT_SECONDS to INFERENCE_API_TIMEOUT, and the README's Project Structure section notes that inference_client.py is now a re-export from py-commons instead of a unified implementation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main change: refactoring BugZooka's inference implementation to use py-commons instead of the old in-file client.
Description check ✅ Passed The description is directly related to the changeset, explaining the py-commons integration, variable rename, and including working examples with demonstration screenshots.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors BugZooka’s inference integration to delegate the inference client implementation to the shared py-commons inference module, while keeping BugZooka’s public imports/backwards compatibility intact. It also updates sync↔async bridging code paths to use anyio.run(...) and renames the inference timeout environment variable.

Changes:

  • Replaced BugZooka’s in-repo inference client implementation with re-exports from py-commons (commons.inference).
  • Renamed INFERENCE_API_TIMEOUT_SECONDSINFERENCE_API_TIMEOUT across docs/config and aligned retry config sourcing.
  • Switched several “run async from sync” call sites to anyio.run(...) (and introduced new dependency expectations).

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
requirements.txt Adds py-commons and cryptography dependencies.
README.md Updates env var name and updates repo tree description of inference client.
CONTRIBUTING.md Updates env var name for timeout.
bugzooka/integrations/slack_socket_listener.py Uses anyio.run(...) instead of manually creating event loops (also introduces an unused import).
bugzooka/integrations/inference_client.py Replaces prior client implementation with py-commons re-exports + compatibility aliases.
bugzooka/core/constants.py Removes local inference constants (now sourced from py-commons) and keeps retry constants.
bugzooka/core/config.py Delegates base inference config parsing to py-commons, then overlays BugZooka retry settings.
bugzooka/analysis/log_analyzer.py Retry config now comes from inference config; switches asyncio.runanyio.run (also introduces an unused import).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 7 to 9
import asyncio
import concurrent.futures
import logging
Comment on lines 1 to 3
import logging
import asyncio
from pydantic import BaseModel, Field

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@requirements.txt`:
- Around line 18-20: requirements.txt lists an unsatisfiable py-commons
constraint and an unclear cryptography bound; replace "py-commons>=0.3.0" with a
valid PyPI release (e.g., "py-commons==0.1.2" or "py-commons>=0.1.2,<0.2.0") and
update the cryptography line to include concrete advisory-backed bounds (e.g.,
change "cryptography>=44.0.0" to a supported safe range like
"cryptography>=X.Y.Z,<A.B.C" where X.Y.Z is the minimum secure version and A.B.C
the next breaking version) and add a brief comment referencing the exact
CVE/advisory URL that justifies the bound so CI/installers can resolve and
auditors can verify the rationale.
- Around line 46-47: Update the cryptography minimum version in requirements.txt
by replacing the current declaration "cryptography>=44.0.0" with a safe floor
such as "cryptography>=46.0.6" (or alternatively specify a range that excludes
vulnerable releases, e.g., "cryptography>=46.0.6,<47.0") so the project will not
install known-vulnerable 44.x/46.x releases; locate and edit the line containing
the literal package spec "cryptography>=44.0.0" to apply this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: f572068f-0766-4164-8485-e7a5602395ab

📥 Commits

Reviewing files that changed from the base of the PR and between 1a090c8 and 79ff3be.

📒 Files selected for processing (8)
  • CONTRIBUTING.md
  • README.md
  • bugzooka/analysis/log_analyzer.py
  • bugzooka/core/config.py
  • bugzooka/core/constants.py
  • bugzooka/integrations/inference_client.py
  • bugzooka/integrations/slack_socket_listener.py
  • requirements.txt

Comment thread requirements.txt
Comment on lines +18 to +20
# py-commons
py-commons>=0.3.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify whether py-commons 0.3.0 is published on PyPI.
status="$(curl -s -o /tmp/pycommons.json -w "%{http_code}" https://pypi.org/pypi/py-commons/json || true)"
echo "PyPI status code for py-commons metadata: ${status}"

if [ "$status" = "200" ]; then
  jq -r '.releases | keys[]' /tmp/pycommons.json | tail -n 20
  echo "Check whether 0.3.0 appears in the list above."
else
  echo "Package metadata unavailable on PyPI (status ${status})."
fi

Repository: redhat-performance/BugZooka

Length of output: 176


Fix broken dependency constraint: py-commons>=0.3.0

  • requirements.txt line 19 uses py-commons>=0.3.0, but PyPI only shows releases 0.1.0 and 0.1.2, so installs/CI using PyPI won’t be able to satisfy this constraint.
  • requirements.txt line 47 uses cryptography>=44.0.0; the vulnerability/exclusion rationale for 44.0.0 needs a concrete advisory/source and corresponding bounds update.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@requirements.txt` around lines 18 - 20, requirements.txt lists an
unsatisfiable py-commons constraint and an unclear cryptography bound; replace
"py-commons>=0.3.0" with a valid PyPI release (e.g., "py-commons==0.1.2" or
"py-commons>=0.1.2,<0.2.0") and update the cryptography line to include concrete
advisory-backed bounds (e.g., change "cryptography>=44.0.0" to a supported safe
range like "cryptography>=X.Y.Z,<A.B.C" where X.Y.Z is the minimum secure
version and A.B.C the next breaking version) and add a brief comment referencing
the exact CVE/advisory URL that justifies the bound so CI/installers can resolve
and auditors can verify the rationale.

Source: Coding guidelines

Comment thread requirements.txt
Comment on lines +46 to +47
# Misc.
cryptography>=44.0.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Query OSV for vulnerabilities affecting cryptography 44.0.0
curl -s https://api.osv.dev/v1/query \
  -H 'Content-Type: application/json' \
  -d '{"package":{"name":"cryptography","ecosystem":"PyPI"},"version":"44.0.0"}' \
  | jq '{affected_version:"44.0.0", vulns:[.vulns[]?.id]}'

Repository: redhat-performance/BugZooka

Length of output: 225


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Confirm requirements.txt constraint around the cited lines
echo "---- requirements.txt (lines 35-60) ----"
nl -ba requirements.txt | sed -n '35,60p'

# 2) Check for any other cryptography constraints in the repo
echo "---- grep for cryptography constraints ----"
rg -n --hidden --no-ignore-vcs -S "cryptography\s*(?:[<>=!~]=?|\[\s*)\s*" .

# 3) Query OSV for cryptography 44.0.0 with full vuln payload (not just IDs)
echo "---- OSV response for cryptography 44.0.0 (full) ----"
curl -s https://api.osv.dev/v1/query \
  -H 'Content-Type: application/json' \
  -d '{"package":{"name":"cryptography","ecosystem":"PyPI"},"version":"44.0.0"}' \
  | jq '.vulns'

# 4) Try likely nearby patch versions to identify a “safe” floor (best-effort)
for v in 44.0.1 44.0.2 44.0.3 44.1.0 44.1.1; do
  echo "---- OSV vulns for cryptography $v ----"
  curl -s https://api.osv.dev/v1/query \
    -H 'Content-Type: application/json' \
    -d "{\"package\":{\"name\":\"cryptography\",\"ecosystem\":\"PyPI\"},\"version\":\"$v\"}" \
    | jq -r --arg v "$v" '{version:$v, count:(.vulns|length), vulns:(.vulns[].id // empty)}'
done

Repository: redhat-performance/BugZooka

Length of output: 173


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- requirements.txt (lines 35-60) ----"
cat -n requirements.txt | sed -n '35,60p'

echo "---- grep for cryptography constraints ----"
rg -n --hidden --no-ignore-vcs -S "cryptography\s*(?:[<>=!~]=?|\[\s*)\s*" .

echo "---- OSV response for cryptography 44.0.0 (full) ----"
curl -s https://api.osv.dev/v1/query \
  -H 'Content-Type: application/json' \
  -d '{"package":{"name":"cryptography","ecosystem":"PyPI"},"version":"44.0.0"}' \
  | jq '{vulns:.vulns, affected_version:"44.0.0"}'

echo "---- OSV extract fixed/patched hints for vulns affecting 44.0.0 ----"
curl -s https://api.osv.dev/v1/query \
  -H 'Content-Type: application/json' \
  -d '{"package":{"name":"cryptography","ecosystem":"PyPI"},"version":"44.0.0"}' \
  | jq -r '
    .vulns[]
    | {id, summary, details: .details?} as $v
    | $v,
    (.affected[]? // empty) as $a
    | (if ($a.ranges) then
        $a.ranges[]
        | {range_type:(.type // null), repo_type:(.repo?.type // null), events:(.events // null)}
      else empty end)
  ' | head -n 200

Repository: redhat-performance/BugZooka

Length of output: 27007


Update cryptography minimum to a patched version (security fix)

requirements.txt line 47 (cryptography>=44.0.0) allows installing 44.0.0, which OSV lists as affected by multiple advisories, including:

Set the floor to at least cryptography>=46.0.6 (or explicitly exclude the affected versions).

🧰 Tools
🪛 OSV Scanner (2.3.8)

[HIGH] 47-47: cryptography 44.0.0: undefined

(PYSEC-2026-35)


[HIGH] 47-47: cryptography 44.0.0: Vulnerable OpenSSL included in cryptography wheels

(GHSA-79v4-65xg-pq4g)


[HIGH] 47-47: cryptography 44.0.0: cryptography has incomplete DNS name constraint enforcement on peer names

(GHSA-m959-cc7f-wv43)


[HIGH] 47-47: cryptography 44.0.0: cryptography Vulnerable to a Subgroup Attack Due to Missing Subgroup Validation for SECT Curves

(GHSA-r6ph-v2qm-q3c2)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@requirements.txt` around lines 46 - 47, Update the cryptography minimum
version in requirements.txt by replacing the current declaration
"cryptography>=44.0.0" with a safe floor such as "cryptography>=46.0.6" (or
alternatively specify a range that excludes vulnerable releases, e.g.,
"cryptography>=46.0.6,<47.0") so the project will not install known-vulnerable
44.x/46.x releases; locate and edit the line containing the literal package spec
"cryptography>=44.0.0" to apply this change.

Sources: Coding guidelines, Linters/SAST tools

)
finally:
loop.close()
analysis_result = anyio.run(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we changing this? @qu4rkn3t do you see any benefits out of this w.r.t previous function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing analyze_pr, I was getting the following error:

slack_error

TaskGroup is an anyio async context manager, so I thought if I used that it would help. Turns out it did. I suspect it's because mcp and/or langchain-mcp-adapters use anyio under the hood and using asyncio created some duality. I suppose the implementation is also cleaner without needing to new/set/close.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. lets see how it goes over time.

@vishnuchalla vishnuchalla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. thanks

)
finally:
loop.close()
analysis_result = anyio.run(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. lets see how it goes over time.

@vishnuchalla vishnuchalla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@qu4rkn3t mind fixing the lint issues real quick please?

@qu4rkn3t

qu4rkn3t commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@vishnuchalla

@qu4rkn3t mind fixing the lint issues real quick please?

I'm not sure how to as it's caused by latest py-commons not existing in PyPi. I re-ran the publishing job, but I get the following Node.js error:

Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected:
actions/checkout@v2, actions/setup-python@v2. Actions will be forced to run with Node.js 24 by default starting June
16th, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. Please check if updated versions of
these actions are available that support Node.js 24. To opt into Node.js 24 now, set the
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once
Node.js 24 becomes the default, you can temporarily opt out by setting
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see:
https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

@vishnuchalla

vishnuchalla commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

@vishnuchalla

@qu4rkn3t mind fixing the lint issues real quick please?

I'm not sure how to as it's caused by latest py-commons not existing in PyPi. I re-ran the publishing job, but I get the following Node.js error:

Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected:
actions/checkout@v2, actions/setup-python@v2. Actions will be forced to run with Node.js 24 by default starting June
16th, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. Please check if updated versions of
these actions are available that support Node.js 24. To opt into Node.js 24 now, set the
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once
Node.js 24 becomes the default, you can temporarily opt out by setting
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see:
https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

Can you try now? updated py-commons release that should have the fix.

@qu4rkn3t

Copy link
Copy Markdown
Contributor Author

@vishnuchalla

@qu4rkn3t mind fixing the lint issues real quick please?

I'm not sure how to as it's caused by latest py-commons not existing in PyPi. I re-ran the publishing job, but I get the following Node.js error:

Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected:
actions/checkout@v2, actions/setup-python@v2. Actions will be forced to run with Node.js 24 by default starting June
16th, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. Please check if updated versions of
these actions are available that support Node.js 24. To opt into Node.js 24 now, set the
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once
Node.js 24 becomes the default, you can temporarily opt out by setting
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see:
https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

Can you try now? updated py-commons release that should have the fix.

No, still running into the same issue.

@qu4rkn3t

Copy link
Copy Markdown
Contributor Author

@vishnuchalla

I re-ran v.0.1.8 and I now get this:

25hWARNING  Error during upload. Retry with the --verbose option for more details. 
ERROR    HTTPError: 403 Forbidden from https://upload.pypi.org/legacy/          
         Forbidden                                                              
Error: Process completed with exit code 1.

@vishnuchalla vishnuchalla merged commit 691110a into redhat-performance:main Jun 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants