xai-review 0.33.0__tar.gz → 0.35.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.33.0/xai_review.egg-info → xai_review-0.35.0}/PKG-INFO +11 -10
- {xai_review-0.33.0 → xai_review-0.35.0}/README.md +8 -7
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/claude/client.py +1 -1
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/claude/schema.py +2 -2
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gemini/client.py +2 -1
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gemini/schema.py +2 -2
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/ollama/client.py +1 -1
- {xai_review-0.33.0/ai_review/clients/openai → xai_review-0.35.0/ai_review/clients/openai/v1}/client.py +9 -9
- {xai_review-0.33.0/ai_review/clients/openai → xai_review-0.35.0/ai_review/clients/openai/v1}/schema.py +1 -1
- xai_review-0.35.0/ai_review/clients/openai/v1/types.py +8 -0
- xai_review-0.35.0/ai_review/clients/openai/v2/client.py +46 -0
- xai_review-0.35.0/ai_review/clients/openai/v2/schema.py +47 -0
- xai_review-0.35.0/ai_review/clients/openai/v2/types.py +11 -0
- xai_review-0.35.0/ai_review/clients/openrouter/client.py +50 -0
- xai_review-0.35.0/ai_review/clients/openrouter/schema.py +36 -0
- xai_review-0.35.0/ai_review/clients/openrouter/types.py +11 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/llm/base.py +8 -1
- xai_review-0.35.0/ai_review/libs/config/llm/meta.py +7 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/llm/openai.py +4 -0
- xai_review-0.35.0/ai_review/libs/config/llm/openrouter.py +12 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/constants/llm_provider.py +1 -0
- xai_review-0.35.0/ai_review/resources/pricing.yaml +93 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/llm/factory.py +3 -0
- xai_review-0.35.0/ai_review/services/llm/openai/client.py +56 -0
- {xai_review-0.33.0/ai_review/services/llm/openai → xai_review-0.35.0/ai_review/services/llm/openrouter}/client.py +10 -7
- xai_review-0.35.0/ai_review/tests/fixtures/clients/openai.py +141 -0
- xai_review-0.35.0/ai_review/tests/fixtures/clients/openrouter.py +72 -0
- xai_review-0.35.0/ai_review/tests/suites/clients/openai/v1/test_client.py +12 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/openai → xai_review-0.35.0/ai_review/tests/suites/clients/openai/v1}/test_schema.py +1 -1
- xai_review-0.35.0/ai_review/tests/suites/clients/openai/v2/test_client.py +12 -0
- xai_review-0.35.0/ai_review/tests/suites/clients/openai/v2/test_schema.py +80 -0
- xai_review-0.35.0/ai_review/tests/suites/clients/openrouter/test_client.py +12 -0
- xai_review-0.35.0/ai_review/tests/suites/clients/openrouter/test_schema.py +57 -0
- xai_review-0.35.0/ai_review/tests/suites/libs/config/llm/test_openai.py +28 -0
- xai_review-0.35.0/ai_review/tests/suites/services/llm/openai/test_client.py +39 -0
- xai_review-0.35.0/ai_review/tests/suites/services/llm/openrouter/test_client.py +22 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/test_factory.py +8 -1
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/gateway/test_review_comment_gateway.py +5 -5
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/gateway/test_review_dry_run_comment_gateway.py +5 -5
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/gateway/test_review_llm_gateway.py +2 -2
- xai_review-0.35.0/ai_review/tests/suites/services/review/internal/policy/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/review/internal/summary/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/review/internal/summary_reply/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/review/runner/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/test_service.py +2 -2
- xai_review-0.35.0/ai_review/tests/suites/services/vcs/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/vcs/bitbucket/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/vcs/gitea/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/vcs/github/__init__.py +0 -0
- xai_review-0.35.0/ai_review/tests/suites/services/vcs/gitlab/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/pyproject.toml +17 -3
- {xai_review-0.33.0 → xai_review-0.35.0/xai_review.egg-info}/PKG-INFO +11 -10
- {xai_review-0.33.0 → xai_review-0.35.0}/xai_review.egg-info/SOURCES.txt +29 -5
- xai_review-0.33.0/ai_review/clients/openai/types.py +0 -8
- xai_review-0.33.0/ai_review/libs/config/llm/meta.py +0 -7
- xai_review-0.33.0/ai_review/resources/pricing.yaml +0 -55
- xai_review-0.33.0/ai_review/tests/fixtures/clients/openai.py +0 -69
- xai_review-0.33.0/ai_review/tests/suites/clients/openai/test_client.py +0 -12
- xai_review-0.33.0/ai_review/tests/suites/services/llm/openai/test_client.py +0 -22
- {xai_review-0.33.0 → xai_review-0.35.0}/LICENSE +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/run_context_review.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/run_inline_reply_review.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/run_inline_review.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/run_review.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/run_summary_reply_review.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/commands/run_summary_review.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/cli/main.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/comments.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/files.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/pull_request.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/user.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/claude/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/claude/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gemini/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gemini/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/comments.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/files.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/pull_request.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/user.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitea/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/comments.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/files.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/pull_request.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/reviews.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/user.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/pr/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/github/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/changes.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/discussions.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/notes.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/position.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/user.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/gitlab/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/ollama/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/ollama/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/ollama/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/clients/openai/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/libs → xai_review-0.35.0/ai_review/clients/openai/v1}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/libs/asynchronous → xai_review-0.35.0/ai_review/clients/openai/v2}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/libs/config → xai_review-0.35.0/ai_review/clients/openrouter}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/config.py +0 -0
- {xai_review-0.33.0/ai_review/libs/config/llm → xai_review-0.35.0/ai_review/libs}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/libs/config/vcs → xai_review-0.35.0/ai_review/libs/asynchronous}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/asynchronous/gather.py +0 -0
- {xai_review-0.33.0/ai_review/libs/constants → xai_review-0.35.0/ai_review/libs/config}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/artifacts.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/base.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/core.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/http.py +0 -0
- {xai_review-0.33.0/ai_review/libs/diff → xai_review-0.35.0/ai_review/libs/config/llm}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/llm/claude.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/llm/gemini.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/llm/ollama.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/logger.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/prompt.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/review.py +0 -0
- {xai_review-0.33.0/ai_review/libs/http → xai_review-0.35.0/ai_review/libs/config/vcs}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/base.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/bitbucket.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/gitea.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/github.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/gitlab.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/pagination.py +0 -0
- {xai_review-0.33.0/ai_review/libs/http/event_hooks → xai_review-0.35.0/ai_review/libs/constants}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/constants/vcs_provider.py +0 -0
- {xai_review-0.33.0/ai_review/libs/http/transports → xai_review-0.35.0/ai_review/libs/diff}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/diff/models.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/diff/parser.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/diff/tools.py +0 -0
- {xai_review-0.33.0/ai_review/libs/llm → xai_review-0.35.0/ai_review/libs/http}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/http/client.py +0 -0
- {xai_review-0.33.0/ai_review/libs/template → xai_review-0.35.0/ai_review/libs/http/event_hooks}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/http/event_hooks/base.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/http/handlers.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/http/paginate.py +0 -0
- {xai_review-0.33.0/ai_review/prompts → xai_review-0.35.0/ai_review/libs/http/transports}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/http/transports/retry.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/json.py +0 -0
- {xai_review-0.33.0/ai_review/resources → xai_review-0.35.0/ai_review/libs/llm}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/llm/output_json_parser.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/logger.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/resources.py +0 -0
- {xai_review-0.33.0/ai_review/services → xai_review-0.35.0/ai_review/libs/template}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/libs/template/render.py +0 -0
- {xai_review-0.33.0/ai_review/services/artifacts → xai_review-0.35.0/ai_review/prompts}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_context.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_inline.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_inline_reply.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_summary.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_summary_reply.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_system_context.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_system_inline.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_system_inline_reply.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_system_summary.md +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/prompts/default_system_summary_reply.md +0 -0
- {xai_review-0.33.0/ai_review/services/cost → xai_review-0.35.0/ai_review/resources}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/services/diff → xai_review-0.35.0/ai_review/services}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/services/git → xai_review-0.35.0/ai_review/services/artifacts}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/artifacts/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/artifacts/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/artifacts/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/artifacts/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/llm → xai_review-0.35.0/ai_review/services/cost}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/cost/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/cost/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/cost/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/llm/claude → xai_review-0.35.0/ai_review/services/diff}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/diff/renderers.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/diff/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/diff/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/diff/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/diff/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/llm/gemini → xai_review-0.35.0/ai_review/services/git}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/git/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/git/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/hook/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/hook/constants.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/hook/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/hook/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/llm/ollama → xai_review-0.35.0/ai_review/services/llm}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/services/llm/openai → xai_review-0.35.0/ai_review/services/llm/claude}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/llm/claude/client.py +0 -0
- {xai_review-0.33.0/ai_review/services/prompt → xai_review-0.35.0/ai_review/services/llm/gemini}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/llm/gemini/client.py +0 -0
- {xai_review-0.33.0/ai_review/services/review → xai_review-0.35.0/ai_review/services/llm/ollama}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/llm/ollama/client.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/gateway → xai_review-0.35.0/ai_review/services/llm/openai}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/internal → xai_review-0.35.0/ai_review/services/llm/openrouter}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/llm/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/internal/inline → xai_review-0.35.0/ai_review/services/prompt}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/prompt/adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/prompt/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/prompt/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/prompt/tools.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/prompt/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/internal/inline_reply → xai_review-0.35.0/ai_review/services/review}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/internal/policy → xai_review-0.35.0/ai_review/services/review/gateway}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/gateway/review_comment_gateway.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/gateway/review_dry_run_comment_gateway.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/gateway/review_llm_gateway.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/gateway/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/internal/summary → xai_review-0.35.0/ai_review/services/review/internal}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/internal/summary_reply → xai_review-0.35.0/ai_review/services/review/internal/inline}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/review/runner → xai_review-0.35.0/ai_review/services/review/internal/inline_reply}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline_reply/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline_reply/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline_reply/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/vcs → xai_review-0.35.0/ai_review/services/review/internal/policy}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/policy/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/policy/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/vcs/bitbucket → xai_review-0.35.0/ai_review/services/review/internal/summary}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/vcs/gitea → xai_review-0.35.0/ai_review/services/review/internal/summary_reply}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary_reply/schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary_reply/service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary_reply/types.py +0 -0
- {xai_review-0.33.0/ai_review/services/vcs/github → xai_review-0.35.0/ai_review/services/review/runner}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/runner/context.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/runner/inline.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/runner/inline_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/runner/summary.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/runner/summary_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/runner/types.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/review/service.py +0 -0
- {xai_review-0.33.0/ai_review/services/vcs/gitlab → xai_review-0.35.0/ai_review/services/vcs}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests → xai_review-0.35.0/ai_review/services/vcs/bitbucket}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/bitbucket/adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/bitbucket/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/factory.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures → xai_review-0.35.0/ai_review/services/vcs/gitea}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/gitea/adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/gitea/client.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/clients → xai_review-0.35.0/ai_review/services/vcs/github}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/github/adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/github/client.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/libs → xai_review-0.35.0/ai_review/services/vcs/gitlab}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/gitlab/adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/gitlab/client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/services/vcs/types.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/libs/llm → xai_review-0.35.0/ai_review/tests}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/services → xai_review-0.35.0/ai_review/tests/fixtures}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/services/review → xai_review-0.35.0/ai_review/tests/fixtures/clients}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/bitbucket.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/claude.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/gemini.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/gitea.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/github.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/gitlab.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/ollama.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/services/review/gateway → xai_review-0.35.0/ai_review/tests/fixtures/libs}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/services/review/internal → xai_review-0.35.0/ai_review/tests/fixtures/libs/llm}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/libs/llm/output_json_parser.py +0 -0
- {xai_review-0.33.0/ai_review/tests/fixtures/services/review/runner → xai_review-0.35.0/ai_review/tests/fixtures/services}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/artifacts.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/cost.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/diff.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/git.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/hook.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/llm.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/prompt.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites → xai_review-0.35.0/ai_review/tests/fixtures/services/review}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/base.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/cli → xai_review-0.35.0/ai_review/tests/fixtures/services/review/gateway}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/gateway/review_comment_gateway.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/gateway/review_dry_run_comment_gateway.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/gateway/review_llm_gateway.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients → xai_review-0.35.0/ai_review/tests/fixtures/services/review/internal}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/inline.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/inline_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/policy.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/summary.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/summary_reply.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/bitbucket → xai_review-0.35.0/ai_review/tests/fixtures/services/review/runner}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/context.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/inline.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/inline_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/summary.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/summary_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/vcs.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/claude → xai_review-0.35.0/ai_review/tests/suites}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/gemini → xai_review-0.35.0/ai_review/tests/suites/cli}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/cli/test_main.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/gitea → xai_review-0.35.0/ai_review/tests/suites/clients}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/github → xai_review-0.35.0/ai_review/tests/suites/clients/bitbucket}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/bitbucket/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/bitbucket/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/gitlab → xai_review-0.35.0/ai_review/tests/suites/clients/claude}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/ollama → xai_review-0.35.0/ai_review/tests/suites/clients/gemini}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/clients/openai → xai_review-0.35.0/ai_review/tests/suites/clients/gitea}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitea/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitea/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs → xai_review-0.35.0/ai_review/tests/suites/clients/github}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/github/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/github/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs/asynchronous → xai_review-0.35.0/ai_review/tests/suites/clients/gitlab}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitlab/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs/config → xai_review-0.35.0/ai_review/tests/suites/clients/ollama}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/ollama/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/ollama/test_schema.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs/diff → xai_review-0.35.0/ai_review/tests/suites/clients/openai}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs/http → xai_review-0.35.0/ai_review/tests/suites/clients/openai/v1}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs/llm → xai_review-0.35.0/ai_review/tests/suites/clients/openai/v2}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/libs/template → xai_review-0.35.0/ai_review/tests/suites/clients/openrouter}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services → xai_review-0.35.0/ai_review/tests/suites/libs}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/artifacts → xai_review-0.35.0/ai_review/tests/suites/libs/asynchronous}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/asynchronous/test_gather.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/cost → xai_review-0.35.0/ai_review/tests/suites/libs/config}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/diff → xai_review-0.35.0/ai_review/tests/suites/libs/config/llm}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/config/test_prompt.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/hook → xai_review-0.35.0/ai_review/tests/suites/libs/diff}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/llm → xai_review-0.35.0/ai_review/tests/suites/libs/http}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/http/test_paginate.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/llm/claude → xai_review-0.35.0/ai_review/tests/suites/libs/llm}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/llm/test_output_json_parser.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/llm/gemini → xai_review-0.35.0/ai_review/tests/suites/libs/template}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/test_json.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/llm/ollama → xai_review-0.35.0/ai_review/tests/suites/services}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/llm/openai → xai_review-0.35.0/ai_review/tests/suites/services/artifacts}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/artifacts/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/artifacts/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/prompt → xai_review-0.35.0/ai_review/tests/suites/services/cost}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/cost/test_schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/cost/test_service.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review → xai_review-0.35.0/ai_review/tests/suites/services/diff}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/gateway → xai_review-0.35.0/ai_review/tests/suites/services/hook}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/hook/test_service.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/internal → xai_review-0.35.0/ai_review/tests/suites/services/llm}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/internal/inline → xai_review-0.35.0/ai_review/tests/suites/services/llm/claude}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/claude/test_client.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/internal/inline_reply → xai_review-0.35.0/ai_review/tests/suites/services/llm/gemini}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/gemini/test_client.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/internal/policy → xai_review-0.35.0/ai_review/tests/suites/services/llm/ollama}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/ollama/test_client.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/internal/summary → xai_review-0.35.0/ai_review/tests/suites/services/llm/openai}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/internal/summary_reply → xai_review-0.35.0/ai_review/tests/suites/services/llm/openrouter}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/review/runner → xai_review-0.35.0/ai_review/tests/suites/services/prompt}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_tools.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/vcs → xai_review-0.35.0/ai_review/tests/suites/services/review}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/vcs/bitbucket → xai_review-0.35.0/ai_review/tests/suites/services/review/gateway}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/vcs/gitea → xai_review-0.35.0/ai_review/tests/suites/services/review/internal}/__init__.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/vcs/github → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/inline}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline/test_schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline/test_service.py +0 -0
- {xai_review-0.33.0/ai_review/tests/suites/services/vcs/gitlab → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/inline_reply}/__init__.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline_reply/test_schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline_reply/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/policy/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary/test_schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary_reply/test_schema.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary_reply/test_service.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_context.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_inline.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_inline_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_summary.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_summary_reply.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/bitbucket/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitea/test_adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitea/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/github/test_adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/github/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitlab/test_adapter.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitlab/test_client.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/test_factory.py +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/setup.cfg +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/xai_review.egg-info/dependency_links.txt +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/xai_review.egg-info/entry_points.txt +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/xai_review.egg-info/requires.txt +0 -0
- {xai_review-0.33.0 → xai_review-0.35.0}/xai_review.egg-info/top_level.txt +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xai-review
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: AI-powered code review tool
|
|
3
|
+
Version: 0.35.0
|
|
4
|
+
Summary: AI-powered code review tool for GitHub, GitLab, Bitbucket and Gitea — built with LLMs like OpenAI, Claude, Gemini, Ollama, and OpenRouter
|
|
5
5
|
Author-email: Nikita Filonov <nikita.filonov@example.com>
|
|
6
6
|
Maintainer-email: Nikita Filonov <nikita.filonov@example.com>
|
|
7
7
|
License: Apache-2.0
|
|
8
8
|
Project-URL: Issues, https://github.com/Nikita-Filonov/ai-review/issues
|
|
9
9
|
Project-URL: Homepage, https://github.com/Nikita-Filonov/ai-review
|
|
10
10
|
Project-URL: Repository, https://github.com/Nikita-Filonov/ai-review
|
|
11
|
-
Keywords: ai,code review,llm,openai,claude,gemini
|
|
11
|
+
Keywords: ai,code review,llm,openai,claude,gemini,ollama,openrouter,ci/cd,gitlab,github,gitea,bitbucket
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -66,7 +66,8 @@ improve code quality, enforce consistency, and speed up the review process.
|
|
|
66
66
|
|
|
67
67
|
✨ Key features:
|
|
68
68
|
|
|
69
|
-
- **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, or **
|
|
69
|
+
- **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, **Ollama**, or **OpenRouter**, and
|
|
70
|
+
switch anytime.
|
|
70
71
|
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, **Bitbucket**, and **Gitea**.
|
|
71
72
|
- **Customizable prompts** — adapt inline, context, and summary reviews to match your team’s coding guidelines.
|
|
72
73
|
- **Reply modes** — AI can now **participate in existing review threads**, adding follow-up replies in both inline and
|
|
@@ -120,7 +121,7 @@ pip install xai-review
|
|
|
120
121
|
Or run directly via Docker:
|
|
121
122
|
|
|
122
123
|
```bash
|
|
123
|
-
docker run --rm -v $(pwd):/app nikitafilonov/ai-review:latest run-summary
|
|
124
|
+
docker run --rm -v $(pwd):/app nikitafilonov/ai-review:latest ai-review run-summary
|
|
124
125
|
```
|
|
125
126
|
|
|
126
127
|
🐳 Pull from [DockerHub](https://hub.docker.com/r/nikitafilonov/ai-review)
|
|
@@ -146,8 +147,8 @@ vcs:
|
|
|
146
147
|
provider: GITLAB
|
|
147
148
|
|
|
148
149
|
pipeline:
|
|
149
|
-
project_id: 1
|
|
150
|
-
merge_request_id: 100
|
|
150
|
+
project_id: "1"
|
|
151
|
+
merge_request_id: "100"
|
|
151
152
|
|
|
152
153
|
http_client:
|
|
153
154
|
timeout: 120
|
|
@@ -176,7 +177,7 @@ for complete, ready-to-use examples.
|
|
|
176
177
|
|
|
177
178
|
Key things you can customize:
|
|
178
179
|
|
|
179
|
-
- **LLM provider** — OpenAI, Gemini, Claude, or
|
|
180
|
+
- **LLM provider** — OpenAI, Gemini, Claude, Ollama, or OpenRouter
|
|
180
181
|
- **Model settings** — model name, temperature, max tokens
|
|
181
182
|
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, **Bitbucket**, and **Gitea**
|
|
182
183
|
- **Review policy** — which files to include/exclude, review modes
|
|
@@ -220,7 +221,7 @@ jobs:
|
|
|
220
221
|
with:
|
|
221
222
|
fetch-depth: 0
|
|
222
223
|
|
|
223
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
224
|
+
- uses: Nikita-Filonov/ai-review@v0.35.0
|
|
224
225
|
with:
|
|
225
226
|
review-command: ${{ inputs.review-command }}
|
|
226
227
|
env:
|
|
@@ -298,7 +299,7 @@ AI Review does **not store**, **log**, or **transmit** your source code to any e
|
|
|
298
299
|
provider** explicitly configured in your `.ai-review.yaml`.
|
|
299
300
|
|
|
300
301
|
All data is sent **directly** from your CI/CD environment to the selected LLM API endpoint (e.g. OpenAI, Gemini,
|
|
301
|
-
Claude). No intermediary servers or storage layers are involved.
|
|
302
|
+
Claude, OpenRouter). No intermediary servers or storage layers are involved.
|
|
302
303
|
|
|
303
304
|
If you use **Ollama**, requests are sent to your **local or self-hosted Ollama runtime**
|
|
304
305
|
(by default `http://localhost:11434`). This allows you to run reviews completely **offline**, keeping all data strictly
|
|
@@ -32,7 +32,8 @@ improve code quality, enforce consistency, and speed up the review process.
|
|
|
32
32
|
|
|
33
33
|
✨ Key features:
|
|
34
34
|
|
|
35
|
-
- **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, or **
|
|
35
|
+
- **Multiple LLM providers** — choose between **OpenAI**, **Claude**, **Gemini**, **Ollama**, or **OpenRouter**, and
|
|
36
|
+
switch anytime.
|
|
36
37
|
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, **Bitbucket**, and **Gitea**.
|
|
37
38
|
- **Customizable prompts** — adapt inline, context, and summary reviews to match your team’s coding guidelines.
|
|
38
39
|
- **Reply modes** — AI can now **participate in existing review threads**, adding follow-up replies in both inline and
|
|
@@ -86,7 +87,7 @@ pip install xai-review
|
|
|
86
87
|
Or run directly via Docker:
|
|
87
88
|
|
|
88
89
|
```bash
|
|
89
|
-
docker run --rm -v $(pwd):/app nikitafilonov/ai-review:latest run-summary
|
|
90
|
+
docker run --rm -v $(pwd):/app nikitafilonov/ai-review:latest ai-review run-summary
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
🐳 Pull from [DockerHub](https://hub.docker.com/r/nikitafilonov/ai-review)
|
|
@@ -112,8 +113,8 @@ vcs:
|
|
|
112
113
|
provider: GITLAB
|
|
113
114
|
|
|
114
115
|
pipeline:
|
|
115
|
-
project_id: 1
|
|
116
|
-
merge_request_id: 100
|
|
116
|
+
project_id: "1"
|
|
117
|
+
merge_request_id: "100"
|
|
117
118
|
|
|
118
119
|
http_client:
|
|
119
120
|
timeout: 120
|
|
@@ -142,7 +143,7 @@ for complete, ready-to-use examples.
|
|
|
142
143
|
|
|
143
144
|
Key things you can customize:
|
|
144
145
|
|
|
145
|
-
- **LLM provider** — OpenAI, Gemini, Claude, or
|
|
146
|
+
- **LLM provider** — OpenAI, Gemini, Claude, Ollama, or OpenRouter
|
|
146
147
|
- **Model settings** — model name, temperature, max tokens
|
|
147
148
|
- **VCS integration** — works out of the box with **GitLab**, **GitHub**, **Bitbucket**, and **Gitea**
|
|
148
149
|
- **Review policy** — which files to include/exclude, review modes
|
|
@@ -186,7 +187,7 @@ jobs:
|
|
|
186
187
|
with:
|
|
187
188
|
fetch-depth: 0
|
|
188
189
|
|
|
189
|
-
- uses: Nikita-Filonov/ai-review@v0.
|
|
190
|
+
- uses: Nikita-Filonov/ai-review@v0.35.0
|
|
190
191
|
with:
|
|
191
192
|
review-command: ${{ inputs.review-command }}
|
|
192
193
|
env:
|
|
@@ -264,7 +265,7 @@ AI Review does **not store**, **log**, or **transmit** your source code to any e
|
|
|
264
265
|
provider** explicitly configured in your `.ai-review.yaml`.
|
|
265
266
|
|
|
266
267
|
All data is sent **directly** from your CI/CD environment to the selected LLM API endpoint (e.g. OpenAI, Gemini,
|
|
267
|
-
Claude). No intermediary servers or storage layers are involved.
|
|
268
|
+
Claude, OpenRouter). No intermediary servers or storage layers are involved.
|
|
268
269
|
|
|
269
270
|
If you use **Ollama**, requests are sent to your **local or self-hosted Ollama runtime**
|
|
270
271
|
(by default `http://localhost:11434`). This allows you to run reviews completely **offline**, keeping all data strictly
|
|
@@ -17,7 +17,7 @@ class ClaudeHTTPClientError(HTTPClientError):
|
|
|
17
17
|
class ClaudeHTTPClient(HTTPClient, ClaudeHTTPClientProtocol):
|
|
18
18
|
@handle_http_error(client="ClaudeHTTPClient", exception=ClaudeHTTPClientError)
|
|
19
19
|
async def chat_api(self, request: ClaudeChatRequestSchema) -> Response:
|
|
20
|
-
return await self.post("/v1/messages", json=request.model_dump())
|
|
20
|
+
return await self.post("/v1/messages", json=request.model_dump(exclude_none=True))
|
|
21
21
|
|
|
22
22
|
async def chat(self, request: ClaudeChatRequestSchema) -> ClaudeChatResponseSchema:
|
|
23
23
|
response = await self.chat_api(request)
|
|
@@ -12,8 +12,8 @@ class ClaudeChatRequestSchema(BaseModel):
|
|
|
12
12
|
model: str
|
|
13
13
|
system: str | None = None
|
|
14
14
|
messages: list[ClaudeMessageSchema]
|
|
15
|
-
max_tokens: int
|
|
16
|
-
temperature: float
|
|
15
|
+
max_tokens: int | None = None
|
|
16
|
+
temperature: float | None = None
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class ClaudeContentSchema(BaseModel):
|
|
@@ -19,7 +19,8 @@ class GeminiHTTPClient(HTTPClient, GeminiHTTPClientProtocol):
|
|
|
19
19
|
async def chat_api(self, request: GeminiChatRequestSchema) -> Response:
|
|
20
20
|
meta = settings.llm.meta
|
|
21
21
|
return await self.post(
|
|
22
|
-
f"/v1beta/models/{meta.model}:generateContent",
|
|
22
|
+
f"/v1beta/models/{meta.model}:generateContent",
|
|
23
|
+
json=request.model_dump(exclude_none=True)
|
|
23
24
|
)
|
|
24
25
|
|
|
25
26
|
async def chat(self, request: GeminiChatRequestSchema) -> GeminiChatResponseSchema:
|
|
@@ -45,8 +45,8 @@ class GeminiCandidateSchema(BaseModel):
|
|
|
45
45
|
class GeminiGenerationConfigSchema(BaseModel):
|
|
46
46
|
model_config = ConfigDict(populate_by_name=True)
|
|
47
47
|
|
|
48
|
-
temperature: float
|
|
49
|
-
max_output_tokens: int = Field(alias="maxOutputTokens")
|
|
48
|
+
temperature: float | None = None
|
|
49
|
+
max_output_tokens: int | None = Field(alias="maxOutputTokens", default=None)
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
class GeminiChatRequestSchema(BaseModel):
|
|
@@ -17,7 +17,7 @@ class OllamaHTTPClientError(HTTPClientError):
|
|
|
17
17
|
class OllamaHTTPClient(HTTPClient, OllamaHTTPClientProtocol):
|
|
18
18
|
@handle_http_error(client="OllamaHTTPClient", exception=OllamaHTTPClientError)
|
|
19
19
|
async def chat_api(self, request: OllamaChatRequestSchema) -> Response:
|
|
20
|
-
return await self.post("/api/chat", json=request.model_dump())
|
|
20
|
+
return await self.post("/api/chat", json=request.model_dump(exclude_none=True))
|
|
21
21
|
|
|
22
22
|
async def chat(self, request: OllamaChatRequestSchema) -> OllamaChatResponseSchema:
|
|
23
23
|
response = await self.chat_api(request)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from httpx import Response, AsyncHTTPTransport, AsyncClient
|
|
2
2
|
|
|
3
|
-
from ai_review.clients.openai.schema import OpenAIChatRequestSchema, OpenAIChatResponseSchema
|
|
4
|
-
from ai_review.clients.openai.types import
|
|
3
|
+
from ai_review.clients.openai.v1.schema import OpenAIChatRequestSchema, OpenAIChatResponseSchema
|
|
4
|
+
from ai_review.clients.openai.v1.types import OpenAIV1HTTPClientProtocol
|
|
5
5
|
from ai_review.config import settings
|
|
6
6
|
from ai_review.libs.http.client import HTTPClient
|
|
7
7
|
from ai_review.libs.http.event_hooks.logger import LoggerEventHook
|
|
@@ -10,22 +10,22 @@ from ai_review.libs.http.transports.retry import RetryTransport
|
|
|
10
10
|
from ai_review.libs.logger import get_logger
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class OpenAIV1HTTPClientError(HTTPClientError):
|
|
14
14
|
pass
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class
|
|
18
|
-
@handle_http_error(client='
|
|
17
|
+
class OpenAIV1HTTPClient(HTTPClient, OpenAIV1HTTPClientProtocol):
|
|
18
|
+
@handle_http_error(client='OpenAIV1HTTPClient', exception=OpenAIV1HTTPClientError)
|
|
19
19
|
async def chat_api(self, request: OpenAIChatRequestSchema) -> Response:
|
|
20
|
-
return await self.post("/chat/completions", json=request.model_dump())
|
|
20
|
+
return await self.post("/chat/completions", json=request.model_dump(exclude_none=True))
|
|
21
21
|
|
|
22
22
|
async def chat(self, request: OpenAIChatRequestSchema) -> OpenAIChatResponseSchema:
|
|
23
23
|
response = await self.chat_api(request)
|
|
24
24
|
return OpenAIChatResponseSchema.model_validate_json(response.text)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
logger = get_logger("
|
|
27
|
+
def get_openai_v1_http_client() -> OpenAIV1HTTPClient:
|
|
28
|
+
logger = get_logger("OPENAI_V1_HTTP_CLIENT")
|
|
29
29
|
logger_event_hook = LoggerEventHook(logger=logger)
|
|
30
30
|
retry_transport = RetryTransport(logger=logger, transport=AsyncHTTPTransport())
|
|
31
31
|
|
|
@@ -40,4 +40,4 @@ def get_openai_http_client() -> OpenAIHTTPClient:
|
|
|
40
40
|
}
|
|
41
41
|
)
|
|
42
42
|
|
|
43
|
-
return
|
|
43
|
+
return OpenAIV1HTTPClient(client=client)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.openai.v1.schema import OpenAIChatRequestSchema, OpenAIChatResponseSchema
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OpenAIV1HTTPClientProtocol(Protocol):
|
|
7
|
+
async def chat(self, request: OpenAIChatRequestSchema) -> OpenAIChatResponseSchema:
|
|
8
|
+
...
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from httpx import Response, AsyncClient, AsyncHTTPTransport
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.openai.v2.schema import (
|
|
4
|
+
OpenAIResponsesRequestSchema,
|
|
5
|
+
OpenAIResponsesResponseSchema
|
|
6
|
+
)
|
|
7
|
+
from ai_review.clients.openai.v2.types import OpenAIV2HTTPClientProtocol
|
|
8
|
+
from ai_review.config import settings
|
|
9
|
+
from ai_review.libs.http.client import HTTPClient
|
|
10
|
+
from ai_review.libs.http.event_hooks.logger import LoggerEventHook
|
|
11
|
+
from ai_review.libs.http.handlers import HTTPClientError, handle_http_error
|
|
12
|
+
from ai_review.libs.http.transports.retry import RetryTransport
|
|
13
|
+
from ai_review.libs.logger import get_logger
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OpenAIV2HTTPClientError(HTTPClientError):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OpenAIV2HTTPClient(HTTPClient, OpenAIV2HTTPClientProtocol):
|
|
21
|
+
@handle_http_error(client='OpenAIV2HTTPClient', exception=OpenAIV2HTTPClientError)
|
|
22
|
+
async def chat_api(self, request: OpenAIResponsesRequestSchema) -> Response:
|
|
23
|
+
return await self.post("/responses", json=request.model_dump(exclude_none=True))
|
|
24
|
+
|
|
25
|
+
async def chat(self, request: OpenAIResponsesRequestSchema) -> OpenAIResponsesResponseSchema:
|
|
26
|
+
response = await self.chat_api(request)
|
|
27
|
+
return OpenAIResponsesResponseSchema.model_validate_json(response.text)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_openai_v2_http_client() -> OpenAIV2HTTPClient:
|
|
31
|
+
logger = get_logger("OPENAI_V2_HTTP_CLIENT")
|
|
32
|
+
logger_event_hook = LoggerEventHook(logger=logger)
|
|
33
|
+
retry_transport = RetryTransport(logger=logger, transport=AsyncHTTPTransport())
|
|
34
|
+
|
|
35
|
+
client = AsyncClient(
|
|
36
|
+
timeout=settings.llm.http_client.timeout,
|
|
37
|
+
headers={"Authorization": f"Bearer {settings.llm.http_client.api_token_value}"},
|
|
38
|
+
base_url=settings.llm.http_client.api_url_value,
|
|
39
|
+
transport=retry_transport,
|
|
40
|
+
event_hooks={
|
|
41
|
+
'request': [logger_event_hook.request],
|
|
42
|
+
'response': [logger_event_hook.response]
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return OpenAIV2HTTPClient(client=client)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class OpenAIResponseUsageSchema(BaseModel):
|
|
5
|
+
total_tokens: int
|
|
6
|
+
input_tokens: int
|
|
7
|
+
output_tokens: int
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class OpenAIInputMessageSchema(BaseModel):
|
|
11
|
+
role: str
|
|
12
|
+
content: str
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OpenAIResponseContentSchema(BaseModel):
|
|
16
|
+
type: str
|
|
17
|
+
text: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OpenAIResponseOutputSchema(BaseModel):
|
|
21
|
+
type: str
|
|
22
|
+
role: str | None = None
|
|
23
|
+
content: list[OpenAIResponseContentSchema] | None = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class OpenAIResponsesRequestSchema(BaseModel):
|
|
27
|
+
model: str
|
|
28
|
+
input: list[OpenAIInputMessageSchema]
|
|
29
|
+
temperature: float | None = None
|
|
30
|
+
instructions: str | None = None
|
|
31
|
+
max_output_tokens: int | None = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class OpenAIResponsesResponseSchema(BaseModel):
|
|
35
|
+
usage: OpenAIResponseUsageSchema
|
|
36
|
+
output: list[OpenAIResponseOutputSchema]
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def first_text(self) -> str:
|
|
40
|
+
results: list[str] = []
|
|
41
|
+
for block in self.output:
|
|
42
|
+
if block.type == "message" and block.content:
|
|
43
|
+
for content in block.content:
|
|
44
|
+
if content.type == "output_text" and content.text:
|
|
45
|
+
results.append(content.text)
|
|
46
|
+
|
|
47
|
+
return "".join(results).strip()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.openai.v2.schema import (
|
|
4
|
+
OpenAIResponsesRequestSchema,
|
|
5
|
+
OpenAIResponsesResponseSchema
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OpenAIV2HTTPClientProtocol(Protocol):
|
|
10
|
+
async def chat(self, request: OpenAIResponsesRequestSchema) -> OpenAIResponsesResponseSchema:
|
|
11
|
+
...
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from httpx import AsyncClient, Response, AsyncHTTPTransport
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.openrouter.schema import OpenRouterChatRequestSchema, OpenRouterChatResponseSchema
|
|
4
|
+
from ai_review.clients.openrouter.types import OpenRouterHTTPClientProtocol
|
|
5
|
+
from ai_review.config import settings
|
|
6
|
+
from ai_review.libs.http.client import HTTPClient
|
|
7
|
+
from ai_review.libs.http.event_hooks.logger import LoggerEventHook
|
|
8
|
+
from ai_review.libs.http.handlers import HTTPClientError, handle_http_error
|
|
9
|
+
from ai_review.libs.http.transports.retry import RetryTransport
|
|
10
|
+
from ai_review.libs.logger import get_logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OpenRouterHTTPClientError(HTTPClientError):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class OpenRouterHTTPClient(HTTPClient, OpenRouterHTTPClientProtocol):
|
|
18
|
+
@handle_http_error(client="OpenRouterHTTPClient", exception=OpenRouterHTTPClientError)
|
|
19
|
+
async def chat_api(self, request: OpenRouterChatRequestSchema) -> Response:
|
|
20
|
+
return await self.post("/chat/completions", json=request.model_dump(exclude_none=True))
|
|
21
|
+
|
|
22
|
+
async def chat(self, request: OpenRouterChatRequestSchema) -> OpenRouterChatResponseSchema:
|
|
23
|
+
response = await self.chat_api(request)
|
|
24
|
+
return OpenRouterChatResponseSchema.model_validate_json(response.text)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_openrouter_http_client() -> OpenRouterHTTPClient:
|
|
28
|
+
logger = get_logger("OPENROUTER_HTTP_CLIENT")
|
|
29
|
+
logger_event_hook = LoggerEventHook(logger=logger)
|
|
30
|
+
retry_transport = RetryTransport(logger=logger, transport=AsyncHTTPTransport())
|
|
31
|
+
|
|
32
|
+
headers = {"Authorization": f"Bearer {settings.llm.http_client.api_token_value}"}
|
|
33
|
+
if settings.llm.meta.title:
|
|
34
|
+
headers["X-Title"] = settings.llm.meta.title
|
|
35
|
+
|
|
36
|
+
if settings.llm.meta.referer:
|
|
37
|
+
headers["Referer"] = settings.llm.meta.referer
|
|
38
|
+
|
|
39
|
+
client = AsyncClient(
|
|
40
|
+
timeout=settings.llm.http_client.timeout,
|
|
41
|
+
headers=headers,
|
|
42
|
+
base_url=settings.llm.http_client.api_url_value,
|
|
43
|
+
transport=retry_transport,
|
|
44
|
+
event_hooks={
|
|
45
|
+
"request": [logger_event_hook.request],
|
|
46
|
+
"response": [logger_event_hook.response],
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return OpenRouterHTTPClient(client=client)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OpenRouterUsageSchema(BaseModel):
|
|
7
|
+
total_tokens: int
|
|
8
|
+
prompt_tokens: int
|
|
9
|
+
completion_tokens: int
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OpenRouterMessageSchema(BaseModel):
|
|
13
|
+
role: Literal["system", "user", "assistant"]
|
|
14
|
+
content: str
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class OpenRouterChoiceSchema(BaseModel):
|
|
18
|
+
message: OpenRouterMessageSchema
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class OpenRouterChatRequestSchema(BaseModel):
|
|
22
|
+
model: str
|
|
23
|
+
messages: list[OpenRouterMessageSchema]
|
|
24
|
+
max_tokens: int | None = None
|
|
25
|
+
temperature: float | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class OpenRouterChatResponseSchema(BaseModel):
|
|
29
|
+
usage: OpenRouterUsageSchema
|
|
30
|
+
choices: list[OpenRouterChoiceSchema]
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def first_text(self) -> str:
|
|
34
|
+
if not self.choices:
|
|
35
|
+
return ""
|
|
36
|
+
return (self.choices[0].message.content or "").strip()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from ai_review.clients.openrouter.schema import (
|
|
4
|
+
OpenRouterChatRequestSchema,
|
|
5
|
+
OpenRouterChatResponseSchema
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OpenRouterHTTPClientProtocol(Protocol):
|
|
10
|
+
async def chat(self, request: OpenRouterChatRequestSchema) -> OpenRouterChatResponseSchema:
|
|
11
|
+
...
|
|
@@ -8,6 +8,7 @@ from ai_review.libs.config.llm.claude import ClaudeHTTPClientConfig, ClaudeMetaC
|
|
|
8
8
|
from ai_review.libs.config.llm.gemini import GeminiHTTPClientConfig, GeminiMetaConfig
|
|
9
9
|
from ai_review.libs.config.llm.ollama import OllamaHTTPClientConfig, OllamaMetaConfig
|
|
10
10
|
from ai_review.libs.config.llm.openai import OpenAIHTTPClientConfig, OpenAIMetaConfig
|
|
11
|
+
from ai_review.libs.config.llm.openrouter import OpenRouterHTTPClientConfig, OpenRouterMetaConfig
|
|
11
12
|
from ai_review.libs.constants.llm_provider import LLMProvider
|
|
12
13
|
from ai_review.libs.resources import load_resource
|
|
13
14
|
|
|
@@ -62,7 +63,13 @@ class OllamaLLMConfig(LLMConfigBase):
|
|
|
62
63
|
http_client: OllamaHTTPClientConfig
|
|
63
64
|
|
|
64
65
|
|
|
66
|
+
class OpenRouterLLMConfig(LLMConfigBase):
|
|
67
|
+
meta: OpenRouterMetaConfig
|
|
68
|
+
provider: Literal[LLMProvider.OPENROUTER]
|
|
69
|
+
http_client: OpenRouterHTTPClientConfig
|
|
70
|
+
|
|
71
|
+
|
|
65
72
|
LLMConfig = Annotated[
|
|
66
|
-
OpenAILLMConfig | GeminiLLMConfig | ClaudeLLMConfig | OllamaLLMConfig,
|
|
73
|
+
OpenAILLMConfig | GeminiLLMConfig | ClaudeLLMConfig | OllamaLLMConfig | OpenRouterLLMConfig,
|
|
67
74
|
Field(discriminator="provider")
|
|
68
75
|
]
|
|
@@ -5,6 +5,10 @@ from ai_review.libs.config.llm.meta import LLMMetaConfig
|
|
|
5
5
|
class OpenAIMetaConfig(LLMMetaConfig):
|
|
6
6
|
model: str = "gpt-4o-mini"
|
|
7
7
|
|
|
8
|
+
@property
|
|
9
|
+
def is_v2_model(self) -> bool:
|
|
10
|
+
return any(self.model.startswith(model) for model in ("gpt-5", "gpt-4.1"))
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
class OpenAIHTTPClientConfig(HTTPClientWithTokenConfig):
|
|
10
14
|
pass
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from ai_review.libs.config.http import HTTPClientWithTokenConfig
|
|
2
|
+
from ai_review.libs.config.llm.meta import LLMMetaConfig
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class OpenRouterMetaConfig(LLMMetaConfig):
|
|
6
|
+
model: str = "openai/gpt-4o-mini"
|
|
7
|
+
title: str | None = None
|
|
8
|
+
referer: str | None = None
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class OpenRouterHTTPClientConfig(HTTPClientWithTokenConfig):
|
|
12
|
+
pass
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# ===============================
|
|
2
|
+
# 📊 Pricing per 1 token (USD)
|
|
3
|
+
# ===============================
|
|
4
|
+
# NOTE:
|
|
5
|
+
# - Prices are per 1 token and can change over time.
|
|
6
|
+
# - For the latest OpenAI and Anthropic pricing, see:
|
|
7
|
+
# - https://openai.com/api/pricing
|
|
8
|
+
# - https://www.anthropic.com/pricing
|
|
9
|
+
# - For OpenRouter models, prices vary by provider: https://openrouter.ai
|
|
10
|
+
|
|
11
|
+
# --- OpenAI ---
|
|
12
|
+
gpt-4o-mini:
|
|
13
|
+
input: 0.15e-6
|
|
14
|
+
output: 0.60e-6
|
|
15
|
+
|
|
16
|
+
gpt-4o:
|
|
17
|
+
input: 5.00e-6
|
|
18
|
+
output: 15.00e-6
|
|
19
|
+
|
|
20
|
+
gpt-4.1-mini:
|
|
21
|
+
input: 0.15e-6
|
|
22
|
+
output: 0.60e-6
|
|
23
|
+
|
|
24
|
+
gpt-4.1:
|
|
25
|
+
input: 5.00e-6
|
|
26
|
+
output: 15.00e-6
|
|
27
|
+
|
|
28
|
+
gpt-5:
|
|
29
|
+
input: 10.00e-6
|
|
30
|
+
output: 30.00e-6
|
|
31
|
+
|
|
32
|
+
gpt-3.5-turbo:
|
|
33
|
+
input: 0.50e-6
|
|
34
|
+
output: 1.50e-6
|
|
35
|
+
|
|
36
|
+
# --- Google Gemini ---
|
|
37
|
+
gemini-2.5-flash-lite:
|
|
38
|
+
input: 0.10e-6
|
|
39
|
+
output: 0.40e-6
|
|
40
|
+
|
|
41
|
+
gemini-2.0-flash-lite:
|
|
42
|
+
input: 0.019e-6
|
|
43
|
+
output: 0.10e-6
|
|
44
|
+
|
|
45
|
+
gemini-2.0-pro:
|
|
46
|
+
input: 0.125e-6
|
|
47
|
+
output: 0.375e-6
|
|
48
|
+
|
|
49
|
+
gemini-2.5-pro:
|
|
50
|
+
input: 1.25e-6
|
|
51
|
+
output: 10.00e-6
|
|
52
|
+
|
|
53
|
+
gemini-2.5-pro-long-context:
|
|
54
|
+
input: 2.50e-6
|
|
55
|
+
output: 15.00e-6
|
|
56
|
+
|
|
57
|
+
# --- Anthropic Claude ---
|
|
58
|
+
claude-3.5-sonnet:
|
|
59
|
+
input: 3.00e-6
|
|
60
|
+
output: 15.00e-6
|
|
61
|
+
|
|
62
|
+
claude-3-opus:
|
|
63
|
+
input: 15.00e-6
|
|
64
|
+
output: 75.00e-6
|
|
65
|
+
|
|
66
|
+
claude-3-sonnet:
|
|
67
|
+
input: 3.00e-6
|
|
68
|
+
output: 15.00e-6
|
|
69
|
+
|
|
70
|
+
claude-3-haiku:
|
|
71
|
+
input: 0.25e-6
|
|
72
|
+
output: 1.25e-6
|
|
73
|
+
|
|
74
|
+
# --- OpenRouter ---
|
|
75
|
+
o3-mini:
|
|
76
|
+
input: 1.10e-6
|
|
77
|
+
output: 4.40e-6
|
|
78
|
+
|
|
79
|
+
openai/chatgpt-4o-latest:
|
|
80
|
+
input: 5.00e-6
|
|
81
|
+
output: 15.00e-6
|
|
82
|
+
|
|
83
|
+
mistralai/mixtral-8x7b:
|
|
84
|
+
input: 0.24e-6
|
|
85
|
+
output: 0.48e-6
|
|
86
|
+
|
|
87
|
+
meta-llama/llama-3-8b-instruct:
|
|
88
|
+
input: 0.20e-6
|
|
89
|
+
output: 0.40e-6
|
|
90
|
+
|
|
91
|
+
meta-llama/llama-3-70b-instruct:
|
|
92
|
+
input: 0.80e-6
|
|
93
|
+
output: 1.60e-6
|
|
@@ -4,6 +4,7 @@ from ai_review.services.llm.claude.client import ClaudeLLMClient
|
|
|
4
4
|
from ai_review.services.llm.gemini.client import GeminiLLMClient
|
|
5
5
|
from ai_review.services.llm.ollama.client import OllamaLLMClient
|
|
6
6
|
from ai_review.services.llm.openai.client import OpenAILLMClient
|
|
7
|
+
from ai_review.services.llm.openrouter.client import OpenRouterLLMClient
|
|
7
8
|
from ai_review.services.llm.types import LLMClientProtocol
|
|
8
9
|
|
|
9
10
|
|
|
@@ -17,5 +18,7 @@ def get_llm_client() -> LLMClientProtocol:
|
|
|
17
18
|
return ClaudeLLMClient()
|
|
18
19
|
case LLMProvider.OLLAMA:
|
|
19
20
|
return OllamaLLMClient()
|
|
21
|
+
case LLMProvider.OPENROUTER:
|
|
22
|
+
return OpenRouterLLMClient()
|
|
20
23
|
case _:
|
|
21
24
|
raise ValueError(f"Unsupported LLM provider: {settings.llm.provider}")
|