xai-review 0.34.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.

Files changed (420) hide show
  1. {xai_review-0.34.0/xai_review.egg-info → xai_review-0.35.0}/PKG-INFO +2 -2
  2. {xai_review-0.34.0 → xai_review-0.35.0}/README.md +1 -1
  3. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/claude/client.py +1 -1
  4. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/claude/schema.py +2 -2
  5. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gemini/client.py +2 -1
  6. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gemini/schema.py +2 -2
  7. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/ollama/client.py +1 -1
  8. {xai_review-0.34.0/ai_review/clients/openai → xai_review-0.35.0/ai_review/clients/openai/v1}/client.py +9 -9
  9. {xai_review-0.34.0/ai_review/clients/openai → xai_review-0.35.0/ai_review/clients/openai/v1}/schema.py +1 -1
  10. xai_review-0.35.0/ai_review/clients/openai/v1/types.py +8 -0
  11. xai_review-0.35.0/ai_review/clients/openai/v2/client.py +46 -0
  12. xai_review-0.35.0/ai_review/clients/openai/v2/schema.py +47 -0
  13. xai_review-0.35.0/ai_review/clients/openai/v2/types.py +11 -0
  14. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/openrouter/client.py +1 -1
  15. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/openrouter/schema.py +2 -2
  16. xai_review-0.35.0/ai_review/libs/config/llm/meta.py +7 -0
  17. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/llm/openai.py +4 -0
  18. xai_review-0.35.0/ai_review/resources/pricing.yaml +93 -0
  19. xai_review-0.35.0/ai_review/services/llm/openai/client.py +56 -0
  20. xai_review-0.35.0/ai_review/tests/fixtures/clients/openai.py +141 -0
  21. xai_review-0.35.0/ai_review/tests/suites/clients/openai/v1/test_client.py +12 -0
  22. {xai_review-0.34.0/ai_review/tests/suites/clients/openai → xai_review-0.35.0/ai_review/tests/suites/clients/openai/v1}/test_schema.py +1 -1
  23. xai_review-0.35.0/ai_review/tests/suites/clients/openai/v2/test_client.py +12 -0
  24. xai_review-0.35.0/ai_review/tests/suites/clients/openai/v2/test_schema.py +80 -0
  25. xai_review-0.35.0/ai_review/tests/suites/libs/config/llm/test_openai.py +28 -0
  26. xai_review-0.35.0/ai_review/tests/suites/services/llm/openai/test_client.py +39 -0
  27. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/test_factory.py +1 -1
  28. xai_review-0.35.0/ai_review/tests/suites/services/vcs/__init__.py +0 -0
  29. xai_review-0.35.0/ai_review/tests/suites/services/vcs/bitbucket/__init__.py +0 -0
  30. xai_review-0.35.0/ai_review/tests/suites/services/vcs/gitea/__init__.py +0 -0
  31. xai_review-0.35.0/ai_review/tests/suites/services/vcs/github/__init__.py +0 -0
  32. xai_review-0.35.0/ai_review/tests/suites/services/vcs/gitlab/__init__.py +0 -0
  33. {xai_review-0.34.0 → xai_review-0.35.0}/pyproject.toml +1 -1
  34. {xai_review-0.34.0 → xai_review-0.35.0/xai_review.egg-info}/PKG-INFO +2 -2
  35. {xai_review-0.34.0 → xai_review-0.35.0}/xai_review.egg-info/SOURCES.txt +16 -5
  36. xai_review-0.34.0/ai_review/clients/openai/types.py +0 -8
  37. xai_review-0.34.0/ai_review/libs/config/llm/meta.py +0 -7
  38. xai_review-0.34.0/ai_review/resources/pricing.yaml +0 -55
  39. xai_review-0.34.0/ai_review/services/llm/openai/client.py +0 -28
  40. xai_review-0.34.0/ai_review/tests/fixtures/clients/openai.py +0 -69
  41. xai_review-0.34.0/ai_review/tests/suites/clients/openai/test_client.py +0 -12
  42. xai_review-0.34.0/ai_review/tests/suites/services/llm/openai/test_client.py +0 -22
  43. {xai_review-0.34.0 → xai_review-0.35.0}/LICENSE +0 -0
  44. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/__init__.py +0 -0
  45. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/__init__.py +0 -0
  46. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/__init__.py +0 -0
  47. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/run_context_review.py +0 -0
  48. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/run_inline_reply_review.py +0 -0
  49. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/run_inline_review.py +0 -0
  50. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/run_review.py +0 -0
  51. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/run_summary_reply_review.py +0 -0
  52. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/commands/run_summary_review.py +0 -0
  53. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/cli/main.py +0 -0
  54. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/__init__.py +0 -0
  55. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/__init__.py +0 -0
  56. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/client.py +0 -0
  57. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/__init__.py +0 -0
  58. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/client.py +0 -0
  59. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/__init__.py +0 -0
  60. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/comments.py +0 -0
  61. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/files.py +0 -0
  62. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/pull_request.py +0 -0
  63. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/schema/user.py +0 -0
  64. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/pr/types.py +0 -0
  65. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/bitbucket/tools.py +0 -0
  66. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/claude/__init__.py +0 -0
  67. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/claude/types.py +0 -0
  68. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gemini/__init__.py +0 -0
  69. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gemini/types.py +0 -0
  70. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/__init__.py +0 -0
  71. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/client.py +0 -0
  72. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/__init__.py +0 -0
  73. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/client.py +0 -0
  74. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/__init__.py +0 -0
  75. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/comments.py +0 -0
  76. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/files.py +0 -0
  77. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/pull_request.py +0 -0
  78. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/schema/user.py +0 -0
  79. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/pr/types.py +0 -0
  80. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitea/tools.py +0 -0
  81. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/__init__.py +0 -0
  82. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/client.py +0 -0
  83. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/__init__.py +0 -0
  84. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/client.py +0 -0
  85. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/__init__.py +0 -0
  86. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/comments.py +0 -0
  87. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/files.py +0 -0
  88. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/pull_request.py +0 -0
  89. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/reviews.py +0 -0
  90. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/schema/user.py +0 -0
  91. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/pr/types.py +0 -0
  92. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/github/tools.py +0 -0
  93. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/__init__.py +0 -0
  94. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/client.py +0 -0
  95. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/__init__.py +0 -0
  96. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/client.py +0 -0
  97. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/__init__.py +0 -0
  98. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/changes.py +0 -0
  99. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/discussions.py +0 -0
  100. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/notes.py +0 -0
  101. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/position.py +0 -0
  102. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/schema/user.py +0 -0
  103. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/mr/types.py +0 -0
  104. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/gitlab/tools.py +0 -0
  105. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/ollama/__init__.py +0 -0
  106. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/ollama/schema.py +0 -0
  107. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/ollama/types.py +0 -0
  108. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/openai/__init__.py +0 -0
  109. {xai_review-0.34.0/ai_review/clients/openrouter → xai_review-0.35.0/ai_review/clients/openai/v1}/__init__.py +0 -0
  110. {xai_review-0.34.0/ai_review/libs → xai_review-0.35.0/ai_review/clients/openai/v2}/__init__.py +0 -0
  111. {xai_review-0.34.0/ai_review/libs/asynchronous → xai_review-0.35.0/ai_review/clients/openrouter}/__init__.py +0 -0
  112. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/clients/openrouter/types.py +0 -0
  113. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/config.py +0 -0
  114. {xai_review-0.34.0/ai_review/libs/config → xai_review-0.35.0/ai_review/libs}/__init__.py +0 -0
  115. {xai_review-0.34.0/ai_review/libs/config/llm → xai_review-0.35.0/ai_review/libs/asynchronous}/__init__.py +0 -0
  116. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/asynchronous/gather.py +0 -0
  117. {xai_review-0.34.0/ai_review/libs/config/vcs → xai_review-0.35.0/ai_review/libs/config}/__init__.py +0 -0
  118. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/artifacts.py +0 -0
  119. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/base.py +0 -0
  120. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/core.py +0 -0
  121. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/http.py +0 -0
  122. {xai_review-0.34.0/ai_review/libs/constants → xai_review-0.35.0/ai_review/libs/config/llm}/__init__.py +0 -0
  123. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/llm/base.py +0 -0
  124. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/llm/claude.py +0 -0
  125. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/llm/gemini.py +0 -0
  126. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/llm/ollama.py +0 -0
  127. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/llm/openrouter.py +0 -0
  128. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/logger.py +0 -0
  129. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/prompt.py +0 -0
  130. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/review.py +0 -0
  131. {xai_review-0.34.0/ai_review/libs/diff → xai_review-0.35.0/ai_review/libs/config/vcs}/__init__.py +0 -0
  132. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/base.py +0 -0
  133. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/bitbucket.py +0 -0
  134. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/gitea.py +0 -0
  135. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/github.py +0 -0
  136. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/gitlab.py +0 -0
  137. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/config/vcs/pagination.py +0 -0
  138. {xai_review-0.34.0/ai_review/libs/http → xai_review-0.35.0/ai_review/libs/constants}/__init__.py +0 -0
  139. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/constants/llm_provider.py +0 -0
  140. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/constants/vcs_provider.py +0 -0
  141. {xai_review-0.34.0/ai_review/libs/http/event_hooks → xai_review-0.35.0/ai_review/libs/diff}/__init__.py +0 -0
  142. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/diff/models.py +0 -0
  143. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/diff/parser.py +0 -0
  144. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/diff/tools.py +0 -0
  145. {xai_review-0.34.0/ai_review/libs/http/transports → xai_review-0.35.0/ai_review/libs/http}/__init__.py +0 -0
  146. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/http/client.py +0 -0
  147. {xai_review-0.34.0/ai_review/libs/llm → xai_review-0.35.0/ai_review/libs/http/event_hooks}/__init__.py +0 -0
  148. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/http/event_hooks/base.py +0 -0
  149. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/http/event_hooks/logger.py +0 -0
  150. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/http/handlers.py +0 -0
  151. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/http/paginate.py +0 -0
  152. {xai_review-0.34.0/ai_review/libs/template → xai_review-0.35.0/ai_review/libs/http/transports}/__init__.py +0 -0
  153. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/http/transports/retry.py +0 -0
  154. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/json.py +0 -0
  155. {xai_review-0.34.0/ai_review/prompts → xai_review-0.35.0/ai_review/libs/llm}/__init__.py +0 -0
  156. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/llm/output_json_parser.py +0 -0
  157. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/logger.py +0 -0
  158. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/resources.py +0 -0
  159. {xai_review-0.34.0/ai_review/resources → xai_review-0.35.0/ai_review/libs/template}/__init__.py +0 -0
  160. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/libs/template/render.py +0 -0
  161. {xai_review-0.34.0/ai_review/services → xai_review-0.35.0/ai_review/prompts}/__init__.py +0 -0
  162. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_context.md +0 -0
  163. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_inline.md +0 -0
  164. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_inline_reply.md +0 -0
  165. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_summary.md +0 -0
  166. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_summary_reply.md +0 -0
  167. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_system_context.md +0 -0
  168. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_system_inline.md +0 -0
  169. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_system_inline_reply.md +0 -0
  170. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_system_summary.md +0 -0
  171. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/prompts/default_system_summary_reply.md +0 -0
  172. {xai_review-0.34.0/ai_review/services/artifacts → xai_review-0.35.0/ai_review/resources}/__init__.py +0 -0
  173. {xai_review-0.34.0/ai_review/services/cost → xai_review-0.35.0/ai_review/services}/__init__.py +0 -0
  174. {xai_review-0.34.0/ai_review/services/diff → xai_review-0.35.0/ai_review/services/artifacts}/__init__.py +0 -0
  175. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/artifacts/schema.py +0 -0
  176. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/artifacts/service.py +0 -0
  177. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/artifacts/tools.py +0 -0
  178. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/artifacts/types.py +0 -0
  179. {xai_review-0.34.0/ai_review/services/git → xai_review-0.35.0/ai_review/services/cost}/__init__.py +0 -0
  180. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/cost/schema.py +0 -0
  181. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/cost/service.py +0 -0
  182. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/cost/types.py +0 -0
  183. {xai_review-0.34.0/ai_review/services/llm → xai_review-0.35.0/ai_review/services/diff}/__init__.py +0 -0
  184. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/diff/renderers.py +0 -0
  185. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/diff/schema.py +0 -0
  186. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/diff/service.py +0 -0
  187. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/diff/tools.py +0 -0
  188. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/diff/types.py +0 -0
  189. {xai_review-0.34.0/ai_review/services/llm/claude → xai_review-0.35.0/ai_review/services/git}/__init__.py +0 -0
  190. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/git/service.py +0 -0
  191. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/git/types.py +0 -0
  192. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/hook/__init__.py +0 -0
  193. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/hook/constants.py +0 -0
  194. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/hook/service.py +0 -0
  195. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/hook/types.py +0 -0
  196. {xai_review-0.34.0/ai_review/services/llm/gemini → xai_review-0.35.0/ai_review/services/llm}/__init__.py +0 -0
  197. {xai_review-0.34.0/ai_review/services/llm/ollama → xai_review-0.35.0/ai_review/services/llm/claude}/__init__.py +0 -0
  198. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/llm/claude/client.py +0 -0
  199. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/llm/factory.py +0 -0
  200. {xai_review-0.34.0/ai_review/services/llm/openai → xai_review-0.35.0/ai_review/services/llm/gemini}/__init__.py +0 -0
  201. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/llm/gemini/client.py +0 -0
  202. {xai_review-0.34.0/ai_review/services/llm/openrouter → xai_review-0.35.0/ai_review/services/llm/ollama}/__init__.py +0 -0
  203. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/llm/ollama/client.py +0 -0
  204. {xai_review-0.34.0/ai_review/services/prompt → xai_review-0.35.0/ai_review/services/llm/openai}/__init__.py +0 -0
  205. {xai_review-0.34.0/ai_review/services/review → xai_review-0.35.0/ai_review/services/llm/openrouter}/__init__.py +0 -0
  206. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/llm/openrouter/client.py +0 -0
  207. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/llm/types.py +0 -0
  208. {xai_review-0.34.0/ai_review/services/review/gateway → xai_review-0.35.0/ai_review/services/prompt}/__init__.py +0 -0
  209. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/prompt/adapter.py +0 -0
  210. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/prompt/schema.py +0 -0
  211. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/prompt/service.py +0 -0
  212. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/prompt/tools.py +0 -0
  213. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/prompt/types.py +0 -0
  214. {xai_review-0.34.0/ai_review/services/review/internal → xai_review-0.35.0/ai_review/services/review}/__init__.py +0 -0
  215. {xai_review-0.34.0/ai_review/services/review/internal/inline → xai_review-0.35.0/ai_review/services/review/gateway}/__init__.py +0 -0
  216. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/gateway/review_comment_gateway.py +0 -0
  217. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/gateway/review_dry_run_comment_gateway.py +0 -0
  218. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/gateway/review_llm_gateway.py +0 -0
  219. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/gateway/types.py +0 -0
  220. {xai_review-0.34.0/ai_review/services/review/internal/inline_reply → xai_review-0.35.0/ai_review/services/review/internal}/__init__.py +0 -0
  221. {xai_review-0.34.0/ai_review/services/review/internal/policy → xai_review-0.35.0/ai_review/services/review/internal/inline}/__init__.py +0 -0
  222. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline/schema.py +0 -0
  223. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline/service.py +0 -0
  224. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline/types.py +0 -0
  225. {xai_review-0.34.0/ai_review/services/review/internal/summary → xai_review-0.35.0/ai_review/services/review/internal/inline_reply}/__init__.py +0 -0
  226. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline_reply/schema.py +0 -0
  227. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline_reply/service.py +0 -0
  228. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/inline_reply/types.py +0 -0
  229. {xai_review-0.34.0/ai_review/services/review/internal/summary_reply → xai_review-0.35.0/ai_review/services/review/internal/policy}/__init__.py +0 -0
  230. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/policy/service.py +0 -0
  231. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/policy/types.py +0 -0
  232. {xai_review-0.34.0/ai_review/services/review/runner → xai_review-0.35.0/ai_review/services/review/internal/summary}/__init__.py +0 -0
  233. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary/schema.py +0 -0
  234. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary/service.py +0 -0
  235. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary/types.py +0 -0
  236. {xai_review-0.34.0/ai_review/services/vcs → xai_review-0.35.0/ai_review/services/review/internal/summary_reply}/__init__.py +0 -0
  237. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary_reply/schema.py +0 -0
  238. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary_reply/service.py +0 -0
  239. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/internal/summary_reply/types.py +0 -0
  240. {xai_review-0.34.0/ai_review/services/vcs/bitbucket → xai_review-0.35.0/ai_review/services/review/runner}/__init__.py +0 -0
  241. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/runner/context.py +0 -0
  242. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/runner/inline.py +0 -0
  243. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/runner/inline_reply.py +0 -0
  244. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/runner/summary.py +0 -0
  245. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/runner/summary_reply.py +0 -0
  246. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/runner/types.py +0 -0
  247. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/review/service.py +0 -0
  248. {xai_review-0.34.0/ai_review/services/vcs/gitea → xai_review-0.35.0/ai_review/services/vcs}/__init__.py +0 -0
  249. {xai_review-0.34.0/ai_review/services/vcs/github → xai_review-0.35.0/ai_review/services/vcs/bitbucket}/__init__.py +0 -0
  250. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/bitbucket/adapter.py +0 -0
  251. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/bitbucket/client.py +0 -0
  252. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/factory.py +0 -0
  253. {xai_review-0.34.0/ai_review/services/vcs/gitlab → xai_review-0.35.0/ai_review/services/vcs/gitea}/__init__.py +0 -0
  254. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/gitea/adapter.py +0 -0
  255. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/gitea/client.py +0 -0
  256. {xai_review-0.34.0/ai_review/tests → xai_review-0.35.0/ai_review/services/vcs/github}/__init__.py +0 -0
  257. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/github/adapter.py +0 -0
  258. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/github/client.py +0 -0
  259. {xai_review-0.34.0/ai_review/tests/fixtures → xai_review-0.35.0/ai_review/services/vcs/gitlab}/__init__.py +0 -0
  260. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/gitlab/adapter.py +0 -0
  261. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/gitlab/client.py +0 -0
  262. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/services/vcs/types.py +0 -0
  263. {xai_review-0.34.0/ai_review/tests/fixtures/clients → xai_review-0.35.0/ai_review/tests}/__init__.py +0 -0
  264. {xai_review-0.34.0/ai_review/tests/fixtures/libs → xai_review-0.35.0/ai_review/tests/fixtures}/__init__.py +0 -0
  265. {xai_review-0.34.0/ai_review/tests/fixtures/libs/llm → xai_review-0.35.0/ai_review/tests/fixtures/clients}/__init__.py +0 -0
  266. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/bitbucket.py +0 -0
  267. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/claude.py +0 -0
  268. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/gemini.py +0 -0
  269. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/gitea.py +0 -0
  270. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/github.py +0 -0
  271. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/gitlab.py +0 -0
  272. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/ollama.py +0 -0
  273. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/clients/openrouter.py +0 -0
  274. {xai_review-0.34.0/ai_review/tests/fixtures/services → xai_review-0.35.0/ai_review/tests/fixtures/libs}/__init__.py +0 -0
  275. {xai_review-0.34.0/ai_review/tests/fixtures/services/review → xai_review-0.35.0/ai_review/tests/fixtures/libs/llm}/__init__.py +0 -0
  276. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/libs/llm/output_json_parser.py +0 -0
  277. {xai_review-0.34.0/ai_review/tests/fixtures/services/review/gateway → xai_review-0.35.0/ai_review/tests/fixtures/services}/__init__.py +0 -0
  278. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/artifacts.py +0 -0
  279. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/cost.py +0 -0
  280. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/diff.py +0 -0
  281. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/git.py +0 -0
  282. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/hook.py +0 -0
  283. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/llm.py +0 -0
  284. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/prompt.py +0 -0
  285. {xai_review-0.34.0/ai_review/tests/fixtures/services/review/internal → xai_review-0.35.0/ai_review/tests/fixtures/services/review}/__init__.py +0 -0
  286. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/base.py +0 -0
  287. {xai_review-0.34.0/ai_review/tests/fixtures/services/review/runner → xai_review-0.35.0/ai_review/tests/fixtures/services/review/gateway}/__init__.py +0 -0
  288. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/gateway/review_comment_gateway.py +0 -0
  289. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/gateway/review_dry_run_comment_gateway.py +0 -0
  290. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/gateway/review_llm_gateway.py +0 -0
  291. {xai_review-0.34.0/ai_review/tests/suites → xai_review-0.35.0/ai_review/tests/fixtures/services/review/internal}/__init__.py +0 -0
  292. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/inline.py +0 -0
  293. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/inline_reply.py +0 -0
  294. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/policy.py +0 -0
  295. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/summary.py +0 -0
  296. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/internal/summary_reply.py +0 -0
  297. {xai_review-0.34.0/ai_review/tests/suites/cli → xai_review-0.35.0/ai_review/tests/fixtures/services/review/runner}/__init__.py +0 -0
  298. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/context.py +0 -0
  299. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/inline.py +0 -0
  300. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/inline_reply.py +0 -0
  301. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/summary.py +0 -0
  302. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/review/runner/summary_reply.py +0 -0
  303. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/fixtures/services/vcs.py +0 -0
  304. {xai_review-0.34.0/ai_review/tests/suites/clients → xai_review-0.35.0/ai_review/tests/suites}/__init__.py +0 -0
  305. {xai_review-0.34.0/ai_review/tests/suites/clients/bitbucket → xai_review-0.35.0/ai_review/tests/suites/cli}/__init__.py +0 -0
  306. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/cli/test_main.py +0 -0
  307. {xai_review-0.34.0/ai_review/tests/suites/clients/claude → xai_review-0.35.0/ai_review/tests/suites/clients}/__init__.py +0 -0
  308. {xai_review-0.34.0/ai_review/tests/suites/clients/gemini → xai_review-0.35.0/ai_review/tests/suites/clients/bitbucket}/__init__.py +0 -0
  309. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/bitbucket/test_client.py +0 -0
  310. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/bitbucket/test_tools.py +0 -0
  311. {xai_review-0.34.0/ai_review/tests/suites/clients/gitea → xai_review-0.35.0/ai_review/tests/suites/clients/claude}/__init__.py +0 -0
  312. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/claude/test_client.py +0 -0
  313. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/claude/test_schema.py +0 -0
  314. {xai_review-0.34.0/ai_review/tests/suites/clients/github → xai_review-0.35.0/ai_review/tests/suites/clients/gemini}/__init__.py +0 -0
  315. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gemini/test_client.py +0 -0
  316. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gemini/test_schema.py +0 -0
  317. {xai_review-0.34.0/ai_review/tests/suites/clients/gitlab → xai_review-0.35.0/ai_review/tests/suites/clients/gitea}/__init__.py +0 -0
  318. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitea/test_client.py +0 -0
  319. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitea/test_tools.py +0 -0
  320. {xai_review-0.34.0/ai_review/tests/suites/clients/ollama → xai_review-0.35.0/ai_review/tests/suites/clients/github}/__init__.py +0 -0
  321. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/github/test_client.py +0 -0
  322. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/github/test_tools.py +0 -0
  323. {xai_review-0.34.0/ai_review/tests/suites/clients/openai → xai_review-0.35.0/ai_review/tests/suites/clients/gitlab}/__init__.py +0 -0
  324. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitlab/test_client.py +0 -0
  325. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/gitlab/test_tools.py +0 -0
  326. {xai_review-0.34.0/ai_review/tests/suites/clients/openrouter → xai_review-0.35.0/ai_review/tests/suites/clients/ollama}/__init__.py +0 -0
  327. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/ollama/test_client.py +0 -0
  328. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/ollama/test_schema.py +0 -0
  329. {xai_review-0.34.0/ai_review/tests/suites/libs → xai_review-0.35.0/ai_review/tests/suites/clients/openai}/__init__.py +0 -0
  330. {xai_review-0.34.0/ai_review/tests/suites/libs/asynchronous → xai_review-0.35.0/ai_review/tests/suites/clients/openai/v1}/__init__.py +0 -0
  331. {xai_review-0.34.0/ai_review/tests/suites/libs/config → xai_review-0.35.0/ai_review/tests/suites/clients/openai/v2}/__init__.py +0 -0
  332. {xai_review-0.34.0/ai_review/tests/suites/libs/diff → xai_review-0.35.0/ai_review/tests/suites/clients/openrouter}/__init__.py +0 -0
  333. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/openrouter/test_client.py +0 -0
  334. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/clients/openrouter/test_schema.py +0 -0
  335. {xai_review-0.34.0/ai_review/tests/suites/libs/http → xai_review-0.35.0/ai_review/tests/suites/libs}/__init__.py +0 -0
  336. {xai_review-0.34.0/ai_review/tests/suites/libs/llm → xai_review-0.35.0/ai_review/tests/suites/libs/asynchronous}/__init__.py +0 -0
  337. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/asynchronous/test_gather.py +0 -0
  338. {xai_review-0.34.0/ai_review/tests/suites/libs/template → xai_review-0.35.0/ai_review/tests/suites/libs/config}/__init__.py +0 -0
  339. {xai_review-0.34.0/ai_review/tests/suites/services → xai_review-0.35.0/ai_review/tests/suites/libs/config/llm}/__init__.py +0 -0
  340. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/config/test_prompt.py +0 -0
  341. {xai_review-0.34.0/ai_review/tests/suites/services/artifacts → xai_review-0.35.0/ai_review/tests/suites/libs/diff}/__init__.py +0 -0
  342. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/diff/test_models.py +0 -0
  343. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/diff/test_parser.py +0 -0
  344. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/diff/test_tools.py +0 -0
  345. {xai_review-0.34.0/ai_review/tests/suites/services/cost → xai_review-0.35.0/ai_review/tests/suites/libs/http}/__init__.py +0 -0
  346. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/http/test_paginate.py +0 -0
  347. {xai_review-0.34.0/ai_review/tests/suites/services/diff → xai_review-0.35.0/ai_review/tests/suites/libs/llm}/__init__.py +0 -0
  348. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/llm/test_output_json_parser.py +0 -0
  349. {xai_review-0.34.0/ai_review/tests/suites/services/hook → xai_review-0.35.0/ai_review/tests/suites/libs/template}/__init__.py +0 -0
  350. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/template/test_render.py +0 -0
  351. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/libs/test_json.py +0 -0
  352. {xai_review-0.34.0/ai_review/tests/suites/services/llm → xai_review-0.35.0/ai_review/tests/suites/services}/__init__.py +0 -0
  353. {xai_review-0.34.0/ai_review/tests/suites/services/llm/claude → xai_review-0.35.0/ai_review/tests/suites/services/artifacts}/__init__.py +0 -0
  354. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/artifacts/test_service.py +0 -0
  355. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/artifacts/test_tools.py +0 -0
  356. {xai_review-0.34.0/ai_review/tests/suites/services/llm/gemini → xai_review-0.35.0/ai_review/tests/suites/services/cost}/__init__.py +0 -0
  357. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/cost/test_schema.py +0 -0
  358. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/cost/test_service.py +0 -0
  359. {xai_review-0.34.0/ai_review/tests/suites/services/llm/ollama → xai_review-0.35.0/ai_review/tests/suites/services/diff}/__init__.py +0 -0
  360. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/diff/test_renderers.py +0 -0
  361. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/diff/test_service.py +0 -0
  362. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/diff/test_tools.py +0 -0
  363. {xai_review-0.34.0/ai_review/tests/suites/services/llm/openai → xai_review-0.35.0/ai_review/tests/suites/services/hook}/__init__.py +0 -0
  364. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/hook/test_service.py +0 -0
  365. {xai_review-0.34.0/ai_review/tests/suites/services/llm/openrouter → xai_review-0.35.0/ai_review/tests/suites/services/llm}/__init__.py +0 -0
  366. {xai_review-0.34.0/ai_review/tests/suites/services/prompt → xai_review-0.35.0/ai_review/tests/suites/services/llm/claude}/__init__.py +0 -0
  367. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/claude/test_client.py +0 -0
  368. {xai_review-0.34.0/ai_review/tests/suites/services/review → xai_review-0.35.0/ai_review/tests/suites/services/llm/gemini}/__init__.py +0 -0
  369. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/gemini/test_client.py +0 -0
  370. {xai_review-0.34.0/ai_review/tests/suites/services/review/gateway → xai_review-0.35.0/ai_review/tests/suites/services/llm/ollama}/__init__.py +0 -0
  371. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/ollama/test_client.py +0 -0
  372. {xai_review-0.34.0/ai_review/tests/suites/services/review/internal → xai_review-0.35.0/ai_review/tests/suites/services/llm/openai}/__init__.py +0 -0
  373. {xai_review-0.34.0/ai_review/tests/suites/services/review/internal/inline → xai_review-0.35.0/ai_review/tests/suites/services/llm/openrouter}/__init__.py +0 -0
  374. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/llm/openrouter/test_client.py +0 -0
  375. {xai_review-0.34.0/ai_review/tests/suites/services/review/internal/inline_reply → xai_review-0.35.0/ai_review/tests/suites/services/prompt}/__init__.py +0 -0
  376. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_adapter.py +0 -0
  377. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_schema.py +0 -0
  378. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_service.py +0 -0
  379. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/prompt/test_tools.py +0 -0
  380. {xai_review-0.34.0/ai_review/tests/suites/services/review/internal/policy → xai_review-0.35.0/ai_review/tests/suites/services/review}/__init__.py +0 -0
  381. {xai_review-0.34.0/ai_review/tests/suites/services/review/internal/summary → xai_review-0.35.0/ai_review/tests/suites/services/review/gateway}/__init__.py +0 -0
  382. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/gateway/test_review_comment_gateway.py +0 -0
  383. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/gateway/test_review_dry_run_comment_gateway.py +0 -0
  384. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/gateway/test_review_llm_gateway.py +0 -0
  385. {xai_review-0.34.0/ai_review/tests/suites/services/review/internal/summary_reply → xai_review-0.35.0/ai_review/tests/suites/services/review/internal}/__init__.py +0 -0
  386. {xai_review-0.34.0/ai_review/tests/suites/services/review/runner → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/inline}/__init__.py +0 -0
  387. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline/test_schema.py +0 -0
  388. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline/test_service.py +0 -0
  389. {xai_review-0.34.0/ai_review/tests/suites/services/vcs → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/inline_reply}/__init__.py +0 -0
  390. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline_reply/test_schema.py +0 -0
  391. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/inline_reply/test_service.py +0 -0
  392. {xai_review-0.34.0/ai_review/tests/suites/services/vcs/bitbucket → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/policy}/__init__.py +0 -0
  393. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/policy/test_service.py +0 -0
  394. {xai_review-0.34.0/ai_review/tests/suites/services/vcs/gitea → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/summary}/__init__.py +0 -0
  395. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary/test_schema.py +0 -0
  396. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary/test_service.py +0 -0
  397. {xai_review-0.34.0/ai_review/tests/suites/services/vcs/github → xai_review-0.35.0/ai_review/tests/suites/services/review/internal/summary_reply}/__init__.py +0 -0
  398. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary_reply/test_schema.py +0 -0
  399. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/internal/summary_reply/test_service.py +0 -0
  400. {xai_review-0.34.0/ai_review/tests/suites/services/vcs/gitlab → xai_review-0.35.0/ai_review/tests/suites/services/review/runner}/__init__.py +0 -0
  401. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_context.py +0 -0
  402. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_inline.py +0 -0
  403. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_inline_reply.py +0 -0
  404. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_summary.py +0 -0
  405. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/runner/test_summary_reply.py +0 -0
  406. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/review/test_service.py +0 -0
  407. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/bitbucket/test_adapter.py +0 -0
  408. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/bitbucket/test_client.py +0 -0
  409. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitea/test_adapter.py +0 -0
  410. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitea/test_client.py +0 -0
  411. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/github/test_adapter.py +0 -0
  412. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/github/test_client.py +0 -0
  413. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitlab/test_adapter.py +0 -0
  414. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/gitlab/test_client.py +0 -0
  415. {xai_review-0.34.0 → xai_review-0.35.0}/ai_review/tests/suites/services/vcs/test_factory.py +0 -0
  416. {xai_review-0.34.0 → xai_review-0.35.0}/setup.cfg +0 -0
  417. {xai_review-0.34.0 → xai_review-0.35.0}/xai_review.egg-info/dependency_links.txt +0 -0
  418. {xai_review-0.34.0 → xai_review-0.35.0}/xai_review.egg-info/entry_points.txt +0 -0
  419. {xai_review-0.34.0 → xai_review-0.35.0}/xai_review.egg-info/requires.txt +0 -0
  420. {xai_review-0.34.0 → xai_review-0.35.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.34.0
3
+ Version: 0.35.0
4
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>
@@ -221,7 +221,7 @@ jobs:
221
221
  with:
222
222
  fetch-depth: 0
223
223
 
224
- - uses: Nikita-Filonov/ai-review@v0.34.0
224
+ - uses: Nikita-Filonov/ai-review@v0.35.0
225
225
  with:
226
226
  review-command: ${{ inputs.review-command }}
227
227
  env:
@@ -187,7 +187,7 @@ jobs:
187
187
  with:
188
188
  fetch-depth: 0
189
189
 
190
- - uses: Nikita-Filonov/ai-review@v0.34.0
190
+ - uses: Nikita-Filonov/ai-review@v0.35.0
191
191
  with:
192
192
  review-command: ${{ inputs.review-command }}
193
193
  env:
@@ -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", json=request.model_dump()
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 OpenAIHTTPClientProtocol
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 OpenAIHTTPClientError(HTTPClientError):
13
+ class OpenAIV1HTTPClientError(HTTPClientError):
14
14
  pass
15
15
 
16
16
 
17
- class OpenAIHTTPClient(HTTPClient, OpenAIHTTPClientProtocol):
18
- @handle_http_error(client='OpenAIHTTPClient', exception=OpenAIHTTPClientError)
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 get_openai_http_client() -> OpenAIHTTPClient:
28
- logger = get_logger("OPENAI_HTTP_CLIENT")
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 OpenAIHTTPClient(client=client)
43
+ return OpenAIV1HTTPClient(client=client)
@@ -21,7 +21,7 @@ class OpenAIChoiceSchema(BaseModel):
21
21
  class OpenAIChatRequestSchema(BaseModel):
22
22
  model: str
23
23
  messages: list[OpenAIMessageSchema]
24
- max_tokens: int
24
+ max_tokens: int | None = None
25
25
  temperature: float
26
26
 
27
27
 
@@ -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
+ ...
@@ -17,7 +17,7 @@ class OpenRouterHTTPClientError(HTTPClientError):
17
17
  class OpenRouterHTTPClient(HTTPClient, OpenRouterHTTPClientProtocol):
18
18
  @handle_http_error(client="OpenRouterHTTPClient", exception=OpenRouterHTTPClientError)
19
19
  async def chat_api(self, request: OpenRouterChatRequestSchema) -> 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: OpenRouterChatRequestSchema) -> OpenRouterChatResponseSchema:
