xai-review 0.22.0__tar.gz → 0.24.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.22.0 → xai_review-0.24.0}/PKG-INFO +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/README.md +1 -1
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/config.py +2 -2
- xai_review-0.22.0/ai_review/libs/config/llm.py → xai_review-0.24.0/ai_review/libs/config/llm/base.py +3 -3
- xai_review-0.22.0/ai_review/libs/config/vcs.py → xai_review-0.24.0/ai_review/libs/config/vcs/base.py +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/http/transports/retry.py +1 -1
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/diff/renderers.py +3 -3
- xai_review-0.24.0/ai_review/services/prompt/schema.py +41 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/clients/claude.py +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/clients/gemini.py +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/clients/github.py +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/clients/gitlab.py +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/clients/openai.py +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/cost/test_service.py +1 -1
- xai_review-0.24.0/ai_review/tests/suites/services/prompt/test_schema.py +136 -0
- xai_review-0.24.0/ai_review/tests/suites/services/vcs/github/__init__.py +0 -0
- xai_review-0.24.0/ai_review/tests/suites/services/vcs/gitlab/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/pyproject.toml +1 -1
- {xai_review-0.22.0 → xai_review-0.24.0}/xai_review.egg-info/PKG-INFO +2 -2
- {xai_review-0.22.0 → xai_review-0.24.0}/xai_review.egg-info/SOURCES.txt +9 -7
- xai_review-0.22.0/ai_review/services/prompt/schema.py +0 -52
- xai_review-0.22.0/ai_review/tests/suites/services/prompt/test_schema.py +0 -71
- {xai_review-0.22.0 → xai_review-0.24.0}/LICENSE +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/commands/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/commands/run_context_review.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/commands/run_inline_review.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/commands/run_review.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/commands/run_summary_review.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/cli/main.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/claude/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/claude/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/claude/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gemini/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gemini/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gemini/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/schema/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/schema/comments.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/schema/files.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/schema/pull_request.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/schema/reviews.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/github/pr/types.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/schema/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/schema/changes.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/schema/discussions.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/schema/notes.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/gitlab/mr/types.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/openai/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/openai/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/clients/openai/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/asynchronous/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/asynchronous/gather.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/artifacts.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/base.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/core.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/http.py +0 -0
- {xai_review-0.22.0/ai_review/libs/constants → xai_review-0.24.0/ai_review/libs/config/llm}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/libs/config → xai_review-0.24.0/ai_review/libs/config/llm}/claude.py +0 -0
- {xai_review-0.22.0/ai_review/libs/config → xai_review-0.24.0/ai_review/libs/config/llm}/gemini.py +0 -0
- {xai_review-0.22.0/ai_review/libs/config → xai_review-0.24.0/ai_review/libs/config/llm}/openai.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/logger.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/prompt.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/config/review.py +0 -0
- {xai_review-0.22.0/ai_review/libs/diff → xai_review-0.24.0/ai_review/libs/config/vcs}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/libs/config → xai_review-0.24.0/ai_review/libs/config/vcs}/github.py +0 -0
- {xai_review-0.22.0/ai_review/libs/config → xai_review-0.24.0/ai_review/libs/config/vcs}/gitlab.py +0 -0
- {xai_review-0.22.0/ai_review/libs/http → xai_review-0.24.0/ai_review/libs/constants}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/constants/llm_provider.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/constants/vcs_provider.py +0 -0
- {xai_review-0.22.0/ai_review/libs/http/event_hooks → xai_review-0.24.0/ai_review/libs/diff}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/diff/models.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/diff/parser.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/diff/tools.py +0 -0
- {xai_review-0.22.0/ai_review/libs/http/transports → xai_review-0.24.0/ai_review/libs/http}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/http/client.py +0 -0
- {xai_review-0.22.0/ai_review/libs/template → xai_review-0.24.0/ai_review/libs/http/event_hooks}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/http/event_hooks/base.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/http/handlers.py +0 -0
- {xai_review-0.22.0/ai_review/prompts → xai_review-0.24.0/ai_review/libs/http/transports}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/json.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/logger.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/resources.py +0 -0
- {xai_review-0.22.0/ai_review/resources → xai_review-0.24.0/ai_review/libs/template}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/libs/template/render.py +0 -0
- {xai_review-0.22.0/ai_review/services → xai_review-0.24.0/ai_review/prompts}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/prompts/default_context.md +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/prompts/default_inline.md +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/prompts/default_summary.md +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/prompts/default_system_context.md +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/prompts/default_system_inline.md +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/prompts/default_system_summary.md +0 -0
- {xai_review-0.22.0/ai_review/services/artifacts → xai_review-0.24.0/ai_review/resources}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/resources/pricing.yaml +0 -0
- {xai_review-0.22.0/ai_review/services/cost → xai_review-0.24.0/ai_review/services}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/services/diff → xai_review-0.24.0/ai_review/services/artifacts}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/artifacts/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/artifacts/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/artifacts/tools.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/artifacts/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/git → xai_review-0.24.0/ai_review/services/cost}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/cost/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/cost/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/cost/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/llm → xai_review-0.24.0/ai_review/services/diff}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/diff/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/diff/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/diff/tools.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/diff/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/llm/claude → xai_review-0.24.0/ai_review/services/git}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/git/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/git/types.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/hook/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/hook/constants.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/hook/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/hook/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/llm/gemini → xai_review-0.24.0/ai_review/services/llm}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/services/llm/openai → xai_review-0.24.0/ai_review/services/llm/claude}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/llm/claude/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/llm/factory.py +0 -0
- {xai_review-0.22.0/ai_review/services/prompt → xai_review-0.24.0/ai_review/services/llm/gemini}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/llm/gemini/client.py +0 -0
- {xai_review-0.22.0/ai_review/services/review → xai_review-0.24.0/ai_review/services/llm/openai}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/llm/openai/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/llm/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/review/gateway → xai_review-0.24.0/ai_review/services/prompt}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/prompt/adapter.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/prompt/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/prompt/tools.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/prompt/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/review/inline → xai_review-0.24.0/ai_review/services/review}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/services/review/policy → xai_review-0.24.0/ai_review/services/review/gateway}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/gateway/comment.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/gateway/llm.py +0 -0
- {xai_review-0.22.0/ai_review/services/review/summary → xai_review-0.24.0/ai_review/services/review/inline}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/inline/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/inline/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/inline/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/vcs → xai_review-0.24.0/ai_review/services/review/policy}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/policy/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/service.py +0 -0
- {xai_review-0.22.0/ai_review/services/vcs/github → xai_review-0.24.0/ai_review/services/review/summary}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/summary/schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/summary/service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/review/summary/types.py +0 -0
- {xai_review-0.22.0/ai_review/services/vcs/gitlab → xai_review-0.24.0/ai_review/services/vcs}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/vcs/factory.py +0 -0
- {xai_review-0.22.0/ai_review/tests → xai_review-0.24.0/ai_review/services/vcs/github}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/vcs/github/client.py +0 -0
- {xai_review-0.22.0/ai_review/tests/fixtures → xai_review-0.24.0/ai_review/services/vcs/gitlab}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/vcs/gitlab/client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/services/vcs/types.py +0 -0
- {xai_review-0.22.0/ai_review/tests/fixtures/clients → xai_review-0.24.0/ai_review/tests}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/fixtures/services → xai_review-0.24.0/ai_review/tests/fixtures}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/fixtures/services/review → xai_review-0.24.0/ai_review/tests/fixtures/clients}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites → xai_review-0.24.0/ai_review/tests/fixtures/services}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/artifacts.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/cost.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/diff.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/git.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/llm.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/prompt.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/clients → xai_review-0.24.0/ai_review/tests/fixtures/services/review}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/review/inline.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/review/summary.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/fixtures/services/vcs.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/clients/claude → xai_review-0.24.0/ai_review/tests/suites}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/clients/gemini → xai_review-0.24.0/ai_review/tests/suites/clients}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/clients/github → xai_review-0.24.0/ai_review/tests/suites/clients/claude}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/clients/gitlab → xai_review-0.24.0/ai_review/tests/suites/clients/gemini}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/clients/openai → xai_review-0.24.0/ai_review/tests/suites/clients/github}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/github/test_client.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/libs → xai_review-0.24.0/ai_review/tests/suites/clients/gitlab}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/libs/asynchronous → xai_review-0.24.0/ai_review/tests/suites/clients/openai}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/openai/test_client.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/clients/openai/test_schema.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/libs/config → xai_review-0.24.0/ai_review/tests/suites/libs}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/libs/diff → xai_review-0.24.0/ai_review/tests/suites/libs/asynchronous}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/asynchronous/test_gather.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/libs/template → xai_review-0.24.0/ai_review/tests/suites/libs/config}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/config/test_prompt.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services → xai_review-0.24.0/ai_review/tests/suites/libs/diff}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/cost → xai_review-0.24.0/ai_review/tests/suites/libs/template}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/libs/test_json.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/diff → xai_review-0.24.0/ai_review/tests/suites/services}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/hook → xai_review-0.24.0/ai_review/tests/suites/services/cost}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/cost/test_schema.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/llm → xai_review-0.24.0/ai_review/tests/suites/services/diff}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/prompt → xai_review-0.24.0/ai_review/tests/suites/services/hook}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/hook/test_service.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/review → xai_review-0.24.0/ai_review/tests/suites/services/llm}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/llm/test_factory.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/review/inline → xai_review-0.24.0/ai_review/tests/suites/services/prompt}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/prompt/test_adapter.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/prompt/test_service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/prompt/test_tools.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/review/policy → xai_review-0.24.0/ai_review/tests/suites/services/review}/__init__.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/review/summary → xai_review-0.24.0/ai_review/tests/suites/services/review/inline}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/review/inline/test_schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/review/inline/test_service.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/vcs → xai_review-0.24.0/ai_review/tests/suites/services/review/policy}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/review/policy/test_service.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/vcs/github → xai_review-0.24.0/ai_review/tests/suites/services/review/summary}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/review/summary/test_schema.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/review/summary/test_service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/review/test_service.py +0 -0
- {xai_review-0.22.0/ai_review/tests/suites/services/vcs/gitlab → xai_review-0.24.0/ai_review/tests/suites/services/vcs}/__init__.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/vcs/github/test_service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/vcs/gitlab/test_service.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/vcs/test_factory.py +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/setup.cfg +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/xai_review.egg-info/dependency_links.txt +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/xai_review.egg-info/entry_points.txt +0 -0
- {xai_review-0.22.0 → xai_review-0.24.0}/xai_review.egg-info/requires.txt +0 -0
- {xai_review-0.22.0 → xai_review-0.24.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.24.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>
|
|
@@ -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.24.0
|
|
213
213
|
with:
|
|
214
214
|
review-command: ${{ inputs.review-command }}
|
|
215
215
|
env:
|
|
@@ -13,11 +13,11 @@ from ai_review.libs.config.base import (
|
|
|
13
13
|
get_json_config_file_or_default
|
|
14
14
|
)
|
|
15
15
|
from ai_review.libs.config.core import CoreConfig
|
|
16
|
-
from ai_review.libs.config.llm import LLMConfig
|
|
16
|
+
from ai_review.libs.config.llm.base import LLMConfig
|
|
17
17
|
from ai_review.libs.config.logger import LoggerConfig
|
|
18
18
|
from ai_review.libs.config.prompt import PromptConfig
|
|
19
19
|
from ai_review.libs.config.review import ReviewConfig
|
|
20
|
-
from ai_review.libs.config.vcs import VCSConfig
|
|
20
|
+
from ai_review.libs.config.vcs.base import VCSConfig
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class Settings(BaseSettings):
|
xai_review-0.22.0/ai_review/libs/config/llm.py → xai_review-0.24.0/ai_review/libs/config/llm/base.py
RENAMED
|
@@ -4,9 +4,9 @@ from typing import Annotated, Literal
|
|
|
4
4
|
import yaml
|
|
5
5
|
from pydantic import BaseModel, Field, FilePath
|
|
6
6
|
|
|
7
|
-
from ai_review.libs.config.claude import ClaudeHTTPClientConfig, ClaudeMetaConfig
|
|
8
|
-
from ai_review.libs.config.gemini import GeminiHTTPClientConfig, GeminiMetaConfig
|
|
9
|
-
from ai_review.libs.config.openai import OpenAIHTTPClientConfig, OpenAIMetaConfig
|
|
7
|
+
from ai_review.libs.config.llm.claude import ClaudeHTTPClientConfig, ClaudeMetaConfig
|
|
8
|
+
from ai_review.libs.config.llm.gemini import GeminiHTTPClientConfig, GeminiMetaConfig
|
|
9
|
+
from ai_review.libs.config.llm.openai import OpenAIHTTPClientConfig, OpenAIMetaConfig
|
|
10
10
|
from ai_review.libs.constants.llm_provider import LLMProvider
|
|
11
11
|
from ai_review.libs.resources import load_resource
|
|
12
12
|
|
xai_review-0.22.0/ai_review/libs/config/vcs.py → xai_review-0.24.0/ai_review/libs/config/vcs/base.py
RENAMED
|
@@ -2,8 +2,8 @@ from typing import Annotated, Literal
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel, Field
|
|
4
4
|
|
|
5
|
-
from ai_review.libs.config.github import GitHubPipelineConfig, GitHubHTTPClientConfig
|
|
6
|
-
from ai_review.libs.config.gitlab import GitLabPipelineConfig, GitLabHTTPClientConfig
|
|
5
|
+
from ai_review.libs.config.vcs.github import GitHubPipelineConfig, GitHubHTTPClientConfig
|
|
6
|
+
from ai_review.libs.config.vcs.gitlab import GitLabPipelineConfig, GitLabHTTPClientConfig
|
|
7
7
|
from ai_review.libs.constants.vcs_provider import VCSProvider
|
|
8
8
|
|
|
9
9
|
|
|
@@ -36,7 +36,7 @@ class RetryTransport(AsyncBaseTransport):
|
|
|
36
36
|
return last_response
|
|
37
37
|
|
|
38
38
|
self.logger.warning(
|
|
39
|
-
f"Attempt {attempt}/{self.max_retries} failed "
|
|
39
|
+
f"Attempt {attempt + 1}/{self.max_retries} failed "
|
|
40
40
|
f"with status={last_response.status_code} for {request.method} {request.url}. "
|
|
41
41
|
f"Retrying in {self.retry_delay:.1f}s..."
|
|
42
42
|
)
|
|
@@ -116,14 +116,14 @@ def render_unified(
|
|
|
116
116
|
added_new_positions = file.added_line_numbers()
|
|
117
117
|
removed_old_positions = file.removed_line_numbers()
|
|
118
118
|
|
|
119
|
-
def in_context(
|
|
119
|
+
def in_context(inner_old_no: int | None, inner_new_no: int | None) -> bool:
|
|
120
120
|
"""Check if an unchanged line falls within context radius."""
|
|
121
121
|
if context <= 0:
|
|
122
122
|
return False
|
|
123
|
-
if include_added and
|
|
123
|
+
if include_added and inner_new_no is not None:
|
|
124
124
|
if any(abs(new_no - a) <= context for a in added_new_positions):
|
|
125
125
|
return True
|
|
126
|
-
if include_removed and
|
|
126
|
+
if include_removed and inner_old_no is not None:
|
|
127
127
|
if any(abs(old_no - r) <= context for r in removed_old_positions):
|
|
128
128
|
return True
|
|
129
129
|
return False
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field, field_serializer
|
|
2
|
+
|
|
3
|
+
from ai_review.config import settings
|
|
4
|
+
from ai_review.libs.template.render import render_template
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PromptContextSchema(BaseModel):
|
|
8
|
+
review_title: str = ""
|
|
9
|
+
review_description: str = ""
|
|
10
|
+
|
|
11
|
+
review_author_name: str = ""
|
|
12
|
+
review_author_username: str = ""
|
|
13
|
+
|
|
14
|
+
review_reviewer: str = ""
|
|
15
|
+
review_reviewers: list[str] = Field(default_factory=list)
|
|
16
|
+
review_reviewers_usernames: list[str] = Field(default_factory=list)
|
|
17
|
+
|
|
18
|
+
review_assignees: list[str] = Field(default_factory=list)
|
|
19
|
+
review_assignees_usernames: list[str] = Field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
source_branch: str = ""
|
|
22
|
+
target_branch: str = ""
|
|
23
|
+
|
|
24
|
+
labels: list[str] = Field(default_factory=list)
|
|
25
|
+
changed_files: list[str] = Field(default_factory=list)
|
|
26
|
+
|
|
27
|
+
@field_serializer(
|
|
28
|
+
"review_reviewers",
|
|
29
|
+
"review_reviewers_usernames",
|
|
30
|
+
"review_assignees",
|
|
31
|
+
"review_assignees_usernames",
|
|
32
|
+
"labels",
|
|
33
|
+
"changed_files",
|
|
34
|
+
when_used="always"
|
|
35
|
+
)
|
|
36
|
+
def list_of_strings_serializer(self, value: list[str]) -> str:
|
|
37
|
+
return ", ".join(value)
|
|
38
|
+
|
|
39
|
+
def apply_format(self, prompt: str) -> str:
|
|
40
|
+
values = {**self.model_dump(), **settings.prompt.context}
|
|
41
|
+
return render_template(prompt, values, settings.prompt.context_placeholder)
|
|
@@ -2,8 +2,8 @@ import pytest
|
|
|
2
2
|
from pydantic import HttpUrl, SecretStr
|
|
3
3
|
|
|
4
4
|
from ai_review.config import settings
|
|
5
|
-
from ai_review.libs.config.
|
|
6
|
-
from ai_review.libs.config.llm import
|
|
5
|
+
from ai_review.libs.config.llm.base import ClaudeLLMConfig
|
|
6
|
+
from ai_review.libs.config.llm.claude import ClaudeMetaConfig, ClaudeHTTPClientConfig
|
|
7
7
|
from ai_review.libs.constants.llm_provider import LLMProvider
|
|
8
8
|
|
|
9
9
|
|
|
@@ -2,8 +2,8 @@ import pytest
|
|
|
2
2
|
from pydantic import HttpUrl, SecretStr
|
|
3
3
|
|
|
4
4
|
from ai_review.config import settings
|
|
5
|
-
from ai_review.libs.config.
|
|
6
|
-
from ai_review.libs.config.llm import
|
|
5
|
+
from ai_review.libs.config.llm.base import GeminiLLMConfig
|
|
6
|
+
from ai_review.libs.config.llm.gemini import GeminiMetaConfig, GeminiHTTPClientConfig
|
|
7
7
|
from ai_review.libs.constants.llm_provider import LLMProvider
|
|
8
8
|
|
|
9
9
|
|
|
@@ -18,8 +18,8 @@ from ai_review.clients.github.pr.schema.pull_request import (
|
|
|
18
18
|
from ai_review.clients.github.pr.schema.reviews import GitHubGetPRReviewsResponseSchema, GitHubPRReviewSchema
|
|
19
19
|
from ai_review.clients.github.pr.types import GitHubPullRequestsHTTPClientProtocol
|
|
20
20
|
from ai_review.config import settings
|
|
21
|
-
from ai_review.libs.config.
|
|
22
|
-
from ai_review.libs.config.vcs import
|
|
21
|
+
from ai_review.libs.config.vcs.base import GitHubVCSConfig
|
|
22
|
+
from ai_review.libs.config.vcs.github import GitHubPipelineConfig, GitHubHTTPClientConfig
|
|
23
23
|
from ai_review.libs.constants.vcs_provider import VCSProvider
|
|
24
24
|
from ai_review.services.vcs.github.client import GitHubVCSClient
|
|
25
25
|
|
|
@@ -20,8 +20,8 @@ from ai_review.clients.gitlab.mr.schema.notes import (
|
|
|
20
20
|
)
|
|
21
21
|
from ai_review.clients.gitlab.mr.types import GitLabMergeRequestsHTTPClientProtocol
|
|
22
22
|
from ai_review.config import settings
|
|
23
|
-
from ai_review.libs.config.
|
|
24
|
-
from ai_review.libs.config.vcs import
|
|
23
|
+
from ai_review.libs.config.vcs.base import GitLabVCSConfig
|
|
24
|
+
from ai_review.libs.config.vcs.gitlab import GitLabPipelineConfig, GitLabHTTPClientConfig
|
|
25
25
|
from ai_review.libs.constants.vcs_provider import VCSProvider
|
|
26
26
|
from ai_review.services.vcs.gitlab.client import GitLabVCSClient
|
|
27
27
|
|
|
@@ -2,8 +2,8 @@ import pytest
|
|
|
2
2
|
from pydantic import HttpUrl, SecretStr
|
|
3
3
|
|
|
4
4
|
from ai_review.config import settings
|
|
5
|
-
from ai_review.libs.config.llm import OpenAILLMConfig
|
|
6
|
-
from ai_review.libs.config.openai import OpenAIMetaConfig, OpenAIHTTPClientConfig
|
|
5
|
+
from ai_review.libs.config.llm.base import OpenAILLMConfig
|
|
6
|
+
from ai_review.libs.config.llm.openai import OpenAIMetaConfig, OpenAIHTTPClientConfig
|
|
7
7
|
from ai_review.libs.constants.llm_provider import LLMProvider
|
|
8
8
|
|
|
9
9
|
|
{xai_review-0.22.0 → xai_review-0.24.0}/ai_review/tests/suites/services/cost/test_service.py
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
|
|
3
|
-
from ai_review.libs.config.llm import LLMPricingConfig, LLMConfigBase
|
|
3
|
+
from ai_review.libs.config.llm.base import LLMPricingConfig, LLMConfigBase
|
|
4
4
|
from ai_review.services.cost.schema import CostReportSchema
|
|
5
5
|
from ai_review.services.cost.service import CostService
|
|
6
6
|
from ai_review.services.llm.types import ChatResultSchema
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from ai_review.config import settings
|
|
4
|
+
from ai_review.services.prompt.schema import PromptContextSchema
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_apply_format_inserts_variables() -> None:
|
|
8
|
+
"""Ensures simple string fields are correctly substituted into the template."""
|
|
9
|
+
context = PromptContextSchema(
|
|
10
|
+
review_title="My Review",
|
|
11
|
+
review_author_username="nikita"
|
|
12
|
+
)
|
|
13
|
+
template = "Title: <<review_title>>, Author: @<<review_author_username>>"
|
|
14
|
+
result = context.apply_format(template)
|
|
15
|
+
assert result == "Title: My Review, Author: @nikita"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_apply_format_with_lists() -> None:
|
|
19
|
+
"""Ensures list fields are serialized as CSV strings and substituted into the template."""
|
|
20
|
+
context = PromptContextSchema(
|
|
21
|
+
review_reviewers=["Alice", "Bob"],
|
|
22
|
+
review_reviewers_usernames=["alice", "bob"],
|
|
23
|
+
labels=["bug", "feature"],
|
|
24
|
+
changed_files=["a.py", "b.py"],
|
|
25
|
+
)
|
|
26
|
+
template = (
|
|
27
|
+
"Reviewers: <<review_reviewers>>\n"
|
|
28
|
+
"Usernames: <<review_reviewers_usernames>>\n"
|
|
29
|
+
"Labels: <<labels>>\n"
|
|
30
|
+
"Files: <<changed_files>>"
|
|
31
|
+
)
|
|
32
|
+
result = context.apply_format(template)
|
|
33
|
+
assert "Alice, Bob" in result
|
|
34
|
+
assert "alice, bob" in result
|
|
35
|
+
assert "bug, feature" in result
|
|
36
|
+
assert "a.py, b.py" in result
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_apply_format_handles_missing_fields() -> None:
|
|
40
|
+
"""Ensures missing fields are replaced with empty strings."""
|
|
41
|
+
context = PromptContextSchema()
|
|
42
|
+
template = "Title: <<review_title>>, Reviewer: <<review_reviewer>>"
|
|
43
|
+
result = context.apply_format(template)
|
|
44
|
+
assert result == "Title: , Reviewer: "
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_apply_format_unknown_placeholder_kept() -> None:
|
|
48
|
+
"""Ensures unknown placeholders remain unchanged in the template."""
|
|
49
|
+
context = PromptContextSchema()
|
|
50
|
+
template = "Unknown: <<does_not_exist>>"
|
|
51
|
+
result = context.apply_format(template)
|
|
52
|
+
assert result == "Unknown: <<does_not_exist>>"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_apply_format_multiple_occurrences() -> None:
|
|
56
|
+
"""Ensures multiple occurrences of the same placeholder are all replaced."""
|
|
57
|
+
context = PromptContextSchema(review_title="My Review")
|
|
58
|
+
template = "<<review_title>> again <<review_title>>"
|
|
59
|
+
result = context.apply_format(template)
|
|
60
|
+
assert result == "My Review again My Review"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_apply_format_override_from_settings(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
64
|
+
"""Ensures values from settings.prompt.context override local model values."""
|
|
65
|
+
monkeypatch.setitem(settings.prompt.context, "review_title", "Overridden")
|
|
66
|
+
context = PromptContextSchema(review_title="Local Value")
|
|
67
|
+
template = "Title: <<review_title>>"
|
|
68
|
+
result = context.apply_format(template)
|
|
69
|
+
assert result == "Title: Overridden"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_apply_format_prefers_override_even_if_empty(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
73
|
+
"""Ensures overrides take precedence even if the override value is empty."""
|
|
74
|
+
monkeypatch.setitem(settings.prompt.context, "review_title", "")
|
|
75
|
+
context = PromptContextSchema(review_title="Local Value")
|
|
76
|
+
template = "Title: <<review_title>>"
|
|
77
|
+
result = context.apply_format(template)
|
|
78
|
+
assert result == "Title: "
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_apply_format_empty_list_serializes_to_empty_string() -> None:
|
|
82
|
+
"""Ensures empty lists are serialized to empty strings."""
|
|
83
|
+
context = PromptContextSchema(labels=[])
|
|
84
|
+
template = "Labels: <<labels>>"
|
|
85
|
+
result = context.apply_format(template)
|
|
86
|
+
assert result == "Labels: "
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_apply_format_single_element_list() -> None:
|
|
90
|
+
"""Ensures lists with a single element are serialized without extra separators."""
|
|
91
|
+
context = PromptContextSchema(labels=["bug"])
|
|
92
|
+
template = "Labels: <<labels>>"
|
|
93
|
+
result = context.apply_format(template)
|
|
94
|
+
assert result == "Labels: bug"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_apply_format_list_with_spaces() -> None:
|
|
98
|
+
"""Ensures list items containing spaces are preserved in serialization."""
|
|
99
|
+
context = PromptContextSchema(labels=[" bug ", " feature "])
|
|
100
|
+
template = "Labels: <<labels>>"
|
|
101
|
+
result = context.apply_format(template)
|
|
102
|
+
assert result == "Labels: bug , feature "
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_apply_format_placeholder_case_sensitive() -> None:
|
|
106
|
+
"""Ensures placeholder matching is case-sensitive."""
|
|
107
|
+
context = PromptContextSchema(review_title="My Review")
|
|
108
|
+
template = "Title: <<Review_Title>>"
|
|
109
|
+
result = context.apply_format(template)
|
|
110
|
+
assert result == "Title: <<Review_Title>>"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_apply_format_override_with_none(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
114
|
+
"""Ensures None in overrides is treated as an empty string."""
|
|
115
|
+
monkeypatch.setitem(settings.prompt.context, "review_title", None)
|
|
116
|
+
context = PromptContextSchema(review_title="Local Value")
|
|
117
|
+
template = "Title: <<review_title>>"
|
|
118
|
+
result = context.apply_format(template)
|
|
119
|
+
assert result == "Title: "
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def test_apply_format_placeholder_inside_word() -> None:
|
|
123
|
+
"""Ensures placeholders inside words are still replaced correctly."""
|
|
124
|
+
context = PromptContextSchema(review_title="REV")
|
|
125
|
+
template = "prefix-<<review_title>>-suffix"
|
|
126
|
+
result = context.apply_format(template)
|
|
127
|
+
assert result == "prefix-REV-suffix"
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_apply_format_large_list() -> None:
|
|
131
|
+
"""Ensures large lists are serialized correctly without truncation."""
|
|
132
|
+
context = PromptContextSchema(labels=[str(index) for index in range(100)])
|
|
133
|
+
template = "Labels: <<labels>>"
|
|
134
|
+
result = context.apply_format(template)
|
|
135
|
+
assert result.startswith("Labels: 0, 1, 2")
|
|
136
|
+
assert "99" in result
|
|
File without changes
|
|
File without changes
|
|
@@ -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.24.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.24.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>
|
|
@@ -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.24.0
|
|
213
213
|
with:
|
|
214
214
|
review-command: ${{ inputs.review-command }}
|
|
215
215
|
env:
|
|
@@ -48,18 +48,20 @@ ai_review/libs/asynchronous/gather.py
|
|
|
48
48
|
ai_review/libs/config/__init__.py
|
|
49
49
|
ai_review/libs/config/artifacts.py
|
|
50
50
|
ai_review/libs/config/base.py
|
|
51
|
-
ai_review/libs/config/claude.py
|
|
52
51
|
ai_review/libs/config/core.py
|
|
53
|
-
ai_review/libs/config/gemini.py
|
|
54
|
-
ai_review/libs/config/github.py
|
|
55
|
-
ai_review/libs/config/gitlab.py
|
|
56
52
|
ai_review/libs/config/http.py
|
|
57
|
-
ai_review/libs/config/llm.py
|
|
58
53
|
ai_review/libs/config/logger.py
|
|
59
|
-
ai_review/libs/config/openai.py
|
|
60
54
|
ai_review/libs/config/prompt.py
|
|
61
55
|
ai_review/libs/config/review.py
|
|
62
|
-
ai_review/libs/config/
|
|
56
|
+
ai_review/libs/config/llm/__init__.py
|
|
57
|
+
ai_review/libs/config/llm/base.py
|
|
58
|
+
ai_review/libs/config/llm/claude.py
|
|
59
|
+
ai_review/libs/config/llm/gemini.py
|
|
60
|
+
ai_review/libs/config/llm/openai.py
|
|
61
|
+
ai_review/libs/config/vcs/__init__.py
|
|
62
|
+
ai_review/libs/config/vcs/base.py
|
|
63
|
+
ai_review/libs/config/vcs/github.py
|
|
64
|
+
ai_review/libs/config/vcs/gitlab.py
|
|
63
65
|
ai_review/libs/constants/__init__.py
|
|
64
66
|
ai_review/libs/constants/llm_provider.py
|
|
65
67
|
ai_review/libs/constants/vcs_provider.py
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
2
|
-
|
|
3
|
-
from ai_review.config import settings
|
|
4
|
-
from ai_review.libs.template.render import render_template
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class PromptContextSchema(BaseModel):
|
|
8
|
-
review_title: str = ""
|
|
9
|
-
review_description: str = ""
|
|
10
|
-
|
|
11
|
-
review_author_name: str = ""
|
|
12
|
-
review_author_username: str = ""
|
|
13
|
-
|
|
14
|
-
review_reviewer: str = ""
|
|
15
|
-
review_reviewers: list[str] = Field(default_factory=list)
|
|
16
|
-
review_reviewers_usernames: list[str] = Field(default_factory=list)
|
|
17
|
-
|
|
18
|
-
review_assignees: list[str] = Field(default_factory=list)
|
|
19
|
-
review_assignees_usernames: list[str] = Field(default_factory=list)
|
|
20
|
-
|
|
21
|
-
source_branch: str = ""
|
|
22
|
-
target_branch: str = ""
|
|
23
|
-
|
|
24
|
-
labels: list[str] = Field(default_factory=list)
|
|
25
|
-
changed_files: list[str] = Field(default_factory=list)
|
|
26
|
-
|
|
27
|
-
@property
|
|
28
|
-
def render_values(self) -> dict[str, str]:
|
|
29
|
-
return {
|
|
30
|
-
"review_title": self.review_title,
|
|
31
|
-
"review_description": self.review_description,
|
|
32
|
-
|
|
33
|
-
"review_author_name": self.review_author_name,
|
|
34
|
-
"review_author_username": self.review_author_username,
|
|
35
|
-
|
|
36
|
-
"review_reviewer": self.review_reviewer,
|
|
37
|
-
"review_reviewers": ", ".join(self.review_reviewers),
|
|
38
|
-
"review_reviewers_usernames": ", ".join(self.review_reviewers_usernames),
|
|
39
|
-
|
|
40
|
-
"review_assignees": ", ".join(self.review_assignees),
|
|
41
|
-
"review_assignees_usernames": ", ".join(self.review_assignees_usernames),
|
|
42
|
-
|
|
43
|
-
"source_branch": self.source_branch,
|
|
44
|
-
"target_branch": self.target_branch,
|
|
45
|
-
|
|
46
|
-
"labels": ", ".join(self.labels),
|
|
47
|
-
"changed_files": ", ".join(self.changed_files),
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
def apply_format(self, prompt: str) -> str:
|
|
51
|
-
values = {**self.render_values, **settings.prompt.context}
|
|
52
|
-
return render_template(prompt, values, settings.prompt.context_placeholder)
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from ai_review.config import settings
|
|
4
|
-
from ai_review.services.prompt.schema import PromptContextSchema
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def test_apply_format_inserts_variables() -> None:
|
|
8
|
-
context = PromptContextSchema(
|
|
9
|
-
review_title="My Review",
|
|
10
|
-
review_author_username="nikita"
|
|
11
|
-
)
|
|
12
|
-
template = "Title: <<review_title>>, Author: @<<review_author_username>>"
|
|
13
|
-
result = context.apply_format(template)
|
|
14
|
-
assert result == "Title: My Review, Author: @nikita"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def test_apply_format_with_lists() -> None:
|
|
18
|
-
context = PromptContextSchema(
|
|
19
|
-
review_reviewers=["Alice", "Bob"],
|
|
20
|
-
review_reviewers_usernames=["alice", "bob"],
|
|
21
|
-
labels=["bug", "feature"],
|
|
22
|
-
changed_files=["a.py", "b.py"],
|
|
23
|
-
)
|
|
24
|
-
template = (
|
|
25
|
-
"Reviewers: <<review_reviewers>>\n"
|
|
26
|
-
"Usernames: <<review_reviewers_usernames>>\n"
|
|
27
|
-
"Labels: <<labels>>\n"
|
|
28
|
-
"Files: <<changed_files>>"
|
|
29
|
-
)
|
|
30
|
-
result = context.apply_format(template)
|
|
31
|
-
assert "Alice, Bob" in result
|
|
32
|
-
assert "alice, bob" in result
|
|
33
|
-
assert "bug, feature" in result
|
|
34
|
-
assert "a.py, b.py" in result
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_apply_format_handles_missing_fields() -> None:
|
|
38
|
-
context = PromptContextSchema()
|
|
39
|
-
template = "Title: <<review_title>>, Reviewer: <<review_reviewer>>"
|
|
40
|
-
result = context.apply_format(template)
|
|
41
|
-
assert result == "Title: , Reviewer: "
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def test_apply_format_unknown_placeholder_kept() -> None:
|
|
45
|
-
context = PromptContextSchema()
|
|
46
|
-
template = "Unknown: <<does_not_exist>>"
|
|
47
|
-
result = context.apply_format(template)
|
|
48
|
-
assert result == "Unknown: <<does_not_exist>>"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def test_apply_format_multiple_occurrences() -> None:
|
|
52
|
-
context = PromptContextSchema(review_title="My Review")
|
|
53
|
-
template = "<<review_title>> again <<review_title>>"
|
|
54
|
-
result = context.apply_format(template)
|
|
55
|
-
assert result == "My Review again My Review"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def test_apply_format_override_from_settings(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
59
|
-
monkeypatch.setitem(settings.prompt.context, "review_title", "Overridden")
|
|
60
|
-
context = PromptContextSchema(review_title="Local Value")
|
|
61
|
-
template = "Title: <<review_title>>"
|
|
62
|
-
result = context.apply_format(template)
|
|
63
|
-
assert result == "Title: Overridden"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def test_apply_format_prefers_override_even_if_empty(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
67
|
-
monkeypatch.setitem(settings.prompt.context, "review_title", "")
|
|
68
|
-
context = PromptContextSchema(review_title="Local Value")
|
|
69
|
-
template = "Title: <<review_title>>"
|
|
70
|
-
result = context.apply_format(template)
|
|
71
|
-
assert result == "Title: "
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|