xai-review 0.28.0__tar.gz → 0.29.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.28.0/xai_review.egg-info → xai_review-0.29.0}/PKG-INFO +2 -2
- {xai_review-0.28.0 → xai_review-0.29.0}/README.md +1 -1
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/schema/discussions.py +3 -11
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/schema/notes.py +2 -0
- xai_review-0.29.0/ai_review/clients/gitlab/mr/schema/position.py +13 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/asynchronous/gather.py +8 -1
- xai_review-0.29.0/ai_review/services/git/service.py +66 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/bitbucket/adapter.py +5 -2
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/bitbucket/client.py +23 -12
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/gitlab/adapter.py +4 -2
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/gitlab/client.py +24 -17
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/gitlab.py +31 -5
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/gitlab/test_adapter.py +35 -6
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/gitlab/test_client.py +24 -12
- {xai_review-0.28.0 → xai_review-0.29.0}/pyproject.toml +1 -1
- {xai_review-0.28.0 → xai_review-0.29.0/xai_review.egg-info}/PKG-INFO +2 -2
- {xai_review-0.28.0 → xai_review-0.29.0}/xai_review.egg-info/SOURCES.txt +1 -0
- xai_review-0.28.0/ai_review/services/git/service.py +0 -35
- {xai_review-0.28.0 → xai_review-0.29.0}/LICENSE +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/run_context_review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/run_inline_reply_review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/run_inline_review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/run_review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/run_summary_reply_review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/commands/run_summary_review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/cli/main.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/schema/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/schema/comments.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/schema/files.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/schema/pull_request.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/schema/user.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/claude/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/claude/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/claude/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/claude/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gemini/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gemini/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gemini/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gemini/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/schema/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/schema/comments.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/schema/files.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/schema/pull_request.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/schema/reviews.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/schema/user.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/pr/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/github/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/schema/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/schema/changes.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/schema/user.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/mr/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/gitlab/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/ollama/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/ollama/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/ollama/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/ollama/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/openai/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/openai/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/openai/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/openai/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/config.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/asynchronous/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/artifacts.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/base.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/core.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/http.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/base.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/claude.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/gemini.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/meta.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/ollama.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/llm/openai.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/logger.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/prompt.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/review.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/vcs/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/vcs/base.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/vcs/bitbucket.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/vcs/github.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/vcs/gitlab.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/config/vcs/pagination.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/constants/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/constants/llm_provider.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/constants/vcs_provider.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/diff/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/diff/models.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/diff/parser.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/diff/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/event_hooks/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/event_hooks/base.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/handlers.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/paginate.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/transports/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/http/transports/retry.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/json.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/llm/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/llm/output_json_parser.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/logger.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/resources.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/template/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/libs/template/render.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_context.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_inline.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_inline_reply.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_summary.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_summary_reply.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_system_context.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_system_inline.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_system_inline_reply.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_system_summary.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/prompts/default_system_summary_reply.md +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/resources/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/resources/pricing.yaml +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/artifacts/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/artifacts/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/artifacts/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/artifacts/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/artifacts/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/cost/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/cost/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/cost/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/cost/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/diff/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/diff/renderers.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/diff/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/diff/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/diff/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/diff/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/git/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/git/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/hook/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/hook/constants.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/hook/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/hook/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/claude/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/claude/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/factory.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/gemini/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/gemini/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/ollama/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/ollama/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/openai/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/openai/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/llm/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/prompt/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/prompt/adapter.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/prompt/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/prompt/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/prompt/tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/prompt/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/gateway/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/gateway/comment.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/gateway/llm.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/gateway/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline_reply/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline_reply/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline_reply/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/inline_reply/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/policy/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/policy/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/policy/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary_reply/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary_reply/schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary_reply/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/internal/summary_reply/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/context.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/inline.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/inline_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/summary.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/summary_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/runner/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/review/service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/bitbucket/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/factory.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/github/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/github/adapter.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/github/client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/gitlab/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/services/vcs/types.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/bitbucket.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/claude.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/gemini.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/github.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/ollama.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/clients/openai.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/libs/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/libs/llm/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/libs/llm/output_json_parser.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/artifacts.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/cost.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/diff.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/git.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/hook.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/llm.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/prompt.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/base.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/gateway/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/gateway/comment.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/gateway/llm.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/internal/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/internal/inline.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/internal/inline_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/internal/policy.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/internal/summary.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/internal/summary_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/runner/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/runner/context.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/runner/inline.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/runner/inline_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/runner/summary.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/review/runner/summary_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/fixtures/services/vcs.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/cli/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/cli/test_main.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/bitbucket/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/bitbucket/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/bitbucket/test_tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/claude/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/gemini/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/github/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/github/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/github/test_tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/gitlab/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/gitlab/test_tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/ollama/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/ollama/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/ollama/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/openai/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/openai/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/clients/openai/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/asynchronous/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/asynchronous/test_gather.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/config/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/config/test_prompt.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/diff/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/http/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/http/test_paginate.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/llm/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/llm/test_output_json_parser.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/template/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/libs/test_json.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/cost/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/cost/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/cost/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/diff/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/hook/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/hook/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/claude/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/claude/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/gemini/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/gemini/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/ollama/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/ollama/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/openai/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/openai/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/llm/test_factory.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/prompt/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/prompt/test_adapter.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/prompt/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/prompt/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/prompt/test_tools.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/gateway/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/gateway/test_comment.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/gateway/test_llm.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/inline/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/inline/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/inline/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/inline_reply/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/inline_reply/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/inline_reply/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/policy/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/policy/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/summary/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/summary/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/summary/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/summary_reply/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/summary_reply/test_schema.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/internal/summary_reply/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/runner/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/runner/test_context.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/runner/test_inline.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/runner/test_inline_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/runner/test_summary.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/runner/test_summary_reply.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/review/test_service.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/bitbucket/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/bitbucket/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/github/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/github/test_adapter.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/github/test_client.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/gitlab/__init__.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/test_factory.py +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/setup.cfg +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/xai_review.egg-info/dependency_links.txt +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/xai_review.egg-info/entry_points.txt +0 -0
- {xai_review-0.28.0 → xai_review-0.29.0}/xai_review.egg-info/requires.txt +0 -0
- {xai_review-0.28.0 → xai_review-0.29.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.29.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>
|
|
@@ -211,7 +211,7 @@ jobs:
|
|
|
211
211
|
runs-on: ubuntu-latest
|
|
212
212
|
steps:
|
|
213
213
|
- uses: actions/checkout@v4
|
|
214
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
214
|
+
- uses: Nikita-Filonov/ai-review@v0.29.0
|
|
215
215
|
with:
|
|
216
216
|
review-command: ${{ inputs.review-command }}
|
|
217
217
|
env:
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
from pydantic import BaseModel, RootModel, Field
|
|
2
2
|
|
|
3
3
|
from ai_review.clients.gitlab.mr.schema.notes import GitLabNoteSchema
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class GitLabDiscussionPositionSchema(BaseModel):
|
|
7
|
-
position_type: str = "text"
|
|
8
|
-
base_sha: str
|
|
9
|
-
head_sha: str
|
|
10
|
-
start_sha: str
|
|
11
|
-
new_path: str
|
|
12
|
-
new_line: int
|
|
4
|
+
from ai_review.clients.gitlab.mr.schema.position import GitLabPositionSchema
|
|
13
5
|
|
|
14
6
|
|
|
15
7
|
class GitLabDiscussionSchema(BaseModel):
|
|
16
8
|
id: str
|
|
17
9
|
notes: list[GitLabNoteSchema]
|
|
18
|
-
position:
|
|
10
|
+
position: GitLabPositionSchema | None = None
|
|
19
11
|
|
|
20
12
|
|
|
21
13
|
class GitLabGetMRDiscussionsQuerySchema(BaseModel):
|
|
@@ -29,7 +21,7 @@ class GitLabGetMRDiscussionsResponseSchema(RootModel[list[GitLabDiscussionSchema
|
|
|
29
21
|
|
|
30
22
|
class GitLabCreateMRDiscussionRequestSchema(BaseModel):
|
|
31
23
|
body: str
|
|
32
|
-
position:
|
|
24
|
+
position: GitLabPositionSchema
|
|
33
25
|
|
|
34
26
|
|
|
35
27
|
class GitLabCreateMRDiscussionResponseSchema(BaseModel):
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from pydantic import BaseModel, RootModel
|
|
2
2
|
|
|
3
|
+
from ai_review.clients.gitlab.mr.schema.position import GitLabPositionSchema
|
|
3
4
|
from ai_review.clients.gitlab.mr.schema.user import GitLabUserSchema
|
|
4
5
|
|
|
5
6
|
|
|
@@ -7,6 +8,7 @@ class GitLabNoteSchema(BaseModel):
|
|
|
7
8
|
id: int
|
|
8
9
|
body: str
|
|
9
10
|
author: GitLabUserSchema | None = None
|
|
11
|
+
position: GitLabPositionSchema | None = None
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class GitLabGetMRNotesQuerySchema(BaseModel):
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class GitLabPositionSchema(BaseModel):
|
|
5
|
+
position_type: str | None = "text"
|
|
6
|
+
base_sha: str | None = None
|
|
7
|
+
head_sha: str | None = None
|
|
8
|
+
start_sha: str | None = None
|
|
9
|
+
old_path: str | None = None
|
|
10
|
+
new_path: str | None = None
|
|
11
|
+
old_line: int | None = None
|
|
12
|
+
new_line: int | None = None
|
|
13
|
+
line_range: dict | None = None
|
|
@@ -2,6 +2,9 @@ import asyncio
|
|
|
2
2
|
from typing import Awaitable, Iterable, TypeVar
|
|
3
3
|
|
|
4
4
|
from ai_review.config import settings
|
|
5
|
+
from ai_review.libs.logger import get_logger
|
|
6
|
+
|
|
7
|
+
logger = get_logger("GATHER")
|
|
5
8
|
|
|
6
9
|
T = TypeVar("T")
|
|
7
10
|
|
|
@@ -11,7 +14,11 @@ async def bounded_gather(coroutines: Iterable[Awaitable[T]]) -> tuple[T, ...]:
|
|
|
11
14
|
|
|
12
15
|
async def wrap(coro: Awaitable[T]) -> T:
|
|
13
16
|
async with sem:
|
|
14
|
-
|
|
17
|
+
try:
|
|
18
|
+
return await coro
|
|
19
|
+
except Exception as error:
|
|
20
|
+
logger.warning(f"Task failed: {type(error).__name__}: {error}")
|
|
21
|
+
return error
|
|
15
22
|
|
|
16
23
|
results = await asyncio.gather(*(wrap(coroutine) for coroutine in coroutines), return_exceptions=True)
|
|
17
24
|
return tuple(results)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from ai_review.libs.logger import get_logger
|
|
5
|
+
from ai_review.services.git.types import GitServiceProtocol
|
|
6
|
+
|
|
7
|
+
logger = get_logger("GIT_SERVICE")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GitService(GitServiceProtocol):
|
|
11
|
+
def __init__(self, repo_dir: str = "."):
|
|
12
|
+
self.repo_dir = Path(repo_dir)
|
|
13
|
+
|
|
14
|
+
def run_git(self, *args: str) -> str:
|
|
15
|
+
cmd = ["git", *args]
|
|
16
|
+
logger.debug(f"Running git command: {' '.join(cmd)} (cwd={self.repo_dir})")
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
result = subprocess.run(
|
|
20
|
+
cmd,
|
|
21
|
+
cwd=self.repo_dir,
|
|
22
|
+
capture_output=True,
|
|
23
|
+
text=True,
|
|
24
|
+
check=True,
|
|
25
|
+
)
|
|
26
|
+
if result.stderr.strip():
|
|
27
|
+
logger.debug(f"Git stderr: {result.stderr.strip()}")
|
|
28
|
+
return result.stdout
|
|
29
|
+
except subprocess.CalledProcessError as error:
|
|
30
|
+
logger.warning(
|
|
31
|
+
f"Git command failed (exit={error.returncode}): {' '.join(cmd)}\n"
|
|
32
|
+
f"stderr: {error.stderr.strip()}"
|
|
33
|
+
)
|
|
34
|
+
raise
|
|
35
|
+
|
|
36
|
+
def get_diff(self, base_sha: str, head_sha: str, unified: int = 3) -> str:
|
|
37
|
+
return self.run_git("diff", f"--unified={unified}", base_sha, head_sha)
|
|
38
|
+
|
|
39
|
+
def get_diff_for_file(self, base_sha: str, head_sha: str, file: str, unified: int = 3) -> str:
|
|
40
|
+
if not file:
|
|
41
|
+
logger.warning(f"Skipping git diff for empty filename (base={base_sha}, head={head_sha})")
|
|
42
|
+
return ""
|
|
43
|
+
|
|
44
|
+
logger.debug(f"Generating diff for {file} between {base_sha}..{head_sha}")
|
|
45
|
+
output = self.run_git("diff", f"--unified={unified}", base_sha, head_sha, "--", file)
|
|
46
|
+
if not output.strip():
|
|
47
|
+
logger.info(f"No diff found for {file} (possibly deleted or not tracked)")
|
|
48
|
+
|
|
49
|
+
return output
|
|
50
|
+
|
|
51
|
+
def get_changed_files(self, base_sha: str, head_sha: str) -> list[str]:
|
|
52
|
+
output = self.run_git("diff", "--name-only", base_sha, head_sha)
|
|
53
|
+
files = [line.strip() for line in output.splitlines() if line.strip()]
|
|
54
|
+
logger.debug(f"Changed files between {base_sha}..{head_sha}: {files}")
|
|
55
|
+
return files
|
|
56
|
+
|
|
57
|
+
def get_file_at_commit(self, file_path: str, sha: str) -> str | None:
|
|
58
|
+
if not file_path:
|
|
59
|
+
logger.warning(f"Skipping git show for empty file_path at {sha}")
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
return self.run_git("show", f"{sha}:{file_path}")
|
|
64
|
+
except subprocess.CalledProcessError as e:
|
|
65
|
+
logger.warning(f"File '{file_path}' not found in commit {sha}: {e.stderr.strip()}")
|
|
66
|
+
return None
|
|
@@ -13,11 +13,14 @@ def get_review_comment_from_bitbucket_pr_comment(comment: BitbucketPRCommentSche
|
|
|
13
13
|
username=user.nickname if user else "",
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
+
file = comment.inline.path if comment.inline and comment.inline.path else None
|
|
17
|
+
line = comment.inline.to_line if comment.inline else None
|
|
18
|
+
|
|
16
19
|
return ReviewCommentSchema(
|
|
17
20
|
id=comment.id,
|
|
18
21
|
body=comment.content.raw or "",
|
|
19
|
-
file=
|
|
20
|
-
line=
|
|
22
|
+
file=file,
|
|
23
|
+
line=line,
|
|
21
24
|
author=author,
|
|
22
25
|
parent_id=parent_id,
|
|
23
26
|
thread_id=thread_id,
|
|
@@ -207,22 +207,33 @@ class BitbucketVCSClient(VCSClientProtocol):
|
|
|
207
207
|
try:
|
|
208
208
|
comments = await self.get_inline_comments()
|
|
209
209
|
|
|
210
|
-
|
|
210
|
+
threads_by_id: dict[str | int, list[ReviewCommentSchema]] = defaultdict(list)
|
|
211
211
|
for comment in comments:
|
|
212
|
-
|
|
212
|
+
if not comment.file:
|
|
213
|
+
continue
|
|
213
214
|
|
|
214
|
-
|
|
215
|
+
threads_by_id[comment.thread_id].append(comment)
|
|
215
216
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
217
|
+
logger.info(f"Built {len(threads_by_id)} inline threads for {self.pull_request_ref}")
|
|
218
|
+
|
|
219
|
+
threads: list[ReviewThreadSchema] = []
|
|
220
|
+
for thread_id, thread in threads_by_id.items():
|
|
221
|
+
file = thread[0].file
|
|
222
|
+
line = thread[0].line
|
|
223
|
+
if not file:
|
|
224
|
+
continue
|
|
225
|
+
|
|
226
|
+
threads.append(
|
|
227
|
+
ReviewThreadSchema(
|
|
228
|
+
id=thread_id,
|
|
229
|
+
kind=ThreadKind.INLINE,
|
|
230
|
+
file=file,
|
|
231
|
+
line=line,
|
|
232
|
+
comments=sorted(thread, key=lambda t: int(t.id)),
|
|
233
|
+
)
|
|
223
234
|
)
|
|
224
|
-
|
|
225
|
-
|
|
235
|
+
|
|
236
|
+
return threads
|
|
226
237
|
except Exception as error:
|
|
227
238
|
logger.exception(f"Failed to fetch inline threads for {self.pull_request_ref}: {error}")
|
|
228
239
|
return []
|
|
@@ -16,11 +16,13 @@ def get_review_comment_from_gitlab_note(
|
|
|
16
16
|
note: GitLabNoteSchema,
|
|
17
17
|
discussion: GitLabDiscussionSchema
|
|
18
18
|
) -> ReviewCommentSchema:
|
|
19
|
+
position = note.position or discussion.position
|
|
20
|
+
|
|
19
21
|
return ReviewCommentSchema(
|
|
20
22
|
id=note.id,
|
|
21
23
|
body=note.body or "",
|
|
22
|
-
file=
|
|
23
|
-
line=
|
|
24
|
+
file=position.new_path if position else None,
|
|
25
|
+
line=position.new_line if position else None,
|
|
24
26
|
author=get_user_from_gitlab_user(note.author),
|
|
25
27
|
thread_id=discussion.id,
|
|
26
28
|
)
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from ai_review.clients.gitlab.client import get_gitlab_http_client
|
|
2
|
-
from ai_review.clients.gitlab.mr.schema.discussions import
|
|
3
|
-
|
|
4
|
-
GitLabCreateMRDiscussionRequestSchema,
|
|
5
|
-
)
|
|
2
|
+
from ai_review.clients.gitlab.mr.schema.discussions import GitLabCreateMRDiscussionRequestSchema
|
|
3
|
+
from ai_review.clients.gitlab.mr.schema.position import GitLabPositionSchema
|
|
6
4
|
from ai_review.config import settings
|
|
7
5
|
from ai_review.libs.logger import get_logger
|
|
8
6
|
from ai_review.services.vcs.gitlab.adapter import get_user_from_gitlab_user, get_review_comment_from_gitlab_note
|
|
@@ -135,7 +133,7 @@ class GitLabVCSClient(VCSClientProtocol):
|
|
|
135
133
|
|
|
136
134
|
request = GitLabCreateMRDiscussionRequestSchema(
|
|
137
135
|
body=message,
|
|
138
|
-
position=
|
|
136
|
+
position=GitLabPositionSchema(
|
|
139
137
|
position_type="text",
|
|
140
138
|
base_sha=response.diff_refs.base_sha,
|
|
141
139
|
head_sha=response.diff_refs.head_sha,
|
|
@@ -191,19 +189,28 @@ class GitLabVCSClient(VCSClientProtocol):
|
|
|
191
189
|
)
|
|
192
190
|
logger.info(f"Fetched inline threads for MR {self.merge_request_ref}")
|
|
193
191
|
|
|
194
|
-
threads = [
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
get_review_comment_from_gitlab_note(note, discussion)
|
|
202
|
-
for note in discussion.notes
|
|
203
|
-
]
|
|
192
|
+
threads: list[ReviewThreadSchema] = []
|
|
193
|
+
for discussion in response.root:
|
|
194
|
+
if not discussion.notes:
|
|
195
|
+
continue
|
|
196
|
+
|
|
197
|
+
position = discussion.position or (
|
|
198
|
+
discussion.notes[0].position if discussion.notes else None
|
|
204
199
|
)
|
|
205
|
-
|
|
206
|
-
|
|
200
|
+
|
|
201
|
+
threads.append(
|
|
202
|
+
ReviewThreadSchema(
|
|
203
|
+
id=discussion.id,
|
|
204
|
+
kind=ThreadKind.INLINE,
|
|
205
|
+
file=position.new_path if position else None,
|
|
206
|
+
line=position.new_line if position else None,
|
|
207
|
+
comments=[
|
|
208
|
+
get_review_comment_from_gitlab_note(note, discussion)
|
|
209
|
+
for note in discussion.notes
|
|
210
|
+
],
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
|
|
207
214
|
logger.info(f"Built {len(threads)} inline threads for MR {self.merge_request_ref}")
|
|
208
215
|
return threads
|
|
209
216
|
except Exception as error:
|
|
@@ -12,13 +12,14 @@ from ai_review.clients.gitlab.mr.schema.discussions import (
|
|
|
12
12
|
GitLabGetMRDiscussionsResponseSchema,
|
|
13
13
|
GitLabCreateMRDiscussionRequestSchema,
|
|
14
14
|
GitLabCreateMRDiscussionResponseSchema,
|
|
15
|
-
GitLabCreateMRDiscussionReplyResponseSchema,
|
|
15
|
+
GitLabCreateMRDiscussionReplyResponseSchema,
|
|
16
16
|
)
|
|
17
17
|
from ai_review.clients.gitlab.mr.schema.notes import (
|
|
18
18
|
GitLabNoteSchema,
|
|
19
19
|
GitLabGetMRNotesResponseSchema,
|
|
20
20
|
GitLabCreateMRNoteResponseSchema,
|
|
21
21
|
)
|
|
22
|
+
from ai_review.clients.gitlab.mr.schema.position import GitLabPositionSchema
|
|
22
23
|
from ai_review.clients.gitlab.mr.types import GitLabMergeRequestsHTTPClientProtocol
|
|
23
24
|
from ai_review.config import settings
|
|
24
25
|
from ai_review.libs.config.vcs.base import GitLabVCSConfig
|
|
@@ -81,17 +82,42 @@ class FakeGitLabMergeRequestsHTTPClient(GitLabMergeRequestsHTTPClientProtocol):
|
|
|
81
82
|
GitLabDiscussionSchema(
|
|
82
83
|
id="discussion-1",
|
|
83
84
|
notes=[
|
|
84
|
-
GitLabNoteSchema(
|
|
85
|
-
|
|
85
|
+
GitLabNoteSchema(
|
|
86
|
+
id=10,
|
|
87
|
+
body="Inline comment A",
|
|
88
|
+
position=GitLabPositionSchema(
|
|
89
|
+
base_sha="abc123",
|
|
90
|
+
head_sha="def456",
|
|
91
|
+
start_sha="ghi789",
|
|
92
|
+
new_path="src/app.py",
|
|
93
|
+
new_line=12,
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
GitLabNoteSchema(
|
|
97
|
+
id=11,
|
|
98
|
+
body="Inline comment B",
|
|
99
|
+
position=GitLabPositionSchema(
|
|
100
|
+
base_sha="abc123",
|
|
101
|
+
head_sha="def456",
|
|
102
|
+
start_sha="ghi789",
|
|
103
|
+
new_path="src/app.py",
|
|
104
|
+
new_line=14,
|
|
105
|
+
),
|
|
106
|
+
),
|
|
86
107
|
],
|
|
87
|
-
position=
|
|
108
|
+
position=GitLabPositionSchema(
|
|
88
109
|
base_sha="abc123",
|
|
89
110
|
head_sha="def456",
|
|
90
111
|
start_sha="ghi789",
|
|
91
112
|
new_path="src/app.py",
|
|
92
113
|
new_line=12,
|
|
93
114
|
),
|
|
94
|
-
)
|
|
115
|
+
),
|
|
116
|
+
GitLabDiscussionSchema(
|
|
117
|
+
id="discussion-2",
|
|
118
|
+
notes=[GitLabNoteSchema(id=20, body="Outdated diff comment", position=None)],
|
|
119
|
+
position=None,
|
|
120
|
+
),
|
|
95
121
|
]
|
|
96
122
|
)
|
|
97
123
|
|
{xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/gitlab/test_adapter.py
RENAMED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
from ai_review.clients.gitlab.mr.schema.discussions import
|
|
2
|
-
GitLabDiscussionSchema,
|
|
3
|
-
GitLabDiscussionPositionSchema,
|
|
4
|
-
)
|
|
1
|
+
from ai_review.clients.gitlab.mr.schema.discussions import GitLabDiscussionSchema
|
|
5
2
|
from ai_review.clients.gitlab.mr.schema.notes import GitLabNoteSchema
|
|
3
|
+
from ai_review.clients.gitlab.mr.schema.position import GitLabPositionSchema
|
|
6
4
|
from ai_review.clients.gitlab.mr.schema.user import GitLabUserSchema
|
|
7
5
|
from ai_review.services.vcs.gitlab.adapter import get_review_comment_from_gitlab_note
|
|
8
6
|
from ai_review.services.vcs.types import ReviewCommentSchema, UserSchema
|
|
@@ -18,7 +16,7 @@ def test_maps_all_fields_correctly():
|
|
|
18
16
|
discussion = GitLabDiscussionSchema(
|
|
19
17
|
id="42",
|
|
20
18
|
notes=[note],
|
|
21
|
-
position=
|
|
19
|
+
position=GitLabPositionSchema(
|
|
22
20
|
base_sha="AAA000",
|
|
23
21
|
head_sha="BBB111",
|
|
24
22
|
start_sha="CCC222",
|
|
@@ -48,7 +46,7 @@ def test_maps_with_missing_author():
|
|
|
48
46
|
discussion = GitLabDiscussionSchema(
|
|
49
47
|
id="7",
|
|
50
48
|
notes=[note],
|
|
51
|
-
position=
|
|
49
|
+
position=GitLabPositionSchema(
|
|
52
50
|
base_sha="AAA000",
|
|
53
51
|
head_sha="BBB111",
|
|
54
52
|
start_sha="CCC222",
|
|
@@ -103,3 +101,34 @@ def test_maps_with_empty_body_and_defaults():
|
|
|
103
101
|
assert result.line is None
|
|
104
102
|
assert result.thread_id == "100"
|
|
105
103
|
assert isinstance(result.author, UserSchema)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_maps_with_note_position_fallback():
|
|
107
|
+
"""Should use note.position when discussion.position is missing."""
|
|
108
|
+
note = GitLabNoteSchema(
|
|
109
|
+
id=77,
|
|
110
|
+
body="Inline note with its own position",
|
|
111
|
+
author=GitLabUserSchema(id=2, name="Carol", username="carol"),
|
|
112
|
+
position=GitLabPositionSchema(
|
|
113
|
+
base_sha="aaa",
|
|
114
|
+
head_sha="bbb",
|
|
115
|
+
start_sha="ccc",
|
|
116
|
+
new_path="module/utils.py",
|
|
117
|
+
new_line=42,
|
|
118
|
+
),
|
|
119
|
+
)
|
|
120
|
+
discussion = GitLabDiscussionSchema(
|
|
121
|
+
id="200",
|
|
122
|
+
notes=[note],
|
|
123
|
+
position=None,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
result = get_review_comment_from_gitlab_note(note, discussion)
|
|
127
|
+
|
|
128
|
+
assert isinstance(result, ReviewCommentSchema)
|
|
129
|
+
assert result.id == 77
|
|
130
|
+
assert result.file == "module/utils.py"
|
|
131
|
+
assert result.line == 42
|
|
132
|
+
assert result.thread_id == "200"
|
|
133
|
+
assert result.body == "Inline note with its own position"
|
|
134
|
+
assert result.author.name == "Carol"
|
{xai_review-0.28.0 → xai_review-0.29.0}/ai_review/tests/suites/services/vcs/gitlab/test_client.py
RENAMED
|
@@ -71,14 +71,20 @@ async def test_get_inline_comments_returns_expected_list(
|
|
|
71
71
|
gitlab_vcs_client: GitLabVCSClient,
|
|
72
72
|
fake_gitlab_merge_requests_http_client: FakeGitLabMergeRequestsHTTPClient,
|
|
73
73
|
):
|
|
74
|
-
"""Should return inline comments from MR discussions."""
|
|
74
|
+
"""Should return inline comments from MR discussions (including ones without position)."""
|
|
75
75
|
comments = await gitlab_vcs_client.get_inline_comments()
|
|
76
76
|
|
|
77
77
|
assert all(isinstance(c, ReviewCommentSchema) for c in comments)
|
|
78
|
-
assert len(comments) ==
|
|
78
|
+
assert len(comments) == 3
|
|
79
79
|
|
|
80
80
|
first = comments[0]
|
|
81
81
|
assert first.body == "Inline comment A"
|
|
82
|
+
assert first.file == "src/app.py"
|
|
83
|
+
assert first.line == 12
|
|
84
|
+
|
|
85
|
+
last = comments[-1]
|
|
86
|
+
assert last.file is None
|
|
87
|
+
assert last.line is None
|
|
82
88
|
|
|
83
89
|
called_methods = [name for name, _ in fake_gitlab_merge_requests_http_client.calls]
|
|
84
90
|
assert called_methods == ["get_discussions"]
|
|
@@ -183,19 +189,25 @@ async def test_get_inline_threads_returns_valid_schema(
|
|
|
183
189
|
gitlab_vcs_client: GitLabVCSClient,
|
|
184
190
|
fake_gitlab_merge_requests_http_client: FakeGitLabMergeRequestsHTTPClient,
|
|
185
191
|
):
|
|
186
|
-
"""Should transform GitLab discussions into inline threads
|
|
192
|
+
"""Should transform GitLab discussions into inline threads, including those without position."""
|
|
187
193
|
threads = await gitlab_vcs_client.get_inline_threads()
|
|
188
194
|
|
|
189
|
-
assert all(isinstance(
|
|
190
|
-
assert len(threads) ==
|
|
195
|
+
assert all(isinstance(thread, ReviewThreadSchema) for thread in threads)
|
|
196
|
+
assert len(threads) == 2
|
|
191
197
|
|
|
192
|
-
|
|
193
|
-
assert
|
|
194
|
-
assert
|
|
195
|
-
assert
|
|
196
|
-
assert
|
|
197
|
-
assert len(
|
|
198
|
-
assert isinstance(
|
|
198
|
+
first_thread = threads[0]
|
|
199
|
+
assert first_thread.id == "discussion-1"
|
|
200
|
+
assert first_thread.kind == ThreadKind.INLINE
|
|
201
|
+
assert first_thread.file == "src/app.py"
|
|
202
|
+
assert first_thread.line == 12
|
|
203
|
+
assert len(first_thread.comments) == 2
|
|
204
|
+
assert isinstance(first_thread.comments[0], ReviewCommentSchema)
|
|
205
|
+
|
|
206
|
+
second_thread = threads[1]
|
|
207
|
+
assert second_thread.id == "discussion-2"
|
|
208
|
+
assert second_thread.file is None
|
|
209
|
+
assert second_thread.line is None
|
|
210
|
+
assert len(second_thread.comments) == 1
|
|
199
211
|
|
|
200
212
|
called = [name for name, _ in fake_gitlab_merge_requests_http_client.calls]
|
|
201
213
|
assert "get_discussions" in called
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "xai-review"
|
|
7
7
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
8
|
-
version = "0.
|
|
8
|
+
version = "0.29.0"
|
|
9
9
|
license = { text = "Apache-2.0" }
|
|
10
10
|
authors = [
|
|
11
11
|
{ name = "Nikita Filonov", email = "nikita.filonov@example.com" }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xai-review
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.29.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>
|
|
@@ -211,7 +211,7 @@ jobs:
|
|
|
211
211
|
runs-on: ubuntu-latest
|
|
212
212
|
steps:
|
|
213
213
|
- uses: actions/checkout@v4
|
|
214
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
214
|
+
- uses: Nikita-Filonov/ai-review@v0.29.0
|
|
215
215
|
with:
|
|
216
216
|
review-command: ${{ inputs.review-command }}
|
|
217
217
|
env:
|
|
@@ -54,6 +54,7 @@ ai_review/clients/gitlab/mr/schema/__init__.py
|
|
|
54
54
|
ai_review/clients/gitlab/mr/schema/changes.py
|
|
55
55
|
ai_review/clients/gitlab/mr/schema/discussions.py
|
|
56
56
|
ai_review/clients/gitlab/mr/schema/notes.py
|
|
57
|
+
ai_review/clients/gitlab/mr/schema/position.py
|
|
57
58
|
ai_review/clients/gitlab/mr/schema/user.py
|
|
58
59
|
ai_review/clients/ollama/__init__.py
|
|
59
60
|
ai_review/clients/ollama/client.py
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import subprocess
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
from ai_review.services.git.types import GitServiceProtocol
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class GitService(GitServiceProtocol):
|
|
8
|
-
def __init__(self, repo_dir: str = "."):
|
|
9
|
-
self.repo_dir = Path(repo_dir)
|
|
10
|
-
|
|
11
|
-
def run_git(self, *args: str) -> str:
|
|
12
|
-
result = subprocess.run(
|
|
13
|
-
["git", *args],
|
|
14
|
-
cwd=self.repo_dir,
|
|
15
|
-
capture_output=True,
|
|
16
|
-
text=True,
|
|
17
|
-
check=True,
|
|
18
|
-
)
|
|
19
|
-
return result.stdout
|
|
20
|
-
|
|
21
|
-
def get_diff(self, base_sha: str, head_sha: str, unified: int = 3) -> str:
|
|
22
|
-
return self.run_git("diff", f"--unified={unified}", base_sha, head_sha)
|
|
23
|
-
|
|
24
|
-
def get_diff_for_file(self, base_sha: str, head_sha: str, file: str, unified: int = 3) -> str:
|
|
25
|
-
return self.run_git("diff", f"--unified={unified}", base_sha, head_sha, "--", file)
|
|
26
|
-
|
|
27
|
-
def get_changed_files(self, base_sha: str, head_sha: str) -> list[str]:
|
|
28
|
-
output = self.run_git("diff", "--name-only", base_sha, head_sha)
|
|
29
|
-
return [line.strip() for line in output.splitlines() if line.strip()]
|
|
30
|
-
|
|
31
|
-
def get_file_at_commit(self, file_path: str, sha: str) -> str | None:
|
|
32
|
-
try:
|
|
33
|
-
return self.run_git("show", f"{sha}:{file_path}")
|
|
34
|
-
except subprocess.CalledProcessError:
|
|
35
|
-
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xai_review-0.28.0 → xai_review-0.29.0}/ai_review/clients/bitbucket/pr/schema/pull_request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|