LCORE-2874: Fix konflux_resolve.py to work with non-custom uv#2185
LCORE-2874: Fix konflux_resolve.py to work with non-custom uv#2185anik120 wants to merge 1 commit into
Conversation
WalkthroughUpdates Konflux dependency resolution to use explicit RHOAI and PyPI indexes, adjusts Tekton prefetch lists, and regenerates source, wheel, and build requirement pins and hashes. ChangesKonflux dependency refresh
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 7✅ Passed checks (7 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@scripts/konflux_requirements.sh`:
- Line 16: Update the comments and echo messages in konflux_requirements.sh to
replace the stale console.redhat.com domain with packages.redhat.com and rename
split_requirements.sh references to konflux_requirements.sh, while preserving
the script’s behavior.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 136c7b32-dee8-4910-8ce2-f396ac3c2438
📒 Files selected for processing (3)
.konflux/requirements.hashes.source.txt.konflux/requirements.hashes.wheel.txtscripts/konflux_requirements.sh
📜 Review details
⏰ Context from checks skipped due to timeout. (13)
- GitHub Check: Pylinter
- GitHub Check: unit_tests (3.12)
- GitHub Check: unit_tests (3.13)
- GitHub Check: integration_tests (3.13)
- GitHub Check: integration_tests (3.12)
- GitHub Check: build-pr
- GitHub Check: E2E Tests for Lightspeed Evaluation job
- GitHub Check: E2E: server mode / ci / group 2
- GitHub Check: E2E: library mode / ci / group 1
- GitHub Check: E2E: library mode / ci / group 3
- GitHub Check: E2E: server mode / ci / group 1
- GitHub Check: E2E: library mode / ci / group 2
- GitHub Check: E2E: server mode / ci / group 3
🧰 Additional context used
📓 Path-based instructions (1)
**/*
📄 CodeRabbit inference engine (Custom checks)
**/*: Flag meaningful O(n^2)+ algorithms on non-trivial inputs, including handlers and Kubernetes list operations.
Flag N+1 patterns that list items and then query once per item, including Kubernetes API and database access.
Flag expensive work inside loops, including API calls, JSON parsing, and regex compilation.
Flag unbounded growth in caches, watchers, or buffers when eviction or limits are missing.
Flag missing pagination or limits on list operations and API endpoints.
Flag secrets or tokens logged in plaintext or hardcoded in source.
Flag API endpoints missing authentication or authorization.
Flag injection vulnerabilities, including SQL injection, command injection, and path traversal.
Flag sensitive data leaked in API responses, WebSocket messages, or logs.
Flag Kubernetes Secrets and Red Hat secrets missing OwnerReferences.Never commit secrets or keys; use environment variables for sensitive data.
Files:
scripts/konflux_requirements.sh
🧠 Learnings (1)
📚 Learning: 2026-05-12T15:14:34.788Z
Learnt from: syedriko
Repo: lightspeed-core/lightspeed-stack PR: 1727
File: scripts/konflux_requirements.sh:9-15
Timestamp: 2026-05-12T15:14:34.788Z
Learning: In this repo, the `.konflux/` directory is committed/tracked and is guaranteed to exist in a fresh clone. Therefore, shell scripts that write output under `.konflux/` (e.g., create files like `.konflux/<...>`) should not waste effort by calling `mkdir -p .konflux` first. Only add directory-creation logic if the script may run in an environment/repo state where `.konflux/` might not be present.
Applied to files:
scripts/konflux_requirements.sh
🔇 Additional comments (3)
scripts/konflux_requirements.sh (1)
79-79: LGTM!.konflux/requirements.hashes.source.txt (1)
1-4: LGTM!Also applies to: 5-23, 96-137, 147-243, 243-287, 288-625
.konflux/requirements.hashes.wheel.txt (1)
1-4: LGTM!Also applies to: 14-16, 26-36, 52-79, 100-168, 177-189, 198-203, 217-322, 344-381, 391-394, 406-448, 457-475
| WHEEL_HASH_FILE="${KONFLUX_DIR}/requirements.hashes.wheel.txt" | ||
| BUILD_FILE="${KONFLUX_DIR}/requirements-build.txt" | ||
| RHOAI_INDEX_URL="https://console.redhat.com/api/pypi/public-rhai/rhoai/3.3/cpu-ubi9/simple/" | ||
| RHOAI_INDEX_URL="https://packages.redhat.com/api/pypi/public-rhai/rhoai/3.5/cpu-ubi9/simple/" |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Update stale script comments and echo messages.
While RHOAI_INDEX_URL was updated to packages.redhat.com, the script's comments and output messages still reference the old console.redhat.com domain. Additionally, they refer to split_requirements.sh instead of the current script name (konflux_requirements.sh). Please update them to reflect the current state.
🧹 Proposed fixes for stale strings
--- scripts/konflux_requirements.sh
+++ scripts/konflux_requirements.sh
@@ -4,2 +4,2 @@
# Packages from pypi.org go to requirements.source.txt
-# Packages from console.redhat.com go to requirements.wheel.txt
+# Packages from packages.redhat.com go to requirements.wheel.txt
@@ -37,4 +37,4 @@
echo "# Packages from pypi.org" > "$SOURCE_FILE"
-echo "# This file was autogenerated by split_requirements.sh" >> "$SOURCE_FILE"
-echo "# Packages from console.redhat.com" > "$WHEEL_FILE"
-echo "# This file was autogenerated by split_requirements.sh" >> "$WHEEL_FILE"
+echo "# This file was autogenerated by konflux_requirements.sh" >> "$SOURCE_FILE"
+echo "# Packages from packages.redhat.com" > "$WHEEL_FILE"
+echo "# This file was autogenerated by konflux_requirements.sh" >> "$WHEEL_FILE"
@@ -74,3 +74,3 @@
echo "Packages from pypi.org written to: $SOURCE_FILE ($(wc -l < "$SOURCE_FILE") packages)"
-echo "Packages from console.redhat.com written to: $WHEEL_FILE ($(wc -l < "$WHEEL_FILE") packages)"
+echo "Packages from packages.redhat.com written to: $WHEEL_FILE ($(wc -l < "$WHEEL_FILE") packages)"
@@ -89,3 +89,3 @@
echo "Packages from pypi.org written to: $SOURCE_HASH_FILE ($(wc -l < "$SOURCE_HASH_FILE") packages)"
-echo "Packages from console.redhat.com written to: $WHEEL_HASH_FILE ($(wc -l < "$WHEEL_HASH_FILE") packages)"
+echo "Packages from packages.redhat.com written to: $WHEEL_HASH_FILE ($(wc -l < "$WHEEL_HASH_FILE") packages)"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| RHOAI_INDEX_URL="https://packages.redhat.com/api/pypi/public-rhai/rhoai/3.5/cpu-ubi9/simple/" | |
| # Packages from pypi.org go to requirements.source.txt | |
| # Packages from packages.redhat.com go to requirements.wheel.txt | |
| echo "# Packages from pypi.org" > "$SOURCE_FILE" | |
| echo "# This file was autogenerated by konflux_requirements.sh" >> "$SOURCE_FILE" | |
| echo "# Packages from packages.redhat.com" > "$WHEEL_FILE" | |
| echo "# This file was autogenerated by konflux_requirements.sh" >> "$WHEEL_FILE" | |
| echo "Packages from pypi.org written to: $SOURCE_FILE ($(wc -l < "$SOURCE_FILE") packages)" | |
| echo "Packages from packages.redhat.com written to: $WHEEL_FILE ($(wc -l < "$WHEEL_FILE") packages)" | |
| echo "Packages from pypi.org written to: $SOURCE_HASH_FILE ($(wc -l < "$SOURCE_HASH_FILE") packages)" | |
| echo "Packages from packages.redhat.com written to: $WHEEL_HASH_FILE ($(wc -l < "$WHEEL_HASH_FILE") packages)" |
🤖 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 `@scripts/konflux_requirements.sh` at line 16, Update the comments and echo
messages in konflux_requirements.sh to replace the stale console.redhat.com
domain with packages.redhat.com and rename split_requirements.sh references to
konflux_requirements.sh, while preserving the script’s behavior.
Remove `--index-strategy` and ` prefer-index` arguments.
8190d32 to
0e3f740
Compare
There was a problem hiding this comment.
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 @.konflux/requirements-build.txt:
- Line 2: Regenerate the autogenerated requirements file using Python 3.12,
matching the project’s py_version setting and requirement-generation scripts,
while preserving the existing dependency inputs and output format.
In @.tekton/lightspeed-stack-0-7-pull-request.yaml:
- Line 56: Restore uv and pip to the packages prefetch lists at
.tekton/lightspeed-stack-0-7-pull-request.yaml:56 and
.tekton/lightspeed-stack-0-7-push.yaml:57, matching the EXTRA_WHEELS appended by
scripts/konflux_requirements.sh and required by
deploy/lightspeed-stack/Containerfile.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1c6d1b81-b4a3-4f61-b5a6-5a35d7a267b3
📒 Files selected for processing (6)
.konflux/requirements-build.txt.konflux/requirements.hashes.source.txt.konflux/requirements.hashes.wheel.txt.tekton/lightspeed-stack-0-7-pull-request.yaml.tekton/lightspeed-stack-0-7-push.yamlscripts/konflux_resolve.py
💤 Files with no reviewable changes (1)
- scripts/konflux_resolve.py
📜 Review details
⏰ Context from checks skipped due to timeout. (14)
- GitHub Check: spectral
- GitHub Check: unit_tests (3.12)
- GitHub Check: unit_tests (3.13)
- GitHub Check: Pylinter
- GitHub Check: integration_tests (3.13)
- GitHub Check: integration_tests (3.12)
- GitHub Check: build-pr
- GitHub Check: E2E: server mode / ci / group 1
- GitHub Check: E2E: library mode / ci / group 1
- GitHub Check: E2E: library mode / ci / group 2
- GitHub Check: E2E: library mode / ci / group 3
- GitHub Check: E2E: server mode / ci / group 3
- GitHub Check: E2E: server mode / ci / group 2
- GitHub Check: E2E Tests for Lightspeed Evaluation job
🔇 Additional comments (2)
.konflux/requirements.hashes.source.txt (1)
5-95: LGTM!Also applies to: 111-116
.konflux/requirements.hashes.wheel.txt (1)
21-24: LGTM!Also applies to: 49-55, 65-66, 88-119, 131-152, 161-162, 172-173, 182-183, 214-226, 251-253, 273-274, 288-309, 335-337, 362-363, 394-414, 424-438
| @@ -1,5 +1,5 @@ | |||
| # | |||
| # This file is autogenerated by pip-compile with Python 3.12 | |||
| # This file is autogenerated by pip-compile with Python 3.13 | |||
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Regenerate with Python 3.12.
This file was generated with Python 3.13, but the project targets Python 3.12 (py_version: 312 and the requirement generation scripts). Regenerate it in a Python 3.12 environment to avoid incompatible dependency pins or hashes.
🤖 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 @.konflux/requirements-build.txt at line 2, Regenerate the autogenerated
requirements file using Python 3.12, matching the project’s py_version setting
and requirement-generation scripts, while preserving the existing dependency
inputs and output format.
| "requirements_build_files": ["requirements-build.txt"], | ||
| "binary": { | ||
| "packages": "a2a-sdk,accelerate,aiofile,aiohappyeyeballs,aiohttp,aiosignal,aiosqlite,annotated-doc,annotated-types,anthropic,anyio,argcomplete,asyncpg,attrs,authlib,autoevals,azure-core,azure-identity,beartype,cachetools,caio,certifi,cffi,chardet,charset-normalizer,chevron,click,cryptography,datasets,dill,distro,dnspython,docstring-parser,durationpy,einops,email-validator,emoji,exceptiongroup,executing,faiss-cpu,fastapi,fastmcp-slim,fastuuid,filelock,fire,frozenlist,fsspec,genai-prices,google-api-core,google-auth,google-cloud-core,google-cloud-storage,google-crc32c,google-genai,google-resumable-media,googleapis-common-protos,greenlet,griffelib,grpc-google-iam-v1,grpcio,grpcio-status,h11,hf-xet,httpcore,httpcore2,httpx,httpx-sse,httpx2,huggingface-hub,idna,importlib-metadata,jaraco-classes,jaraco-context,jaraco-functools,jeepney,jinja2,jiter,joblib,joserfc,jsonpath-ng,jsonschema,jsonschema-specifications,keyring,kubernetes,langdetect,litellm,logfire,logfire-api,markdown-it-py,markupsafe,maturin,mcp,mdurl,more-itertools,mpmath,msal,msal-extensions,multidict,multiprocess,narwhals,networkx,nltk,numpy,oauthlib,openai,opentelemetry-api,opentelemetry-distro,opentelemetry-exporter-otlp,opentelemetry-exporter-otlp-proto-common,opentelemetry-exporter-otlp-proto-grpc,opentelemetry-exporter-otlp-proto-http,opentelemetry-instrumentation,opentelemetry-instrumentation-httpx,opentelemetry-proto,opentelemetry-sdk,opentelemetry-semantic-conventions,opentelemetry-util-http,oracledb,packaging,pandas,peft,pip,platformdirs,polyleven,prometheus-client,prompt-toolkit,propcache,proto-plus,protobuf,psutil,psycopg2-binary,py-key-value-aio,pyaml,pyarrow,pyasn1,pyasn1-modules,pycparser,pydantic,pydantic-ai,pydantic-ai-slim,pydantic-core,pydantic-evals,pydantic-graph,pydantic-settings,pygments,pyjwt,pyopenssl,pypdf,pyperclip,python-dateutil,python-dotenv,python-multipart,pytz,pyyaml,referencing,regex,requests,requests-oauthlib,rich,rpds-py,safetensors,scikit-learn,scipy,secretstorage,semver,sentence-transformers,sentry-sdk,setuptools,shellingham,six,sniffio,sqlalchemy,sse-starlette,starlette,sympy,tenacity,termcolor,threadpoolctl,tiktoken,tokenizers,torch,tornado,tqdm,transformers,tree-sitter,triton,trl,truststore,typer,typing-extensions,typing-inspection,urllib3,uv,uv-build,uvicorn,wcwidth,websocket-client,websockets,wrapt,xxhash,yarl,zipp", | ||
| "packages": "a2a-sdk,accelerate,aiofile,aiohappyeyeballs,aiohttp,aiosignal,aiosqlite,annotated-doc,annotated-types,anthropic,anyio,argcomplete,asyncpg,attrs,authlib,autoevals,azure-core,azure-identity,beartype,cachetools,caio,certifi,cffi,chardet,charset-normalizer,chevron,click,cryptography,datasets,defusedxml,dill,distro,dnspython,docstring-parser,durationpy,einops,email-validator,emoji,exceptiongroup,executing,faiss-cpu,fastapi,fastmcp-slim,fastuuid,filelock,fire,frozenlist,fsspec,genai-prices,google-api-core,google-auth,google-cloud-core,google-cloud-storage,google-crc32c,google-genai,google-resumable-media,googleapis-common-protos,greenlet,griffelib,grpc-google-iam-v1,grpcio,grpcio-status,h11,hf-xet,httpcore,httpcore2,httpx,httpx-sse,httpx2,huggingface-hub,idna,importlib-metadata,jaraco-classes,jaraco-context,jaraco-functools,jeepney,jinja2,jiter,joblib,joserfc,jsonpath-ng,jsonschema,jsonschema-specifications,keyring,kubernetes,langdetect,litellm,logfire,logfire-api,markdown-it-py,markupsafe,maturin,mcp,mdurl,more-itertools,mpmath,msal,msal-extensions,multidict,multiprocess,narwhals,networkx,nltk,numpy,oauthlib,openai,opentelemetry-api,opentelemetry-distro,opentelemetry-exporter-otlp,opentelemetry-exporter-otlp-proto-common,opentelemetry-exporter-otlp-proto-grpc,opentelemetry-exporter-otlp-proto-http,opentelemetry-instrumentation,opentelemetry-instrumentation-httpx,opentelemetry-proto,opentelemetry-sdk,opentelemetry-semantic-conventions,opentelemetry-util-http,oracledb,packaging,pandas,peft,platformdirs,polyleven,prometheus-client,prompt-toolkit,propcache,proto-plus,protobuf,psutil,psycopg2-binary,py-key-value-aio,pyaml,pyarrow,pyasn1,pyasn1-modules,pycparser,pydantic,pydantic-ai,pydantic-ai-slim,pydantic-core,pydantic-evals,pydantic-graph,pydantic-settings,pygments,pyjwt,pyopenssl,pypdf,pyperclip,python-dateutil,python-dotenv,python-multipart,pytz,pyyaml,referencing,regex,requests,requests-oauthlib,rich,rpds-py,safetensors,scikit-learn,scipy,secretstorage,semver,sentence-transformers,sentry-sdk,setuptools,shellingham,six,sniffio,sqlalchemy,sse-starlette,starlette,sympy,tenacity,termcolor,threadpoolctl,tiktoken,tokenizers,torch,tornado,tqdm,transformers,tree-sitter,triton,trl,truststore,typer,typing-extensions,typing-inspection,urllib3,uv-build,uvicorn,wcwidth,websocket-client,websockets,wrapt,xxhash,yarl,zipp", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== target files ==\n'
for f in .tekton/lightspeed-stack-0-7-pull-request.yaml .tekton/lightspeed-stack-0-7-push.yaml; do
echo "--- $f"
nl -ba "$f" | sed -n '45,70p'
done
printf '\n== search for EXTRA_WHEELS, uv, pip, Containerfile references ==\n'
rg -n --hidden --glob '!.git' --glob '!node_modules' --glob '!dist' --glob '!build' \
'EXTRA_WHEELS|uv venv|pip install|"\buv\b"|"\bpip\b"|prefetch|packages":' .
printf '\n== list potential related files ==\n'
git ls-files | rg '(^|/)(Containerfile|Dockerfile|.*tekton.*|.*prefetch.*|.*wheel.*|.*uv.*|.*pip.*)$'Repository: lightspeed-core/lightspeed-stack
Length of output: 281
🏁 Script executed:
#!/bin/bash
set -euo pipefail
line_range() {
file="$1"
start="$2"
end="$3"
awk -v s="$start" -v e="$end" 'NR>=s && NR<=e { printf "%5d %s\n", NR, $0 }' "$file"
}
printf '\n== target files ==\n'
for f in .tekton/lightspeed-stack-0-7-pull-request.yaml .tekton/lightspeed-stack-0-7-push.yaml; do
echo "--- $f"
line_range "$f" 45 70
done
printf '\n== search for EXTRA_WHEELS, uv venv, pip install, prefetch ==\n'
rg -n --hidden --glob '!.git' --glob '!node_modules' --glob '!dist' --glob '!build' \
'EXTRA_WHEELS|uv venv|pip install|prefetch|packages:"|packages":' .
printf '\n== files with likely relevant names ==\n'
git ls-files | rg '(^|/)(Containerfile|Dockerfile|.*tekton.*|.*prefetch.*|.*wheel.*|.*uv.*|.*pip.*)$'Repository: lightspeed-core/lightspeed-stack
Length of output: 50389
🏁 Script executed:
#!/bin/bash
set -euo pipefail
line_range() {
file="$1"
start="$2"
end="$3"
awk -v s="$start" -v e="$end" 'NR>=s && NR<=e { printf "%5d %s\n", NR, $0 }' "$file"
}
printf '\n== target files ==\n'
for f in .tekton/lightspeed-stack-0-7-pull-request.yaml .tekton/lightspeed-stack-0-7-push.yaml; do
echo "--- $f"
line_range "$f" 50 65
done
printf '\n== grep for relevant symbols ==\n'
rg -n --hidden --glob '!.git' --glob '!node_modules' --glob '!dist' --glob '!build' \
'EXTRA_WHEELS|uv venv|pip install|prefetch|packages:' .
printf '\n== candidate files ==\n'
git ls-files | rg '(^|/)(Containerfile|Dockerfile|.*tekton.*|.*prefetch.*|.*wheel.*|.*uv.*|.*pip.*)$'Repository: lightspeed-core/lightspeed-stack
Length of output: 50389
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
for f in [Path('.tekton/lightspeed-stack-0-7-pull-request.yaml'), Path('.tekton/lightspeed-stack-0-7-push.yaml')]:
print(f"--- {f}")
lines = f.read_text().splitlines()
for i in range(50, 62):
if i <= len(lines):
print(f"{i:5d} {lines[i-1]}")
PY
printf '\n== build/bootstrap references ==\n'
rg -n --hidden --glob '!.git' --glob '!node_modules' --glob '!dist' --glob '!build' \
-g 'Containerfile' -g 'Dockerfile' -g '*.sh' -g '*.yaml' -g '*.yml' \
'uv venv|pip install|EXTRA_WHEELS|uv\b|pip\b' .
printf '\n== candidate file names ==\n'
git ls-files | rg '(^|/)(Containerfile|Dockerfile|.*tekton.*|.*sh|.*yaml|.*yml)$'Repository: lightspeed-core/lightspeed-stack
Length of output: 29604
Restore uv and pip in the prefetch package lists
.tekton/lightspeed-stack-0-7-pull-request.yaml#L56 and .tekton/lightspeed-stack-0-7-push.yaml#L57 are missing the EXTRA_WHEELS entries (uv,pip) that scripts/konflux_requirements.sh still appends, and deploy/lightspeed-stack/Containerfile uses both to bootstrap the hermetic build.
📍 Affects 2 files
.tekton/lightspeed-stack-0-7-pull-request.yaml#L56-L56(this comment).tekton/lightspeed-stack-0-7-push.yaml#L57-L57
🤖 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 @.tekton/lightspeed-stack-0-7-pull-request.yaml at line 56, Restore uv and
pip to the packages prefetch lists at
.tekton/lightspeed-stack-0-7-pull-request.yaml:56 and
.tekton/lightspeed-stack-0-7-push.yaml:57, matching the EXTRA_WHEELS appended by
scripts/konflux_requirements.sh and required by
deploy/lightspeed-stack/Containerfile.
|
/ok-to-test |
Description
Sync the RHOAI index URL in konflux_requirements.sh with the current requirements files (packages.redhat.com/rhoai/3.5 instead of console.redhat.com/rhoai/3.3).
Also add --universal flag to source requirements compilation to allow the script to run successfully on macOS in addition to Linux
Type of change
Tools used to create PR
Identify any AI code assistants used in this PR (for transparency and review context)
Related Tickets & Documents
Checklist before requesting a review
Testing
Summary by CodeRabbit