xai-review 0.25.0__tar.gz → 0.27.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xai-review might be problematic. Click here for more details.
- {xai_review-0.25.0 → xai_review-0.27.0}/PKG-INFO +4 -4
- {xai_review-0.25.0 → xai_review-0.27.0}/README.md +3 -3
- xai_review-0.27.0/ai_review/clients/bitbucket/client.py +31 -0
- xai_review-0.27.0/ai_review/clients/bitbucket/pr/client.py +141 -0
- xai_review-0.27.0/ai_review/clients/bitbucket/pr/schema/comments.py +49 -0
- xai_review-0.27.0/ai_review/clients/bitbucket/pr/schema/files.py +30 -0
- xai_review-0.27.0/ai_review/clients/bitbucket/pr/schema/pull_request.py +38 -0
- xai_review-0.27.0/ai_review/clients/bitbucket/pr/types.py +44 -0
- xai_review-0.27.0/ai_review/clients/bitbucket/tools.py +6 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/pr/client.py +66 -12
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/pr/schema/comments.py +2 -1
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/pr/schema/files.py +2 -1
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/pr/schema/reviews.py +2 -1
- xai_review-0.27.0/ai_review/clients/github/tools.py +6 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gitlab/mr/client.py +35 -6
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gitlab/mr/schema/discussions.py +2 -1
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gitlab/mr/schema/notes.py +2 -1
- xai_review-0.27.0/ai_review/clients/gitlab/tools.py +5 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/vcs/base.py +13 -1
- xai_review-0.27.0/ai_review/libs/config/vcs/bitbucket.py +13 -0
- xai_review-0.27.0/ai_review/libs/config/vcs/pagination.py +6 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/constants/vcs_provider.py +1 -0
- xai_review-0.27.0/ai_review/libs/http/paginate.py +43 -0
- xai_review-0.27.0/ai_review/services/vcs/bitbucket/client.py +185 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/vcs/factory.py +3 -0
- xai_review-0.27.0/ai_review/tests/fixtures/clients/bitbucket.py +204 -0
- xai_review-0.27.0/ai_review/tests/suites/clients/bitbucket/test_client.py +14 -0
- xai_review-0.27.0/ai_review/tests/suites/clients/bitbucket/test_tools.py +31 -0
- xai_review-0.27.0/ai_review/tests/suites/clients/github/test_tools.py +31 -0
- xai_review-0.27.0/ai_review/tests/suites/clients/gitlab/test_tools.py +26 -0
- xai_review-0.27.0/ai_review/tests/suites/libs/http/test_paginate.py +95 -0
- xai_review-0.27.0/ai_review/tests/suites/services/review/inline/__init__.py +0 -0
- xai_review-0.27.0/ai_review/tests/suites/services/review/policy/__init__.py +0 -0
- xai_review-0.27.0/ai_review/tests/suites/services/review/summary/__init__.py +0 -0
- xai_review-0.27.0/ai_review/tests/suites/services/vcs/__init__.py +0 -0
- xai_review-0.27.0/ai_review/tests/suites/services/vcs/bitbucket/__init__.py +0 -0
- xai_review-0.27.0/ai_review/tests/suites/services/vcs/bitbucket/test_service.py +117 -0
- xai_review-0.27.0/ai_review/tests/suites/services/vcs/github/__init__.py +0 -0
- xai_review-0.27.0/ai_review/tests/suites/services/vcs/gitlab/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/vcs/test_factory.py +8 -1
- {xai_review-0.25.0 → xai_review-0.27.0}/pyproject.toml +1 -1
- {xai_review-0.25.0 → xai_review-0.27.0}/xai_review.egg-info/PKG-INFO +4 -4
- {xai_review-0.25.0 → xai_review-0.27.0}/xai_review.egg-info/SOURCES.txt +27 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/LICENSE +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/commands/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/commands/run_context_review.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/commands/run_inline_review.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/commands/run_review.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/commands/run_summary_review.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/cli/main.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/clients/claude → xai_review-0.27.0/ai_review/clients/bitbucket}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/clients/gemini → xai_review-0.27.0/ai_review/clients/bitbucket/pr}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/clients/github → xai_review-0.27.0/ai_review/clients/bitbucket/pr/schema}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/clients/github/pr → xai_review-0.27.0/ai_review/clients/claude}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/claude/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/claude/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/claude/types.py +0 -0
- {xai_review-0.25.0/ai_review/clients/github/pr/schema → xai_review-0.27.0/ai_review/clients/gemini}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gemini/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gemini/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gemini/types.py +0 -0
- {xai_review-0.25.0/ai_review/clients/gitlab → xai_review-0.27.0/ai_review/clients/github}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/client.py +0 -0
- {xai_review-0.25.0/ai_review/clients/gitlab/mr → xai_review-0.27.0/ai_review/clients/github/pr}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/clients/gitlab/mr → xai_review-0.27.0/ai_review/clients/github/pr}/schema/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/pr/schema/pull_request.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/github/pr/types.py +0 -0
- {xai_review-0.25.0/ai_review/clients/ollama → xai_review-0.27.0/ai_review/clients/gitlab}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gitlab/client.py +0 -0
- {xai_review-0.25.0/ai_review/clients/openai → xai_review-0.27.0/ai_review/clients/gitlab/mr}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/libs → xai_review-0.27.0/ai_review/clients/gitlab/mr/schema}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gitlab/mr/schema/changes.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/gitlab/mr/types.py +0 -0
- {xai_review-0.25.0/ai_review/libs/asynchronous → xai_review-0.27.0/ai_review/clients/ollama}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/ollama/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/ollama/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/ollama/types.py +0 -0
- {xai_review-0.25.0/ai_review/libs/config → xai_review-0.27.0/ai_review/clients/openai}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/openai/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/openai/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/clients/openai/types.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/config.py +0 -0
- {xai_review-0.25.0/ai_review/libs/config/llm → xai_review-0.27.0/ai_review/libs}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/libs/config/vcs → xai_review-0.27.0/ai_review/libs/asynchronous}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/asynchronous/gather.py +0 -0
- {xai_review-0.25.0/ai_review/libs/constants → xai_review-0.27.0/ai_review/libs/config}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/artifacts.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/base.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/core.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/http.py +0 -0
- {xai_review-0.25.0/ai_review/libs/diff → xai_review-0.27.0/ai_review/libs/config/llm}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/llm/base.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/llm/claude.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/llm/gemini.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/llm/meta.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/llm/ollama.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/llm/openai.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/logger.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/prompt.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/review.py +0 -0
- {xai_review-0.25.0/ai_review/libs/http → xai_review-0.27.0/ai_review/libs/config/vcs}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/vcs/github.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/config/vcs/gitlab.py +0 -0
- {xai_review-0.25.0/ai_review/libs/http/event_hooks → xai_review-0.27.0/ai_review/libs/constants}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/constants/llm_provider.py +0 -0
- {xai_review-0.25.0/ai_review/libs/http/transports → xai_review-0.27.0/ai_review/libs/diff}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/diff/models.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/diff/parser.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/diff/tools.py +0 -0
- {xai_review-0.25.0/ai_review/libs/template → xai_review-0.27.0/ai_review/libs/http}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/http/client.py +0 -0
- {xai_review-0.25.0/ai_review/prompts → xai_review-0.27.0/ai_review/libs/http/event_hooks}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/http/event_hooks/base.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/http/handlers.py +0 -0
- {xai_review-0.25.0/ai_review/resources → xai_review-0.27.0/ai_review/libs/http/transports}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/http/transports/retry.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/json.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/logger.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/resources.py +0 -0
- {xai_review-0.25.0/ai_review/services → xai_review-0.27.0/ai_review/libs/template}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/libs/template/render.py +0 -0
- {xai_review-0.25.0/ai_review/services/artifacts → xai_review-0.27.0/ai_review/prompts}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/prompts/default_context.md +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/prompts/default_inline.md +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/prompts/default_summary.md +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/prompts/default_system_context.md +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/prompts/default_system_inline.md +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/prompts/default_system_summary.md +0 -0
- {xai_review-0.25.0/ai_review/services/cost → xai_review-0.27.0/ai_review/resources}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/resources/pricing.yaml +0 -0
- {xai_review-0.25.0/ai_review/services/diff → xai_review-0.27.0/ai_review/services}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/services/git → xai_review-0.27.0/ai_review/services/artifacts}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/artifacts/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/artifacts/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/artifacts/tools.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/artifacts/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/llm → xai_review-0.27.0/ai_review/services/cost}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/cost/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/cost/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/cost/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/llm/claude → xai_review-0.27.0/ai_review/services/diff}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/diff/renderers.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/diff/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/diff/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/diff/tools.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/diff/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/llm/gemini → xai_review-0.27.0/ai_review/services/git}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/git/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/git/types.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/hook/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/hook/constants.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/hook/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/hook/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/llm/ollama → xai_review-0.27.0/ai_review/services/llm}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/services/llm/openai → xai_review-0.27.0/ai_review/services/llm/claude}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/llm/claude/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/llm/factory.py +0 -0
- {xai_review-0.25.0/ai_review/services/prompt → xai_review-0.27.0/ai_review/services/llm/gemini}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/llm/gemini/client.py +0 -0
- {xai_review-0.25.0/ai_review/services/review → xai_review-0.27.0/ai_review/services/llm/ollama}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/llm/ollama/client.py +0 -0
- {xai_review-0.25.0/ai_review/services/review/gateway → xai_review-0.27.0/ai_review/services/llm/openai}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/llm/openai/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/llm/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/review/inline → xai_review-0.27.0/ai_review/services/prompt}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/prompt/adapter.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/prompt/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/prompt/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/prompt/tools.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/prompt/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/review/policy → xai_review-0.27.0/ai_review/services/review}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/services/review/summary → xai_review-0.27.0/ai_review/services/review/gateway}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/gateway/comment.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/gateway/llm.py +0 -0
- {xai_review-0.25.0/ai_review/services/vcs → xai_review-0.27.0/ai_review/services/review/inline}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/inline/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/inline/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/inline/types.py +0 -0
- {xai_review-0.25.0/ai_review/services/vcs/github → xai_review-0.27.0/ai_review/services/review/policy}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/policy/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/service.py +0 -0
- {xai_review-0.25.0/ai_review/services/vcs/gitlab → xai_review-0.27.0/ai_review/services/review/summary}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/summary/schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/summary/service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/review/summary/types.py +0 -0
- {xai_review-0.25.0/ai_review/tests → xai_review-0.27.0/ai_review/services/vcs}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/fixtures → xai_review-0.27.0/ai_review/services/vcs/bitbucket}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/fixtures/clients → xai_review-0.27.0/ai_review/services/vcs/github}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/vcs/github/client.py +0 -0
- {xai_review-0.25.0/ai_review/tests/fixtures/services → xai_review-0.27.0/ai_review/services/vcs/gitlab}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/vcs/gitlab/client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/services/vcs/types.py +0 -0
- {xai_review-0.25.0/ai_review/tests/fixtures/services/review → xai_review-0.27.0/ai_review/tests}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites → xai_review-0.27.0/ai_review/tests/fixtures}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites → xai_review-0.27.0/ai_review/tests/fixtures}/clients/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/clients/claude.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/clients/gemini.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/clients/github.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/clients/gitlab.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/clients/ollama.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/clients/openai.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/clients/claude → xai_review-0.27.0/ai_review/tests/fixtures/services}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/artifacts.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/cost.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/diff.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/git.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/llm.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/prompt.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/clients/gemini → xai_review-0.27.0/ai_review/tests/fixtures/services/review}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/review/inline.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/review/summary.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/fixtures/services/vcs.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/clients/github → xai_review-0.27.0/ai_review/tests/suites}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/clients/gitlab → xai_review-0.27.0/ai_review/tests/suites/clients}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/clients/ollama → xai_review-0.27.0/ai_review/tests/suites/clients/bitbucket}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/clients/openai → xai_review-0.27.0/ai_review/tests/suites/clients/claude}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/libs → xai_review-0.27.0/ai_review/tests/suites/clients/gemini}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/libs/asynchronous → xai_review-0.27.0/ai_review/tests/suites/clients/github}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/github/test_client.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/libs/config → xai_review-0.27.0/ai_review/tests/suites/clients/gitlab}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/libs/diff → xai_review-0.27.0/ai_review/tests/suites/clients/ollama}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/ollama/test_client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/ollama/test_schema.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/libs/template → xai_review-0.27.0/ai_review/tests/suites/clients/openai}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/openai/test_client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/clients/openai/test_schema.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services → xai_review-0.27.0/ai_review/tests/suites/libs}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/cost → xai_review-0.27.0/ai_review/tests/suites/libs/asynchronous}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/asynchronous/test_gather.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/diff → xai_review-0.27.0/ai_review/tests/suites/libs/config}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/config/test_prompt.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/hook → xai_review-0.27.0/ai_review/tests/suites/libs/diff}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/llm → xai_review-0.27.0/ai_review/tests/suites/libs/http}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/llm/claude → xai_review-0.27.0/ai_review/tests/suites/libs/template}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/libs/test_json.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/llm/gemini → xai_review-0.27.0/ai_review/tests/suites/services}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/llm/ollama → xai_review-0.27.0/ai_review/tests/suites/services/cost}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/cost/test_schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/cost/test_service.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/llm/openai → xai_review-0.27.0/ai_review/tests/suites/services/diff}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/prompt → xai_review-0.27.0/ai_review/tests/suites/services/hook}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/hook/test_service.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/review → xai_review-0.27.0/ai_review/tests/suites/services/llm}/__init__.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/review/inline → xai_review-0.27.0/ai_review/tests/suites/services/llm/claude}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/llm/claude/test_client.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/review/policy → xai_review-0.27.0/ai_review/tests/suites/services/llm/gemini}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/llm/gemini/test_client.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/review/summary → xai_review-0.27.0/ai_review/tests/suites/services/llm/ollama}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/llm/ollama/test_client.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/vcs → xai_review-0.27.0/ai_review/tests/suites/services/llm/openai}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/llm/openai/test_client.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/llm/test_factory.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/vcs/github → xai_review-0.27.0/ai_review/tests/suites/services/prompt}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/prompt/test_adapter.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/prompt/test_schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/prompt/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/prompt/test_tools.py +0 -0
- {xai_review-0.25.0/ai_review/tests/suites/services/vcs/gitlab → xai_review-0.27.0/ai_review/tests/suites/services/review}/__init__.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/review/inline/test_schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/review/inline/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/review/policy/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/review/summary/test_schema.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/review/summary/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/review/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/vcs/github/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/ai_review/tests/suites/services/vcs/gitlab/test_service.py +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/setup.cfg +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/xai_review.egg-info/dependency_links.txt +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/xai_review.egg-info/entry_points.txt +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/xai_review.egg-info/requires.txt +0 -0
- {xai_review-0.25.0 → xai_review-0.27.0}/xai_review.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xai-review
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: AI-powered code review tool
|
|
5
5
|
Author-email: Nikita Filonov <nikita.filonov@example.com>
|
|
6
6
|
Maintainer-email: Nikita Filonov <nikita.filonov@example.com>
|
|
@@ -67,7 +67,7 @@ improve code quality, enforce consistency, and speed up the review process.
|
|
|
67
67
|
✨ Key features:
|
|
68
68
|
|
|
69
69
|
- **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, or **Ollama**, and switch anytime.
|
|
70
|
-
- **VCS integration** — works out of the box with GitLab
|
|
70
|
+
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, and **Bitbucket**.
|
|
71
71
|
- **Customizable prompts** — adapt inline, context, and summary reviews to match your team’s coding guidelines.
|
|
72
72
|
- **Flexible configuration** — supports `YAML`, `JSON`, and `ENV`, with seamless overrides in CI/CD pipelines.
|
|
73
73
|
- **AI Review runs fully client-side** — it never proxies or inspects your requests.
|
|
@@ -170,7 +170,7 @@ Key things you can customize:
|
|
|
170
170
|
|
|
171
171
|
- **LLM provider** — OpenAI, Gemini, Claude, or Ollama
|
|
172
172
|
- **Model settings** — model name, temperature, max tokens
|
|
173
|
-
- **VCS integration** — works out of the box with **GitLab** and **
|
|
173
|
+
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, and **Bitbucket**
|
|
174
174
|
- **Review policy** — which files to include/exclude, review modes
|
|
175
175
|
- **Prompts** — inline/context/summary prompt templates
|
|
176
176
|
|
|
@@ -209,7 +209,7 @@ jobs:
|
|
|
209
209
|
runs-on: ubuntu-latest
|
|
210
210
|
steps:
|
|
211
211
|
- uses: actions/checkout@v4
|
|
212
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
212
|
+
- uses: Nikita-Filonov/ai-review@v0.27.0
|
|
213
213
|
with:
|
|
214
214
|
review-command: ${{ inputs.review-command }}
|
|
215
215
|
env:
|
|
@@ -33,7 +33,7 @@ improve code quality, enforce consistency, and speed up the review process.
|
|
|
33
33
|
✨ Key features:
|
|
34
34
|
|
|
35
35
|
- **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, or **Ollama**, and switch anytime.
|
|
36
|
-
- **VCS integration** — works out of the box with GitLab
|
|
36
|
+
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, and **Bitbucket**.
|
|
37
37
|
- **Customizable prompts** — adapt inline, context, and summary reviews to match your team’s coding guidelines.
|
|
38
38
|
- **Flexible configuration** — supports `YAML`, `JSON`, and `ENV`, with seamless overrides in CI/CD pipelines.
|
|
39
39
|
- **AI Review runs fully client-side** — it never proxies or inspects your requests.
|
|
@@ -136,7 +136,7 @@ Key things you can customize:
|
|
|
136
136
|
|
|
137
137
|
- **LLM provider** — OpenAI, Gemini, Claude, or Ollama
|
|
138
138
|
- **Model settings** — model name, temperature, max tokens
|
|
139
|
-
- **VCS integration** — works out of the box with **GitLab** and **
|
|
139
|
+
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, and **Bitbucket**
|
|
140
140
|
- **Review policy** — which files to include/exclude, review modes
|
|
141
141
|
- **Prompts** — inline/context/summary prompt templates
|
|
142
142
|
|
|
@@ -175,7 +175,7 @@ jobs:
|
|
|
175
175
|
runs-on: ubuntu-latest
|
|
176
176
|
steps:
|
|
177
177
|
- uses: actions/checkout@v4
|
|
178
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
178
|
+
- uses: Nikita-Filonov/ai-review@v0.27.0
|
|
179
179
|
with:
|
|
180
180
|
review-command: ${{ inputs.review-command }}
|
|
181
181
|
env:
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from ai_review.clients.bitbucket.pr.client import BitbucketPullRequestsHTTPClient
|
|
2
|
+
from httpx import AsyncClient, AsyncHTTPTransport
|
|
3
|
+
|
|
4
|
+
from ai_review.config import settings
|
|
5
|
+
from ai_review.libs.http.event_hooks.logger import LoggerEventHook
|
|
6
|
+
from ai_review.libs.http.transports.retry import RetryTransport
|
|
7
|
+
from ai_review.libs.logger import get_logger
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BitbucketHTTPClient:
|
|
11
|
+
def __init__(self, client: AsyncClient):
|
|
12
|
+
self.pr = BitbucketPullRequestsHTTPClient(client)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_bitbucket_http_client() -> BitbucketHTTPClient:
|
|
16
|
+
logger = get_logger("BITBUCKET_HTTP_CLIENT")
|
|
17
|
+
logger_event_hook = LoggerEventHook(logger=logger)
|
|
18
|
+
retry_transport = RetryTransport(logger=logger, transport=AsyncHTTPTransport())
|
|
19
|
+
|
|
20
|
+
client = AsyncClient(
|
|
21
|
+
timeout=settings.llm.http_client.timeout,
|
|
22
|
+
headers={"Authorization": f"Bearer {settings.vcs.http_client.api_token_value}"},
|
|
23
|
+
base_url=settings.vcs.http_client.api_url_value,
|
|
24
|
+
transport=retry_transport,
|
|
25
|
+
event_hooks={
|
|
26
|
+
"request": [logger_event_hook.request],
|
|
27
|
+
"response": [logger_event_hook.response],
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return BitbucketHTTPClient(client=client)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
from httpx import Response, QueryParams
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.bitbucket.pr.schema.comments import (
|
|
4
|
+
BitbucketPRCommentSchema,
|
|
5
|
+
BitbucketGetPRCommentsQuerySchema,
|
|
6
|
+
BitbucketGetPRCommentsResponseSchema,
|
|
7
|
+
BitbucketCreatePRCommentRequestSchema,
|
|
8
|
+
BitbucketCreatePRCommentResponseSchema,
|
|
9
|
+
)
|
|
10
|
+
from ai_review.clients.bitbucket.pr.schema.files import (
|
|
11
|
+
BitbucketPRFileSchema,
|
|
12
|
+
BitbucketGetPRFilesQuerySchema,
|
|
13
|
+
BitbucketGetPRFilesResponseSchema,
|
|
14
|
+
)
|
|
15
|
+
from ai_review.clients.bitbucket.pr.schema.pull_request import BitbucketGetPRResponseSchema
|
|
16
|
+
from ai_review.clients.bitbucket.pr.types import BitbucketPullRequestsHTTPClientProtocol
|
|
17
|
+
from ai_review.clients.bitbucket.tools import bitbucket_has_next_page
|
|
18
|
+
from ai_review.config import settings
|
|
19
|
+
from ai_review.libs.http.client import HTTPClient
|
|
20
|
+
from ai_review.libs.http.handlers import handle_http_error, HTTPClientError
|
|
21
|
+
from ai_review.libs.http.paginate import paginate
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BitbucketPullRequestsHTTPClientError(HTTPClientError):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BitbucketPullRequestsHTTPClient(HTTPClient, BitbucketPullRequestsHTTPClientProtocol):
|
|
29
|
+
@handle_http_error(client="BitbucketPullRequestsHTTPClient", exception=BitbucketPullRequestsHTTPClientError)
|
|
30
|
+
async def get_pull_request_api(self, workspace: str, repo_slug: str, pull_request_id: str) -> Response:
|
|
31
|
+
return await self.get(f"/repositories/{workspace}/{repo_slug}/pullrequests/{pull_request_id}")
|
|
32
|
+
|
|
33
|
+
@handle_http_error(client="BitbucketPullRequestsHTTPClient", exception=BitbucketPullRequestsHTTPClientError)
|
|
34
|
+
async def get_diffstat_api(
|
|
35
|
+
self,
|
|
36
|
+
workspace: str,
|
|
37
|
+
repo_slug: str,
|
|
38
|
+
pull_request_id: str,
|
|
39
|
+
query: BitbucketGetPRFilesQuerySchema,
|
|
40
|
+
) -> Response:
|
|
41
|
+
return await self.get(
|
|
42
|
+
f"/repositories/{workspace}/{repo_slug}/pullrequests/{pull_request_id}/diffstat",
|
|
43
|
+
query=QueryParams(**query.model_dump(by_alias=True)),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
@handle_http_error(client="BitbucketPullRequestsHTTPClient", exception=BitbucketPullRequestsHTTPClientError)
|
|
47
|
+
async def get_comments_api(
|
|
48
|
+
self,
|
|
49
|
+
workspace: str,
|
|
50
|
+
repo_slug: str,
|
|
51
|
+
pull_request_id: str,
|
|
52
|
+
query: BitbucketGetPRCommentsQuerySchema,
|
|
53
|
+
) -> Response:
|
|
54
|
+
return await self.get(
|
|
55
|
+
f"/repositories/{workspace}/{repo_slug}/pullrequests/{pull_request_id}/comments",
|
|
56
|
+
query=QueryParams(**query.model_dump(by_alias=True)),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
@handle_http_error(client="BitbucketPullRequestsHTTPClient", exception=BitbucketPullRequestsHTTPClientError)
|
|
60
|
+
async def create_comment_api(
|
|
61
|
+
self,
|
|
62
|
+
workspace: str,
|
|
63
|
+
repo_slug: str,
|
|
64
|
+
pull_request_id: str,
|
|
65
|
+
request: BitbucketCreatePRCommentRequestSchema,
|
|
66
|
+
) -> Response:
|
|
67
|
+
return await self.post(
|
|
68
|
+
f"/repositories/{workspace}/{repo_slug}/pullrequests/{pull_request_id}/comments",
|
|
69
|
+
json=request.model_dump(by_alias=True),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
async def get_pull_request(
|
|
73
|
+
self,
|
|
74
|
+
workspace: str,
|
|
75
|
+
repo_slug: str,
|
|
76
|
+
pull_request_id: str
|
|
77
|
+
) -> BitbucketGetPRResponseSchema:
|
|
78
|
+
resp = await self.get_pull_request_api(workspace, repo_slug, pull_request_id)
|
|
79
|
+
return BitbucketGetPRResponseSchema.model_validate_json(resp.text)
|
|
80
|
+
|
|
81
|
+
async def get_files(
|
|
82
|
+
self,
|
|
83
|
+
workspace: str,
|
|
84
|
+
repo_slug: str,
|
|
85
|
+
pull_request_id: str
|
|
86
|
+
) -> BitbucketGetPRFilesResponseSchema:
|
|
87
|
+
async def fetch_page(page: int) -> Response:
|
|
88
|
+
query = BitbucketGetPRFilesQuerySchema(page=page, page_len=settings.vcs.pagination.per_page)
|
|
89
|
+
return await self.get_diffstat_api(workspace, repo_slug, pull_request_id, query)
|
|
90
|
+
|
|
91
|
+
def extract_items(response: Response) -> list[BitbucketPRFileSchema]:
|
|
92
|
+
result = BitbucketGetPRFilesResponseSchema.model_validate_json(response.text)
|
|
93
|
+
return result.values
|
|
94
|
+
|
|
95
|
+
items = await paginate(
|
|
96
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
97
|
+
fetch_page=fetch_page,
|
|
98
|
+
extract_items=extract_items,
|
|
99
|
+
has_next_page=bitbucket_has_next_page
|
|
100
|
+
)
|
|
101
|
+
return BitbucketGetPRFilesResponseSchema(
|
|
102
|
+
size=len(items),
|
|
103
|
+
values=items,
|
|
104
|
+
page_len=settings.vcs.pagination.per_page
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
async def get_comments(
|
|
108
|
+
self,
|
|
109
|
+
workspace: str,
|
|
110
|
+
repo_slug: str,
|
|
111
|
+
pull_request_id: str
|
|
112
|
+
) -> BitbucketGetPRCommentsResponseSchema:
|
|
113
|
+
async def fetch_page(page: int) -> Response:
|
|
114
|
+
query = BitbucketGetPRCommentsQuerySchema(page=page, page_len=settings.vcs.pagination.per_page)
|
|
115
|
+
return await self.get_comments_api(workspace, repo_slug, pull_request_id, query)
|
|
116
|
+
|
|
117
|
+
def extract_items(response: Response) -> list[BitbucketPRCommentSchema]:
|
|
118
|
+
result = BitbucketGetPRCommentsResponseSchema.model_validate_json(response.text)
|
|
119
|
+
return result.values
|
|
120
|
+
|
|
121
|
+
items = await paginate(
|
|
122
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
123
|
+
fetch_page=fetch_page,
|
|
124
|
+
extract_items=extract_items,
|
|
125
|
+
has_next_page=bitbucket_has_next_page
|
|
126
|
+
)
|
|
127
|
+
return BitbucketGetPRCommentsResponseSchema(
|
|
128
|
+
size=len(items),
|
|
129
|
+
values=items,
|
|
130
|
+
page_len=settings.vcs.pagination.per_page
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
async def create_comment(
|
|
134
|
+
self,
|
|
135
|
+
workspace: str,
|
|
136
|
+
repo_slug: str,
|
|
137
|
+
pull_request_id: str,
|
|
138
|
+
request: BitbucketCreatePRCommentRequestSchema
|
|
139
|
+
) -> BitbucketCreatePRCommentResponseSchema:
|
|
140
|
+
response = await self.create_comment_api(workspace, repo_slug, pull_request_id, request)
|
|
141
|
+
return BitbucketCreatePRCommentResponseSchema.model_validate_json(response.text)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BitbucketCommentContentSchema(BaseModel):
|
|
5
|
+
raw: str
|
|
6
|
+
html: str | None = None
|
|
7
|
+
markup: str | None = None
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BitbucketCommentInlineSchema(BaseModel):
|
|
11
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
12
|
+
|
|
13
|
+
path: str
|
|
14
|
+
to_line: int | None = Field(alias="to", default=None)
|
|
15
|
+
from_line: int | None = Field(alias="from", default=None)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BitbucketPRCommentSchema(BaseModel):
|
|
19
|
+
id: int
|
|
20
|
+
inline: BitbucketCommentInlineSchema | None = None
|
|
21
|
+
content: BitbucketCommentContentSchema
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BitbucketGetPRCommentsQuerySchema(BaseModel):
|
|
25
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
26
|
+
|
|
27
|
+
page: int = 1
|
|
28
|
+
page_len: int = Field(alias="pagelen", default=100)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BitbucketGetPRCommentsResponseSchema(BaseModel):
|
|
32
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
33
|
+
|
|
34
|
+
size: int
|
|
35
|
+
page: int | None = None
|
|
36
|
+
next: str | None = None
|
|
37
|
+
values: list[BitbucketPRCommentSchema]
|
|
38
|
+
page_len: int = Field(alias="pagelen")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class BitbucketCreatePRCommentRequestSchema(BaseModel):
|
|
42
|
+
inline: BitbucketCommentInlineSchema | None = None
|
|
43
|
+
content: BitbucketCommentContentSchema
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class BitbucketCreatePRCommentResponseSchema(BaseModel):
|
|
47
|
+
id: int
|
|
48
|
+
inline: BitbucketCommentInlineSchema | None = None
|
|
49
|
+
content: BitbucketCommentContentSchema
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BitbucketPRFilePathSchema(BaseModel):
|
|
5
|
+
path: str
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BitbucketPRFileSchema(BaseModel):
|
|
9
|
+
new: BitbucketPRFilePathSchema | None = None
|
|
10
|
+
old: BitbucketPRFilePathSchema | None = None
|
|
11
|
+
status: str
|
|
12
|
+
lines_added: int
|
|
13
|
+
lines_removed: int
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BitbucketGetPRFilesQuerySchema(BaseModel):
|
|
17
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
18
|
+
|
|
19
|
+
page: int = 1
|
|
20
|
+
page_len: int = Field(alias="pagelen", default=100)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BitbucketGetPRFilesResponseSchema(BaseModel):
|
|
24
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
25
|
+
|
|
26
|
+
size: int
|
|
27
|
+
page: int | None = None
|
|
28
|
+
next: str | None = None
|
|
29
|
+
values: list[BitbucketPRFileSchema]
|
|
30
|
+
page_len: int = Field(alias="pagelen")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BitbucketUserSchema(BaseModel):
|
|
5
|
+
uuid: str
|
|
6
|
+
nickname: str
|
|
7
|
+
display_name: str
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BitbucketBranchSchema(BaseModel):
|
|
11
|
+
name: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BitbucketCommitSchema(BaseModel):
|
|
15
|
+
hash: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BitbucketRepositorySchema(BaseModel):
|
|
19
|
+
uuid: str
|
|
20
|
+
full_name: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BitbucketPRLocationSchema(BaseModel):
|
|
24
|
+
branch: BitbucketBranchSchema
|
|
25
|
+
commit: BitbucketCommitSchema
|
|
26
|
+
repository: BitbucketRepositorySchema
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class BitbucketGetPRResponseSchema(BaseModel):
|
|
30
|
+
id: int
|
|
31
|
+
title: str
|
|
32
|
+
description: str | None = None
|
|
33
|
+
state: str
|
|
34
|
+
author: BitbucketUserSchema
|
|
35
|
+
source: BitbucketPRLocationSchema
|
|
36
|
+
destination: BitbucketPRLocationSchema
|
|
37
|
+
reviewers: list[BitbucketUserSchema] = Field(default_factory=list)
|
|
38
|
+
participants: list[BitbucketUserSchema] = Field(default_factory=list)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.bitbucket.pr.schema.comments import (
|
|
4
|
+
BitbucketGetPRCommentsResponseSchema,
|
|
5
|
+
BitbucketCreatePRCommentRequestSchema,
|
|
6
|
+
BitbucketCreatePRCommentResponseSchema,
|
|
7
|
+
)
|
|
8
|
+
from ai_review.clients.bitbucket.pr.schema.files import BitbucketGetPRFilesResponseSchema
|
|
9
|
+
from ai_review.clients.bitbucket.pr.schema.pull_request import BitbucketGetPRResponseSchema
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BitbucketPullRequestsHTTPClientProtocol(Protocol):
|
|
13
|
+
async def get_pull_request(
|
|
14
|
+
self,
|
|
15
|
+
workspace: str,
|
|
16
|
+
repo_slug: str,
|
|
17
|
+
pull_request_id: str
|
|
18
|
+
) -> BitbucketGetPRResponseSchema:
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
async def get_files(
|
|
22
|
+
self,
|
|
23
|
+
workspace: str,
|
|
24
|
+
repo_slug: str,
|
|
25
|
+
pull_request_id: str
|
|
26
|
+
) -> BitbucketGetPRFilesResponseSchema:
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
async def get_comments(
|
|
30
|
+
self,
|
|
31
|
+
workspace: str,
|
|
32
|
+
repo_slug: str,
|
|
33
|
+
pull_request_id: str
|
|
34
|
+
) -> BitbucketGetPRCommentsResponseSchema:
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
async def create_comment(
|
|
38
|
+
self,
|
|
39
|
+
workspace: str,
|
|
40
|
+
repo_slug: str,
|
|
41
|
+
pull_request_id: str,
|
|
42
|
+
request: BitbucketCreatePRCommentRequestSchema,
|
|
43
|
+
) -> BitbucketCreatePRCommentResponseSchema:
|
|
44
|
+
...
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from httpx import Response, QueryParams
|
|
2
2
|
|
|
3
3
|
from ai_review.clients.github.pr.schema.comments import (
|
|
4
|
+
GitHubPRCommentSchema,
|
|
4
5
|
GitHubGetPRCommentsQuerySchema,
|
|
5
6
|
GitHubGetPRCommentsResponseSchema,
|
|
6
7
|
GitHubCreateIssueCommentRequestSchema,
|
|
@@ -9,17 +10,22 @@ from ai_review.clients.github.pr.schema.comments import (
|
|
|
9
10
|
GitHubCreateReviewCommentResponseSchema
|
|
10
11
|
)
|
|
11
12
|
from ai_review.clients.github.pr.schema.files import (
|
|
13
|
+
GitHubPRFileSchema,
|
|
12
14
|
GitHubGetPRFilesQuerySchema,
|
|
13
15
|
GitHubGetPRFilesResponseSchema
|
|
14
16
|
)
|
|
15
17
|
from ai_review.clients.github.pr.schema.pull_request import GitHubGetPRResponseSchema
|
|
16
18
|
from ai_review.clients.github.pr.schema.reviews import (
|
|
19
|
+
GitHubPRReviewSchema,
|
|
17
20
|
GitHubGetPRReviewsQuerySchema,
|
|
18
21
|
GitHubGetPRReviewsResponseSchema
|
|
19
22
|
)
|
|
20
23
|
from ai_review.clients.github.pr.types import GitHubPullRequestsHTTPClientProtocol
|
|
24
|
+
from ai_review.clients.github.tools import github_has_next_page
|
|
25
|
+
from ai_review.config import settings
|
|
21
26
|
from ai_review.libs.http.client import HTTPClient
|
|
22
27
|
from ai_review.libs.http.handlers import HTTPClientError, handle_http_error
|
|
28
|
+
from ai_review.libs.http.paginate import paginate
|
|
23
29
|
|
|
24
30
|
|
|
25
31
|
class GitHubPullRequestsHTTPClientError(HTTPClientError):
|
|
@@ -114,24 +120,72 @@ class GitHubPullRequestsHTTPClient(HTTPClient, GitHubPullRequestsHTTPClientProto
|
|
|
114
120
|
return GitHubGetPRResponseSchema.model_validate_json(response.text)
|
|
115
121
|
|
|
116
122
|
async def get_files(self, owner: str, repo: str, pull_number: str) -> GitHubGetPRFilesResponseSchema:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
async def fetch_page(page: int) -> Response:
|
|
124
|
+
query = GitHubGetPRFilesQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
|
|
125
|
+
return await self.get_files_api(owner, repo, pull_number, query)
|
|
126
|
+
|
|
127
|
+
def extract_items(response: Response) -> list[GitHubPRFileSchema]:
|
|
128
|
+
result = GitHubGetPRFilesResponseSchema.model_validate_json(response.text)
|
|
129
|
+
return result.root
|
|
130
|
+
|
|
131
|
+
items = await paginate(
|
|
132
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
133
|
+
fetch_page=fetch_page,
|
|
134
|
+
extract_items=extract_items,
|
|
135
|
+
has_next_page=github_has_next_page
|
|
136
|
+
)
|
|
137
|
+
return GitHubGetPRFilesResponseSchema(root=items)
|
|
120
138
|
|
|
121
139
|
async def get_issue_comments(self, owner: str, repo: str, issue_number: str) -> GitHubGetPRCommentsResponseSchema:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
140
|
+
async def fetch_page(page: int) -> Response:
|
|
141
|
+
query = GitHubGetPRCommentsQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
|
|
142
|
+
return await self.get_issue_comments_api(owner, repo, issue_number, query)
|
|
143
|
+
|
|
144
|
+
def extract_items(response: Response) -> list[GitHubPRCommentSchema]:
|
|
145
|
+
result = GitHubGetPRCommentsResponseSchema.model_validate_json(response.text)
|
|
146
|
+
return result.root
|
|
147
|
+
|
|
148
|
+
items = await paginate(
|
|
149
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
150
|
+
fetch_page=fetch_page,
|
|
151
|
+
extract_items=extract_items,
|
|
152
|
+
has_next_page=github_has_next_page
|
|
153
|
+
)
|
|
154
|
+
return GitHubGetPRCommentsResponseSchema(root=items)
|
|
125
155
|
|
|
126
156
|
async def get_review_comments(self, owner: str, repo: str, pull_number: str) -> GitHubGetPRCommentsResponseSchema:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
157
|
+
async def fetch_page(page: int) -> Response:
|
|
158
|
+
query = GitHubGetPRCommentsQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
|
|
159
|
+
return await self.get_review_comments_api(owner, repo, pull_number, query)
|
|
160
|
+
|
|
161
|
+
def extract_items(response: Response) -> list[GitHubPRCommentSchema]:
|
|
162
|
+
result = GitHubGetPRCommentsResponseSchema.model_validate_json(response.text)
|
|
163
|
+
return result.root
|
|
164
|
+
|
|
165
|
+
items = await paginate(
|
|
166
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
167
|
+
fetch_page=fetch_page,
|
|
168
|
+
extract_items=extract_items,
|
|
169
|
+
has_next_page=github_has_next_page
|
|
170
|
+
)
|
|
171
|
+
return GitHubGetPRCommentsResponseSchema(root=items)
|
|
130
172
|
|
|
131
173
|
async def get_reviews(self, owner: str, repo: str, pull_number: str) -> GitHubGetPRReviewsResponseSchema:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
174
|
+
async def fetch_page(page: int) -> Response:
|
|
175
|
+
query = GitHubGetPRReviewsQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
|
|
176
|
+
return await self.get_reviews_api(owner, repo, pull_number, query)
|
|
177
|
+
|
|
178
|
+
def extract_items(response: Response) -> list[GitHubPRReviewSchema]:
|
|
179
|
+
result = GitHubGetPRReviewsResponseSchema.model_validate_json(response.text)
|
|
180
|
+
return result.root
|
|
181
|
+
|
|
182
|
+
items = await paginate(
|
|
183
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
184
|
+
fetch_page=fetch_page,
|
|
185
|
+
extract_items=extract_items,
|
|
186
|
+
has_next_page=github_has_next_page
|
|
187
|
+
)
|
|
188
|
+
return GitHubGetPRReviewsResponseSchema(root=items)
|
|
135
189
|
|
|
136
190
|
async def create_review_comment(
|
|
137
191
|
self,
|
|
@@ -2,20 +2,25 @@ from httpx import Response, QueryParams
|
|
|
2
2
|
|
|
3
3
|
from ai_review.clients.gitlab.mr.schema.changes import GitLabGetMRChangesResponseSchema
|
|
4
4
|
from ai_review.clients.gitlab.mr.schema.discussions import (
|
|
5
|
+
GitLabDiscussionSchema,
|
|
5
6
|
GitLabGetMRDiscussionsQuerySchema,
|
|
6
7
|
GitLabGetMRDiscussionsResponseSchema,
|
|
7
8
|
GitLabCreateMRDiscussionRequestSchema,
|
|
8
9
|
GitLabCreateMRDiscussionResponseSchema
|
|
9
10
|
)
|
|
10
11
|
from ai_review.clients.gitlab.mr.schema.notes import (
|
|
12
|
+
GitLabNoteSchema,
|
|
11
13
|
GitLabGetMRNotesQuerySchema,
|
|
12
14
|
GitLabGetMRNotesResponseSchema,
|
|
13
15
|
GitLabCreateMRNoteRequestSchema,
|
|
14
16
|
GitLabCreateMRNoteResponseSchema,
|
|
15
17
|
)
|
|
16
18
|
from ai_review.clients.gitlab.mr.types import GitLabMergeRequestsHTTPClientProtocol
|
|
19
|
+
from ai_review.clients.gitlab.tools import gitlab_has_next_page
|
|
20
|
+
from ai_review.config import settings
|
|
17
21
|
from ai_review.libs.http.client import HTTPClient
|
|
18
22
|
from ai_review.libs.http.handlers import handle_http_error, HTTPClientError
|
|
23
|
+
from ai_review.libs.http.paginate import paginate
|
|
19
24
|
|
|
20
25
|
|
|
21
26
|
class GitLabMergeRequestsHTTPClientError(HTTPClientError):
|
|
@@ -86,18 +91,42 @@ class GitLabMergeRequestsHTTPClient(HTTPClient, GitLabMergeRequestsHTTPClientPro
|
|
|
86
91
|
project_id: str,
|
|
87
92
|
merge_request_id: str
|
|
88
93
|
) -> GitLabGetMRNotesResponseSchema:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
async def fetch_page(page: int) -> Response:
|
|
95
|
+
query = GitLabGetMRNotesQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
|
|
96
|
+
return await self.get_notes_api(project_id, merge_request_id, query)
|
|
97
|
+
|
|
98
|
+
def extract_items(response: Response) -> list[GitLabNoteSchema]:
|
|
99
|
+
result = GitLabGetMRNotesResponseSchema.model_validate_json(response.text)
|
|
100
|
+
return result.root
|
|
101
|
+
|
|
102
|
+
items = await paginate(
|
|
103
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
104
|
+
fetch_page=fetch_page,
|
|
105
|
+
extract_items=extract_items,
|
|
106
|
+
has_next_page=gitlab_has_next_page
|
|
107
|
+
)
|
|
108
|
+
return GitLabGetMRNotesResponseSchema(root=items)
|
|
92
109
|
|
|
93
110
|
async def get_discussions(
|
|
94
111
|
self,
|
|
95
112
|
project_id: str,
|
|
96
113
|
merge_request_id: str
|
|
97
114
|
) -> GitLabGetMRDiscussionsResponseSchema:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
115
|
+
async def fetch_page(page: int) -> Response:
|
|
116
|
+
query = GitLabGetMRDiscussionsQuerySchema(page=page, per_page=settings.vcs.pagination.per_page)
|
|
117
|
+
return await self.get_discussions_api(project_id, merge_request_id, query)
|
|
118
|
+
|
|
119
|
+
def extract_items(response: Response) -> list[GitLabDiscussionSchema]:
|
|
120
|
+
result = GitLabGetMRDiscussionsResponseSchema.model_validate_json(response.text)
|
|
121
|
+
return result.root
|
|
122
|
+
|
|
123
|
+
items = await paginate(
|
|
124
|
+
max_pages=settings.vcs.pagination.max_pages,
|
|
125
|
+
fetch_page=fetch_page,
|
|
126
|
+
extract_items=extract_items,
|
|
127
|
+
has_next_page=gitlab_has_next_page
|
|
128
|
+
)
|
|
129
|
+
return GitLabGetMRDiscussionsResponseSchema(root=items)
|
|
101
130
|
|
|
102
131
|
async def create_note(
|
|
103
132
|
self,
|
|
@@ -18,7 +18,8 @@ class GitLabDiscussionPositionSchema(BaseModel):
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class GitLabGetMRDiscussionsQuerySchema(BaseModel):
|
|
21
|
-
|
|
21
|
+
page: int = 1
|
|
22
|
+
per_page: int = 100
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class GitLabGetMRDiscussionsResponseSchema(RootModel[list[GitLabDiscussionSchema]]):
|