23
23
  response = await self.chat_api(request)
@@ -21,8 +21,8 @@ class OpenRouterChoiceSchema(BaseModel):
21
21
  class OpenRouterChatRequestSchema(BaseModel):
22
22
  model: str
23
23
  messages: list[OpenRouterMessageSchema]
24
- max_tokens: int
25
- temperature: float
24
+ max_tokens: int | None = None
25
+ temperature: float | None = None
26
26
 
27
27
 
28
28
  class OpenRouterChatResponseSchema(BaseModel):
@@ -0,0 +1,7 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ class LLMMetaConfig(BaseModel):
5
+ model: str
6
+ max_tokens: int | None = Field(default=None, ge=1)
7
+ temperature: float | None = Field(default=None, ge=0.0, le=2.0)
@@ -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,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
@@ -0,0 +1,56 @@
1
+ from ai_review.clients.openai.v1.client import get_openai_v1_http_client
2
+ from ai_review.clients.openai.v1.schema import OpenAIChatRequestSchema, OpenAIMessageSchema
3
+ from ai_review.clients.openai.v2.client import get_openai_v2_http_client
4
+ from ai_review.clients.openai.v2.schema import OpenAIInputMessageSchema, OpenAIResponsesRequestSchema
5
+ from ai_review.config import settings
6
+ from ai_review.services.llm.types import LLMClientProtocol, ChatResultSchema
7
+
8
+
9
+ class OpenAILLMClient(LLMClientProtocol):
10
+ def __init__(self):
11
+ self.meta = settings.llm.meta
12
+
13
+ self.http_client_v1 = get_openai_v1_http_client()
14
+ self.http_client_v2 = get_openai_v2_http_client()
15
+
16
+ async def chat_v1(self, prompt: str, prompt_system: str) -> ChatResultSchema:
17
+ request = OpenAIChatRequestSchema(
18
+ model=self.meta.model,
19
+ messages=[
20
+ OpenAIMessageSchema(role="system", content=prompt_system),
21
+ OpenAIMessageSchema(role="user", content=prompt),
22
+ ],
23
+ max_tokens=self.meta.max_tokens,
24
+ temperature=self.meta.temperature,
25
+ )
26
+ response = await self.http_client_v1.chat(request)
27
+ return ChatResultSchema(
28
+ text=response.first_text,
29
+ total_tokens=response.usage.total_tokens,
30
+ prompt_tokens=response.usage.prompt_tokens,
31
+ completion_tokens=response.usage.completion_tokens,
32
+ )
33
+
34
+ async def chat_v2(self, prompt: str, prompt_system: str) -> ChatResultSchema:
35
+ request = OpenAIResponsesRequestSchema(
36
+ model=self.meta.model,
37
+ input=[
38
+ OpenAIInputMessageSchema(role="system", content=prompt_system),
39
+ OpenAIInputMessageSchema(role="user", content=prompt),
40
+ ],
41
+ temperature=self.meta.temperature,
42
+ max_output_tokens=self.meta.max_tokens,
43
+ )
44
+ response = await self.http_client_v2.chat(request)
45
+ return ChatResultSchema(
46
+ text=response.first_text,
47
+ total_tokens=response.usage.total_tokens,
48
+ prompt_tokens=response.usage.input_tokens,
49
+ completion_tokens=response.usage.output_tokens,
50
+ )
51
+
52
+ async def chat(self, prompt: str, prompt_system: str) -> ChatResultSchema:
53
+ if self.meta.is_v2_model:
54
+ return await self.chat_v2(prompt, prompt_system)
55
+
56
+ return await self.chat_v1(prompt, prompt_system)
@@ -0,0 +1,141 @@
1
+ from typing import Any
2
+
3
+ import pytest
4
+ from pydantic import HttpUrl, SecretStr
5
+
6
+ from ai_review.clients.openai.v1.schema import (
7
+ OpenAIUsageSchema,
8
+ OpenAIChoiceSchema,
9
+ OpenAIMessageSchema,
10
+ OpenAIChatRequestSchema,
11
+ OpenAIChatResponseSchema,
12
+ )
13
+ from ai_review.clients.openai.v1.types import OpenAIV1HTTPClientProtocol
14
+ from ai_review.clients.openai.v2.schema import (
15
+ OpenAIResponsesRequestSchema,
16
+ OpenAIResponsesResponseSchema,
17
+ OpenAIResponseUsageSchema,
18
+ OpenAIResponseOutputSchema,
19
+ OpenAIResponseContentSchema,
20
+ )
21
+ from ai_review.clients.openai.v2.types import OpenAIV2HTTPClientProtocol
22
+ from ai_review.config import settings
23
+ from ai_review.libs.config.llm.base import OpenAILLMConfig
24
+ from ai_review.libs.config.llm.openai import OpenAIMetaConfig, OpenAIHTTPClientConfig
25
+ from ai_review.libs.constants.llm_provider import LLMProvider
26
+ from ai_review.services.llm.openai.client import OpenAILLMClient
27
+
28
+
29
+ class FakeOpenAIV1HTTPClient(OpenAIV1HTTPClientProtocol):
30
+ def __init__(self, responses: dict[str, Any] | None = None) -> None:
31
+ self.calls: list[tuple[str, dict]] = []
32
+ self.responses = responses or {}
33
+
34
+ async def chat(self, request: OpenAIChatRequestSchema) -> OpenAIChatResponseSchema:
35
+ self.calls.append(("chat", {"request": request}))
36
+ return self.responses.get(
37
+ "chat",
38
+ OpenAIChatResponseSchema(
39
+ usage=OpenAIUsageSchema(total_tokens=12, prompt_tokens=5, completion_tokens=7),
40
+ choices=[
41
+ OpenAIChoiceSchema(
42
+ message=OpenAIMessageSchema(
43
+ role="assistant",
44
+ content="FAKE_OPENAI_V1_RESPONSE"
45
+ )
46
+ )
47
+ ],
48
+ ),
49
+ )
50
+
51
+
52
+ class FakeOpenAIV2HTTPClient(OpenAIV2HTTPClientProtocol):
53
+ def __init__(self, responses: dict[str, Any] | None = None) -> None:
54
+ self.calls: list[tuple[str, dict]] = []
55
+ self.responses = responses or {}
56
+
57
+ async def chat(self, request: OpenAIResponsesRequestSchema) -> OpenAIResponsesResponseSchema:
58
+ self.calls.append(("chat", {"request": request}))
59
+ return self.responses.get(
60
+ "chat",
61
+ OpenAIResponsesResponseSchema(
62
+ usage=OpenAIResponseUsageSchema(
63
+ total_tokens=20, input_tokens=10, output_tokens=10
64
+ ),
65
+ output=[
66
+ OpenAIResponseOutputSchema(
67
+ type="message",
68
+ role="assistant",
69
+ content=[
70
+ OpenAIResponseContentSchema(
71
+ type="output_text",
72
+ text="FAKE_OPENAI_V2_RESPONSE"
73
+ )
74
+ ],
75
+ )
76
+ ],
77
+ ),
78
+ )
79
+
80
+
81
+ @pytest.fixture
82
+ def fake_openai_v1_http_client() -> FakeOpenAIV1HTTPClient:
83
+ return FakeOpenAIV1HTTPClient()
84
+
85
+
86
+ @pytest.fixture
87
+ def fake_openai_v2_http_client() -> FakeOpenAIV2HTTPClient:
88
+ return FakeOpenAIV2HTTPClient()
89
+
90
+
91
+ @pytest.fixture
92
+ def openai_llm_client(
93
+ monkeypatch: pytest.MonkeyPatch,
94
+ fake_openai_v1_http_client: FakeOpenAIV1HTTPClient,
95
+ fake_openai_v2_http_client: FakeOpenAIV2HTTPClient,
96
+ ) -> OpenAILLMClient:
97
+ monkeypatch.setattr(
98
+ "ai_review.services.llm.openai.client.get_openai_v1_http_client",
99
+ lambda: fake_openai_v1_http_client,
100
+ )
101
+ monkeypatch.setattr(
102
+ "ai_review.services.llm.openai.client.get_openai_v2_http_client",
103
+ lambda: fake_openai_v2_http_client,
104
+ )
105
+ return OpenAILLMClient()
106
+
107
+
108
+ @pytest.fixture
109
+ def openai_v1_http_client_config(monkeypatch: pytest.MonkeyPatch):
110
+ fake_config = OpenAILLMConfig(
111
+ meta=OpenAIMetaConfig(
112
+ model="gpt-4o-mini",
113
+ max_tokens=1200,
114
+ temperature=0.3
115
+ ),
116
+ provider=LLMProvider.OPENAI,
117
+ http_client=OpenAIHTTPClientConfig(
118
+ timeout=10,
119
+ api_url=HttpUrl("https://api.openai.com/v1"),
120
+ api_token=SecretStr("fake-token"),
121
+ ),
122
+ )
123
+ monkeypatch.setattr(settings, "llm", fake_config)
124
+
125
+
126
+ @pytest.fixture
127
+ def openai_v2_http_client_config(monkeypatch: pytest.MonkeyPatch):
128
+ fake_config = OpenAILLMConfig(
129
+ meta=OpenAIMetaConfig(
130
+ model="gpt-5",
131
+ max_tokens=2000,
132
+ temperature=0.2
133
+ ),
134
+ provider=LLMProvider.OPENAI,
135
+ http_client=OpenAIHTTPClientConfig(
136
+ timeout=10,
137
+ api_url=HttpUrl("https://api.openai.com/v1"),
138
+ api_token=SecretStr("fake-token"),
139
+ ),
140
+ )
141
+ monkeypatch.setattr(settings, "llm", fake_config)
@@ -0,0 +1,12 @@
1
+ import pytest
2
+ from httpx import AsyncClient
3
+
4
+ from ai_review.clients.openai.v1.client import get_openai_v1_http_client, OpenAIV1HTTPClient
5
+
6
+
7
+ @pytest.mark.usefixtures('openai_v1_http_client_config')
8
+ def test_get_openai_v1_http_client_builds_ok():
9
+ openai_http_client = get_openai_v1_http_client()
10
+
11
+ assert isinstance(openai_http_client, OpenAIV1HTTPClient)
12
+ assert isinstance(openai_http_client.client, AsyncClient)
@@ -1,4 +1,4 @@
1
- from ai_review.clients.openai.schema import (
1
+ from ai_review.clients.openai.v1.schema import (
2
2
  OpenAIUsageSchema,
3
3
  OpenAIMessageSchema,
4
4
  OpenAIChoiceSchema,
@@ -0,0 +1,12 @@
1
+ import pytest
2
+ from httpx import AsyncClient
3
+
4
+ from ai_review.clients.openai.v2.client import get_openai_v2_http_client, OpenAIV2HTTPClient
5
+
6
+
7
+ @pytest.mark.usefixtures('openai_v2_http_client_config')
8
+ def test_get_openai_v2_http_client_builds_ok():
9
+ openai_http_client = get_openai_v2_http_client()
10
+
11
+ assert isinstance(openai_http_client, OpenAIV2HTTPClient)
12
+ assert isinstance(openai_http_client.client, AsyncClient)